Пишем телеграм-бота. Часть 2: Создание бота и привязка его к гугл таблице

Про сам процесс создания бота в интернете есть огромное количество статей, самый подробный по ссылке ниже:

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), то строка вид будет иметь «приятный и понятный»:

Итак я получаю данные от телеграма. Теперь их надо как-то обработать и куда-то записать. А еще надо в телеграм передать данные. И об этом — в следующей части


Ваше мнение важно и может улучшить блог

Я хочу услышать ваше мнение и ваши идеи о том, как сделать этот сайт еще лучше. Примите участие в опросе, чтобы поделиться вашими пожеланиями, предложениями и замечаниями. Пройдите опрос сейчас и помогите сделать этот сайт более полезным для вас!

Добавить комментарий