Telegram
q15 can answer in Telegram. It is the same agent you reach in the browser: the same transcript, the same memory, the same tools. Connecting it costs you two values and about ten minutes.
Be clear about the trade before you start: Telegram sees your messages. The browser channel seals content between your browser and the agent; the Telegram channel does not, because the messages pass through Telegram’s servers by definition. Use it for the things you would type into any chat app. Anything you want sealed stays in the browser client.
What you need
Section titled “What you need”- A bot token from Telegram’s @BotFather. Send it
/newbot, answer two questions, and it prints a token. - Your numeric user ID. Telegram identifies people by number, not by username. Any of the well-known ID bots reports yours when you message it.
Set it up
Section titled “Set it up”-
Put the token in a file.
The Compose stack mounts one file per secret and passes its path to the agent. Copy the tracked template and fill it in:
in your deployment directory cp secrets/q15_telegram_token.example secrets/q15_telegram_tokenchmod 600 secrets/q15_telegram_tokenIt reaches the agent as
Q15_TELEGRAM_TOKEN_FILE, pointing at/run/q15-secrets/q15_telegram_tokeninside the container.You should now have a second file beside the template.
ls -l secrets/shows it mode 600, andsecrets/q15_telegram_token.exampleuntouched. -
Put your user ID in a second file.
Terminal window cp secrets/q15_telegram_allowed_user_ids.example secrets/q15_telegram_allowed_user_idsOne numeric ID per line. This list is the only thing standing between your agent and anyone who finds the bot, so it is not optional: q15 refuses to build a Telegram channel with an empty allow-list rather than reading an empty list as “everyone”.
You should now have both files in
secrets/, each containing one line and nothing else. A file with a trailing blank line is fine; a file with two IDs is not, unless both people should be able to talk to your agent. -
Point the config at both.
agent-config.yaml agent:telegram:token_env: Q15_TELEGRAM_TOKENallowed_user_ids_env: Q15_TELEGRAM_ALLOWED_USER_IDSThe stack sets the matching
*_FILEvariables, so the values themselves never appear in the YAML.You should now see a third file under
secrets/, andgrep -n TELEGRAM deploy/compose/docker-compose.image-first.ymlshows the two*_FILEvariables the agent will read. -
Restart the agent and send the bot a message.
Terminal window podman compose --env-file deploy/compose/release.env \-f deploy/compose/docker-compose.image-first.yml up -d --force-recreate q15-agentYou should now see the agent’s reply in the chat, and the same exchange in your browser client’s history a moment later.
If nothing arrives: the user ID is wrong, or the token file is still the empty template. Both are logged on stdout by the agent, and the second is listed in Troubleshooting.
What it looks like in use
Section titled “What it looks like in use”In a private chat, a long answer grows in place while it is being written. Telegram’s native thinking indicator shows while the model works, reasoning appears as a short excerpt when the model streams it, and the finished answer replaces it. Updates reuse one message, are coalesced to at most one per second, and refresh every 20 seconds during long waits. Telegram’s Stop button cancels the run; the unfinished draft is discarded.
How much of the machinery you see is your choice, per chat:
| Command | What the chat shows |
|---|---|
/progress quiet |
Thinking, partial replies and routine tool activity stay hidden. Only the long-wait notice appears. |
/progress progress |
The current action, with a short command, file or search preview (up to 320 characters, five lines). This is the default. |
/progress verbose |
The same action, with a longer preview (up to 640 characters, ten lines) and longer reasoning excerpts. |
Tool output is never dumped into a progress message; only what the agent asked for. Commands keep their line breaks and shell syntax inside a code block.
Attachments
Section titled “Attachments”Both directions work.
- To the agent: send a photo, a document, a voice note, a video, a sticker or a GIF. It is stored in the agent’s media store under a content hash and attached to your message, so the agent sees the file, not a link.
- From the agent: when the agent attaches something, it arrives as the matching Telegram kind: photo, audio, document, video, animation, sticker or video note.
A failed attachment does not lose your caption: the message still arrives, with a line saying what could not be ingested.
Limits
Section titled “Limits”- No sealing. Everything on this channel passes through Telegram.
- The token is a bearer credential. Anyone holding it can act as your bot. It belongs in a secret file, not in the YAML, and it belongs in your backup only if that backup is encrypted.
- Long polling, so no inbound port. q15 asks Telegram for updates; it never accepts a connection. There is nothing to expose, and it works behind NAT.
- One bot per agent. Two agents need two bots, and they keep two separate conversations.
- The two clients share one transcript. An exchange from Telegram shows up in the browser history, because the agent keeps one conversation and both clients read it. What differs is delivery: an answer written in Telegram is sent to Telegram, and is not repeated in the browser.
Where to go next
Section titled “Where to go next”- Chat for the browser client that seals its payloads.
- Jobs for scheduled work; a job created here reports back here.
- Credentials for how the bot token is held.