Задать вопрос
@fakin_kiska
Telegram Bots and iOS

Как вывести ответ после нажатия на кнопку?

Возникла следующая проблема - написал бота в телеграме (без библиотек), подключил к нему вебхук и застрял на моменте с кнопками, а точнее с обработкой запроса после нажатия на них. По идее после нажатия должно прийти другое сообщение от бота, но в итоге ничего не приходит в ответ.

Исполняемый код бота:

<?php

include 'config.php'; // Токен бота
include 'functions.php'; // Основные функции

// В теле запроса содержится JSON, php://input читает сырой запрос, а json_decode расшифровывает в виде массива
$update = json_decode(file_get_contents('php://input'), JSON_OBJECT_AS_ARRAY);

$chat_id = $update['message']['chat']['id']; // Определяет ID чата
$message = $update['message']['text']; // Определяет текст сообщения
$message_id = ['callback_query']['message']['message_id']; // Определяет ID сообщения

$callback_query = $update['callback_query'];
$callback_query_id = $callback_query['id'];
$callback_data = $callback_query['data'];

// Делается запрос
$method = 'setWebhook';
$url = 'https://api.telegram.org/bot' . BOT_TOKEN . '/' . $method;
$options = [
    'url' => 'https://example.ru/bot.php'
];

// То, что возвращается из запроса
$response = file_get_contents($url . '?' . http_build_query($options));
var_dump($response);

if (strpos($message, "/help") === 0) { // Команда /help
    $post = [
      'chat_id' => $chat_id,
      'text' => 'Эта памятка создана для объяснения различных
терминов, посуды',
        $help_buttons = [
            [['text' => 'Термины ', 'callback_data' => 'terms']],
            [['text' => 'Посуда / Штучки ', 'callback_data' => 'dishes']]
        ],
        'reply_markup' => inline_keyboard($help_buttons),
    ];
    sendRequest('sendMessage', $post);
} else {
// Начальное сообщение
    $post = [
        'chat_id' => $chat_id,
        'text' => 'Давай определимся с категорией коктейлей:',
        $main_menu = [
            [['text' => 'Незабываемые', 'callback_data' => 'the_unforgettables']],
            [['text' => 'Современная Классика', 'callback_data' => 'contemporary_classic']],
            [['text' => 'Напитки Новой Эры', 'callback_data' => 'new_era_drinks']]
        ],
        'reply_markup' => inline_keyboard($main_menu)
    ];
    sendRequest('sendMessage', $post);
}

switch ($callback_data) {
    case 'the_unforgettables':
        $post = [
            'chat_id' => $chat_id,
            'text' => 'Отлично, теперь выбери любой коктейль из списка:',
            $InlineTheUnforgettables = [
                [['text' => 'Негрони', 'callback_data' => 'negroni']],
                [['text' => 'Манхэттен', 'callback_data' => 'manhattan']],
                [['text' => 'Американо', 'callback_data' => 'americano']]
            ],
            'reply_markup' => inline_keyboard($InlineTheUnforgettables),
        ];
        sendRequest('sendMessage', $post);
        break;
}


Функция отправки сообщений:

function sendRequest($method, $params = [])
{
    if (!empty($params)) {
        $url = BOT_URL . $method . '?' . http_build_query($params);
    } else {
        $url = BOT_URL . $method;
    }
    return json_decode(
        file_get_contents($url),
        JSON_OBJECT_AS_ARRAY
    );
}


В то же время в вебхуке висит следующая ошибка:

