Ответы пользователя по тегу TeleBot
  • Как сделать чтобы извлекался user_id пользователя, а не бота?

    Vindicar
    @Vindicar
    RTFM!
    Читаем доки telebot.
    https://docs.python-telegram-bot.org/en/stable/tel...
    message (telegram.MaybeInaccessibleMessage, optional) - Message sent by the bot with the callback button that originated the query

    Выделение моё. Теперь понятно, почему ты получаешь id самого бота?
    А если чуть выше глянуть, там ещё интереснее.
    from_user (telegram.User) – Sender.


    Привыкай находить и читать документацию, там много интересного.
    Ответ написан
    1 комментарий
  • Бот на python/telebot не приветствует новых пользователей, что не так?

    Vindicar
    @Vindicar
    RTFM!
    А почему ты вызываешь bot.polling()? Это для асинхронных ботов, а твой синхронный. Используй infinity_polling().
    Вообще, читай официальные примеры, вроде вот этого, и сравнивай со своим кодом.
    Ответ написан
  • Как сделать так, чтобы бот, написанный на модуле telebot, включал у пользователя режим ответа на cообщение?

    Vindicar
    @Vindicar
    RTFM!
    А доки на телебот читать пробовал? Нет? Ну так попробуй, там много интересного.

    send_message(...)
    reply_markup (telebot.types.InlineKeyboardMarkup or telebot.types.ReplyKeyboardMarkup or telebot.types.ReplyKeyboardRemove or telebot.types.ForceReply) – Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user.

    Выделение моё.
    Т.е. вместо клавиатуры передаёшь специальный объект. А дальше тыкаешь по ссылке ForceReply и смотришь что это за объект и как его сконструировать.
    Ответ написан
  • Бот перестает работать после определенного блока, как исправить?

    Vindicar
    @Vindicar
    RTFM!
    Ну так ты не озаботился изучением работы инлайн-кнопок, вот и результат.
    У тебя две функции отмечены декоратором
    @bot.callback_query_handler(func=lambda call: True)

    Эта проблема встречается регулярно, и на этом сайте уже есть несколько вопросов по ней.
    Вот один из них, с моим ответом.
    Ответ написан
    Комментировать
  • Как заставить бота ждать ответа пользователя?

    Vindicar
    @Vindicar
    RTFM!
    Ну для начала твоя лесенка из if-elif-elif-... - плохое решение.
    Сделай нормальную структуру данных вместо пачки переменных. Используй словарь, или ещё что. Например, такого вида:
    # словарь, где ключ - строка с названием пунка отправления, а значение - ещё словарь,
    #   где ключ - строка с названием пункта назначения, а значение - список,
    #     где элементы - пары строк ("время отправления", "время прибытия")
    # Тогда с таким словарём можно будет работать так:
    bus_timetable: dict[str, dict[str, list[tuple[str, str]]]] = {
        # ты словарь заполняешь по результатам парсинга, ну и то хорошо
        # я для примера запишу прямо так
        'Владимир' : {
            'Муром': [
                ('8:00', '11:00'),
                ('9:00', '12:00'),
                ('10:00', '13:00'),
            ],
        },
    }
    point_from = 'Владимир'
    point_to = 'Муром'
    # для примера вывожу в консоль, для бота перепишешь сам
    print(f'Автобус из {point_from} в {point_to}')  
    for departure, arrival in bus_timetable[point_from][point_to]:
        print(f'Отходит в {departure}, прибывает в {arrival}')

    Тогда тебе не потребуется делать кучу веток для разных городов, достаточно лишь определить значения point_from и point_to. Более того, ты можешь просто перечислить ключи внешнего словаря при создании кнопок:
    kbd_from = types.ReplyKeyboardMarkup(resize_keyboard=True)
    buttons = [types.KeyboardButton(point_from) for point_from in bus_timetable]  # список кнопок
    kbd_from.add(*buttons)  # если надо добавить все кнопки сразу

    Похожий приём возможен и для определения кнопок для городов назначения.

    А теперь по тому, как сделать выбор. Тут есть два варианта, но давай пока поговорим о ReplyKeyboardMarkup, которую ты используешь.
    Если ты хочешь использовать ReplyKeyboardMarkup, то стоит помнить - её кнопки дают тот же эффект, как если бы пользователь просто ввёл текст кнопки сам. Поэтому тебе потребуется использовать register_next_step_handler(). Ты не привёл код своей попытки, но в целом идея несложная. В основном обработчике события ты проверяешь, что текст сообщения содержится в bus_timetable (оператор in в помощь) - это значит, что текст сообщения содержит название известного боту города.
    Тогда ты делаешь вызов register_next_step_handler() и ставишь обработчик второго сообщения. Единственное "но": тебе нужно будет обработчику передать первый выбранный город. Это будет выглядеть как-то так:
    @bot.message_handler(content_types=['text'])
    def first_message_handler(message):
        if message.text in bus_timetable:  # назвали известный город? Это пункт отправления
            kbd = ...  # тут определяешь клавиатуру, опираясь на города в bus_timetable[message.text]
            response = bot.reply_to(message, "А теперь назовите пункт назначения", reply_markup=kbd)
            # обрати внимание: все параметры после указания функции second_message_handler будут
            # переданы в эту функцию при её вызове. А вызвана она будет, когда пользователь ответит.
            bot.register_next_step_handler(response, second_message_handler, message.text)
        elif ...  # нам назвали не город - тут можно проверить другие команды
    
    def second_message_handler(message, point_from):
        # а эта функция будет вызвана только когда пользователь уже назвал пункт отправления
        # point_from будет содержать название города, отправленное пользователем.
        if message.text in bus_timetable[point_from]:  # нам назвали допустимый пункт назначения
            bus_rides = bus_timetable[point_from][message.text]  # список рейсов
            ...  # дальше перебираем список bus_rides и выводим его пользователю
        else:  # пользователь назвал что-то другое
            ...  # говорим пользователю, что он дурак
    Ответ написан
    1 комментарий
  • Почему Telegram бот не отвечает?

    Vindicar
    @Vindicar
    RTFM!
    Ну тебе же английским по белому написано:
    RuntimeError: This Application was not initialized via `Application.initialize`!

    Нужно перед вызовом application.start() добавить аналогичный вызов initialize().

    И да, ты пытаешься трогать элементы управления своего окна из другого потока. Так нельзя.
    Ответ написан
    Комментировать
  • Почему возникает ошибка при создании Telegram бота?

    Vindicar
    @Vindicar
    RTFM!
    Открываем официальные примеры, находим простейший эхобот, и начинаем с него.
    В частности, смотрим, каким методом запускается работа бота.
    Спойлер
    bot.infinity_polling()
    Ответ написан
    Комментировать
  • Почему когда отвечаю на сообщение в чате, сообщение не присылается пользователю в бота обртано?

    Vindicar
    @Vindicar
    RTFM!
    У тебя handle_message() стоит первым - поэтому бот будет пытаться использовать его для любых текстовых сообщений. А поскольку у тебя там тупо if, без какой-либо реакции на неожиданные сообщения, то если if не выполнился, бот молча ничего не сделает.
    Ответ написан
    Комментировать
  • Стоит ли использовать ООП для бота на Telebot?

    Vindicar
    @Vindicar
    RTFM!
    Ну почему бы и нет?
    Вон, discord.py вообще реализует механизм когов (cogs), который позволяет заключать отдельные наборы поведений в класс, и подгружать/выгружать этот класс по ходу работы.
    Нечто подобное можно построить на базе почти любой библиотеки чат-ботов, особенно если с выгрузкой заморачиваться не требуется.
    Просто если у тебя только один набор связанных поведений, то и класс с обработчиками будет один - и смысл тогда?
    Ответ написан
    Комментировать
  • Ошибка TypeError: work_command() missing 1 required positional argument: 'points' что делать?

    Vindicar
    @Vindicar
    RTFM!
    @bot.message_handler(content_types=['text'])
    def work_command(message, points):


    Бот ничего не знает про points и откуда оно берётся. Бот ожидает, что любая функция, отмеченная как обработчик сообщений, принимает ровно один параметр - объект принятого сообщения. Если это условие не выполняется, это твой косяк.

    если делать global points то будет у всех один баланс

    Вовсе нет. Ты не обратил внимание, что у тебя points - словарь, где ключ - id пользователя? (к слову, кто код писал? уж точно не разраб-крут). У тебя для разных id пользователей будут отдельные элементы в словаре, с отдельными значениями.

    Другое дело, что словарь не переживёт перезапуска бота...
    Ответ написан
  • Как сделать бота поддержки с при помощи библиотеки telebot?

    Vindicar
    @Vindicar
    RTFM!
    Не пытайся объявлять обработчики событий динамически, внутри других обработчиков. Это не будет работать так, как ты это ожидаешь!
    А для начала определись с ответом на вопрос: если есть несколько одновременных обращений, то как бот поймёт, кому отвечает оператор?

    Один из вариантов

    Оператор должен явно отвечать (через соотв. пункт меню) на сообщение бота.
    Тогда бот должен хранить список вида "id сообщения в группе, id пользователя. Можешь хранить в БД или ином хранилище (БД в конечном итоге будет проще всего).

    В этом случае логика бота по обработке сообщения будет такая:
    1. Если сообщение в личке: отправить копию сообщения в группу, сохранить в БД id пользователя и id отправленного ботом сообщения.
    2. Если сообщение в группе, и это ответ: поискать в БД id сообщения, на которое ответ. Если id найдено - извлечь соответствующее id пользователя, отправить ему копию сообщения.
    3. Если id не найдено: что должен сделать бот?
    4. Если сообщение в группе, но это не ответ: что должен сделать бот?

    Можно также прикреплять к записи в БД дату, чтобы время от времени можно было выкидывать из БД старые сообщения. Это уже упражнение для читателя.
    Ответ написан
    Комментировать
  • Бот отправляет 2 раза сообщение, которое не нужно отправлять в данный момент + не хочет отправлять результаты в группу, Как решить эти 2 проблемы?

    Vindicar
    @Vindicar
    RTFM!
    return (test_g, test_k)
    bot.send_message(айди группы, f'@{message.from_user.username} / {message.from_user.id} отправил тест на проверку\nЕго варианты были\nhttps://forms.gle/{test(message)[0]}\nhttps://forms.gle/{test(message)[1]}')


    Полнейшая чушь.

    Во-первых, запомни, что обработчики событий (всё, что декорировано message_handler() или подобным) не следует вызывать самостоятельно. Вот просто не следует. Их вызывает бот по мере надобности. Как следствие, возвращать из них тоже ничего не следует - бот это проигнорирует, а ты эти значения не получишь.

    Во-вторых, выучи концепцию побочных эффектов при вызове функции и держи её в голове. Ты на ровном месте делаешь два вызова test(), которая имеет побочные эффекты в виде отправки сообщения, а потом удивляешься, что два раза отправляются сообщения! Причем именно что на ровном месте. Вот тебе что, грозят болтающееся отрезать за сохранение результата test() в ещё одну локальную переменную перед использованием этого результа? Конечно, это непринципиально, потому что test() вызывать нельзя (см. пункт 1), но всё равно показательно.

    А что касается передачи инфы о действиях пользователя - заведи хранилище вида "id пользователя - пара ссылок". Подойдёт даже словарь, если тебе не нужно, чтобы инфа переживала перезапуск бота. И вот оттуда уже в well() вытаскивай инфу о том, что проходил текущий пользователь.

    Учись программировать, потом пиши ботов. Не наоборот.
    Ответ написан
    Комментировать
  • Как при создании телеграмм бота сложить несколько переменных?

    Vindicar
    @Vindicar
    RTFM!
    Это потому что текст сообщения пользователя - строка. Для строк, "1" + "1" = "11", потому что сложение строк - это конкатенация.
    Преобразуй строки в числа. Для целых это просто
    s = "11"
    x = int(s)  # x = 11

    Для дробных чисел сложнее. Конечно, можно сделать по аналогии:
    s = "1.1"
    x = float(s)  # x = 1.1

    Но тут требуется десятичная точка, т.е. "1,1" не прокатит. Отчасти это можно компенсировать заменой, например,
    s = "1,1"
    x = float(s.replace(",", "."))  # x = 1.1

    Коряво, но сработает.
    Ответ написан
    Комментировать
  • Как причесать текст в telegram боте?

    Vindicar
    @Vindicar
    RTFM!
    Ты уж решай - или ты хочешь структурированный ответ, например, json, или ты хочешь простой текст.
    В зависимости от этого формулируй запрос и указывай тип ожидаемого ответа.
    Если хочешь json - имеет смысл приложить образец jsonки, чтобы в ней были те поля, которые ты ожидаешь получить.
    Ответ написан
    Комментировать
  • Почему не работает база данных sqlite3 для телеграм бота?

    Vindicar
    @Vindicar
    RTFM!
    cursor.executemany('''
            INSERT INTO bugs (bug_name, bug_info, developer) VALUES (?, ?, ?)
        ''', (bug_name_var, bug_info_var, developer))


    Почему тут executemany()? Ты вызываешь его, как будто это простой execute().
    Ответ написан
    Комментировать
  • Можно ли и каким образом прописать команду telegram-боту обрабатывать только определенные изображения (скрины,документы), а остальные игнорировать?

    Vindicar
    @Vindicar
    RTFM!
    Простого способа нет. Метаданные могут кое-что подсказать - некоторые форматы изображений содержат комментарии, например, каким ПО файл был создан. Но метаданные могут отсутствовать или быть некорректными.
    Не говоря уже о том, что ваше определение "скриншоты, документы" - ОЧЕНЬ расплывчатое. Фотография экрана - это скриншот? А с точки зрения метаданных она будет неотличима от просто фотки. Фотография девушки с паспортом в руках - считается документом или нет?

    Так что или пытаться обрабатывать всё (и ругаться, если не получается), или ставить какой-то предварительный фильтр на базе того или иного классификатора изображений. Но тогда будут проблемы с ошибками - или фильтр пропустит левое изображение, или, что хуже, не пропустит правильное.
    Ответ написан
    Комментировать
  • Как правильно написать многоуровневое меню для телеграмм бота в библиотеке telebot?

    Vindicar
    @Vindicar
    RTFM!
    Ну первое, что я замечу: в коде только call_start_menu() помечена как обработчик событий от кнопок, потому что только перед ней стоит декоратор callback_query_handler.
    Советую ознакомиться с документацией и примерами, чтобы понять, как регистрируются обработчики.
    А заодно (поскольку это будет ваш следующий вопрос) понять, что такое func= и для чего оно нужно.
    Ответ написан
    1 комментарий
  • Как отправить разные изображения для сообщений с одинаковым содержанием в Telebot?

    Vindicar
    @Vindicar
    RTFM!
    Тебе нужен автомат состояний (finite state machine, FSM). Не знаю, есть ли его реализация в комплекте с telebot, но идея простая: нужно помнить, что пользователь делал раньше, т.е. иметь хранилище ключ-значение вида "id пользователя -> состояние+доп. инфа". В простейшем варианте хватит и словаря (если тебе не критично, чтобы сведения переживали перезагрузку бота).
    Ответ написан
    Комментировать
  • Python Telebot. Не сохраняется значение в переменную. Сможете помочь?

    Vindicar
    @Vindicar
    RTFM!
    Читай, как работают глобальные переменные (ключевое слово global) в питоне.

    Ты сейчас создаёшь в обработчике события локальную переменную a, которая, разумеется, пропадает, когда обработчик завершается.

    Ну и да, я исхожу из того, что у тебя дальше есть код по запуску бота, которому ты привязал этот обработчик.
    Ответ написан
    Комментировать
  • Как получить сообщение, на которое ответил пользователь?

    Vindicar
    @Vindicar
    RTFM!
    А зачем ты делаешь get_message(), если message.reply_to_message уже должен содержать информацию о сообщении, на которое был сделан ответ?
    Ответ написан