Ответы пользователя по тегу Боты
  • Телеграм бот перестает работать, пишет ошибка в базе данных. Где ошибка?

    Vindicar
    @Vindicar
    RTFM!
    Включи голову и подумай.
    Судя по ошибке, у тебя в таблице users ID пользователя - уникальный ключ.
    Запрос на создание таблицы у тебя не содержит указания ключа, что, к слову, нехорошо. Я полагаю, ты убрал запись о ключе в какой-то момент, но не пересоздал таблицу.
    Ты записываешь в эту таблицу данные о пользователе всякий раз, когда получаешь команду /start.
    Внимание, вопрос: что произойдёт, если пользователь введёт /start ещё раз?
    Прааааавильно, бот попытается создать ещё одну запись для этого пользователя. Что запрещено наличием первичного ключа.

    Для начала ответь себе на вопрос: что тебе нужно сделать в базе, если пользователь ввёл /start ещё раз?
    Ничего? Читай про форму INSERT OR IGNORE, она как раз позволяет молча пропустить запись, если такой первичный ключ уже есть.
    Сообщить пользователю? Тогда сначала проверь в базе наличие записи для этого пользователя, и если она есть - сообщай, если её нет, то вноси в базу.
    Ответ написан
    Комментировать
  • Как получить сообщение, на которое ответил пользователь?

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

    Vindicar
    @Vindicar
    RTFM!
    Во-первых, переводим слово "warning". Это не ошибка, это предупреждение.
    Во-вторых, погуглить не пробовал?
    В ранних версиях asyncio get_event_loop() создавал рабочий цикл asyncio, если он ещё не был создан, и возвращал существующий, если он был. Потом от этого поведения решили отказаться. Пока что оно ещё работает, но потом сломается.
    Так что в начале программы используй new_event_loop(), а если нужно получить ссылку на цикл в корутине - get_running_loop()

    И я удивлюсь, если окажется, что ошибка именно в этом. У тебя где-то ещё должен быть косяк. Скорее всего одна из запускаемых корутин выполняет длительную операцию синхронно.
    Ответ написан
  • С чем может быть связана ошибка "asyncio.exceptions.CancelledError"?

    Vindicar
    @Vindicar
    RTFM!
    Открой доки и почитай. CancelledError выбрасывается в корутине, когда она завёрнута в таск через create_task() и на этом таске вызван метод cancel(). Это позволяет прервать выполнение корутины через выбрасывание специального исключения. Исключение не наследуется от Exception, поэтому обычный try-except его не ловит, если только специально не указать try ... except CancelledError. Так сделано, потому что при выходе через всплывание исключения будут отрабатывать все нормальные питоновские механизмы: блоки finally, блоки with и так далее.
    Я полагаю, команда на остановку бота делает cancel() на его главной корутине, скорее всего запущенной внутри start_polling(). Это исключение всплывает в твой main(). Но поскольку main() выполняется в asyncio.run(), то исключение всплывает туда. Это исключение не имеет особого смысла вне asyncio, так что я полагаю, run() ловит это исключение и вместо него выбрасывает KeyboardInterrupt() как ближайший не-асинхронный эквивалент. Это исключение всплывает на верхний уровень и останавливает интерпретатор.

    Ты можешь ловить CancelledError в main(), чтобы спокойно завершить работу бота. Ну или ловить KeyboardInterrupt() в теле скрипта, на вызове asyncio.run().
    Ответ написан
    1 комментарий
  • Как сохранить полное форматирование текста при его копировании?

    Vindicar
    @Vindicar
    RTFM!
    Как насчёт вместо message.text посмотреть в message.text_markdown или message.text_html (доки)? Ну и соответственно указать не text, а markdown или html при вызове send_message().
    Ответ написан
    4 комментария
  • Как реализовать рандомные видео для бота вк?

    Vindicar
    @Vindicar
    RTFM!
    Ну по существу ты уже всё сказал.
    Получить ссылки из альбома группы - читай доки на библиотеку, которую используешь для взаимодействия с VK.
    Выбрать случайную ссылку из списка - random.choice().
    Чтобы не спамить запросами, можешь схитрить - хранить дату и время, когда ты последний раз загружал список. Когда у бота запрашивается видео, проверяешь - если эта дата достаточно давно в прошлом, то обновляешь список.
    Про работу с датами смотри встроенную библиотеку datetime.

    Про примеры можно будет говорить, когда придёшь с кодом бота и конкретной проблемой.
    Ответ написан
    Комментировать
  • Не работает код ошибки Python Bot?

    Vindicar
    @Vindicar
    RTFM!
    group_members = await bot.get_chat_member(group_id)

    Я подозреваю, что ты хотел вызвать bot.get_chat_members()
    Ответ написан
    Комментировать
  • Как подойти к составлению архитектуры многопользовательского бота?

    Vindicar
    @Vindicar
    RTFM!
    Читай про машины состояний. У тебя есть машина состояний, описывающая ход матча ("матч закончен", "ожидание игроков", "ход игрока" и т.п.), и ряд вложенных машин для отдельных игроков ("ожидание готовности", "готовность", "ожидание хода игрока", "ход сделан" и т.п.), которые активируются в определённом состоянии основной машины.
    Ответ написан
    Комментировать
  • Почему не работает meber_join disnake?

    Vindicar
    @Vindicar
    RTFM!
    Разберись уже, как работает utils.get().
    Она принимает коллекцию объектов, и набор атрибутов в виде kwargs.
    Возвращает первый объект в этой коллекции, у которого атрибуты совпадают с заданными.
    Т.е. тебе надо туда передать список ролей сервера и атрибут id.
    Ну или использовать другой метод, например, member.guild.get_role().

    Читай документацию, короче.
    Ответ написан
    Комментировать
  • Как продолжить разговаривать с нейросетью?

    Vindicar
    @Vindicar
    RTFM!
    Гугли finite state machine (FSM) для библиотеки, которой пользуешься.
    Ответ написан
    Комментировать
  • Как соединить 2 python файла в один код?

    Vindicar
    @Vindicar
    RTFM!
    У тебя будет проблема в том, что во второй файл надо будет передать объект bot, которого, скорее всего, не будет на момент импорта этого файла.
    Есть не слишком изящный, но простой способ.
    # imported_file.py
    import telebot
    from telebot import types
    
    def setup(bot):  # setup() принимает бота и прочее как параметры.
        # да, прописываем обработчики прямо внутри setup()
        # но вот глобальные переменные здесь прописывать не стоит
        @bot.message_handler(content_types=['text'])
        def get_text_messages(message):
            ...
    
    # main_file.py
    import telebot
    from telebot import types
    import time
    
    import imported_file
    
    bot = telebot.TeleBot("ТОКЕН")
    # убедись, что setup() вызывается строго один раз для каждого дополнительного файла!
    imported_file.setup(bot)  
    ...  # дальше работаем как обычно


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

    Vindicar
    @Vindicar
    RTFM!
    1. Записать в переменной ID получателя.
    2. Разобраться, как отправить сообщение по заранее известному ID.
    3. Разобраться, как пользоваться aioschedule.
    Ответ написан
    Комментировать
  • Как настроить универсальный хендлер в аиограм?

    Vindicar
    @Vindicar
    RTFM!
    Вместо text в callback_query_handler() укажи функцию, которая принимает CallbackQuery и возвращает True, если надо обработать данный запрос, и False, если нужно поискать другой обработчик. Для ускорения можешь все коды запросов в БД пометить отдельным префиксом (например, пусть они начинаются с "db_"), чтобы сразу отсечь посторонние коды.
    Просто погугли callback_query_handler, увидишь что-то типа lambda callback_query: True - это означает "принимать любые коды запроса". Но ведь можно True возвращать не всегда.
    Ответ написан
    Комментировать
  • Хочу прописать арифметические действия телеграм боту. Как это сделать?

    Vindicar
    @Vindicar
    RTFM!
    Читай на тему finite state machine. Не знаю конкретно насчёт telebot, а другие библиотеки содержат эту фичу.
    Но в целом идея несложная - ты должен для каждого пользователя помнить, на каком шаге он находится (ожидание первого числа, ожидание оператора, ожидание второго числа) и что он вводил раньше. Получив сообщение, смотришь по ID пользователя его шаг, и обрабатываешь текст сообщения соответственно. Можно это и вручную реализовать.

    Хранение сведений можно для начала реализовать в простом словаре, если нет нужды, чтобы бот помнил происходящее после перезапуска.
    Ответ написан
  • Телеграм бот запоминает первое введенное значение Х. Что не так с кодом?

    Vindicar
    @Vindicar
    RTFM!
    @dp.message_handler()
            async def reply_message_X1(message: types.Message):

    Не надо описывать обработчики событий динамически, внутри других обработчиков. Поведение очень нетривиальное, и затрагивает ВСЕХ пользователей.
    Набор обработчиков должен быть статичен. Вместо этого храни и проверяй, что до этого делал данный пользователь.
    Почитай про finite state machine.
    Ответ написан
    Комментировать
  • Как перезапустить на Линукс упавшего бота, если он многопоточный?

    Vindicar
    @Vindicar
    RTFM!
    1. Починить бота, чтобы не падал. Лови исключения в обработчиках событий, для начала. А если падает не из-за исключения там (а, например, инет отвалился) - ставь обработку исключений на тело бота и заверни всё в цикл while, например.
    2. Пометить вспомогательный поток как daemon. Скрипт завершается, когда не остаётся активных потоков - при этом daemon-потоки не считаются. Смотри документацию на модуль threading.
    Ответ написан
    5 комментариев
  • Как направить вывод ошибок из консоли в файл?

    Vindicar
    @Vindicar
    RTFM!
    Посмотри в сторону модуля atexit. Если падение прогарммы вызвано питоновским исключением, а не чем-то низкоуровневым, то это позволит сделать flush при выходе из программы.
    Ответ написан
  • Ошибка в боте 'NoneType' object has no attribute 'lower'?

    Vindicar
    @Vindicar
    RTFM!
    Очевидно, event.obj.text содержит значение None по какой-то причине. Проверяй значение, прежде чем пытаться вызывать его методы.
    Ответ написан
  • Выдает ошибку после того как нажимаю команду /buy. Как исправить ошибку?

    Vindicar
    @Vindicar
    RTFM!
    Один из сайтов, на которые ты делаешь запрос через get(), или не отвечает, или недоступен по какой-то другой причине.

    Собственно, наивно думать, что это всегда сработает. Сеть непредсказуема. Сайт может работать, может тормозить, может лежать, может тебя забанить, у тебя может не быть интернета - есть сто и одна причина, почему сайт может не работать. Так что готовься к ошибкам заранее. Заворачивай обращения к сайту в try-except, продумывай, что делать, если обращение не удалось, и т.д.
    Ответ написан
    Комментировать
  • To many values to unpack как фиксить?

    Vindicar
    @Vindicar
    RTFM!
    Если ты используешь распаковку коллекции (т.е. оператор вида a, b, c = some_value), тебе нужно быть уверенным, что some_value содержит в точности столько значений, сколько переменных ты распаковываешь.
    Если это не так, есть три варианта:
    1. Если ты знаешь, сколько значений в возвращаемой коллекции, ты можешь просто добавить нужное количество переменных. a, b, c, _ = some_value. Символом _ обычно обозначаются неиспользуемые переменные/параметры.
    2. Если ты не знаешь, сколько значений в возвращаемой коллекции, или это число меняется, можно не выпендриваться, а работать с индексами. Но тебе нужно быть уверенным, что у тебя всегда есть как минимум нужное число значений.
    a = some_value[0]
    b = some_value[1]
    c = some_value[2]
    # и так далее.

    3. Есть ещё вариант распаковки, который работает, если ты значешь, что значений больше, чем нужно:
    a, b, c, *_ = somevalue

    Я бы посоветовал второй вариант
    Ответ написан
    Комментировать