string(64) "{"ok":true,"result":true,"description":"Webhook is already set"}"
Warning: file_get_contents(https://api.telegram.org/bot[BOT_TOKEN]/sendMessage?
text=%D0%94%D0%B0%D0%B2%D0%B0%D0%B9+%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B8%D0%B
C%D1%81%D1%8F+%D1%81+%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D0%B5%D0%B9+%D0%BA%
D0%BE%D0%BA%D1%82%D0%B5%D0%B9%D0%BB%D0%B5%D0%B9%3A&0%5B0%5D%5B0%5D%5Btext%5D=%D0%9D%D0%B5
%D0%B7%D0%B0%D0%B1%D1%8B%D0%B2%D0%B0%D0%B5%D0%BC%D1%8B%D0%B5+%E2%99%BE&0%5B0%5D%5B0%5D%5B
callback_data%5D=the_unforgettables&0%5B1%5D%5B0%5D%5Btext%5D=%D0%A1%D0%BE%D0%B2%D1%80%D0
%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F+%D0%9A%D0%BB%D0%B0%D1%81%D1%81%D0%B8%D0%BA%D0%B0+
%F0%9F%8D%B9&0%5B1%5D%5B0%5D%5Bcallback_data%5D=contemporary_classic&0%5B2%5D%5B0%5D%5Bte
xt%5D=%D0%9D%D0%B0%D0%BF%D0%B8%D1%82%D0%BA%D0%B8+%D0%9D%D0%BE%D0%B2%D0%BE%D0%B9+%D0%AD%D1
%80%D1%8B+%F0%9F%86%95&0%5B2%5D%5B0%5D%5Bcallback_data%5D=new_era_drinks&reply_markup=%7B
%22inline_keyboard%22%3A%5B%5B%7B%22text%22%3A%22%5Cu041d%5Cu0435%5Cu0437%5Cu0430%5Cu0431
% in /home/db_name/public_html/example.ru/functions.php on line 12


То есть вебхук жалуется на эту строчку - file_get_contents($url)

В чем конкретно может быть ошибка и как ее можно исправить? Является ли она причиной того, что при нажатии на кнопку не выводится другое сообщение бота?
  • Вопрос задан
  • 95 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
@fakin_kiska Автор вопроса
Telegram Bots and iOS
Сначала я разобрался с ошибкой в вебхуке - причину ее возникновения я не нашел, так как в файле поле description отсутствовало, следовательно из-за чего конкретно вылезала ошибка было трудно понять. Я заменил функцию отправки сообщений на другую:

function sendRequest($method, $post = '') {
$ch = curl_init('https://api.telegram.org/bot' . BOT_TOKEN . '/' . $method);

if ($post) {
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
}

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}


Она работает так же и ошибок не вызывает.

Затем я разобрался с обработкой кнопок, точнее их обратных запросах (callback_query/callback_data). Я создал два файла - data, где я получаю chat_id, message, message_id, это мне нужно для отправки первичных сообщений (по типу приветствия, команд). Затем создал файл callback_query, куда поместил следующие строки -

<?php

$data = json_decode(file_get_contents('php://input'));


    $callback_query = $data->callback_query;
    $callback_query_id = $callback_query->id;
    $callback_data = $callback_query->data;

    $from = $callback_query->from;

    $user_id = $from->id;
    $username = $from->username;

    $message = $callback_query->message;
    $message_id = $message->message_id;
    $callback_message_text = $message->text;

    $chat = $message->chat;
    $chat_id = $chat->id;

    $inline_message_id = $callback_query->inline_message_id;


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

<?php

include 'config.php'; // Токен бота
include 'functions.php'; // Основные функции
include 'data.php'; // Получение данных

// Делается запрос
$method = 'setWebhook';
$url = 'https://api.telegram.org/bot' . BOT_TOKEN . '/' . $method;
$options = [
    'url' => 'https://example.ru/bot.php'
];

// То, что возвращается из запроса
$response = file_get_contents($url . '?' . http_build_query($options));
var_dump($response);

if (strpos($message, "/help") === 0) { // Команда /help
    $post = [
      'chat_id' => $chat_id,
      'text' => 'Эта памятка создана для объяснения различных барменских
терминов, посуды',
        $help_buttons = [
            [['text' => 'Термины ', 'callback_data' => 'terms']],
            [['text' => 'Посуда / Штучки ', 'callback_data' => 'dishes']]
        ],
        'reply_markup' => inline_keyboard($help_buttons)
    ];
    sendRequest('sendMessage', $post);
} else {
// Начальное сообщение
    $post = [
        'chat_id' => $chat_id,
        'text' => 'Давай определимся с категорией коктейлей:',
        $main_menu = [
            [['text' => 'Незабываемые ♾', 'callback_data' => 'the_unforgettables']],
            [['text' => 'Современная Классика ', 'callback_data' => 'contemporary_classic']],
            [['text' => 'Напитки Новой Эры ', 'callback_data' => 'new_era_drinks']]
        ],
        'reply_markup' => inline_keyboard($main_menu)
    ];
    sendRequest('sendMessage', $post);
}

include 'callback_query.php'; // Получение обратных запросов

switch ($callback_data) {
    case 'the_unforgettables':
        $post = [
            'chat_id' => $chat_id,
            'message_id' => $message_id,
            'text' => 'Отлично, теперь выбери любой коктейль из списка:',
            $InlineTheUnforgettables = [
                [['text' => 'Negroni', 'callback_data' => 'negroni']],
                [['text' => 'Manhattan', 'callback_data' => 'manhattan']],
                [['text' => 'Americano', 'callback_data' => 'americano']],
                [['text' => 'Daikiri', 'callback_data' => 'daiqiri']],
                [['text' => 'Old Fashioned', 'callback_data' => 'old_fashioned']],
                [['text' => 'Ramos Fizz', 'callback_data' => 'ramos_fizz']],
                [['text' => 'Clover Club', 'callback_data' => 'clover_club']],
                [['text' => 'Gin Fizz', 'callback_data' => 'gin_fizz']],
                [['text' => 'Vieux Carre', 'callback_data' => 'vieux_carre']],
                [['text' => 'Sazerac', 'callback_data' => 'sazerac']]
            ],
            'reply_markup' => inline_keyboard($InlineTheUnforgettables),
        ];
        sendRequest('editMessageText', $post);
        break;
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы