Создаем чат-бот в Telegram на функциях: пошаговая инструкция

Рассказываем, как с помощью бессерверных вычислений сделать своего чат-бота в Telegram с нуля. Он сможет отвечать на запросы простыми сообщениями и отправлять картинки. Подойдет для организации процессов разработки, поддержки и продаж.

5 июня 2021 г.
0

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

Такого бота можно написать с использованием serverless-подхода в крупных облаках, например, с помощью AWS Lambda или Google Cloud Functions. Мы напишем функцию на Yandex Cloud Function, сделаем Object Storage, чтобы хранить файлы, и спрячем нашу serverless-архитектуру от пользователя с помощью сервиса Yandex API Gateway, который позволяет выступить фронтом для пользователя.

Шаг 1. Создайте бота с помощью BotFather

Прежде всего нужно зарегистрировать наше приложение в Telegram. Найдите в мессенджере главного бота BotFather и наберите команду /newbot. Для этого достаточно написать его имя user name и account name. В нашем случае account name — Serverless Hello Telegram Bot, username — ServerlessHelloTelegramBot. В результате вы получите token, запомните его, он потребуется на следующих этапах.

С помощью команды /setuserpic установите иконку для вашего бота. В нашем случае это картинка с именем sayhello.png.

На этом этапе у нас уже есть заготовка для бота. Дальше переходим в Yandex.Cloud и начинаем создавать инфраструктуру для бота.

Шаг 2. Создайте сервисный аккаунт

Войдите в ваш рабочий каталог.

Создайте новый сервисный аккаунт для работы telegram-бота. Например, serverless-telegram. Задайте роли для него: serverless.functions.invoker и editor. Роль serverless.functions.invoker необходима для запуска функций.

Обратите внимание: editor перекрывает роль serverless.function.invoker.

Запомните идентификатор созданного сервисного аккаунта.

Шаг 3. Создайте Object Storage

Нам нужно где-то хранить файлы для бота. Перейдите в каталог и выберете сервис Object Storage. Нажмите кнопку Создать бакет.

Введите имя бакета: for-serverless-hello-telegram-bot. Затем задайте максимальный размер в 1 ГБ и установите параметр Доступ на чтение объектов — Публичный.

Когда мы размещаем объект, есть возможность поместить его в два разных хранилища: стандартное с быстрым доступом или холодное. Холодное — это долговременное хранилище, оно отдельно тарифицируется и чаще всего используется для бэкапов. В нашем случае выбираем стандартное.

Загрузите картинку в созданный бакет. В нашем случае это тот же самый файл, который мы установили аватаром для бота: sayhello.png. Получите ссылку на загруженную картинку и проверьте её доступность по ссылке в браузере.

Шаг 4. Опубликуйте картинку через API Gateway

Давайте опубликуем нашу картинку через сервис API Gateway. Таким образом мы создадим заготовку, чтобы пользователь мог работать с нашим telegram-ботом, но не видел, что находится внутри. Перейдите в каталог и выберете сервис API Gateway. Нажмите кнопку Создать API-шлюз:

Введите имя for-serverless-hello-telegram-bot и вставьте спецификацию:

info:
title: for-serverless-hello-telegram-bot
version: 1.0.0
paths:
/sayhello.png:
get:
x-yc-apigateway-integration:
type: object-storage
bucket: for-serverless-hello-telegram-bot
object: sayhello.png
presigned_redirect: false
service_account: IDYOURACCOUNT
operationId: static

Обязательно замените:

  • sayhello.png — на имя вашей картинки (два раза).

  • for-serverless-hello-telegram-bot — на имя вашего бакета.

  • IDYOURACCOUNT— на id вашего сервисного аккаунта, созданного ранее.

После опубликования API-шлюза в спецификации появится секция servers с адресом url. Через этот адресом вы сможете обратиться к ранее опубликованной картинке. В нашем случае к sayhello.png.

