Создаём чат‑бот в Telegram на функциях: пошаговая инструкция
Рассказываем, как с помощью бессерверных вычислений сделать своего чат‑бота в Telegram с нуля. Он сможет отвечать на запросы простыми сообщениями и отправлять картинки. Подойдёт для организации процессов разработки, поддержки и продаж.
Мы напишем простого бота‑заготовку, которого можно использовать для написания полноценного приложения, добавив нужную вам функциональность.
Такого бота можно написать с использованием 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. Получите ссылку на загруженную картинку и проверьте её доступность по ссылке в браузере.
Object Storage
Шаг 4. Опубликуйте картинку через API Gateway
Давайте опубликуем нашу картинку через сервис API Gateway. Таким образом мы создадим заготовку, чтобы пользователь мог работать с нашим telegram‑ботом, но не видел, что находится внутри. Перейдите в каталог и выберете сервис API Gateway. Нажмите кнопку Создать API‑шлюз:
Введите имя for‑serverless‑hello‑telegram‑bot и вставьте спецификацию:
openapi: 3.0.0
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, который публично предоставляет доступ к каким‑то ресурсам.
API Gateway
Шаг 5. Создадим Cloud Function
Идём дальше. Теперь нам нужно сделать функцию. Перейдите в каталог и выберете сервис Cloud Functions. Нажмите кнопку Создать функцию. Задайте имя. В нашем случае: fshtb‑function.
Мы создали объект, но сама функция ещё не создана. Нам необходимо выбрать среду выполнения. Внутри Yandex Cloud несколько разных сред. Мы выберем nodejs, у нас есть там python.
Выберете среду выполнения node12js‑preview.
Создайте два файла: index.js и package.json. Здесь мы используем известный в JavaScript‑комьюнити фреймфорк Telegraf.
Для файла index.js скопируйте следующий код:
const { Telegraf } = require("telegraf");
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.
bot.on("text", (ctx) => {
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
:
/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 в мире и в России, где вы сможете найти ещё больше полезных примеров использования функций: