Найти в Дзене
КиберMamedov 💻🔥

Телеграм-бот на гугл таблицах

Сегодня можно найти библиотеки для создания телеграм ботов практически на каждый язык программирования. Но как только мы создаем бота, то упираемся в две вещи:

  1. Где развертывать созданного бота;
  2. Какую базу данных использовать.

В данной статье я предложу бесплатный и удобный способ, который отвечает на оба вопроса. У каждого из нас есть учетная запись в гугл, а многие уже давно перешли от обычных excel файлов на гугл таблицы. И ответ кроется в том, что гугл таблицы будут выступать в роли базы данных, где мы можем хранить все необходимые данные, а сервером будет являться сам гугл. Дело в том, что гугл предоставляет возможность создавать собственные сценарии на языке ActionScript, синтаксически - это тот же JavaScript.

Думаю вводную часть закончили, теперь давай перейдем к проекту. Давайте рассмотрим какую-то практическую задачу и на её примере будем разрабатывать бота.

Представим, что вы являетесь руководителем какого-то подразделения и у вас есть зарплатная ведомость и своим сотрудникам необходимо каким-то образом отправлять информацию об их ЗП, надбавкам и т.д. отдельно каждому. Естественно в первую очередь вы это начинаете делать руками, но со временем это начинает съедать все больше времени и требуется автоматизировать данный процесс. Тут вам приходит идея, что у всех ваших сотрудников есть телеграм, в который вы и так руками отправляли информацию. А что если, эту информацию будет отправлять бот? Звучит логично и позитивно.

Но перед тем, как работать с ведомостью, в первую очередь необходимо обеспечить регистрацию пользователей, а для этого они должны оставить свои минимальные данные, которые в итоге будут связывать данные из ведомости с учетными данными телеграмма. Сегодня решим эту задачу.

Данная тема предполагает цикл статей, где последовательно, шаг за шагом мы будем проходить весь путь разработки от идеи к её реализации. А сейчас для работы нам понадобится:

  1. Гугл таблица;
  2. Бот созданный в телеграм.

Переходи в свой гугл диск и в любой из папок создай новую таблицу.

Новая гугл таблица
Новая гугл таблица

Как мы уже обсудили, в первую очередь нам необходимо решить вопрос с регистрацией наших сотрудников в боте. Для этого выделим отдельную вкладку, т.е. просто переименуем вновь созданную вкладку и назовем её users.

Переименовали вкладку
Переименовали вкладку

Данная вкладка будет у нас играть роль таблицы users, если бы мы использовали привычную реляционную базу данных. Теперь переходим в телеграм и создаем нового бота. Для этого необходимо найти бота отца @BotFather.

Учетная запись бота отца
Учетная запись бота отца

Теперь создайте нового бота, для этого необходимо выбрать в меню пункт новый бот.

Создаем нового бота
Создаем нового бота

После нажатия телеграм попросит вас ввести название нового бота, я своего назвал мой маленький помощник “MyLittleHelper”.

После ввода имени бота нажимайте кнопку отправить
После ввода имени бота нажимайте кнопку отправить

Теперь телеграм просит нас ввести пользовательское имя бота, оно должно быть уникальным и в конце должно содержать _bot.

Подбираем уникальное пользовательское имя для бота
Подбираем уникальное пользовательское имя для бота

Если пользовательское имя вы подобрали уникальным, то вам будет выдано поздравление и ключ, который нам необходим в программе.

Получение токена
Получение токена

Копируйте этот токен и переходите в гугл таблицу, выбирайте в главном меню ФайлApps Script.

Открываем редактор кода
Открываем редактор кода

Открывается редактор кода, в котором давай сразу напишем все необходимые для нас константы:

  • TOKEN - токен вашего бота;
  • DEPLOYMENT_ID - это код развертывания вашего приложения, чуть позже мы его заполним, пока оставь пустым;
  • URI = `https://script.google.com/macros/s/${DEPLOYMENT_ID}/exec` - ссылка на выполнение развертывания, обрати внимание, что в неё вставляется код развертывания. К сожалению есть небольшое неудобство в гугл таблицах, оно выражается в том, что при работе с запуском скрипта из вне, каждое изменение нужно развертывать. Позже ты поймешь о чем идет речь;
  • ACTIVE_SPREADSHEET - таблица с которой работаем
  • USER_TAB - вкладка пользователи, в которой будет происходить регистрация сотрудников.
