
Подробнее о хостинге для размещения Телеграм бота можно узнать из статьи
Взаимодействие пользователя с ботом должно быть интуитивным. Пользователь должен понимать, как общаться с ботом чтобы получить необходимый результат. Давайте рассмотрим какие есть способы взаимодействия с ботом.
При открытии бота по умолчанию сразу доступна кнопка Старт, при нажатии, на которую будет начат диалог и в бот будет отправлена команда /start
. Уже здесь мы можем поймать эту команду, обработать и выполнить какие-то действия. Вместе с этой командой в бот отправляется минимальная информация о пользователе:
У каждого бота есть ссылка, которая открывает диалог с ним в Telegram — https://telegram.me/ИМЯ_БОТА. К этой ссылке можно добавить параметры start
или startgroup
со значениями. Значение может быть длиной от 1 до 64 символов и состоять из букв латинского алфавита (больших - A-Z и маленьких - a-z), цифр - 0-9, нижнего подчеркивания _ и тире -.
https://telegram.me/ИМЯ_БОТА?start=ВАШЕ_ЗНАЧЕНИЕ
Telegram Bot API рекомендует использовать base64url для кодирования параметров с двоичным и другими типами контента.
По ссылке с параметром start будет открыт диалог с ботом, с кнопкой Старт в месте поля ввода. Если используется параметр startgroup, пользователю будет предложено выбрать группу для добавления бота.
Как только пользователь подтвердит действие (нажмет кнопку Пуск в своем приложении или выберет группу для добавления бота), ваш бот получит сообщение от этого пользователя в таком формате:
/start ВАШЕ_ЗНАЧЕНИЕ
Для удобства пользователя, можно через настройки Commands
вашего бота у @BotFather, задать список поддерживаемых ботом команд. Тогда при вводе знака слеш /
, пользователь увидит все команды и сможет сразу их отправить, просто нажав на одну из них. Каждая команда состоит из собственно командного слова, начинающегося со слеша и короткого описания:
/invoice Выписать счет
Для управления ботом вы как создатель бота предполагаете какой-то сценарий. Пользователю чтобы получить от бота желаемый результат нужно отправить команду. Бот, когда получит команду обработает ее и отреагирует по установленному вами сценарию. Но представьте, что пользователь написал команду с ошибкой, бот в этом случае должен предупредить что команда не распознана и попросить попробовать еще раз. Это не совсем удобно пользователю, и он может пойти искать другого бота с аналогичными возможностями. Вы можете потерять потенциального клиента, это не совсем хорошо.
В этом случае нам помогут клавиатуры. Ее нужно просто после старта диалога с ботом вывести на экран пользователю, и когда тот нажмет на нужную ему кнопку, боту отправиться заложенная вами правильная команда. В этом случае уходим от возможных ошибок, интерфейс бота выглядит более приветливо и профессионально. Качество бота повышается.
С каждым сообщением бот может отправлять разный набор кнопок как по количеству, так и по назначению. Кнопки можно расположить непосредственно под сообщением (InlineKeyboardButton), или зафиксировать под тестовым полем для ввода сообщения (KeyboardButton). Различия в них очень существенные на мой взгляд. Давайте рассмотрим некоторые их возможности.
Этот объект представляет одну кнопку клавиатуры, располагающуюся под текстовым полем для отправки сообщения. Поставляется она в интерфейс приложения в наборе с другими аналогичными кнопками через объект ReplyKeyboardMarkup. В качестве параметров с ним можно передать:
Если будет заполнен только обязательный параметр text, то при нажатии на кнопку будет отправлено текстовое сообщение с содержанием из этого параметра. Если будет включено дополнительно одно из необязательных параметров или локация, или контакт, то будет отправлен или контакт, или локация соответственно. Необязательные параметры взаимоисключающие.
Помимо набора кнопок в объект ReplyKeyboardMarkup можно передать еще ряд параметров:
При необходимости удалить клавиатуру используйте объект ReplyKeyboardRemove.
Это объект одной кнопки встроенной клавиатуры. Располагается набор таких кнопок сразу под сообщением. С помощью этого объекта можно передать кнопке url, или использовать его для голосования как одним из вариантов. В любом случае можно сделать много интересного и полезного. Рассмотрим его возможности на практике чуть ниже. Передается в наборе с другими аналогичными кнопками через объект InlineKeyboardMarkup. Принимает параметры:
Предлагаю рассмотреть поближе возможности клавиатур. Для примера я сделаю 4 кнопки: 2 KeyboardButton и 2 InlineKeyboardButton. Для этого будем работать с теми же инструментами, которые были в предыдущей статье. Добавим только несколько новых методов.
Логика скрипта будет простая, при старте бот будет выводить сообщение о готовности и 2 кнопки Голосовать и Помощь. При нажатии на кнопку Помощь - выведется сообщение с небольшой инструкцией, а при нажатии на кнопку Голосовать на экране появиться сообщение и под ним 2 кнопки, при нажатии на которые произойдет увеличения счетчика.
Чтобы обрабатывать команды от всех типов кнопок нам надо составить условия проверки. В моем примере от кнопки KeyboardButton команда приходит в виде обычного текстового сообщения вместе с объектом Message под ключом text, а от кнопки InlineKeyboardButton в объекте CallbackQuery под ключом data.
<?php
// если это просто объект message
if (array_key_exists('message', $arrData)) {
// получаем id чата
$chat_id = $arrData['message']['chat']['id'];
// текстовое значение
$message = $arrData['message']['text'];
// если это объект callback_query
} elseif (array_key_exists('callback_query', $arrData)) {
$chat_id = $arrData['callback_query']['message']['chat']['id'];
$message = $arrData['callback_query']['data'];
}
?>
Кнопки будем отправлять в параметре reply_markup в методе sendMessage. Набор кнопок идет в таком формате:
Массив данных (
'Тип клавиатуры' =>
Массив строк кнопок (
Массив кнопок строки (
Массив параметров кнопки (
)
)
),
// если предусмотрено
'Дополнительный параметр',
)
Создадим два метода для разных клавиатур, на входе принимают массив строк кнопок, на выходе строку в формате JSON.
<?php
private function getInlineKeyBoard($data)
{
$inlineKeyboard = array(
"inline_keyboard" => $data,
);
return json_encode($inlineKeyboard);
}
private function getKeyBoard($data)
{
$keyboard = array(
"keyboard" => $data,
"one_time_keyboard" => false,
"resize_keyboard" => true
);
return json_encode($keyboard);
}
?>
Сам набор кнопок будет выглядеть вот так.
<?php
$justKeyboard = $this->getKeyBoard([[["text" => "Голосовать"], ["text" => "Помощь"]]]);
$inlineKeyboard = $this->getInlineKeyBoard([[
['text' => hex2bin('F09F918D') . ' 0', 'callback_data' => 'vote_1_0_0'],
['text' => hex2bin('F09F918E') . ' 0', 'callback_data' => 'vote_0_0_0']
]]);
?>
Во встроенных кнопках (inlineKeyboardButton) в качестве значения параметра callback_data будем передавать служебную информацию в виде action_type_count1_count2
, где
В значении параметра text передаем бинарный код эмодзи в кодировке UTF-8 (список эмодзи), которые преобразуются из шестнадцатеричных данных в двоичные данные функцией hex2bin, и еще выведем текущее числовое значение счетчика кнопки.
Теперь нам остается только описать механизм определения команды и механизм ее обработки. Поэтому в методе init() создадим конструкцию оператора switch
<?php
switch ($message) {
// если начало диалога
case '/start':
$dataSend = array(
'text' => "Приветствую, давайте начнем нашу практику. Нажмите на кнопку Голосовать.",
'chat_id' => $chat_id,
// отправляем клавиатуру
'reply_markup' => $justKeyboard,
);
$this->requestToTelegram($dataSend, "sendMessage");
break;
// если пришла команда Голосовать
case 'Голосовать':
$dataSend = array(
'text' => "Выберите один из вариантов",
'chat_id' => $chat_id,
// отправляем встроенную клавиатуру
'reply_markup' => $inlineKeyboard,
);
$this->requestToTelegram($dataSend, "sendMessage");
break;
// если запросили Помощь
case 'Помощь':
$dataSend = array(
'text' => "Просто нажмите на кнопку Голосовать.",
'chat_id' => $chat_id,
);
$this->requestToTelegram($dataSend, "sendMessage");
break;
// если вызвана встроенная кнопка
case (preg_match('/^vote/', $message) ? true : false):
// получаем новую клавиатуру
$params = $this->setParams($message);
$dataSend = array(
'reply_markup' => $params[0],
'message_id' => $arrData['callback_query']['message']['message_id'],
'chat_id' => $chat_id,
);
// изменяем клавиатуру под выбранным сообщением
$this->changeVote($dataSend, $params[1], $arrData['callback_query']['id']);
break;
// незапланированное действие обрабатываем как поумолчанию
default:
$dataSend = array(
'text' => "Не запланированная реакция, может просто нажмете на кнопку Голосовать.",
'chat_id' => $chat_id,
);
$this->requestToTelegram($dataSend, "sendMessage");
break;
}
?>
Давайте разберемся, что в этом коде происходит. Оператор switch принимает значение $message, которое может быть, как просто текст сообщения (в том числе команды), так и значение объекта callbackQuery.
action
, в нашем случае это vote. Мы формируем новую клавиатуру изменяем в ней текстовое значение, увеличиваем счетчик у нажатой кнопки и подставляем новую служебную информацию в параметрах callback_data. Для создания новой клавиатуры мы используем метод setParams(), а для отправки изменений мы используем метод changeVote(). Здесь остановим внимание на методах Bot API
<?php
private function changeVote($data, $emoji, $callback_query_id)
{
// готовим текст уведомления взависимости от результата
// обновления клавиатуры у сообщения
$text = $this->requestToTelegram($data, "editMessageReplyMarkup")
? "Вы проголосовали " . hex2bin($emoji)
: "Непредвиденная ошибка, попробуйте позже.";
// отправляем уведомление при любом результате
$this->requestToTelegram([
'callback_query_id' => $callback_query_id,
'text' => $text,
'cache_time' => 3,
], "answerCallbackQuery");
}
private function setParams($data)
{
// разбиваем в массив по знаку _
$params = explode("_", $data);
// увеличиваем значение или левой или правой кнопки
$params[1] ? $params[2]++ : $params[3]++;
// готови клавиатуру с новыми значениями callback_data
$arr[] = $this->getInlineKeyBoard([[
[
'text' => hex2bin('F09F918D') . ' ' . $params[2],
'callback_data' => 'vote_1_' . $params[2] . '_' . $params[3]
],
[
'text' => hex2bin('F09F918E') . ' ' . $params[3],
'callback_data' => 'vote_0_' . $params[2] . '_' . $params[3]
]
]]);
// готовим эмодзи для уведомления
$arr[] = $params[1] ? 'F09F918D' : 'F09F918E';
return $arr;
}
?>
Мы рассмотрели некоторые способы взаимодействия между пользователем и ботом, в основном это элементы интерфейса бота. Исходный код можно скачать по этой ссылке. Далее нас ждет знакомство с медиа-файлами.
Авторизуйтесь через Telegram, чтобы оставить комментарий.
Откройте бот @SiteAuthBot,
нажмите кнопку Старт/Start. Следуйте инструкциям бота.
private function setFileLog($data)
{
$fh = fopen('log.txt', 'a') or die('can't open file');
((is_array($data)) || (is_object($data))) ? fwrite($fh, print_r($data, TRUE) . "n") : fwrite($fh, $data . "n");
fclose($fh);
}
private function setFileLog($chat_id, $data)
{
$fh = fopen('./log/' . $chat_id . '.log', 'a') or die('cant open file');
((is_array($data)) || (is_object($data))) ? fwrite($fh, print_r($data, TRUE) . "\n") : fwrite($fh, $data . "\n");
fclose($fh);
}
case 'Рефералы':
$reftitle = "Ваша реферальная ссылка: http://t.me/мой бот?start=".$chat_id;
$dataSend = array(
'text' => $reftitle,
'chat_id' => $chat_id,
);
$this->requestToTelegram($dataSend, "sendMessage");
break;
ТАК я формирую ссылкуdefault:
$dataSend = array(
'text' => "Не запланированная реакция.",
'chat_id' => $chat_id,
);
$this->requestToTelegram($dataSend, "sendMessage");
break;
case '/start':
$startinfo ="hi";
$dataSend = array(
'text' => $startinfo,
'chat_id' => $chat_id,
'reply_markup' => $justKeyboard,
);
$this->requestToTelegram($dataSend, "sendMessage");
break;
мне нужно 30 шт вывести из базы