Проверяем, все работает. Отлично! Мы соединили два сервиса. У нас, с одной стороны, есть Object Storage, в котором что-то хранится. И есть API Gateway, который публично предоставляет доступ к каким-то ресурсам.

Шаг 5. Создадим Cloud Function

Идем дальше. Теперь нам нужно сделать функцию. Перейдите в каталог и выберете сервис Cloud Functions. Нажмите кнопку Создать функцию. Задайте имя. В нашем случае: fshtb-function.

Мы создали объект, но сама функция еще не создана. Нам необходимо выбрать среду выполнения. Внутри Yandex.Cloud несколько разных сред. Мы выберем nodejs, у нас есть там python.

Выберете среду выполнения node12js-preview.

Создайте два файла: index.js и package.json. Здесь мы используем известный в JavaScript-комьюнити фреймфорк Telegraf.

Для файла index.js скопируйте следующий код:



const bot = new Telegraf(process.env.BOT_TOKEN);
bot.start((ctx) => ctx.reply(`Hello. \nMy name Serverless Hello Teleram Bot \nI'm working on Cloud Function in the Yandex.Cloud.`))
bot.help((ctx) => ctx.reply(`Hello, ${ctx.message.from.username}.\nI can say Hello and nothing more`))
bot.on("text", (ctx) => {
ctx.reply(`Hello, ${ctx.message.from.username}`);


});


module.exports.handler = async function (event, context) {
const message = JSON.parse(event.body);
await bot.handleUpdate(message);
return {
statusCode: 200,
body: "",
};
};

Этим мы научили нашего бота отвечать на команды /start, /help, а также на любой написанный текст. Но давайте сразу изменим функцию так, чтобы она на любой текст отправляла картинку. Для этого внесите изменение в файл index.js.

ctx.replyWithPhoto("YOURAPIGWURL/sayhello.png");
ctx.reply(`Hello, ${ctx.message.from.username}`);

Важно: не забудьте заменить YOURAPIGWURL на url из секции servers вашего API-шлюза. После создания версии функции, ваш telegram-бот будет отправлять вам картинку из Object Storage, опубликованную через API-шлюз.

Для файла package.json введите следующий код:

"name": "ycf-telegram-example",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "MIT",
"dependencies": {
"telegraf": "^3.38.0"
}
}

Укажите точку входа index.handler. Увеличьте таймаут до 5 секунд. В переменные окружения добавьте переменную BOT_TOKEN со значением токена вашего telegram-бота, полученного ранее.

Обязательно нажмите кнопку — Создать версию. После создания функции сделайте ее публичной. Запомните идентификатор вашей функции.

Шаг 6. Свяжем функцию и бота в Telegram

Теперь нам нужно соединить нашу функцию с ботом в Telegram. Для этого вернитесь в сервис API Gateway и выберете ранее созданный API-шлюз с именем for-serverless-hello-telegram-bot. Измените его спецификацию — в конце добавьте в нее секцию fshtb-function:

post:
x-yc-apigateway-integration:
type: cloud-functions
function_id: IDYOURFUNCTION
operationId: fshtb-function

Замените IDYOURFUNCTION на id вашей функции, созданной ранее. Сохраните изменения.

Теперь для создания связи между ранее созданным телеграм-ботом и вашей функцией нужно запустить команду в терминале (командной строке).

curl --request POST --url https://api.telegram.org/botYOURTOKEN/setWebhook --header "content-type: application/json" --data "{"url": "YOURAPIGWURL/fshtb-function"}"

Замените YOURTOKEN на токен вашего telegram-бота и YOURAPIGWURL на url из секции servers вашего API-шлюза. Нажмите Enter. После положительного ответа связь создана, и вы сможете поговорить со своим ботом. Если не вылезать из лимитов Free tier, ваш бот обойдется вам в 0 рублей.

Оставляем полезные ссылки на каналы и сообщества Serverless в мире и в России, где вы сможете найти еще больше полезных примеров использования функций:

Команда Yandex Cloud
Создаем чат-бот в Telegram на функциях: пошаговая инструкция
5 июня 2021 г.
0