Создаем константы
Создаем константы

Получение активной таблицы SpreadsheetApp.getActiveSpreadsheet() состоит из двух частей:

  1. SpreadsheetApp - это класс в Google Apps Script, который предоставляет доступ к гугл таблицам. Он предлагает различные методы для манипулирования электронными таблицами;
  2. Один из таких методов getActiveSpreadsheet(), который в Google Apps Script возвращает текущую активную таблицу или null, если таковой нет.

В данной строке ACTIVE_SPREADSHEET.getSheetByName("users") мы обращаемся к таблице и получаем вкладку по её имени используя для этого метод getSheetByName.

Нам необходимо работать с таблицей, поэтому сразу создадим функцию, которая будет записывать данные в конкретную ячейку.

Функция для записи значения в конкретную ячейку таблицы
Функция для записи значения в конкретную ячейку таблицы

В константе USER_TAB у нас хранится текущая вкладка users, а используя метод setActiveSelection мы выбираем ячейку по имени, которое придет в аргументе cell. Метод setNumberFormat('@STRING@') устанавливает строковый формат ячейки, а метод setValue записывает значение из аргумента функции value в ячейку.

Забегая наперед скажу, что нам при регистрации логично сохранять дату и время регистрации, а телеграм в ответ отправит нам не стандартную дату, а количество секунд с 1 января 1970 года. Предлагаю сразу создать функцию, которая будет переводить это значение в дату и время.

Функция для перевода секунд в дату и время
Функция для перевода секунд в дату и время

Теперь главная вещь, которая нам нужна - это функция отправки сообщения в чат телеграм. Не буду вас мучить походами в документацию телеграм, просто получите готовую функцию со всеми параметрами.

Функция отправки сообщения в чат телеграм
Функция отправки сообщения в чат телеграм

Аргумент функции chatId будет получать идентификатор чата с сотрудником, которому необходимо отправить сообщение, а второй аргумент messageForUser говорит сам за себя, здесь будет находиться текст сообщения.

Данные о пользователе мы должны записать в первую пустую строку таблицы. Создаем функцию, которая возьмет учетные данные из сообщения от пользователя, когда он нажмет на кнопку “Старт” при первом входе в бота и запишет их в таблицу.

Функция записывает данные о пользователе в таблицу
Функция записывает данные о пользователе в таблицу

Здесь все просто, мы получаем первую незаполненную строку в переменной lastRow, а далее присваиваем переменным текущую дату, т.е. дату регистрации, идентификатор чата, имя пользователя и настоящее имя в учетной записи. В последних четырех строках мы пользуясь благами ранее созданной функции записываем каждое значение в отдельную ячейку.

Напомню, что принцип регистрации такой, в первую очередь мы собираем данные из учетной записи телеграм, а затем просим ввести пользователя свое Ф.И.О., чтобы его можно было идентифицировать в зарплатной ведомости. Значит нам нужна функция, которая будет проверять, а есть ли пользователь с таким идентификатором чата в талице или нет. Чтобы в дальнейшем просить его ввести данные о себе или наоборот просить нажать на кнопку старт, чтобы зарегистрироваться, если он её каким-то образом обошел и сразу написал сообщение.

Поиск записи по идентификатору чата в столбце B
Поиск записи по идентификатору чата в столбце B

Так как мы идентификатор чата записывали в столбец B, то используя метод getRange мы получаем значения всего столбца, т.е. массив. Затем пробегаемся циклом по каждой ячейке и сравниваем с чатом в аргументе chatId, если совпадает, то возвращаем номер строки +1, т.к. индексация массива и таблицы начинаются по-разному.

У нас заняты столбцы при заполнении данных о пользователе по столбец F, нам еще необходимо ввести настоящее Ф.И.О., поэтому введем его в следующий столбец E. Для этого напишем функцию, которая будет записывать данные в эту ячейку, если такой чат существует или говорить о том, что необходимо зарегистрироваться.

Функция записывающая Ф.И.О. пользователя
Функция записывающая Ф.И.О. пользователя

До этого момента мы писали вспомогательные функции, а сейчас необходимо создать функцию обязательную, без которой не будут работать хуки. Что такое хуки? Если объяснить коротко, то нам каким-то образом необходимо запускать функции здесь в гугл таблице в момент, когда пользователь отправит нашему боту сообщение. Другими словами, необходимо постоянно отслеживать активность в нашем боте. Для этого нам предоставляют специальный инструмент веб хуки, которые позволяют привязаться к событиям телеграм и запускать определенную функцию.

