Кукбук: 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.
- Создайте бота у @BotFather →
/newbot→ получите API-токен (он пригодится только для проверок через Bot API, платформе нужен другой токен). - Там же: ваш бот → 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.