Как создать бота в Telegram с поддержкой AI-агента с помощью Yandex Workflows
Важно
Часть ресурсов, необходимых для прохождения практического руководства, доступны только в регионе Россия.
С помощью serverless-технологий можно создать бота для Telegram с поддержкой модели генерации текста на базе сервиса Yandex AI Studio.
В этом руководстве вы создадите бота для подбора фильмов на основании предпочтений пользователя. Для этого вы организуете хранение данных в Yandex Object Storage и Yandex Lockbox, настроите логику бота в Yandex Workflows и вебхук с помощью Yandex API Gateway.
Чтобы создать бота:
- Подготовьте облако к работе.
- Зарегистрируйте Telegram-бота.
- Создайте секрет.
- Создайте бакет.
- Создайте сервисные аккаунты.
- Настройте рабочий процесс.
- Настройте API-шлюз.
- Настройте вебхук для бота.
- Проверьте работу бота.
- Настройте агент под вашу задачу.
Если созданные ресурсы вам больше не нужны, удалите их.
Перед началом работы
Зарегистрируйтесь в Yandex Cloud и создайте платежный аккаунт:
- Перейдите в консоль управления
, затем войдите в Yandex Cloud или зарегистрируйтесь. - На странице Yandex Cloud Billing
убедитесь, что у вас подключен платежный аккаунт, и он находится в статусеACTIVEилиTRIAL_ACTIVE. Если платежного аккаунта нет, создайте его и привяжите к нему облако.
Если у вас есть активный платежный аккаунт, вы можете создать или выбрать каталог, в котором будет работать ваша инфраструктура, на странице облака
Подробнее об облаках и каталогах.
Необходимые платные ресурсы
В стоимость поддержки Telegram-бота входят:
- плата за генерацию текста (см. тарифы Yandex AI Studio);
- плата за хранение секрета и запросы к нему (см. тарифы Yandex Lockbox);
- плата за объем хранилища, занятый данными, количество операций с данными и исходящий трафик (см. тарифы Yandex Object Storage);
- плата за количество запросов к созданному API-шлюзу и исходящий трафик (см. тарифы Yandex API Gateway);
- плата за получение и хранение логов (см. тарифы Yandex Cloud Logging).
Зарегистрируйте Telegram-бота
Зарегистрируйте вашего бота в Telegram и получите токен.
-
Для регистрации нового бота запустите бота BotFather
и отправьте команду:/newbot -
Укажите имя создаваемого бота, например
Serverless AI Telegram Bot. Это имя увидят пользователи при общении с ботом. -
Укажите имя пользователя создаваемого бота, например
ServerlessAITelegramBot. По имени пользователя можно будет найти бота в Telegram. Имя пользователя должно оканчиваться на...Botили..._bot.В результате вы получите токен. Сохраните его, он потребуется в дальнейшем.
Создайте секрет
Создайте секрет, в котором будет храниться токен для доступа к API Telegram.
- В консоли управления
выберите каталог, в котором вы будете создавать инфраструктуру. - Выберите сервис Lockbox.
- Нажмите Создать секрет.
- В поле Имя введите имя секрета.
- Выберите тип секрета
Пользовательский. - В поле Ключ введите
token. - В поле Значение укажите токен бота, полученный при его создании.
- Нажмите Создать.
Если у вас еще нет интерфейса командной строки Yandex Cloud (CLI), установите и инициализируйте его.
По умолчанию используется каталог, указанный при создании профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду yc config set folder-id <идентификатор_каталога>. Также для любой команды вы можете указать другой каталог с помощью параметров --folder-name или --folder-id.
-
Посмотрите описание команды CLI для создания секрета:
yc lockbox secret create --help -
Создайте секрет:
yc lockbox secret create \ --name tg-bot-token \ --payload '[{"key":"token","text_value":"<токен_бота>"}]'Где:
-
--name— имя секрета. -
--payload— содержимое секрета в виде массива формата YAML или JSON:key— ключ секрета.text_value— значение секрета. Укажите токен, полученный при создании бота.
Результат:
id: e6qf05v4ftms******** folder_id: b1g681qpemb4******** created_at: "2025-08-20T12:26:02.961Z" name: tg-bot-token status: ACTIVE current_version: id: e6q768pl3vrf******** secret_id: e6qf05v4ftms******** created_at: "2025-08-20T12:26:02.961Z" status: ACTIVE payload_entry_keys: - token -
Чтобы создать секрет, воспользуйтесь методом REST API Create для ресурса Secret или вызовом gRPC API SecretService/Create.
Создайте бакет
Создайте бакет для хранения истории чата с ботом.
- В консоли управления
выберите сервис Object Storage. - На панели сверху нажмите Создать бакет.
- Введите имя бакета в соответствии с правилами именования.
- Укажите максимальный размер бакета
5 ГБ. - Нажмите Создать бакет.
-
Посмотрите описание команды CLI для создания бакета:
yc storage bucket create --help -
Создайте бакет в каталоге по умолчанию:
yc storage bucket create \ --name <имя_бакета> \ --default-storage-class standard \ --max-size 5368709120Где:
--name— имя бакета в соответствии с правилами именования.--default-storage-class— класс хранилища.--max-size— максимальный размер бакета в байтах.
Результат:
name: bot-history-storage folder_id: b1g681qpemb4******** anonymous_access_flags: {} default_storage_class: STANDARD versioning: VERSIONING_DISABLED max_size: "5368709120" created_at: "2025-08-20T12:23:21.361186Z" resource_id: e3erbgk1qmih********
Если у вас еще нет интерфейса командной строки AWS CLI, установите и сконфигурируйте его.
Чтобы создать бакет, назначьте сервисному аккаунту, через который работает AWS CLI, роль storage.editor.
В терминале выполните команду:
aws s3api create-bucket \
--endpoint-url=https://storage.yandexcloud.kz \
--bucket <имя_бакета>
Где:
--endpoint-url— эндпоинт Object Storage.--bucket— имя бакета в соответствии с правилами именования.
Чтобы создать бакет, воспользуйтесь методом REST API Create для ресурса Bucket, вызовом gRPC API BucketService/Create или методом S3 API create.
Создайте сервисные аккаунты
Cоздайте два сервисных аккаунта:
sa-apigw— от его имени будет запускаться рабочий процесс Workflows;sa-workflows— от его имени будут выполняться шаги рабочего процесса.
- В консоли управления
выберите сервис Identity and Access Management. - Нажмите Создать сервисный аккаунт.
- Введите имя сервисного аккаунта
sa-apigw. - Нажмите
Добавить роль и выберите рольserverless.workflows.executor. - Нажмите Создать.
Аналогичным образом создайте сервисный аккаунт с именем sa-workflows и назначьте ему роли:
storage.uploaderstorage.viewerlockbox.payloadViewerai.languageModels.user
-
Посмотрите описание команды CLI для создания сервисного аккаунта:
yc iam service-account create --help -
Создайте сервисные аккаунты:
yc iam service-account create --name sa-apigw yc iam service-account create --name sa-workflowsГде
--name— имя сервисного аккаунта.Результат:
id: ajeu2s3k358j******** folder_id: b1g681qpemb4******** created_at: "2025-08-20T12:18:37.599632350Z" name: sa-apigw id: ajersnus6rb2******** folder_id: b1g681qpemb4******** created_at: "2025-08-20T12:18:41.869376672Z" name: sa-workflows -
Сохраните идентификаторы сервисных аккаунтов и идентификатор каталога в переменные:
APIGW_SA=$(yc iam service-account get --name sa-apigw --format json | jq -r .id) WF_SA=$(yc iam service-account get --name sa-workflows --format json | jq -r .id) FOLDER_ID=$(yc config get folder-id) -
Посмотрите описание команды CLI для назначения роли на каталог:
yc resource-manager folder add-access-binding --help -
Назначьте сервисным аккаунтам роли на каталог:
yc resource-manager folder add-access-binding \ --id $FOLDER_ID \ --role serverless.workflows.executor \ --subject serviceAccount:$APIGW_SA yc resource-manager folder add-access-binding \ --id $FOLDER_ID \ --role storage.uploader \ --subject serviceAccount:$WF_SA yc resource-manager folder add-access-binding \ --id $FOLDER_ID \ --role storage.viewer \ --subject serviceAccount:$WF_SA yc resource-manager folder add-access-binding \ --id $FOLDER_ID \ --role lockbox.payloadViewer \ --subject serviceAccount:$WF_SA yc resource-manager folder add-access-binding \ --id $FOLDER_ID \ --role ai.languageModels.user \ --subject serviceAccount:$WF_SAГде:
--id— идентификатор каталога.--role— роль.--subject— идентификатор сервисного аккаунта.
Результат:
effective_deltas: - action: ADD access_binding: role_id: serverless.workflows.executor subject: id: ajeu2s3k358j******** type: serviceAccount ... effective_deltas: - action: ADD access_binding: role_id: ai.languageModels.user subject: id: ajersnus6rb2******** type: serviceAccount
Создайте сервисные аккаунты:
-
sa-apigwс рольюserverless.workflows.executor. -
sa-workflowsс ролями:storage.uploaderstorage.viewerlockbox.payloadViewerai.languageModels.user
Чтобы создать сервисный аккаунт, воспользуйтесь методом REST API Create для ресурса ServiceAccount или вызовом gRPC API ServiceAccountService/Create.
Чтобы назначить роль сервисному аккаунту, воспользуйтесь методом REST API updateAccessBindings для ресурса ServiceAccount или вызовом gRPC API ServiceAccountService/UpdateAccessBindings.
Настройте рабочий процесс
Настройте рабочий процесс, который обеспечит чтение и сохранение истории чата, вызов AI-агента и отправку ответов в Telegram.
Совет
В этом руководстве описано создание рабочего процесса с помощью YaWL-спецификации, но его также можно создать и редактировать с помощью конструктора.

