TelegramBot / Api

Native PHP Wrapper for Telegram BOT API
MIT License
1.07k stars 324 forks source link

Автоматический перезапуск бота для отдельного чата #311

Closed maksutovnurda closed 3 years ago

maksutovnurda commented 3 years ago

Написал бот для группы. Но иногда бот зависает там, но будет нормально работать на личке или на другом чате. Как можно это исправить? Кстати думаю лаги из за долгой время ожидания обработки PHP кода, так как обычно зависает когда пишу команды для которого ответа надо немного ждать. Например бот завает если писать ему например так /do. $bot->command('do', function ($message) use ($bot) { $bot->sendMessage($message->getChat()->getId(), $answer); });

Прошу прошение если ошибки в тексте, так как я не руский :)

MyZik commented 3 years ago

Хм, у такой проблемы может быть много причин. Если я правильно тебя понял, то думаю, что твоя основная проблема это слабый сервер. Посмотри в логи, какие там ошибки, когда бот лагает?

maksutovnurda commented 3 years ago

Нет проблема не в сервере бот отключиться (не обработает запросы) на группе в котором произошло ошибка но продолжает работать на других группах. И я сделал специальную команду чтоб перезапустить бота в случай ошибки. file_get_contents('https://api.telegram.org/bot$token/setWebhookurl=$url&drop_pending_updates=true') Как это можно решать. Автоматизировать обнуление getUpdates

MyZik commented 3 years ago

Странное решение, ну да ладно. Покажи логи (error.log на сервере) какую ошибку ты получаешь?

Можешь сделать консольную команду, которая обнуляет getUpdates и вызывать её с помощью Cron каждую минуту.

maksutovnurda commented 3 years ago

Странно, попробовал на нескольких серверах. На некоторых серверах getUpdates обнуляется само по себе и бот продолжает работать дальше. [Mon Jan 18 17:34:14.687430 2021] [fcgid:warn] mod_fcgid: stderr: PHP Fatal error: Uncaught TelegramBot\Api\HttpException: Bad Request: message text is empty in vendor/telegram-bot/api/src/BotApi.php:285 [Mon Jan 18 17:34:47.726093 2021] [fcgid:warn] mod_fcgid: stderr: #7 vendor/telegram-bot/api/src/BotApi.php on line 285 Так начинается и продолжается кучим mod_fcgid ошибками

MyZik commented 3 years ago

Что твой бот делает? Может быть в этом и проблема, что у тебя текст сообщения пустой?

maksutovnurda commented 3 years ago

Мой бот отправляет прогнозы на погоду. Но иногда не знаю почему то бот зависает. Ну может быть из за пустых ответов от api. Кстати как можно реализовать отложенные сообщений на вашем библиотеке?

MyZik commented 3 years ago

К сожалению, без сторонних сервисов не обойтись.

Проверяй ответ с API, если он пустой - отправляй сообщение юзеру о том, что сервис пока не доступен.

groza-a-a commented 3 years ago

У меня такая же проблема. Бот подвисает. И я почти уверен, что проблема связана с сообщениями которые были отредактированы. У нас бот добавлен в группу. Дали боту доступ ко всем сообщениям. Т.Е. он понимает все сообщения даже те что без "/" в начале сообщения.

Уже второй раз происходит такое, что он подвисает после того как кто-то напишет сообщение и потом это сообщение отредактирует. Не важно было ли это сообщение командой боту или нет. После этого ничего не помогает. Ни удаление сообщения ни переустановка вебхука. надеюсь поможет кому-то. Я решения пока не нашел адекватного. Люди всегда будут тупить и редактировать сообщения. А ограничивать команды "/" в нашем случае еще большее зло(

groza-a-a commented 3 years ago

Совет @maksutovnurda от части помог. Нужно удалять вебхук с дополнительным параметром: 'drop_pending_updates'. Но можно сделать это немного короче: 'https://api.telegram.org/bot1415124757:AAHBOxHdsfsdsdfdfffs1lhB9hyWOA/deleteWebhook?drop_pending_updates=true'

После этого если установить вебхук заново, то бот начинает отвечать.

В документации все написано. https://core.telegram.org/bots/api#deletewebhook

MyZik commented 3 years ago

Совет @maksutovnurda от части помог. Нужно удалять вебхук с дополнительным параметром: 'drop_pending_updates'. Но можно сделать это немного короче:

Хм. Если я правильно Вас понимаю и Ваш бот наблюдает за сообщениями пользователей в группе и реагирует на них, то я думаю, что можно поступить следующим образом: отлавливать сообщения, и те, которые были отредактированы - просто игнорировать.

groza-a-a commented 3 years ago

Хм. Если я правильно Вас понимаю и Ваш бот наблюдает за сообщениями пользователей в группе и реагирует на них, то я думаю, что можно поступить следующим образом: отлавливать сообщения, и те, которые были отредактированы - просто игнорировать.

Подскажите, пожалуйста, как это лучше всего можно сделать? Я использую следующую схему:

https://gist.github.com/groza-a-a/918adf30bdc2fabb32929e92968e3956

Для примера я очень сильно упростил. Но смысл, думаю понятен.

Как можно отловить отредактированное сообщение и какой ответ нужно отдать, чтобы такое сообщение не зацикливалось?

MyZik commented 3 years ago

Непонятно, что у вас переменной в $message лежит. Объект Message или как?

groza-a-a commented 3 years ago

$message - это строка, которую получаем после того как отработает метод, соответствующий команде. То есть к нам приходит хук, из хука мы берем сообщение и пытаемся распознать команду. Если распознали вызываем соответствующий для нее метод и он всегда должен вернуть для пользователя сообщение о результате выполнения команды.

maksutovnurda commented 3 years ago

Кстати параметр drop_pending_updates=true можно задать и на setWebhook. Таким образом установить вебхук заново не придется. Я так сделал и вызывал её с помощью Cron каждую минуту. _file_get_contents('https://api.telegram.org/bot'TOKEN'/setWebhook?url='URL'&drop_pending_updates=true');_

groza-a-a commented 3 years ago

Кстати параметр drop_pending_updates=true можно задать и на setWebhook. Таким образом установить вебхук заново не придется. Я так сделал и вызывал её с помощью Cron каждую минуту. _file_get_contents('https://api.telegram.org/bot'TOKEN'/setWebhook?url='URL'&drop_pending_updates=true');_

Радикальненько)

MyZik commented 3 years ago

Как можно отловить отредактированное сообщение и какой ответ нужно отдать, чтобы такое сообщение не зацикливалось?

$bot->on(function (\TelegramBot\Api\Types\Update $update) use ($bot) {
        $message = $update->getMessage();
        $id = $message->getChat()->getId();
        $bot->sendMessage($id, 'Your message: ' . $message->getText());
    }, function () {
        return true;
    });

Вот пример из README. Берешь объект Message и вытаскиваешь оттуда edit_date: https://github.com/TelegramBot/Api/blob/master/src/Types/Message.php#L597