Telegram Bot
Run Agent AFK as a Telegram bot — same tools, same memory, on your phone. Set up takes under five minutes.
Agent AFK can run as a Telegram bot, giving you a private chat interface backed by the same session manager and full tool set as the REPL. You can also use Telegram as a notification channel — the daemon pushes a message whenever a scheduled task completes.
Setup
1. Create a bot token
Open Telegram and message @BotFather:
- Send
/newbot - Follow the prompts to name your bot
- Copy the token BotFather gives you (it looks like
1234567890:ABC...)
2. Run the setup wizard
afk telegram setupThe wizard validates your token against the Telegram API, then walks you through discovering
your chat ID (send your bot a message and it polls for it automatically), and writes both to
~/.afk/config/afk.env:
TELEGRAM_BOT_TOKEN=1234567890:ABC...
AFK_TELEGRAM_ALLOWED_CHAT_IDS=123456783. Start the bot
afk telegram startThe bot starts as a background daemon and logs to ~/.afk/logs/telegram.log.
Manual configuration
Skip the wizard by setting the env vars directly in ~/.afk/config/afk.env or your shell profile:
export TELEGRAM_BOT_TOKEN=1234567890:ABC...
export AFK_TELEGRAM_ALLOWED_CHAT_IDS=12345678AFK_TELEGRAM_ALLOWED_CHAT_IDS is a comma-separated list of chat IDs whose messages the bot
will accept. Messages from any other chat are silently ignored. You must set at least one ID or
the bot will start but never respond.
To allow multiple users:
AFK_TELEGRAM_ALLOWED_CHAT_IDS=12345678,87654321Environment variable reference
All Telegram-related env vars belong in ~/.afk/config/afk.env. Prefer afk config env set <VAR> for secrets — it masks input so the value never appears in your shell history.
| Variable | Required | Description |
|---|---|---|
TELEGRAM_BOT_TOKEN | Yes | Bot token from @BotFather. |
AFK_TELEGRAM_ALLOWED_CHAT_IDS | Yes | Comma-separated chat IDs the bot will accept messages from. |
AFK_TELEGRAM_PRIMARY_CHAT_ID | No | Default chat for outbound notifications. When unset, notifications go to the first private/DM chat in AFK_TELEGRAM_ALLOWED_CHAT_IDS. Overridden by telegram.notify in afk.config.json. |
AFK_TELEGRAM_NOTIFY_MODE | No | Outbound notification fan-out: primary (default — one chat), broadcast (every allowed chat), or custom (telegram.notify.targets in afk.config.json picks the list). Overridden by telegram.notify.mode. |
AFK_TELEGRAM_TAG_ONLY_CHAT_IDS | No | Comma-separated chat IDs where the bot responds only when directly addressed — a reply to the bot, an @mention, or a text_mention entity resolving to the bot. Slash-commands are unaffected; unlisted chats behave normally. Requires Telegram privacy mode OFF (BotFather /setprivacy Disable) for non-addressed group messages to reach the bot at all. Overridden by telegram.tagOnlyChats in afk.config.json. |
AFK_TELEGRAM_CWD | No | Override the working directory used when the bot spawns agent sessions. Useful when the bot runs as a service and the default cwd is not your project root. |
afk.config.json — telegram block
Structured Telegram settings live under the telegram key in afk.config.json (typically at
~/.afk/config/afk.config.json for global settings, or <cwd>/afk.config.json for
per-project overrides).
{
"telegram": {
"notify": {
"mode": "primary",
"primaryChatId": 12345678,
"targets": [12345678, 87654321]
},
"tagOnlyChats": [-100987654321],
"chatAliases": {
"ops": -100987654321,
"personal": 12345678
},
"verifyDone": false
}
}| Key | Type | Description |
|---|---|---|
telegram.notify.mode | "primary" | "broadcast" | "custom" | Fan-out strategy for outbound notifications. primary (default): one target chat. broadcast: every chat in AFK_TELEGRAM_ALLOWED_CHAT_IDS. custom: only the IDs in targets. |
telegram.notify.primaryChatId | number | Explicit primary chat, overriding the env var and the first-DM fallback. |
telegram.notify.targets | number[] | Chat IDs used when mode is custom. |
telegram.tagOnlyChats | number[] | Per-chat tag-only policy (takes precedence over AFK_TELEGRAM_TAG_ONLY_CHAT_IDS). The bot responds to non-command messages in these chats only when directly addressed. |
telegram.chatAliases | Record<string, number> | Named aliases for chat IDs. The send_telegram tool's chat param and a scheduled task's notifyChat accept an alias name in place of a raw numeric ID. The resolved alias must still be in the allowlist (fail-closed). |
telegram.verifyDone | boolean | When true, a Done notification is downgraded to "⚠️ Done (unverified)" unless the session produced corroborating evidence (a file write or executed command). Default: false. |
Bot commands
Inside Telegram, the bot recognizes:
| Command | Description |
|---|---|
/start | Welcome message |
/clear | Clear conversation history and start fresh |
/model opus | Switch the active model (opus, sonnet, haiku, fable) |
Any other message is sent to the session as a regular turn. The bot runs in the default permission mode — tools execute without per-tool prompts, and file access outside the working directory stays contained, the same as the REPL. See Permissions.
Managing the bot process
afk telegram start # start as a background daemon
afk telegram stop # SIGTERM (then SIGKILL after 5 seconds)
afk telegram restart # stop + start
afk telegram status # running state, PID, uptime, memory, recent log lines
afk telegram logs # print the last 50 log lines
afk telegram logs -f # follow the log (like tail -f)
afk telegram logs -n 100 # show the last 100 linesafk telegram status shows:
- Running / stopped state with PID
- Uptime (when running)
- Memory usage in MB (when running)
- Path to the PID file and log file
- Recent log entries
Telegram as a notification channel
Even without the interactive bot surface, you can use Telegram purely for push notifications.
The daemon pushes a message on every scheduled task completion; where that message goes is
controlled by the notification routing described above — primary (default), broadcast, or
custom.
The send_telegram tool is also available inside agent sessions. You can target a specific chat
by raw numeric ID or by a chatAliases name defined in afk.config.json:
{
"telegram": {
"chatAliases": {
"ops": -100987654321,
"personal": 12345678
}
}
}Then in a session the agent can route to "ops" by name instead of the raw ID. The resolved
alias is still validated against the allowlist — a non-allowlisted target is rejected.
The send_telegram tool is safe to attempt unconditionally: if Telegram is not configured,
it returns an error instead of crashing.
Troubleshooting
Bot starts but never responds — the most common cause is a missing or incorrect
AFK_TELEGRAM_ALLOWED_CHAT_IDS. Run afk telegram status and check the log with
afk telegram logs. Send your bot a message, then check the log for "message from unknown chat"
or similar.
afk telegram start exits immediately — the bot process crashed on startup. Check the logs:
afk telegram logsCommon causes: invalid TELEGRAM_BOT_TOKEN, network connectivity, or a port conflict.
Token not set — afk telegram setup reads from and writes to ~/.afk/config/afk.env.
If you set the token in your shell profile, it may not be available to the bot daemon. Write
it to afk.env instead — afk config env set prompts for the token with a masked input so it
never lands in your shell history:
afk config env set TELEGRAM_BOT_TOKEN # masked prompt (recommended)
echo "TELEGRAM_BOT_TOKEN=<token>" >> ~/.afk/config/afk.env # or append by handDaemon
afk daemon runs Agent AFK as a long-running headless process that fires scheduled tasks on cron expressions or session-start triggers.
Web Dashboard
afk web serves a local browser UI for live agent sessions — streaming output, schedule management, background job inspection, and slash-command dispatch.