Типы клавиатур в чат ботах
Сегодня познакомимся с существующими клавиатурами в ботах и тем, как их подключить и настроить.
Всего есть два типа клавиатур:
- ReplyKeyboardMarkup;
- InlineKeyboardMarkup.
ReplyKeyboardMarkup используется в случаях, когда вы хотите получить от пользователя конкретный ответ, предоставляя ему возможность не печатать ручками, а выбрать из предлагаемых вариантов. Иными словами, это заготовки текстовых сообщений. Расположены кнопки под полем ввода сообщения
InlineKeyboardMarkup - это более продвинутый вариант кнопок, за которыми скрыт дополнительный функционал. В данном случае кнопки прикрепляются непосредственно к сообщению от бота
В зависимости от выбранной кнопки могут последовать те или иные действия. Эту логику мы задаем в скрипте для каждой кнопки.
В приведенном примере мы хотим записать пользователя на маникюр и предлагаем ему определиться с днем (в качестве примера приведены только два варианта, но это можно закастомить).
После выбора того или иного дня бот внесет инфу в ГТ, а именно: дату, имя пользователя и ид чата.
Запись через чат имеет следующий вид
Здесь мы выбрали кнопку Сегодня и получили ответ от бота.
В ГТ при этом появилась строчка
Подключение и настройка
Каждая клава (инлайн-клавиатур может быть сколько угодно) записана в соответствующую переменную:
var INLINE_Days =
{
"inline_keyboard": [
[{"text": "Сегодня", "callback_data": "today"}],
[{"text": "Завтра", "callback_data": "tomorrow"}],
],
"resize_keyboard": true
}
var KEYBOARD =
{
"keyboard": [
["Записаться", "Отменить запись"]
],
"resize_keyboard": true
}
Обратите внимание, что синтаксис для инлайн (INLINE_Days) и обычной (KEYBOARD) клавиатур различается.
Клавиатурам можно добавить дополнительные свойства, мы использовали только resize_keyboard со значением true. Их не так много и они есть в документации телеграма.
Далее в коде обращаемся к клавам по имени переменной.
С ReplyKeyboardMarkup все достаточно просто. Она добавляется при первом прогоне скрипта, когда вы отправляете в чат команду /start, например.
Нам нужна функция, которая отправит в чат клавиатуру. Функция та же, что и при отправке сообщения ботом send(), за двумя исключениями:
- у функции появляется дополнительный параметр - keyboard;
- у объекта payload появляется доп свойство - reply_markup : JSON.stringify(keyboard)
Ниже скрипт функции отправки обычной клавы в чат:
function send_key (msg, chat_id, api, keyboard)
{
var payload = {
'method': 'sendMessage',
'chat_id': String(chat_id),
'text': msg,
'parse_mode': 'HTML',
reply_markup : JSON.stringify(keyboard)
}
var data = {
"method": "post",
"payload": payload
}
UrlFetchApp.fetch('https://api.telegram.org/bot' + api + '/', data);
}
Вызов функции осуществляется из тела функции doPost(e) одной строкой:
send_key("Поехали", chat_id, API_TOKEN, KEYBOARD)
Здесь всё.
Что касается инлайн-клавиатур.
Отправка клавиатуры наступает при определенном условии. Если пользователь отправил в чат слово “Записаться”, то отправляем ему нашу инлайн-клаву:
if (text == "Записаться") {
Demo.send_key("Выберите день", chat_id, API_TOKEN, INLINE_Days)
}
Переменная text содержит текст сообщения, которое мы и проверяем на соответствие.
Результатом выполнения функции send_key будет сообщение от бота Выберите день и кнопки под ним.
Далее нужно предусмотреть алгоритм обработки нажатия этих кнопок.
Если мы кликаем на какую-либо из кнопок (“Сегодня” или "Завтра"), то добавляем новую строку в ГТ и отправляем сообщение в чат, что запись создана.
if (data == "today")
{
let date = Demo.getNewDate(0);
let ind = get_ind(chat_id);
Clients.getRange(ind,1).setValue(user_name);
Clients.getRange(ind,2).setValue(chat_id);
Clients.getRange(ind,3).setValue(date);
Demo.send("Вы успешно записались. "+"Дата визита: "+ date, chat_id, API_TOKEN);
}
Ниже скрипт полностью (не забываем, что значения глобальных переменных у вас будут свои):
// Объявляем все нужные нам переменные. Док важно открывать именно по ID, а не брать активный док, т.к. запуск кода будет производить бот
const API_TOKEN = "1946675042:AAHg1HTHe42GhR9EEt0EdbR94j1G8pDcTWE";
const DOC = SpreadsheetApp.openById("1ALJLtLdt-LT7GEF4hawIizVeJXFnoPZCsC0pw7kcp70");
const Clients = DOC.getSheetByName("Clients");
const Calendar = DOC.getSheetByName("Calendar");
function api_connector ()
{
var App_link = "https://script.google.com/macros/s/AKfycbx9izXW_GcUvg-OlXuP9...";
UrlFetchApp.fetch("https://api.telegram.org/bot"+API_TOKEN+"/setWebHook?url="+App_link);
}
function doPost(e)
{
var update = JSON.parse(e.postData.contents);
if (update.hasOwnProperty('message'))
{
var msg = update.message;
var chat_id = msg.chat.id;
var text = msg.text;
var msg_array = msg.text.split(" ");
var date = (msg.date/86400)+25569.125;
var user = msg.from.username;
if (text == "Записаться") {
Demo.send_key("Выберите день", chat_id, API_TOKEN, INLINE_Days)
}
if (text == "Отменить запись") {
let ind = get_ind(chat_id);
Clients.getRange(ind,1,1,3).deleteCells(SpreadsheetApp.Dimension.ROWS);
Demo.send("Запись отменена", chat_id, API_TOKEN)
}
}
if (update.hasOwnProperty('callback_query'))
{
var data = update.callback_query.data;
var text = update.callback_query.message.text;
var id = update.callback_query.message.message_id;
var chat_id = update.callback_query.message.chat.id;
var user_name = update.callback_query.from.username;
if (data == "today")
{
let date = Demo.getNewDate(0);
let ind = get_ind(chat_id);
Clients.getRange(ind,1).setValue(user_name);
Clients.getRange(ind,2).setValue(chat_id);
Clients.getRange(ind,3).setValue(date);
Demo.send("Вы успешно записались. "+"Дата визита: "+ date, chat_id, API_TOKEN);
}
if (data == "tomorrow") {
let date = Demo.getNewDate(1);
let ind = get_ind(chat_id);
Clients.getRange(ind,1).setValue(user_name);
Clients.getRange(ind,2).setValue(chat_id);
Clients.getRange(ind,3).setValue(date);
Demo.send("Вы успешно записались. "+"Дата визита: "+ date, chat_id, API_TOKEN);
}
}
}
Отдельно ниже представлена доп функция, которая проверяет наличие ид в ГТ. Если ид уже есть в таблице, мы обновляем данные у строки с этим ид. В противном случае создаем новую строку.
function get_ind() {
let chat_id = 311157431;
let arr = Clients.getRange(1,2,Clients.getLastRow()).getValues()
arr = arr.flat()
let ind = arr.indexOf(chat_id)
if (ind > -1) {
ind = ind+1;
} else {
ind = Clients.getLastRow()+1;
}
return ind
}
ID для подключения библиотеки Demo: 1JkXEW_zfhr6v0TKsvU_ZbygNLpXEczxZcC46fMF_ffk-noMk8UKcMitz
Здесь также заметим, что клик по кнопке в инлайн клавиатуре отправляет боту JSON со свойством callback_query. Это значит, что нам нужны дополнительные переменные, в которые мы запишем значения из этого JSON пакета.
Это краткая вводная в мир клавиатур. Скоро будут посты про простые сервисы, куда будут добавлены и доработаны те же клавиатуры и доп функции.
MS, Libreoffice & Google docs
756 постов15K подписчик
Правила сообщества
1. Не нарушать правила Пикабу
2. Публиковать посты соответствующие тематике сообщества
3. Проявлять уважение к пользователям
4. Не допускается публикация постов с вопросами, ответы на которые легко найти с помощью любого поискового сайта.
По интересующим вопросам можно обратиться к автору поста схожей тематики, либо к пользователям в комментариях
Важно - сообщество призвано помочь, а не постебаться над постами авторов! Помните, не все обладают 100 процентными знаниями и навыками работы с Office. Хотя вы и можете написать, что вы знали об описываемом приёме раньше, пост неинтересный и т.п. и т.д., просьба воздержаться от подобных комментариев, вместо этого предложите способ лучше, либо дополните его своей полезной информацией и вам будут благодарны пользователи.
Утверждения вроде "пост - отстой", это оскорбление автора и будет наказываться баном.