A serverless Telegram AI assistant and companion Svelte web app, running entirely on Cloudflare Workers, Workers AI, Durable Objects and Pages.
Send the bot a message and it answers using a model of your choice from Workers AI. It can read documents you upload, search the web, look things up on Wikipedia, transcribe voice notes, generate images, and run Python or TypeScript in a per-user sandbox container.
It also works in business mode, replying on your behalf to customers in Telegram Business chats, and in group chats when mentioned directly.
| Command | Description |
|---|---|
/start | Welcome message and the command list. |
/balance | Show your current Star balance. |
/load <amount> | Top up your balance with Telegram Stars (1–1000). |
/photo <prompt> | Generate an image. Costs 100 Stars. |
/model [name] | Show or switch the AI model. Without an argument, lists every model and its price. |
/prompt ["text"] | Show, set, or reset your custom system prompt. |
/facts ["text"] | Show, set, or reset the facts the bot uses in business mode. |
/clear | Delete your conversation history. |
/commit | Link to the currently deployed commit. |
Anything that is not a command is treated as a prompt. Reply to a message or a document to include it as context.
Prices are per message, in Telegram Stars. This table is generated from the bot's model registry at build time.
| Model | Stars | Tools | Vision |
|---|---|---|---|
glm-4.7-flash default |
5 | ✓ | ✓ |
gemma4 |
8 | ✓ | ✓ |
llama-3.2-vision |
8 | ✓ | ✓ |
google/gemini-3.1-flash-lite |
12 | ✓ | ✓ |
nemotron-3 |
20 | ✓ | — |
google/gemini-3-flash |
25 | ✓ | ✓ |
kimi-k2.6 |
45 | ✓ | ✓ |
deepseek-r1-32b |
80 | — | — |
google/gemini-3.1-pro |
150 | ✓ | ✓ |
Switch models with /model <name>. If your chosen model cannot handle a request — an image
for a text-only model, for example — the bot automatically falls back to one that can and charges that
model's price instead.
/load <amount>, paid in Telegram Stars.Balances are held in a Durable Object, so concurrent messages are billed serially and a failed generation is refunded automatically.
Models that support tool calling can reach for these on their own:
| Tool | What it does |
|---|---|
fetch | Perform an HTTP request and read the response. |
wikipedia | Search Wikipedia. |
tavily_search | Search the live web (feature-flagged). |
code_interpreter | Run Python in your sandbox, with numpy, pandas and matplotlib available. |
code_workspace | Write files, run commands, and send results back as a document. |
read_telegram_file | Extract text from PDF, DOCX, PPTX, XLSX, CSV, TXT and Markdown uploads. |
search_telegram_file | Semantic search over an indexed document using Vectorize. |
Sandboxes are isolated per user, and workspace file access is confined to /workspace.
The Mini App at tux-robot.codebam.ca adds a chat UI, a live balance and transaction history, a sandbox log viewer, a voice recorder, a prompt designer, and an arena for comparing prompt and model variations side by side.
Sign in happens through Telegram; every request is authenticated by a signed Telegram auth proof.
| Piece | Role |
|---|---|
bot | grammY bot on Workers. Handles webhooks, billing, and tool execution. |
webapp | SvelteKit Mini App on Cloudflare Pages. |
packages/shared | Types, model registry, Telegram auth verification, Markdown helpers. |
| Workflows | Generation runs as a durable workflow step with retries and automatic refunds. |
| Durable Objects | UserAccount for balances, Sandbox for code execution. |
| KV / R2 / Vectorize | Conversation history and caches, uploaded files, document embeddings. |
| Path | Description | |
|---|---|---|
| POST | / | Telegram webhook. Requires the X-Telegram-Bot-Api-Secret-Token header when SECRET_TELEGRAM_WEBHOOK is configured. |
| GET | /?command=set&token=… | Register the webhook with Telegram. Requires SECRET_ADMIN_TOKEN. |
| POST | /verify | Validate a Telegram auth proof. Returns { valid, userId }. |
| POST | /api/account | Authoritative balance for the authenticated user. |
| POST | /api/account/charge | Atomically debit the authenticated user. |
| POST | /workflow | Run a generation. Identity, model and price are all derived server-side from the auth proof. |
Authenticated endpoints take an x-telegram-auth header containing Mini App
initData or Login Widget query data. The user id is always taken from the verified
proof, never from the request body.
git clone --recursive https://github.com/codebam/cf-workers-telegram-bot.git
cd cf-workers-telegram-bot
bun install
bunx wrangler login
Set the bot's secrets, then deploy:
cd bot
bunx wrangler secret put SECRET_TELEGRAM_API_TOKEN --env production
bunx wrangler secret put SECRET_TELEGRAM_WEBHOOK --env production
bunx wrangler secret put SECRET_ADMIN_TOKEN --env production
bunx wrangler secret put TAVILY_API_KEY --env production
make deploy
Finally, point Telegram at your worker:
curl "https://<your-worker-host>/?command=set&token=<SECRET_ADMIN_TOKEN>"
Give the dev and production environments separate KV namespaces and
Vectorize indexes — otherwise a development deploy writes to live user balances and history.