Про сам процесс создания бота в интернете есть огромное количество статей, самый подробный по ссылке ниже:
https://sendpulse.com/ru/knowledge-base/chatbot/create-telegram-chatbot
поэтому я опишу этот этап очень коротко — необходимо обратиться к @BotFather, затем выполнить команду /newbot , указать имя бота и его username по которому его можно будет найти в телеграме.
Cамое важное что нужно — это API Token.
Все запросы к телеграм боту должны обслуживаться через HTTPS и должны быть представлены в следующей форме: https://api.telegram.org/bot/METHOD_NAME
То есть мне понадобится ссылка на телеграм через которую бот будет получать данные с «серверной» (гугл таблицы) стороны
Сохраняю их в скрипт:
const botToken = 'token'
const telegramUrl = "https://api.telegram.org/bot" + botToken + "/";
Как устроен бот
Есть два взаимоисключающих способа получения обновлений для бота — метод getUpdates и Webhooks.
Разница между ними такая же, как разница между «тянуть» и «толкать». При Webhooks бот не будет делать ничего, пока его об этом не попросит пользователь путем команд либо со своей стороны либо со стороны сервера, при getUpdates все происходит с точностью наоборот — бот сам обращается к серверу и спрашивает его на предмет изменений.
В силу все тех же ограничений и квот гугла, мне больше подходит Webhooks.
Предварительные действия
Для того, чтобы бот начал общаться с таблицей их необходимо связать.
Так как все общение бота происходит через https, рабочий скрипт надо «deploy as Web app» — в таком случае гугл дает ссылку на веб апп. И вот тут есть нюанс. Если коротко — каждое изменение в коде при «deploy as web app» надо деплоить заново. Это жутко неудобно когда разрабатываешь и тестируешь функционал бота, потому что каждый раз ссылка новая и в боте надо удалять текущий вебхук и прописывать новый вебхук.
Данная проблема лечится двумя способами:
- Через создание дополнительной библиотеки
- Через старый режим среды разработки: для этого необходимо перейти в устаревшую версию «Использовать устаревшую версию» и выбрать
И получить ссылку(1) на web app и так же ее скопировать куда-нибудь
После этого еще раз открыть «Развернуть как веб-приложение…» и нажать Disable web app
Затем снова проделать развертывание веб-приложения и еще раз скопировать ссылку(2)
Далее сравнить ссылку(1) с ссылкой(2) — ссылка(2) должна быть короче.
При таком сценарии в случае сохранения заново деплоить ничего не надо — все будет автоматически сохраняться.
Далее можно вернуться в новый режим и прописать ссылку(2) в переменную.
const googleUrl = "https://script.google.com/macros/s/short_symbols/exec";
Установка вебхука
Итак, у меня есть телеграм токен, телеграм ссылка для общения и гугл-ссылка для приема и передачи данных бота. Осталось их связать:
// Установка вебхука в телеграме
function setWebHook() {
const url = telegramUrl+"setWebhook?url="+googleUrl;
const response = UrlFetchApp.fetch(url).getContentText();
const textResponse = JSON.parse(response);
console.log(textResponse)
}
скрипт выполняется разово и в результате console.log выведет что вебхук установлен. Если запустить скрипт еще раз, то со стороны телеграма придет следующий ответ:
Удаление вебхука
Тоже понадобится как по причинам описанным выше, так и просто потому, что в функционале бота в какой-то момент не будет необходимости. Скрипт так же выполняется единожды
// Удаление вебхука в телеграме
function deleteWebHook() {
const url = telegramUrl+"deleteWebhook?url="+googleUrl;
const response = UrlFetchApp.fetch(url).getContentText();
const textResponse = JSON.parse(response);
console.log(textResponse)
}
Общение бота с таблицей — doPost(e)
И вот я подошел к самой интересной части. Пути прописаны, вебхук установлен. Пора получить от бота что-то в таблицу.
function doPost(e){
const main = JSON.parse(e.postData.contents); // получаем данные из телеграм бота
wsDebug.getRange(1,1).setValue(JSON.stringify(main, null, 5));
}
Все что приходит от телеграма на гугловый web app есть объект е и он имеет следующие параметры:
https://developers.google.com/apps-script/guides/web
e.postData.contents — основное «тело», в котором содержится все необходимое, что приходит от телеграм бота.
И тут надо сделать оговорку: гугл скрипт не позволяет делать console.log в функции doPost()
Чтобы увидеть что приходит со стороны телеграма я создал лист «Debug»
const wsDebug = ss.getSheetByName("Debug")
и в первую ячейку записываю все то, что пришло
wsDebug.getRange(1,1).setValue(JSON.stringify(main, null, 5));
Что такое JSON.parse
Обычно JSON используется для обмена данными с / на веб-сервер. При получении данных с веб-сервера такие данные всегда являются строкой. JSON.parse делает их объектом JavaScript.
Что такое JSON.stringify
При отправке данных на веб-сервер данные должны быть строкой. Преобразование объекта JavaScript в строку осуществляется с помощью JSON.stringify.
А зачем тогда строку сначала парсить в объект, а потом обратно конвертить в строку?
Спросите вы 🙂
Все дело в том, что если записать в ячейку объект то ИМЕННО вид он будет иметь следующий т.е. неудобно читаемый:
Если же записывать через JSON.stringify(main, null, 5), то строка вид будет иметь «приятный и понятный»:
Итак я получаю данные от телеграма. Теперь их надо как-то обработать и куда-то записать. А еще надо в телеграм передать данные. И об этом — в следующей части
Ваше мнение важно и может улучшить блог
Я хочу услышать ваше мнение и ваши идеи о том, как сделать этот сайт еще лучше. Примите участие в опросе, чтобы поделиться вашими пожеланиями, предложениями и замечаниями. Пройдите опрос сейчас и помогите сделать этот сайт более полезным для вас!