Skip to main content

Кукбук: serverless-бот с мини-аппом за вечер#

Рассказ в этом файле на русском. Команды CLI и имена инструментов от языка не зависят. English, 中文, العربية, Deutsch and Français overviews: docs/cookbook.<lang>.mdx.

Пошаговый рецепт по платформе Telegram serverless (@tgcloud) на примере реального бота «Дневник обучения» (srl_assistant_bot): хранит заметки в базе, отвечает кнопками, показывает записи в Mini App.

Всё проверено на живом боте; форматы вывода CLI — самоснятые.


0. Подготовка (5 минут)#

Нужны: Node.js 18+, npm, Telegram.

  1. Создайте бота у @BotFather → /newbot → получите API-токен (он пригодится только для проверок через Bot API, платформе нужен другой токен).
  2. Там же: ваш бот → Serverless → CLI Access → Access token → получите CLI access token формата app<id>:<secret>.

⚠️ Это два разных токена. CLI отвергнет API-токен с ошибкой Token format looks wrong. Expected "app<id>:<secret>".

1. Скаффолд и логин (5 минут)#

Для CI/неинтерактива:

Структура проекта — весь платформенный код в tgcloud/:

⚠️ Импорты проектных модулей — относительные пути С расширением .js: import { notes } from '../schema.js'. Без .js не компилируется. SDK — по имени: import { db, api, fetch, EndpointError, BotApiError } from 'sdk'.

2. Хендлер сообщений + база (20 минут)#

tgcloud/schema.js — таблица заметок:

tgcloud/handlers/message.js — имя файла = тип апдейта, export default получает payload (для message — сам Message):

Правила БД, о которых не скажет компилятор:

  • всё async — всегда await;
  • нет foreign keys (.references() бросит при декларации);
  • удаление колонок/таблиц — только .deprecated('reason'), удаление декларации ничего не дропает;
  • push никогда не трогает базу — миграции отдельным шагом.

3. Деплой и миграция (5 минут)#

Сначала предпросмотр миграции:

Применение. В терминале — интерактив (Proceed? → [1/1] Apply? [y]es/[n]o/[q]uit). В CI/скриптах интерактив не сработает:

Быстрая проверка без живого чата (payload — JSON5):

chat not found при фейковом chat id — нормально: значит, запись в БД прошла, упала только отправка ответа несуществующему чату.

При первом push на бота с уже задеплоенным скаффолдом увидите конфликт ревизий: This bot already has 2 deployed modules (revision 1). Лечение — npx tgcloud fetch, затем повторный push (или осознанный push --force).

Вебхук платформа ведёт сама по handlers/*:

4. Inline-кнопки (callback_query) (15 минут)#

Добавляем кнопки к ответу о сохранении (message.js):

Скаффолд и хендлер:

push — и платформа сама добавит callback_query в allowed_updates вебхука.

5. Mini App (30 минут)#

Три части: endpoint (сервер), статика (фронт), конфиг.

Endpoint tgcloud/endpoints/listNotes.js — вызывается из мини-аппа как POST /api/listNotes, платформа проверяет init data до запуска вашего кода:

Статика web/index.html — без сборки, обычный HTML + официальный telegram-web-app.js:

Конфиг tgcloud.jsonc:

Чтобы бот открывал мини-апп, добавьте /app-команду с web_app-кнопкой (https://app<id_бота>.tgcloud.ai/) или Menu Button в @BotFather (/setmenubutton).

Не ставьте X-Frame-Options/строгий frame-ancestors на статику — Telegram Web открывает мини-аппы в iframe.

6. Если что-то молчит#

Шпаргалка по токенам и CLI#

ЧтоЗначение
API-токен (123:AA…)Bot API вручную; платформе не нужен
CLI access token (app<id>:<secret>)@BotFather → Serverless → CLI Access; для tgcloud login / TGCLOUD_TOKEN
login неинтерактивноTGCLOUD_ASSUME_TTY=1 + stdin, или только env TGCLOUD_TOKEN (CI)
migrate неинтерактивно--dry-run / --yes / --safe

Полный SDK-референс — в docs/tgcloud-sdk.md вашего скаффолда. Управлять всем этим из AI-агента — MCP-сервер tgcloud-mcp.