agentafk
Surfaces

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:

  1. Send /newbot
  2. Follow the prompts to name your bot
  3. Copy the token BotFather gives you (it looks like 1234567890:ABC...)

2. Run the setup wizard

afk telegram setup

The 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=12345678

3. Start the bot

afk telegram start

The 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=12345678

AFK_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,87654321

Environment 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.

VariableRequiredDescription
TELEGRAM_BOT_TOKENYesBot token from @BotFather.
AFK_TELEGRAM_ALLOWED_CHAT_IDSYesComma-separated chat IDs the bot will accept messages from.
AFK_TELEGRAM_PRIMARY_CHAT_IDNoDefault 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_MODENoOutbound 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_IDSNoComma-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_CWDNoOverride 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
  }
}
KeyTypeDescription
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.primaryChatIdnumberExplicit primary chat, overriding the env var and the first-DM fallback.
telegram.notify.targetsnumber[]Chat IDs used when mode is custom.
telegram.tagOnlyChatsnumber[]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.chatAliasesRecord<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.verifyDonebooleanWhen 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:

CommandDescription
/startWelcome message
/clearClear conversation history and start fresh
/model opusSwitch 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 lines

afk 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 logs

Common causes: invalid TELEGRAM_BOT_TOKEN, network connectivity, or a port conflict.

Token not setafk 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 hand

On this page