Подготовьте YaWL-спецификацию
Сохраните YaWL-спецификацию рабочего процесса в YAML-файле, например yawl-spec.yaml:
yawl: '0.1'
start: do_work
steps:
do_work:
parallel:
branches:
# Ветка, отправляющая «typing», чтобы чат ожил быстрее
send_typing_action:
start: send_typing_action
steps:
send_typing_action:
httpCall:
url: >-
https://api.telegram.org/bot\(lockboxPayload("<идентификатор_секрета>"; "token"))/sendChatAction
method: POST
headers:
Content-Type: application/json
body: |
\({
chat_id: .input.message.chat.id,
action: "typing"
})
# Основная логика
handle_update:
start: get_history
steps:
get_history:
objectStorage:
bucket: <имя_бакета>
object: history/\(.input.message.chat.id).json
get:
contentType: JSON
output: '\({history: .Content})'
next: call_ai
catch:
- errorList:
- STEP_INVALID_ARGUMENT # файла нет или не JSON -> инициализируем
errorListMode: INCLUDE
output: '\({history: []})'
next: call_ai
call_ai:
aiAgent:
agentConfig:
role: Ты консультант по подбору фильмов
goal: >-
Помочь пользователю выбрать фильм по его предпочтениям.
При первом обращении попроси несколько любимых фильмов
(по одной в строке). Дальше используй их для рекомендаций
и задавай уточняющие вопросы.
backstory: >-
История предыдущего общения (формат JSON-массив объектов {role,message}):
"\(.history)"
model:
name: yandexgpt
tasks:
- description: \(.input.message.text)
result: Ответ в Markdown для отправки в Telegram.
output: '\({reply: .Result})'
next: send_reply
send_reply:
telegramBot:
token: \(lockboxPayload("<идентификатор_секрета>"; "token"))
sendMessage:
chatId: \(.input.message.chat.id)
text: \(.reply)
replyTo: \(.input.message.message_id)
parseMode: MARKDOWN
next: save_history
save_history:
objectStorage:
bucket: <имя_бакета>
object: history/\(.input.message.chat.id).json
put:
contentType: JSON
content: >-
\(
.history +
[
{role:"user", message:.input.message.text},
{role:"assistant", message:.reply}
]
)
Где:
<имя_бакета>— имя бакета, созданного ранее.<идентификатор_секрета>— идентификатор секрета, созданного ранее.
В примере используется текстовая модель YandexGPT Pro (name: yandexgpt). Вы можете использовать другую модель, доступную в синхронном режиме в сервисе AI Studio.
Создайте рабочий процесс
-
В консоли управления
выберите сервис Serverless Integrations. -
На панели слева нажмите
Workflows. -
В правом верхнем углу нажмите Создать рабочий процесс.
-
Выберите способ
YaML-спецификация. -
В редакторе кода вставьте текст подготовленной ранее YaWL-спецификации рабочего процесса.
-
Раскройте блок Дополнительные параметры:
-
Введите имя рабочего процесса. Требования к имени:
- длина — от 2 до 63 символов;
- может содержать строчные буквы латинского алфавита, цифры и дефисы;
- первый символ — буква, последний — не дефис.
-
Выберите сервисный аккаунт
sa-workflows. -
В блоке Логирование отключите опцию Запись логов, если не хотите платить за хранение логов.
-
-
Нажмите Создать.
-
Посмотрите описание команды CLI для создания рабочего процесса:
yc serverless workflow create --help -
Создайте рабочий процесс:
yc serverless workflow create \ --yaml-spec <файл_спецификации> \ --name <имя_рабочего_процесса> \ --service-account-id $WF_SAГде:
-
--yaml-spec— путь к файлу с YaWL-спецификацией рабочего процесса, подготовленной ранее. Например:./yawl-spec.yaml. -
--name— имя рабочего процесса. Требования к имени:- длина — от 2 до 63 символов;
- может содержать строчные буквы латинского алфавита, цифры и дефисы;
- первый символ — буква, последний — не дефис.
-
--service-account-id— идентификатор сервисного аккаунтаsa-workflows.
Результат:
id: dfqjl5hh5p90******** folder_id: b1g681qpemb4******** specification: spec_yaml: "yawl: ..." created_at: "2025-03-11T09:27:51.691990Z" name: my-workflow status: ACTIVE log_options: {} service_account_id: aje4tpd9coa******** -
Чтобы создать рабочий процесс, воспользуйтесь методом REST API Create для ресурса Workflows или вызовом gRPC API Workflow/Create.
Настройте API-шлюз
Настройте API-шлюз в качестве вебхука Telegram.
Подготовьте спецификацию API
Сохраните спецификацию API по стандарту OpenAPI 3.0api-spec.yaml:
openapi: 3.0.0
info:
title: Telegram Webhook → Workflows
version: 1.0.0
paths:
/handle:
post:
x-yc-apigateway-integration:
type: http
method: POST
service_account_id: <идентификатор_сервисного_аккаунта> # сервисный аккаунт sa-apigw
url: https://serverless-workflows.api.cloud.yandex.net/workflows/v1/execution/start
requestBody:
description: Telegram update passthrough to Workflows
content:
application/json:
schema:
x-yc-schema-mapping:
type: static
template:
workflowId: <идентификатор_рабочего_процесса> # ваш рабочий процесс
input:
inputJson: ${.|tojson} # весь апдейт Telegram как input
Где:
<идентификатор_сервисного_аккаунта>— идентификатор сервисного аккаунтаsa-apigw.<идентификатор_рабочего_процесса>— идентификатор рабочего процесса, созданного на предыдущем шаге.
Создайте API-шлюз
-
В консоли управления
выберите сервис API Gateway. -
Нажмите Создать API-шлюз.
-
В поле Имя введите имя API-шлюза. Требования к имени:
- длина — от 2 до 63 символов;
- может содержать строчные буквы латинского алфавита, цифры и дефисы;
- первый символ — буква, последний — не дефис.
-
В блок Спецификация вставьте текст спецификации OpenAPI, подготовленной ранее.
-
В блоке Логирование отключите опцию Запись логов, если не хотите платить за хранение логов.
-
Нажмите Создать.
-
Дождитесь создания API-шлюза и выберите его.
-
Сохраните значение поля Служебный домен — оно понадобится на следующем шаге.
-
Посмотрите описание команды CLI для создания API-шлюза:
yc serverless api-gateway create --help -
Создайте API-шлюз:
yc serverless api-gateway create \ --name <имя_API-шлюза> \ --spec=<путь_к_файлу_спецификации>Где:
-
--name— имя API-шлюза. Требования к имени:- длина — от 2 до 63 символов;
- может содержать строчные буквы латинского алфавита, цифры и дефисы;
- первый символ — буква, последний — не дефис.
-
--spec— путь к созданному ранее файлу со спецификацией.
Результат:
id: d5d63uh1h26g******** folder_id: b1g681qpemb4******** created_at: "2025-06-14T10:23:19.682Z" name: ai-bot-gw status: ACTIVE domain: d5d63uh1h26g********.********.apigw.yandexcloud.net connectivity: {} log_options: folder_id: b1g681qpemb4******** execution_timeout: 300s -
-
Сохраните значение поля
domain— оно понадобится на следующем шаге.
Чтобы создать API-шлюз, воспользуйтесь методом REST API Create для ресурса ApiGateway или вызовом gRPC API ApiGatewayService/Create.
Настройте вебхук для бота
Выполните команду:
curl -s "https://api.telegram.org/bot<токен_бота>/setWebhook" \
-d "url=<служебный_домен>/handle"
Где:
<токен_бота>— токен, полученный при создании бота.<служебный_домен>— служебный домен API-шлюза, полученный при его создании.
Например:
curl -s "https://api.telegram.org/bot1357246809:AAFhSteLniAw71g8jx6K5kTErO3********/setWebhook" \
-d "url=https://d5d0jdhgrro2********.********.apigw.yandexcloud.net/handle"
Результат:
{"ok":true,"result":true,"description":"Webhook was set"}
Проверьте работу бота
-
Найдите бота в Telegram по имени пользователя бота, созданного ранее.
-
Нажмите СТАРТ, чтобы начать чат.
-
Отправьте боту список из нескольких фильмов — по одному названию в строке.
Например:
Фильм 1 Фильм 2 Фильм 3Ответ бота:
Здравствуйте! Спасибо за ваши предпочтения. На основе ваших любимых фильмов я могу предложить вам следующие кинокартины: ... Какой из предложенных фильмов вас заинтересовал? Или, может быть, у вас есть ещё какие-то предпочтения, которые вы хотели бы учесть?
Что дальше
Попробуйте изменить YaWL-спецификацию рабочего процесса под вашу задачу. Например, измените запрос к текстовой модели:
...
call_ai:
aiAgent:
agentConfig:
role: Ты консультант по подбору музыкальных исполнителей
goal: >-
Помочь пользователю выбрать музыку по его предпочтениям.
При первом обращении попроси несколько любимых
групп, музыкантов, композиторов, жанров (по одному в строке).
Дальше используй их для рекомендаций и задавай уточняющие вопросы.
Также вы можете добавить текст или файлы в качестве источников информации. Подробнее см. описание интеграционного шага AIAgent.
Как удалить созданные ресурсы
Чтобы перестать платить за созданные ресурсы: