Runs on Telegram Serverless — no host, no database to rent, nothing to keep alive.
/set (source) (destination) |
Add a forward |
/get (source) |
List your destinations for a source, or all of them with /get |
/rm (source) (destination) |
Remove one of your destinations, or all with /rm (source) |
/reload |
Refresh the chat names shown in /get |
/cancel |
Stop a half-finished /set |
/settings |
Open the Mini App |
/help |
How it works |
Anyone can use it, and everyone's routes are their own. You must administer the destination — posting into a chat is what needs authority. For a source, you have to be in the chat yourself unless it is public, and the bot has to be in it too — an administrator, in a channel — to see the messages at all.
Whoever claims the bot administers it, and gets two more commands:
/private on|off |
Keep the bot to yourself; everyone else's routes go quiet |
/transfer (user id) |
Hand the bot over, after confirming on a button |
Nobody runs a fresh bot until someone says so: /claim takes charge of
it while it is unclaimed, and /claim (bot token) takes it back at any
time — holding the token from @BotFather is the
proof of ownership, so there is no secret to configure and no way to lock
yourself out by mistyping an id in /transfer. The message carrying the
token is deleted on sight.
Anywhere a chat is expected you can pass a chat id, an @username or a t.me
link — including a message link, which yields the chat it belongs to. Invite
links carry no id and are rejected.
bun install
bunx tgcloud login # paste the CLI token from @BotFather → your bot → Serverless
bun run deploy # build the Mini App, push it and the bot's code
bunx tgcloud migrate # create the tablespush prints the Mini App's address — https://app<your bot id>.tgcloud.ai/.
The bot id is the app id, so nothing needs configuring.
deploy ends by running endpoints/setup, which tells Telegram the bot's
command list, its description, and the menu button that opens the Mini App.
There is nothing to set by hand in @BotFather, and nothing to remember after
changing a command — it is applied on the next deploy, and skipped when
nothing changed.
- Albums arrive as separate messages. Parts land in different invocations and there is no process to hold them together.
- Patterns run on native
RegExp, not RE2. A pattern with a repeated group inside a repeated group is refused at save time; that is a heuristic, not the linear-time guarantee RE2 gave. - One bot per project. A project is tied to one bot, and only that bot can hold the webhook, so there is no way to run a second bot's updates here.
- Commands work in a private chat with the bot, not in groups.
- Chat names and avatars are stored, not looked up. They refresh when a
chat announces itself — the bot added or removed, a rename — and on
/reload. Avatars load after the list, never with it.
GPL-3.0-or-later.
The icons are other people's work: the outline glyphs are Lucide (ISC, parts MIT), the bot's own mark is "send" by Keval from the Noun Project (CC BY), and GitHub's mark comes from Simple Icons (CC0).