Отправить "следующее" сообщение из телеграм бота на PHP
Вопрос прозвучит довольно таки глупым, прошу сильно не ругать. Прежде никак не сталкивался с ботами. Собственно бот для заказа допустим воды. После старта бот спрашивает хотите ли заказать и если последует ответ ДА бот скажет отправьте свой контакт. и если юзер отправит свой контакт то после отправки контакта бот должен отправить уже следующее сообщение с вопросом введите ФИО и после фио уже другой вопрос и т д. Но у меня после отправки контакта заново спрашивает хотите вы заказать и не идет дальше. Помогите пожалуйста. А вот собственно и код.
<?php
$data = json_decode(file_get_contents('php://input'), TRUE);
file_put_contents('file.txt', '$data: '.print_r($data, 1)."\n", FILE_APPEND);
$data = $data['callback_query'] ? $data['callback_query'] : $data['message'];
define('TOKEN', '0000000000:собственно сам токен полученный у bot father');
$message = mb_strtolower(($data['text'] ? $data['text'] : $data['data']),'utf-8');
$method = 'sendMessage';
$send_data = [
'text' => 'Хотите ли вы заказать?',
'reply_markup' => [
'resize_keyboard' => true,
'keyboard' => [
[
['text' => 'Да'],
['text' => 'Нет'],
]
]
]
];
if ($message=='да')
{
$method = 'sendMessage';
$send_data = [
'text' => 'Пожалуйста нажмите на кнопку отправить контакт',
'reply_markup' => [
'resize_keyboard' => true,
'keyboard' => [
[
['text' => 'Отправить контакт','request_contact'=>true],
]
]
]
];
$contact=$data['contact']['phone_number'];
}
elseif (isset($contact)) {
$method = 'sendMessage';
$send_data = ['text' => 'Напишите ФИО'];
}
elseif ($message=='нет')
{
$method = 'sendMessage';
$send_data = ['text' => 'Спасибо, приходите еще'];
}
$send_data['chat_id'] = $data['chat'] ['id'];
$res = sendTelegram($method, $send_data);
function sendTelegram($method, $data, $headers = [])
{
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_POST => 1,
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'https://api.telegram.org/bot' . TOKEN . '/' . $method,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => array_merge(array("Content-Type: application/json"))
]);
$result = curl_exec($curl);
curl_close($curl);
return (json_decode($result, 1) ? json_decode($result, 1) : $result);
}
?>
Ответы (1 шт):
Мне кажется, вам надо познакомиться с ООП. Это такой способ думать о программе как о взаимодействии объектов. Это очень естественный для людей способ думать, поэтому он помогает организовать код.
У вас есть бот (объект). Бот умеет отправлять сообщения (объекты), пользователь (тоже объект) на эти сообщения может давать ответы (объекты) в зависимости от которых, бот отправит новые сообщения. Получается, что бот -- это набор сообщений и знание о том, какое сообщение текущее; сообщение -- это текст и варианты ответов; вариант ответа -- это текст и ссылка на следующее сообщение.
Если вы ещё не изучили средства ООП в php, то можно обойтись и ассоциативными массивами.
<?php
$bot = [
'currentMessage' => null,
'messages' => [
0 => [
'text' => 'Хотите ли вы заказать?',
'answers' => [
[
'text' => 'Да',
'next' => 1,
],
[
'text' => 'Нет',
'next' => 3,
],
],
],
1 => [
'text' => 'Пожалуйста нажмите на кнопку отправить контакт',
'answers' => [
[
'text' => 'Отправить контакт',
'next' => 2
],
],
],
2 => [
'text' => 'Напишите ФИО',
'answers' => [],
],
3 => [
'text' => 'Спасибо, приходите еще',
'answers' => [],
],
],
];
Пока тут нет кода логики. Но думаю, что глядя на эту структуру, вы уже можете понять, как эта логика будет устроена. Вся фишка в том, что объекты одного типа имеют одинаковую структуру и могут быть обработаны одинаково.
Проговорим логику словами:
1. Узнать какое сообщение текущее
В своём примере вы делаете это косвенно. Если ответ "нет", то подразумевается, что текущий вопрос "Хотите ли вы заказать?". Можно оставить и так, но лучше передавать текущее сообщение в явном виде (API телеграм бота наверняка поддерживает какой-нибудь идентификатор сообщения).
2. Найти ответ пользователя в текущем сообщении
Можно просто сопоставить текст ответа или использовать идентификаторы.
3. Перейти к следующему сообщению
Следующее сообщение указано в next ответа. Если сообщение не предусматривает ответов, то диалог заканчивается.
function messages_getMessage(array $messages, int $messageId): ?array {
return $messages[$messageId]?? null;
}
function answers_getAnswer(array $answers, string $answerId): ?array {
$result = null;
foreach ($answers as $answer) {
if ($answer['text'] === $answerId) {
$result = $answer;
break;
}
}
return $result;
}
function bot_init(array &$bot, int $messageId) {
$message = messages_getMessage($bot['messages'], $messageId);
if ($message) {
$bot['currentMessage'] = $message;
} else {
// тут можно как-то обработать ошибку, я просто начну с начала
$bot['currentMessage'] = $bot['messages'][0];
}
}
function bot_reply(array &$bot, string $answerId): array {
$answer = answers_getAnswer($bot['currentMessage']['answers'], $answerId);
if ($answer) {
$bot['currentMessage'] = $bot['messages'][$answer['next']];
}
return $bot['currentMessage'];
}
// например
bot_init($bot, 0);
$message = bot_reply($bot, ''); // начинаем диалог
echo $message['text'] . "\n";
$answer = readline( implode("/", array_column($message['answers'], 'text')) . ":\n");
$message2 = bot_reply($bot, $answer);
echo $message2['text'] . "\n";
Остаётся только завязать это с телеграмом. Думаю, вы справитесь. Думайте о программе как о взаимодействии объектов и тогда код перестанет быть загадкой. В первую очередь важно кто и что делает, как делает -- это второй вопрос.