Telegram
Wire up a Telegram agent and control access.
Telegram is the first messenger interface Koda ships with. It pairs cleanly with the runtime — users DM an agent bot, the handler normalises the message into a runtime request, the task executes, and the reply streams back in the same chat.
What you get
- A one-to-one chat interface per agent. Users DM the bot; the bot replies.
- Allowed-user policy enforced at the handler layer — unapproved users are silently dropped before any runtime work starts.
- Full runtime trace for every Telegram message. The dashboard shows the same transcript an operator sees, plus the tool calls and memory writes underneath.
- The
/skillcommand works natively in Telegram — same names, same auto-selection rules, same token budgets.
Setting up a Telegram agent
Create a bot with BotFather
Open Telegram, find@BotFather, and run/newbot. Pick a display name, pick a username ending inbot, and copy the token BotFather hands back. Koda never sees your BotFather account — only the token.Open the Telegram wizard in the dashboard
On the home dashboard the setup checklist offers a Connect Telegram step. The drawer that opens asks for the bot token and the agent you want to bind it to.Paste the bot token
Koda verifies the token against Telegram's getMe endpoint before saving it. A bad token fails here, not at message-delivery time.Pick the agent
One agent per bot. Multiple agents can coexist — each bot binds to exactly one — but the first setup is one bot, one agent.Decide who can reach it
Add allowed Telegram user IDs or usernames. Unlisted users get no response. The dashboard shows a live feed of rejected attempts so you can spot misconfiguration.
Access policy
Telegram access is controlled at the handler layer through the system-settings allow list. The runtime never sees messages from users who aren't on it.
- By ID — stable across username changes. This is what Koda actually stores.
- By username — convenient to enter, resolved to an ID on first contact and then ignored. A username change doesn't silently lose access.
security.telegram.rejected audit event. If the audit feed fills up with a single attacker's ID, block them at the BotFather level — removing access to the bot itself — rather than leaving Koda to filter indefinitely.Message flow
- User sends a DM to the bot.
- The Telegram handler receives it, normalises the message into the canonical runtime request shape, and enforces the allow-list check.
- The queue manager picks up the request, assembles context (memory recall, knowledge retrieval), and dispatches to the bound agent.
- Provider execution and the tool loop run exactly like any other runtime task. Streaming responses are edited into a single Telegram message in place.
- The final reply is sent. The transcript — with every tool call, memory hit, and retrieval result — is visible in the dashboard's runtime view.
Commands in chat
/skill— list available skills./skill <name> [question]— invoke a specific skill explicitly.- Any other message — routed through the normal queue and picks up skills automatically if triggers match.
Where credentials live
The bot token is stored as a secret in Postgres, encrypted at rest using the same master key as the rest of the control plane. It's never echoed back through the API — once saved, the dashboard shows only a fingerprint. Rotate by re-running the Telegram wizard with a new token; the old one is overwritten atomically.
Common issues
- Bot replies nothing. Check the allow list first — a rejected message produces no user-facing feedback by design.
- Bot token keeps failing verification. BotFather tokens can be regenerated; an old token stops working immediately.
- Message doesn't match a skill. Expected. The selector falls through to the agent's default prompt contract — look at the runtime trace to see which skill, if any, was scored.