Вот этой определенной функцией, в то же время обязательной является doPost(e). Будет запускаться эта функция всегда при срабатывании хука. А вот что будет в этой функции зависит от нас. Напиши её, а ниже поясню логику.

Функция  запускающаяся хуком
Функция запускающаяся хуком

Мы получаем событие хука, которое хранится в аргументе e. Из него в строке 106 мы извлекаем содержимое отправленное телеграмом. Из содержимого получаем объект сообщения (message). А далее проверяем, если в этом объекте есть свойство message, то проверяем есть свойство сущности (entity), в котором нас интересует тип указывающий на то, что это не просто текст, а команда бота. Речь идет о строке 113.

Если это команда бота, то нас интересует реакция только на команду /start. Поэтому мы проверяем текст на её наличие в строке 116. Заключительная проверка в строке 121 необходима для того, чтобы удостовериться, что пользователь еще не был зарегистрирован. Если его нет, то данные о нем записываются и ему присылается сообщение о том, что он должен ввести свое Ф.И.О. Если же отправил команду /start повторно, то его предупреждают о том, что необходимо отправлять Ф.И.О.

Если же это не команда, то принимаем текст сообщения и записываем его в ячейку E.

Остается заключительная функция, которая нам необходима для того, чтобы писать регистрировать новое развертывание.

Функция устанавливает веб хук
Функция устанавливает веб хук

Когда мы начинали писать код, то в константах определили идентификатор развертывания и ссылку, вот их мы будем каждый раз привязывать к веб хуку телеграм. Почему каждый раз? Потому, что каждое изменение в коде требует нового развертывания и телеграм не увидит изменения, если вы что-то изменили, но не развернули программу вновь.

Как же её разворачивать? Это не сложно. Давайте в первую очередь сохраним код.

Сохранение кода
Сохранение кода

Сразу выбери функцию, которую мы будем выполнять для регистрации развертывания, т.е. setWebhook.

Выбор функции для запуска регистрации развертывания в хуках телеграм
Выбор функции для запуска регистрации развертывания в хуках телеграм

Теперь нажимай на кнопку Начать развертывание ⇒ Новое развертывание.

Создаем новое развертывание приложения
Создаем новое развертывание приложения

В открывшемся окне нажимаем на шестеренку и выбираем веб-приложение.

Создаем веб-приложение
Создаем веб-приложение

Выбираем пункт “Все” и нажимаем кнопку “Начать развертывание”.

Выдача доступа
Выдача доступа

Первый раз придется выдать доступ.

Нажимаем на кнопку Предоставить доступ
Нажимаем на кнопку Предоставить доступ

В открывшемся окне выбираем свой аккаунт.

Выбор аккаунта
Выбор аккаунта

Подтверждение
Подтверждение

Делаем заключительное подтверждение.

Подтверждаем работу с приложением
Подтверждаем работу с приложением

В появившемся окне копируем полученный код сверху.

Копируем идентификатор развертывания
Копируем идентификатор развертывания

Нажимаем ок и идем вверх к константам, нас интересует константа DEPLOYMENT_ID, данный код вставь в ней и нажми на кнопку сохранить, а затем выполнить (важно, чтобы в списке была выбрана функция setWebhook, как на картинке).

Сохраняем изменения и регистрируем развертывание запуская функцию setWebhook
Сохраняем изменения и регистрируем развертывание запуская функцию setWebhook

Если регистрация прошла успешно, то в журнале выполнения получаете такие записи.

Журнал выполнения
Журнал выполнения

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

Устанавливаем заголовки для столбцов
Устанавливаем заголовки для столбцов

Теперь можно переходить в телеграм, находить своего бота по его пользовательскому имени и нажать на кнопку Старт.

Первый вход, нажимаем на кнопку старт
Первый вход, нажимаем на кнопку старт

Ура, бот ответил и просит нас ввести Ф.И.О.

Бот просит ввести Ф.И.О.
Бот просит ввести Ф.И.О.

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

Запись учетных данных в таблицу
Запись учетных данных в таблицу

Прекрасно! Регистрация в таблицу удалась, теперь проверим, работает ли получение дополнительной информации о пользователе.

Получение дополнительных данных и запись в ячейку
Получение дополнительных данных и запись в ячейку

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

Следующая часть здесь.