Как перезапустить бота?
Теперь хочу осуществить полный перезапуск бота, по вводе команды в самом боте, т.е. полностью подгрузить все файлы с обработчиками команд по новой.
Есть у кого-нибудь идеи как это можно осуществить?
- Вопрос задан более года назад
- 1835 просмотров
Комментировать
Решения вопроса 0
Ответы на вопрос 1
У меня бот запускается сервисом supervisored, он умеет перезапускать скрипт при полном падении, но завершить бота из функции у меня не вышло, процесс не завершается.
Пока использую для telegram (python-telegram-bot)*:
def cmd_restart_service(update, context): if update.message.from_user.id == 777777777: # id пользователя import subprocess update.message.reply_text("будет исполнено. ") subprocess.run("sudo supervisorctl restart mybotname".split())
И нет мне за это чести 🙂
* Внешние команды перезапуска и сама такая возможность зависит от операцинной системы/сервиса/служб/настроек, где запущен бот.
Как перезапустить бота кодом, при нажатии inline кнопки(pytelegrambotapi)?
Когда я запускаю бота, с первого раза всё работает стабильно, но когда я нажимаю сбросить, и хочу начать по новой (начать вводить имя), то бот работает по предыдущему запросу, и думает что я ввёл фамилию. Соответственно сначала бот пишет «Введите имя», а потом он думает что я ввожу фамилию, и выдаёт результат «Вас зовут» + имя и фамилия введённая пользователем, затем такую ошибку:
2021-10-31 21:53:34,798 (__init__.py:663 MainThread) ERROR - TeleBot: "A request to the Telegram API was unsuccessful. Error code: 400. Description: Bad Request : message to delete not found"
Как можно при нажатии inline кнопки сбросить работу программы, перезапустить бота и начать сначала? Чтобы при каждом нажатии на inline кнопку, скрипт будто закрыли и открыли заново. Не знаю как сделать это кодом, чтобы бот работал без остановки 24/7.
Отслеживать
задан 31 окт 2021 в 19:23
user464804 user464804
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Можно повторно вызывать функцию send_welcome прямо из inline_handler , которая ловит нажатие кнопки сброса.
А в самой функции send_welcome сбрасывать все зарегистрированные обработчики с помощью вызова bot.clear_step_handler(message) .
Тогда если send_welcome вызвана первый раз, никаких обработчиков еще не установлено и ничего не произойдет, а если повторно — они будут сброшены, как и требуется.
Вот пример рабочего кода:
@bot.message_handler(commands=["start"]) def send_welcome(message): global DELETEuserName1 bot.clear_step_handler(message) userName = bot.send_message(message.chat.id, "Здравствуйте, введите имя") DELETEuserName1 = userName.message_id bot.register_next_step_handler(userName, userSurNameFUNC) def userSurNameFUNC(message): global userName, DELETEuserSurName, DELETEuserSurName1 userName = message.text markup = types.InlineKeyboardMarkup() resetDataKey = types.InlineKeyboardButton("Сбросить", callback_data="resetData") markup.add(resetDataKey) userSurName = bot.send_message(message.chat.id, "Теперь введите фамилию", reply_markup=markup) DELETEuserSurName = userSurName.chat.id DELETEuserSurName1 = userSurName.message_id bot.delete_message(message.chat.id, message.message_id) bot.delete_message(message.chat.id, DELETEuserName1) bot.register_next_step_handler(userSurName, endProgrammFUNC) def endProgrammFUNC(message): global userSurName, DELETEendProgramm, DELETEendProgramm1 userSurName = message.text endProgramm = bot.send_message(message.chat.id, "Вас зовут " + userName + " " + userSurName) DELETEendProgramm = endProgramm.chat.id DELETEendProgramm1 = endProgramm.message_id bot.delete_message(message.chat.id, message.message_id) bot.delete_message(DELETEuserSurName, DELETEuserSurName1) @bot.callback_query_handler(func=lambda call: True) def inline_handler(call): if call.data == "resetData": bot.delete_message(call.message.chat.id, call.message.message_id) send_welcome(call.message) bot.infinity_polling()
Как перезапустить бота в телеграмме
Боты на тестовом тарифе ограничены числом пользователей. Тестовый тариф работает только у пяти тестировщиков.
Назначьте себя и коллег тестировщиками, чтобы бот отвечал вам, либо оплатите подписку.
Узнать подробнее о тарифах и сравнить их вы можете на странице Тарифные планы.
В логике бота есть ошибки
В Telegram
- Попробуйте перезапустить бота через команду /start и повторить исполнение ошибки.
- Внимательно проверьте причину ошибки: возможно, вы зашли в тупик (пустой экран, нет перехода на другой экран) или не исполнился компонент экрана из-за некорректного исполнения (некорректные данные, незаполненные данные).
Если бот не перезапускается через /start:
- Проверьте настройки токена.
- Нажмите «Сохранить» в конструкторе. Если бот не «отвис», попробуйте ещё раз отправить команду /start.
- Если бот всё ещё не «отвис», дайте боту @Botfather команду /revoke, получите новый токен и измените токен в Настройках.
В Viber, ВКонтакте и Одноклассниках
- Добавьте событие Шаблон, исполняющее Стартовый экран. Отправьте боту команду.
- Если бот перезапустился, проверьте причину ошибки: возможно, вы зашли в тупик (пустой экран, нет перехода на другой экран) или не исполнился компонент экрана из-за некорректного исполнения (некорректные данные).
Если бот не перезапускается:
- Проверьте настройки подключения платформы.
- Нажмите «Сохранить» в конструкторе. Если бот не «отвис», попробуйте ещё раз отправить команду из события Шаблон.
Во всех платформах сразу
Если бот перестал работать во всех платформах, но при этом не отправлял никаких ошибок, попробуйте нажать на кнопку «Сохранить» в конструкторе.
Проверьте почту на наличие уведомлений: возможно, бот был заблокирован из-за превышения лимита запросов (это бывает, когда бот зациклился) или за нарушения Пользовательского соглашения.
Проверьте, чтобы бот был открыт только в одной вкладке браузера.
Если бот не начал работать после вышеупомянутых действий, напишите в чат поддержки или на sup@botmother.com. Обязательно в письме укажите почту, на которую зарегистрирован бот, и прикрепите скриншоты диалога в Telegram.
Глава 6 Повышаем стабильность работы бота
К этому моменту вы знаете уже достаточно для того, что бы решить значительную часть своих задач по ботостроению. Простой бот будет работать достаточно стабильно, но всё равно иногда сервера API Telegram могут давать сбой. Даже если в вашем коде нет ошибок, и пользователи используют его правильно, иногда он может падать.
В этой главе мы поговорим о том, как повысить работоспособность бота за счёт отлавливания и обработки ошибок пуллинга.
6.1 Конструкция tryCatch()
Повысить работоспособность вашего бота поможет конструкция tryCatch() . Данная конструкция имеет следующий синтаксис:
tryCatch(expr = ~ Тут код который будет выполняться ~ >, error = function(err) ~ код который будет выполняться в случае возникновения ошибки в блоке expr ~ >, finally = ~ Код который будет выполняться в любом случае, не зависимо от того закончилось выражение expr ошибкой или нет ~ >)
6.2 Логика работы конструкции tryCatch()
Из описанного синтаксиса понятно, что вам необходимо завернуть выражение в фигурные скобки в аргументе expr . Это выражение будет выполняться либо до тех пор, пока не встретится ошибка, либо если ошибки нет, оно будет выполнено полностью.
Если в выражении переданном в expr встречается ошибка, то конструкция tryCath() запустит анонимную функцию, которую вы передали в блоке error .
В любом случае, не зависимо от того, встретилась в выражении expr ошибка или нет, в завершении выполнения будет выполнен код, переданный в аргумент finally .
Если вы хотите более подробно узнать про конструкцию tryCatch() посмотрите этот видео урок.
6.3 Используем tryCatch() внутри бота
По большому счёту вы можете использовать tryCatch() внутри каждой функции вашего бота. Но можно убить всех зайцев одним выстрелом.
В разработке ботов слабым местом является пуллинг, т.е. метод updater$start_polling() . Пуллинг — это бесконечный цикл, именно он выполняется всё время работы бота, и даёт сбой если пользователь неправильно использовал бота, или API Telegram не отправил вам ответ. Соответственно если завернуть пуллинг в tryCatch() , и перезапускать вашего бота в бота в блоке finally то при любой ошибке он будет самостоятельно перезапускаться.
Перед перезапуском бота не забывайте очистить его апдейты, что бы избавиться от ошибки, которая вызвала падение бота.
Выглядеть такой пуллинг будет следующим образом:
tryCatch( # запускаем пуллинг expr = updater$start_polling(), # действия при ошибке пуллинга error = function(err) # бот для оповещения bot Bot(token = bot_token("Токен вашего бота")) # чат для оповещения chat_id "Идентификатор чата в который необходимо отправить сообщение" # сообщение msg str_glue("*Бот упал*: Ошибка (__).") bot$sendMessage(chat_id = chat_id, text = msg, parse_mode = 'Markdown') # очищаем полученный апдейт бота, который вызвал ошибку updater$bot$clean_updates() # информация о том, что бот будет перезапущен bot$sendMessage(chat_id = chat_id, text = str_glue('*Перезапускаю бота* в '), parse_mode = 'Markdown') >, # действия которые будут выполненны в любом случае finally = # останавливаем пулинг updater$stop_polling() # перезапускаем скрипт бота source('C:\\telegram_bot\\my_bot.R') > )
В приведённом выше коде вам необходимо подставить токен созданного вами бота, и указать ID чата, в который бот будет отправлять уведомление о падении пуллинга.
В блок expr мы завернули процесс пуллинга, таким образом он постоянно контролируется конструкцией tryCatch .
Далее в блок error мы передали безымянную функцию, которая принимает всего один аргумент err , т.е. саму ошибку. Сообщение об ошибке мы получаем через err$message , и отправляем в указанный чат. С помощью updater$bot$clean_updates() мы очищаем очередь апдейтов бота, т.к. последний апдейт вызвал ошибку и падение нашего бота.
В блоке finally мы останавливаем пуллинг, и командой source(‘C:\\telegram_bot\\my_bot.R’) занова запускаем скрипт с ботом.
Такая схема позволяет боту очищаться и подниматься при любой ошибке пуллинга.
Очищать апдейты бота с помощью комманды updater$bot$clean_updates() можно так же и при запуске бота, указав эту команду сразу, после инициализации объекта бота.