pi-telegram-group-topic
v0.1.0
Published
Control multiple pi sessions from Telegram forum topics
Downloads
25
Maintainers
Readme
pi-telegram-group-topic
Control several pi sessions from one Telegram bot.
This pi extension lets a Telegram forum group act like a control room for pi: bind one topic to one live pi session, bind another topic to another session, and keep the normal Telegram DM bridge for quick one-on-one use. It supports streaming replies, queued turns, attachments, generated files, inline buttons, /status, /model, /compact, /stop, and topic binding through /bind codes.
It started as a fork of Mario Zechner's badlogic/pi-telegram, then grew into a multi-topic router for people who keep several pi sessions open at the same time.
Good for
- running several pi sessions from one Telegram group;
- keeping each project/session in its own Telegram forum topic;
- checking model, token, cost, and queue state from Telegram;
- sending screenshots, documents, and generated files between Telegram and pi;
- mirroring local pi prompts/replies back to a bound topic when you want a shared log.
What it adds
- Multi-topic group routing: one Telegram forum topic maps to one live pi session.
- A single Telegram poller: one lock-owning pi process consumes
getUpdates; other sessions receive routed updates through local inboxes. - Simple Telegram commands:
/status,/model,/compact,/stop,/bind,/help, and/start. - Pi-side commands under
/tg-*, so they do not collide with Telegram command names. - Inline status and model menus from Telegram, including inside forum topics.
- Streaming Telegram previews while pi is generating a reply.
- Queue controls for busy sessions.
/stopaborts the active run and clears queued Telegram turns. - Media and file handling for images, albums, documents, and generated artifacts.
- Optional local chat broadcast from pi back to the bound Telegram topic.
- Usage limits in
/statuswhenpi-usage-barsis installed; otherwise it shows token/cost/context data.
Install
From npm:
pi install npm:pi-telegram-group-topicFrom GitHub:
pi install git:github.com/AlekseiSeleznev/pi-telegram-group-topicTry it for one pi session without installing globally:
pi -e npm:pi-telegram-group-topicCreate a Telegram bot
- Open @BotFather.
- Run
/newbot. - Choose a bot name and username.
- Copy the bot token.
For group-topic routing, also add the bot to a Telegram group with Topics enabled. Give the bot permission to read and send messages in the group.
Configure pi
Start pi and run:
/tg-setupPaste your Telegram bot token when prompted.
The extension stores bot configuration in:
~/.pi/agent/telegram.jsonIf a token already exists there, the setup prompt shows it as the default. If no saved token exists, the setup prompt can prefill from these environment variables:
TELEGRAM_BOT_TOKENTELEGRAM_BOT_KEYTELEGRAM_TOKENTELEGRAM_KEY
The config file is written with private 0600 permissions.
Connect a pi session
In the pi session that should own Telegram polling, run:
/tg-connectOnly one live pi process should poll the Telegram Bot API for a bot token. pi-telegram-group-topic stores polling ownership in:
~/.pi/agent/locks.jsonIf another live pi process already owns the lock, /tg-connect asks whether to move ownership to the current session.
To stop polling from the current session:
/tg-disconnectTo inspect bridge state from pi:
/tg-statusPair your Telegram account
After configuring the token and running /tg-connect:
- Open a DM with your bot.
- Send
/start.
The first Telegram user to pair becomes the allowed user. Messages from other users are ignored.
Basic DM usage
Send a message to the bot DM. The message is forwarded into pi with a [telegram] prefix.
Examples:
summarize this filewrite a shell script and send it back to meexplain this screenshotTelegram commands
Use these commands in Telegram DMs or in a bound group topic:
| Command | What it does |
| --- | --- |
| /start | Pair the first allowed Telegram user and show help. |
| /help | Show Telegram help. |
| /status | Show model, usage, cost/context or usage-bar limits, plus inline controls. |
| /model | Open the interactive model selector. |
| /compact | Compact the current pi session when it is idle. |
| /stop | Abort the current pi run and clear queued Telegram turns. |
| /bind <code> | Bind the current Telegram chat/topic to the pi session that generated the code. |
Telegram-side commands intentionally keep their short names. The longer /tg-* commands are for pi only.
Pi commands
Run these commands inside pi, not Telegram:
| Command | What it does |
| --- | --- |
| /tg-setup | Configure or update the Telegram bot token. |
| /tg-status | Show bridge diagnostics, polling state, queue state, and recent redacted runtime/API events. |
| /tg-connect | Start Telegram polling in this pi session and acquire or move the singleton lock. |
| /tg-disconnect | Stop polling in this pi session and release the singleton lock. |
| /tg-connect-topic <chatId> [threadId] | Manually bind this pi session to a Telegram chat or forum topic. |
| /tg-bind-code | Generate a temporary code that can be used with Telegram /bind <code>. |
| /tg-topic-unbind | Remove this pi session's Telegram topic binding. |
| /tg-topic-status | Show this pi session's current topic binding. |
| /tg-broadcast-on | Mirror local pi prompts and final assistant replies to the bound Telegram topic. |
| /tg-broadcast-off | Disable local chat mirroring. |
| /tg-broadcast-status | Show local chat mirroring status. |
Multi-topic group routing
The main feature of this fork is routing different Telegram forum topics to different live pi sessions.
Why this exists
The Telegram Bot API allows only one getUpdates consumer per bot token. Running one Telegram extension per pi session would conflict. This extension solves that by keeping a single active poller and routing updates locally.
How it works
- The lock-owning pi session runs the Telegram poller.
- Every live pi session registers itself in:
~/.pi/agent/pi-telegram-sessions.json- Each target session has a UTF-8-safe local inbox under:
~/.pi/agent/pi-telegram-router/inbox/- The poller maps
(chat_id, message_thread_id)to the registered target session. - The target session consumes the routed update through the normal Telegram pipeline: commands, media downloads, queueing, rendering, buttons, and replies.
Bind a topic with a code
In the target pi session, run:
/tg-bind-codepi will show a code. In the Telegram topic that should talk to that session, send:
/bind CODEAfter that, messages and Telegram-side commands in that topic go to the bound pi session.
Manually bind a topic
If you already know the Telegram chat id and topic thread id, run this inside the target pi session:
/tg-connect-topic <chatId> <threadId>For a non-topic chat, omit threadId:
/tg-connect-topic <chatId>Check or remove a binding
/tg-topic-status/tg-topic-unbindLocal broadcast to Telegram
By default, Telegram-originated messages get Telegram replies, but ordinary local pi prompts stay local.
To mirror local pi prompts and final assistant replies to the currently bound Telegram topic:
/tg-broadcast-onTo stop mirroring:
/tg-broadcast-offTo inspect the setting:
/tg-broadcast-statusThe footer in pi uses compact indicators:
tg: poll 🟢 · bind 🟢 · brc 🟡poll 🟢/poll 🟡: this pi session owns Telegram polling / does not own polling.bind 🟢/bind 🟡: this pi session is bound to a Telegram chat or topic / is not bound.brc 🟢/brc 🟡: local chat broadcast to Telegram is on / off.
A normal routed target session can show poll 🟡 · bind 🟢: it does not call getUpdates itself, but Telegram messages and menu callbacks still reach it through the router.
Status and usage limits
Telegram /status shows model and context information. If pi-usage-bars is installed and emits usage data, /status prefers limit information such as:
Limits: S 74% left W 37% left
Reset: S 2h W 4d
Context: 22.9%/272kIf usage-bar data is unavailable, it falls back to token usage, cost, and context:
Usage: ↑1.1M ↓98k R37M
Cost: $26.939 (sub)
Context: 22.9%/272kMedia and attachments
You can send images, albums, voice messages, and files from Telegram. The extension downloads inbound files to:
~/.pi/agent/tmp/telegramIt includes local file paths in the prompt and forwards supported images as image inputs to pi.
When pi needs to send generated artifacts back to Telegram, it should call the provided telegram_attach tool with local file paths. The extension sends those files with the next Telegram reply.
Queueing and controls
If pi is busy, new Telegram turns are queued and processed later.
- Normal messages enter the default prompt queue.
- Important control actions such as model switching use a higher-priority control lane.
/stopaborts the active pi run and clears queued Telegram turns.- Reactions can be used for queue management where supported by Telegram updates.
Streaming replies
Assistant replies are streamed back to Telegram as previews while pi is generating.
The extension first tries Telegram draft streaming with sendMessageDraft. If that is not available for the bot/client combination, it falls back to sending and editing normal Telegram messages.
Long replies are split below Telegram's message-size limit.
Files and runtime state
Important local files:
| Path | Purpose |
| --- | --- |
| ~/.pi/agent/telegram.json | Bot token and allowed Telegram user configuration. |
| ~/.pi/agent/locks.json | Singleton polling ownership. |
| ~/.pi/agent/pi-telegram-sessions.json | Live pi session registry and topic bindings. |
| ~/.pi/agent/pi-telegram-router/inbox/ | Per-session routed update inboxes. |
| ~/.pi/agent/tmp/telegram/ | Downloaded Telegram files and media. |
Troubleshooting
/status or /model replies appear in General instead of the topic
Make sure the live pi process has been fully restarted after updating the extension. A pi /reload may not replace old in-memory Telegram hooks. Stop old pi processes, start pi again, run /tg-connect, and retry.
Telegram says another poller is active
Only one process can call getUpdates for a bot token. Run /tg-connect in the intended router session and confirm takeover if prompted. Stop stale pi processes if necessary.
A topic says it is not bound
Generate a new code in the target pi session:
/tg-bind-codeThen send the shown command in the Telegram topic:
/bind CODEAn old experimental topic broker is installed
This project does not use the temporary telegram-topic-broker experiment. If it exists under ~/.pi/agent/extensions/telegram-topic-broker, disable or remove it before using this extension.
Development
npm install
npm run validateValidation runs TypeScript typechecking, tests, npm audit, and a dry-run package check.
Acknowledgements
This project is based on badlogic/pi-telegram, the original Telegram DM bridge for pi. The current fork keeps the original spirit and core bridge behavior while adding multi-session Telegram forum-topic routing, topic-aware command menus, usage-limit status integration, broadcast controls, compact status indicators, and additional tests/docs.
License
MIT. See LICENSE.
