TelegramBot / Api

Native PHP Wrapper for Telegram BOT API
MIT License
1.09k stars 325 forks source link

Ответ после inline-кнопки приходит 3 раза в Yii2 #195

Closed igorwebb closed 4 years ago

igorwebb commented 5 years ago

Прикручиваю библиотеку к фреймворку yii2. Почему-то после того, как я добавил 2ую функцию on() для обработки текста пришедшего сообщение - ответы с первого on() (которая обрабатывает кнопки) приходят по 3 (три) раза... Если убирать вторую on() - работает, как надо - один ответ. Раньше на нативном php такой код работал. На фреймворке что-то магия какая-то...

Код экшна, где лежит бот:

function start($bot, $message) {

            $mess = 'Приветствую тебя!';

            $keyboard = new \TelegramBot\Api\Types\Inline\InlineKeyboardMarkup(
                [
                    [
                        ['callback_data' => 'start', 'text' => ' Начать']
                    ],
                    [
                        ['callback_data' => 'start2', 'text' => ' Магазин']
                    ],
                    [
                        ['url' => 'http://google.com/', 'text' => ' Инструкция'],
                    ],
                ]
            );

            $bot->sendMessage($message->getChat()->getId(), $mess, false, null, null, $keyboard);

        }

        if(true){
            error_reporting(E_ALL & ~(E_NOTICE | E_USER_NOTICE | E_DEPRECATED));
            ini_set('display_errors', 1);
        }

        $token = Yii::$app->params['botToken'];

        try {

            $bot = new \TelegramBot\Api\Client($token, null);

            $bot->command('start', function ($message) use ($bot) {

                if (!BotUsers::findOne(['user_id' => $message->getChat()->getId()])) {

                    $user = new BotUsers();
                    $user->user_id = $message->getChat()->getId();
                    $user->date = Yii::$app->formatter->asDate('now', 'php:Y-m-d');
                    $user->time = Yii::$app->formatter->asTime('now', 'php:H:i:s');
                    $user->last_login = $message->getChat()->getUserName();
                    $user->save(false);

                } else {

                    $user = BotUsers::findOne(['user_id' => $message->getChat()->getId()]);

                    if ($user->last_login != $message->getChat()->getUserName()) {

                        $user->last_login = $message->getChat()->getUserName();
                        $user->save(false);

                    }

                }

                start($bot, $message);

            });

            $bot->on(function($update) use ($bot){

                $callback = $update->getCallbackQuery();
                $message = $callback->getMessage();
                $data = $callback->getData();

                $bot->answerCallbackQuery($callback->getId());

                $user = BotUsers::find()->where(['user_id' => $message->getChat()->getId()])->one();

                if($data == 'start'){

                    start($bot, $message);

                }

                if($data == 'start2'){

                    $bot->sendMessage($message->getChat()->getId(), $data);

                }

            }, function($update) {
                $callback = $update->getCallbackQuery();
                if (is_null($callback) || !strlen($callback->getData()))
                    return false;
                return true;
            });

            // Отлов любых сообщений + обрабтка reply-кнопок
            $bot->on(function($Update) use ($bot){

                $message = $Update->getMessage();
                $mtext = $message->getText();
                $cid = $message->getChat()->getId();

                if(mb_stripos($mtext,"власть советам") !== false){
                    $bot->sendMessage($message2->getChat()->getId(), "Смерть богатым!");
                }

            }, function($message) use ($bot){
                return true; // когда тут true - команда проходит
            });

            $bot->run();

        } catch (\TelegramBot\Api\Exception $e) {
            $e->getMessage();
        }
igorwebb commented 5 years ago

Проверил тот же код нативно, без фремворка, просто подключил библиотеку через composer - работает. Это как вообще понимать?

igorwebb commented 5 years ago

Заметил, что по логам каждое сообщение сайт даёт боту: Error: Call to a member function getText() on null in..

А на крайнее - нет.

igorwebb commented 5 years ago

Я не понимаю, как это связанно, но когда я добавил: print_r($Update); после

// Отлов любых сообщений + обрабтка reply-кнопок
            $bot->on(function($Update) use ($bot){

Всё заработало, как надо. Это как вообще понимать? Что за магия? В логах та же ошибка, но работает...

ImDoode commented 4 years ago

У меня была похожая проблема. Путь решения был следующим -- 1) Проверить статус через апи https://api.telegram.org/bot<ТОКЕН БОТА>/getWebhookInfo 2) Обнаружить, что pending_update_count больше 0 (что странно для тестируемого бота, получившего одну команду) и что last_error_date постоянно обновляется, а значит, на сервере ошибка ("last_error_message":"Wrong response from the webhook: 500 Internal Server Error") 3) Зайти в логи сервера, почитать ошибку 4) Исправить 5) Радоваться жизни У меня была проблема в том, что у меня было два разных обработчика $bot->on(function($update) ... для инлайновых кнопок и команд, из-за во втором обработчике случался питик. Надеюсь, мой ответ будет кому-то полезен.