Ошибка в Telegram боте chat_id is empty [PHP]

402
19 сентября 2017, 09:06

Суть такова, если человек, у которого не установлен в настройках Telegram юзернейм, то есть он пустой, то при заходе в бот после нажатия на кнопку /start у пользователя ничего не происходит, а администратору бота выдаётся ошибка

Ошибка при работе с API. Детали: {"ok":false,"error_code":400,"description":"Bad Request: chat_id is empty"}

У бота есть база данных, куда записывается инфо о юзерах.

Вот код о проверке и записи данных о пользователях:

// Функция-обработчик, отвечающая на команды
$bot->addHandler(function($update, Telegram &$bot) {
    if (!isset($update->{"message"}->{"text"})) {
        $update->{"message"}->{"text"} = " ";
    }
    if (empty($update->{"message"}->{"chat"}->{"username"})) {
        $bot->sendMessage($chatId, "Уважаемый пользователь. У Вас не установлен username. Пожалуйста, установите его в настройках. После этого выполните команду /start еще раз. Спасибо за понимание");
        return;
    }
    $chatId = $update->{"message"}->{"chat"}->{"id"};
    $messageIn = $update->{"message"}->{"text"};
    $firstname = "";
    $lastname = "";
    if (isset($update->{"message"}->{"chat"}->{"first_name"})) {
        $firstname = $update->{"message"}->{"chat"}->{"first_name"};
    }
    if (isset($update->{"message"}->{"chat"}->{"last_name"})) {
        $lastname = $update->{"message"}->{"chat"}->{"last_name"};
    }
    //Проверка на пользователя
    if(DB::uCountColumns("SELECT * FROM `Users` WHERE `chat_id` = '".$chatId."'")){
        // обновление
        DB::uQuery("UPDATE `Users` SET `username`='".$update->{"message"}->{"chat"}->{"username"}."', `lastname`='".$lastname."', `firstname`='".$firstname."' WHERE `chat_id` = '".$chatId."'");
    }else{
        // запись
        DB::uQuery("INSERT INTO `Users`(`chat_id`, `username`, `lastname`, `firstname`, `regDate`) VALUES ('".$chatId."','".$update->{"message"}->{"chat"}->{"username"}."','".$lastname."','".$firstname."',NOW())");
    }
    $userInfo = DB::uFetch("SELECT * FROM `Users` WHERE `chat_id` = '$chatId'");
    $rMessage = explode(' ', $messageIn);
    switch ($rMessage[0]) {
        case '/start': {
                // Открываем файл для получения существующего содержимого
                if ($rMessage[1] > 0 AND ($rMessage[1]!=$chatId)){
                    // проверка есть ли такой пользователь
                    if(DB::uCountColumns("SELECT * FROM `Users` WHERE `chat_id` = '".$rMessage[1]."'") AND !DB::uCountColumns("SELECT * FROM `Reffer` WHERE `chat_id` = '".$rMessage[1]."'")){
                        DB::uQuery("INSERT INTO `Reffer`(`chat_id`, `reffers_id`, `money`) VALUES ('".$chatId."','".$rMessage[1]."','". REF_MONEY ."')");
                        DB::uQuery("UPDATE `Users` SET `balanse`= `balanse` + '". REF_MONEY ."' WHERE `chat_id` = '".$rMessage[1]."'");
                    }
                }
                $welcomeMsg = "Текст приветствия";
                $buttons = [];
                $buttons[] = [['text' => "\xF0\x9F\x92\xB5 Получить бонус"],['text' => "\xF0\x9F\x92\xB0 Кошелек"]];
                $buttons[] = [['text' => "\xF0\x9F\x91\xAB Друзья"],['text' => "\xF0\x9F\x93\x88 Статистика"]];
                $buttons[] = [['text' => "\xF0\x9F\x8C\x8D Язык"],['text' => "\xE2\x84\xB9 Помощь"]];
                $bot->sendMessage($chatId, $welcomeMsg, array('keyboard' => $buttons, 'resize_keyboard' => true));
                break;
        }
        // Помощь
        case "\xE2\x84\xB9": {
                help($bot, $chatId);
                break;
        }

Что тут не так?

Answer 1

Проблема в том, что в самом начале идёт проверка на пустоту юзернейма и это ключевой момент в работе бота. Если условие проверки выполняется и юзернейм пуст, то бот должен отправить сообщение пользователю и прервать дальнейшее выполнение функции.

 if (empty($update->{"message"}->{"chat"}->{"username"})) {
        $bot->sendMessage($chatId, "Уважаемый пользователь. У Вас не установлен username. Пожалуйста, установите его в настройках. После этого выполните команду /start еще раз. Спасибо за понимание");
        return;
    }  

Однако, проблема в том, что переменная $chatId на момент передачи в метод sendMessage не содержит никакого значения, соответственно метод никак не может выполниться и выбрасывает ошибку (это обязательный ненулевой параметр). Определение переменной $chatId и заполнение её значения происходит далее по коду.

$chatId = $update->{"message"}->{"chat"}->{"id"};

Соответственно, решением проблемы является перенос этой строки кода с определением переменной $chatId выше проверки.

Answer 2

Этот код вообще хоть как-то отрабатывает? какая версия php?

в самом начале нужно проверить, есть у пользователя username
от пользователя нам приходит строка, но идет сравнение с целым числом

array (size=2)
  0 => string '/start' (length=6)
  1 => string '001101001' (length=9)

так же заменил бы использование волшебных кавычек и конкатенацию.

исправления:

//Проверка имени пользователя
$username = isset($update->{"message"}->{"chat"}->{"username"}) ? $update->{"message"}->{"chat"}->{"username"} : "no_username"
//Проверка на пользователя
if(DB::uCountColumns("SELECT * FROM `Users` WHERE `chat_id` = '".$chatId."'")){
    // обновление
    DB::uQuery("UPDATE `Users` SET `username`='".$username."', `lastname`='".$lastname."', `firstname`='".$firstname."' WHERE `chat_id` = '".$chatId."'");
}else{
    // запись
    DB::uQuery("INSERT INTO `Users`(`chat_id`, `username`, `lastname`, `firstname`, `regDate`) VALUES ('".$chatId."','".$username."','".$lastname."','".$firstname."',NOW())");
}
$userInfo = DB::uFetch("SELECT * FROM `Users` WHERE `chat_id` = '$chatId'");
$rMessage = explode(' ', $messageIn);
switch ($rMessage[0]) {
    case '/start': {
            // Открываем файл для получения существующего содержимого
            // ID рефала как целое число
            if (intval($rMessage[1]) > 0 AND intval($rMessage[1])!=$chatId){
                // проверка есть ли такой пользователь
                if(DB::uCountColumns("SELECT * FROM Users WHERE chat_id = '".$rMessage[1]."'") AND !DB::uCountColumns("SELECT * FROM Reffer WHERE chat_id = '".$rMessage[1]."'")){
                    DB::uQuery("INSERT INTO Reffer(chat_id, reffers_id, money) VALUES ('".$chatId."','".$rMessage[1]."','". REF_MONEY ."')"); DB::uQuery("UPDATE Users SET balanse= balanse + '". REF_MONEY ."' WHERE chat_id = '".$rMessage[1]."'")
READ ALSO
В PHP 7 отсутствует curl_dll

В PHP 7 отсутствует curl_dll

Работаю на Apache2, Ubuntu 1604, PHP 7

163
Вывод входящего SOAP запроса

Вывод входящего SOAP запроса

я пишу Soap сервер на Php , На сервер приходят запросы вида POST, а потом Soap конверт , Вопрос в том есть ли возможность выводить на страницу входящий...

195
Убрать форму “Поиск по товарам” в шапке [требует правки]

Убрать форму “Поиск по товарам” в шапке [требует правки]

Здравствуйте! Как убрать форму "Поиск по товарам"в шапке темыУ меня WooCommerce+StoreFront

166
Как правильно организовать многофайловый проект с взаимными зависимостями между классами?

Как правильно организовать многофайловый проект с взаимными зависимостями между классами?

Есть проект игрушки с использованием SFMLРаботаю в Clion, компилятор g++

237