Ответы пользователя по тегу AIOgram
  • Что такое inline_query запрос и как отправить его боту?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    У ботов есть интерфейс, который помогает пользователю написать новое сообщение. Для этого надо ввести в любом чате имя бота в начале (@###bot) и какой-то текст, секунду спустя бот вернёт список вариантов для использования. Например, @vid "текст" сделает поиск видео на YouTube и покажет варианты. Пользователь может выбрать вариант и отправить его в текущий чат, а может не выбрать - бот об этом не узнает.

    Пример
    65c3cc74bef59374568860.png


    Как вариант, можно посмотреть моего бота glagolitic_bot, который помогает писать в чатах глаголицей, тифинагицей, коптицей и ивритицей. Ссылка на исходный код есть в описании бота.

    Чтобы бот мог работать в таком режиме, его надо включить у BotFather (Bot Settings - Inline Mode). Надо ещё не забывать, что Телеграм может кэшировать такие подсказки бота.
    Ответ написан
    Комментировать
  • Где можно хранить данные, которые тг-бот использует в работе?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Хранить картинки в git-репе проекта - это обычно плохая идея, кроме случаев, когда их совсем немного. Хранить их в каталоге рядом с ботом - нормальная.

    Но если картинки для разных пользователей будут повторяться, то лучше запоминать file_id ранее загруженных, чтобы в следующий раз не отправлять сами файлы. Это ускорит отправку, да и Телеграму лишние копии файлов на их серверах ни к чему.

    spoiler
    У меня есть бот, у которого в репе лежит несколько картинок, плюс он помнит в своей базе, какие уже отправлял, чтобы передавать их только по file_id https://github.com/shurshur/glagolitic-bot/blob/ma...
    Ответ написан
    Комментировать
  • Как решить проблему, если телеграм-бот выдаёт ошибку Task exception was never retrieved и не отправляет файл в чат повторно?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Дело в том, что photo это file handle, после того файл один раз прочитан, его надо переоткрыть заново сначала. Так что надо считывать прям внутри обработчика, а не снаружи.
    Ответ написан
    Комментировать
  • Как сделать так,чтобы при отправке любого сообщения бот реагировал?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Тут аж несколько проблем.

    Зачем бот отправляет пользователю пустое сообщение? Скорее всего, на это выскочит ошибка.

    Зачем секция вызова поллинга бота засунута в обработчик, а не находится в основном теле бота? Такой бот просто молча завершится.

    Зачем сравнивать строку message.text с модулем random? Всегда будет False, очевидно же.

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

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Если это сторонний API, который не выполняет следующий запрос до завершения текущего, то бесполезно что-то у себя ковырять, всё равно пока запрос первого не будет обработан, запрос второго обрабатывать не начнёт. Тут ничего уже не поможет.

    Если же проблема в том, что обращение к API делается синхронным кодом... Ну так это и надо лечить. Например, если API работает по протоколу http, то меняем библиотеку requests (или что там используется?) на aiohttp. Тогда следующий запрос может выполняться до завершения уже начатого.
    Ответ написан
    Комментировать
  • Как исправить ошибку sqlite3.IntegrityError: UNIQUE constraint failed: users.user_id?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Нет, эта ошибка возникает при INSERT либо UPDATE, если в результате операции в таблице users появятся две записи с одинаковым user_id. От SELECT такого быть не может. Я бы рекомендовал всё же проверить точный номер нужной строки, чтобы убедиться в этом.

    Чтобы этого не происходило, нужно уметь следить за тем, чтобы пользователи второй раз не вставлялись таблицу или чтобы их id не изменялись на конфликтующие при UPDATE. Но тут, скорее всего, влияет только INSERT. Вот с ним и надо делать аккуратно, вставлять только новых пользователей, а если пользователь уже есть - ничего не делать либо обновлять имеющуюся запись (смотря как именно требуется для логики приложения).

    Как вариант, можно сделать совсем по-простому: вместо INSERT использовать REPLACE, который комбинирует INSERT и UPDATE - если при вставке запись с таким id уже есть и случается ошибка, то фактически выполняется UPDATE соответствующей записи с изменением всех перечисленных полей. Например, для REPLACE INTO users (user_id, referrer_id) фактически выполнится что-то типа UPDATE users SET referrer_id=... WHERE user_id=...
    Ответ написан
    Комментировать
  • Aiogram бот выдаёт ошибку. TypeError: rezume() missing 1 required positional argument: 'message' что делать?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Потому что плохо читаем документацию. Потому что копипастим куски кода без понимания как они работают.

    message_handler принимает один аргумент - Message.

    callback_query_handler принимает один аргумент - CallbackQuery.

    Тут зачем-то в callback_query_handler два аргумента - call и message. Но бот-то вызывает его так, как и требуется по документации - с одним аргументом. И python обоснованно жалуется, что второй аргумент (message) не передавался.

    До кучи, никогда (НИКОГДА!) нельзя объявлять новые handler'ы внутри имеющихся. Это работает не так, как ты думаешь, и может вызвать очень забавные глюки. Вообще, я не знаю, где люди такому учатся, но на этом сайте с таким приходят регулярно.

    Например...
    Если есть в двух разных функциях-обработчиках "верхнего уровня" есть обработчики с одинаковым фильтром в декораторе (вариант: обработчики могут покрывать общее подмножество случаев), то бот зарегистрирует первым тот "суб-обработчик", для которого "верхнеуровневый обработчик" вызвался первым. В итоге другой обработчик не будет вызываться вообще никогда, а поведение бота может быть весьма неожиданным.


    Далее, в обработчике надо ответить пользователю, установить следующее состояние и сразу же завершить работу этого обработчика. Всю дальнейшую обработку следует выполнять в следующих обработчиках. А сейчас в этом коде все вопросы задаются подряд в одной и той же функции по имени rezume подряд, безо всякого ожидания ответа от пользователя. Короче, сейчас в коде полная лажа, так работать не будет вообще никак.

    PS: Слово "резюме" по-английски пишется совсем не так.
    Ответ написан
    Комментировать
  • Как получить chat_id из обьекта query | Aiogram?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Очевидно, в данном случае запрос делается из группового чата, а у групповых чатов user_id не совпадает с chat_id. Это вообще очень распространённая ошибка. Я вообще рекомендую всем всегда явно использовать chat_id, потому что в теории Телеграм может когда-нибудь даже для личных чатов начать использовать id, отличные от id пользователей.

    В query есть объект query.message, который содержит исходное сообщение, в котором нажали на кнопку. А в нём, соответственно, есть query.message.chat с объектом чата. А в query.message.chat уже есть id.
    Ответ написан
    Комментировать
  • Как сделать меню с inline - стрелками влево - вправо?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Например, пусть у нас есть каруселька из N элементов с номерами от 1 до N. Тогда можно просто показывать элемент 1, а у него две кнопки "влево" с callback=item:N и "вправо" с item:2. При нажатии на кнопку с callback=item:k редактировать это сообщение, выводя в него содержание элемента k и клавиатуру с кнопками item:(k-1) и item:(k+1).

    Это в общих чертах. Конкретная реализация может сильно различаться в зависимости от уровня хотелок, структуры данных итд итп. Например, можно показывать список категорий (в том числе с постраничным выводом), а в категориях уже позволять листать элементы категорий. Или можно позволить сделать поиск и устроить карусель из результатов поиска. Человеческая фантазия практически безгранична.
    Ответ написан
    Комментировать