7.0 KiB
7.0 KiB
summary, read_when
| summary | read_when | |
|---|---|---|
| Telegram bot support status, capabilities, and configuration |
|
Telegram (Bot API)
Updated: 2025-12-07
Status: ready for bot-mode use with grammY (long-polling by default; webhook supported when configured). Text + media send, mention-gated group replies with per-group overrides, and optional proxy support are implemented.
Goals
- Let you talk to Clawdbot via a Telegram bot in DMs and groups.
- Share the same
mainsession used by WhatsApp/WebChat; groups stay isolated astelegram:group:<chatId>. - Keep transport routing deterministic: replies always go back to the provider they arrived on.
How it will work (Bot API)
- Create a bot with @BotFather and grab the token.
- Configure Clawdbot with
TELEGRAM_BOT_TOKEN(ortelegram.botTokenin~/.clawdbot/clawdbot.json). - Run the gateway; it auto-starts Telegram only when a
telegramconfig section exists and a bot token is set (unlesstelegram.enabled = false).- If you prefer env vars, still add
telegram: { enabled: true }to~/.clawdbot/clawdbot.jsonand setTELEGRAM_BOT_TOKEN. - Long-polling is the default.
- Webhook mode is enabled by setting
telegram.webhookUrl(optionallytelegram.webhookSecret/telegram.webhookPath).- The webhook listener currently binds to
0.0.0.0:8787and servesPOST /telegram-webhookby default. - If you need a different public port/host, set
telegram.webhookUrlto the externally reachable URL and use a reverse proxy to forward to:8787.
- The webhook listener currently binds to
- If you prefer env vars, still add
- Direct chats: secure by default — unknown senders are gated by
telegram.dmPolicy(default:"pairing"). The bot responds with a pairing code that the owner must approve before messages are processed. If you really want public inbound DMs: settelegram.dmPolicy="open"andtelegram.allowFrom=["*"]. - Groups: add the bot, disable privacy mode (or make it admin) so it can read messages; group threads stay on
telegram:group:<chatId>. Whentelegram.groupsis set, it becomes a group allowlist (use"*"to allow all). Mention/command gating defaults come fromtelegram.groups. - Allowlist + pairing:
- Direct chats:
telegram.allowFrom(chat ids) or pairing approvals viaclawdbot pairing approve --provider telegram <code>(alias:clawdbot telegram pairing approve <code>). - Groups: set
telegram.groupPolicy = "allowlist"and list senders intelegram.groupAllowFrom(fallback: explicittelegram.allowFrom). - Commands respect group allowlists/policies by default; set
commands.useAccessGroups: falseto bypass.
- Direct chats:
- Native commands: set
commands.native: trueto register/commands; setcommands.native: falseto clear previously registered commands.
Capabilities & limits (Bot API)
- Sees only messages sent after it’s added to a chat; no pre-history access.
- Cannot DM users first; they must initiate. Channels are receive-only unless the bot is an admin poster.
- File size caps follow Telegram Bot API (up to 2 GB for documents; smaller for some media types).
- Typing indicators (
sendChatAction) supported; native replies are off by default and enabled viatelegram.replyToMode+ reply tags.
Planned implementation details
- Library: grammY is the only client for send + gateway (fetch fallback removed); grammY throttler is enabled by default to stay under Bot API limits.
- Inbound normalization: maps Bot API updates to
MsgContextwithProvider: "telegram",ChatType: direct|group,SenderName,MediaPath/MediaTypewhen attachments arrive,Timestamp, and reply-to metadata (ReplyToId,ReplyToBody,ReplyToSender) when the user replies; reply context is appended toBodyas a[Replying to ...]block (includesid:when available); groups require @bot mention or arouting.groupChat.mentionPatternsmatch by default (override per chat in config). - Outbound: text and media (photo/video/audio/document) with optional caption; chunked to limits. Typing cue sent best-effort.
- Config:
TELEGRAM_BOT_TOKENenv ortelegram.botTokenrequired;telegram.dmPolicy,telegram.groups(group allowlist + mention defaults),telegram.allowFrom,telegram.groupAllowFrom,telegram.groupPolicy,telegram.mediaMaxMb,telegram.replyToMode,telegram.proxy,telegram.webhookSecret,telegram.webhookUrl,telegram.webhookPathsupported.- Ack reactions are controlled globally via
messages.ackReaction+messages.ackReactionScope. - Mention gating precedence (most specific wins):
telegram.groups.<chatId>.requireMention→telegram.groups."*".requireMention→ defaulttrue.
- Ack reactions are controlled globally via
Example config:
{
telegram: {
enabled: true,
botToken: "123:abc",
dmPolicy: "pairing", // pairing | allowlist | open | disabled
replyToMode: "off",
groups: {
"*": { requireMention: true }, // allow all groups
"123456789": { requireMention: false } // group chat id
},
allowFrom: ["123456789"], // direct chat ids allowed ("open" requires ["*"])
groupPolicy: "allowlist",
groupAllowFrom: ["tg:123456789", "@alice"],
mediaMaxMb: 5,
proxy: "socks5://localhost:9050",
webhookSecret: "mysecret",
webhookPath: "/telegram-webhook",
webhookUrl: "https://yourdomain.com/telegram-webhook"
}
}
- Tests: grammY-based paths in
src/telegram/*.test.tscover DM + group gating; add more media and webhook cases as needed.
Group etiquette
- Keep privacy mode off if you expect the bot to read all messages; with privacy on, it only sees commands/mentions.
- Make the bot an admin if you need it to send in restricted groups or channels.
- Mention the bot (
@yourbot), use arouting.groupChat.mentionPatternstrigger, or send a standalone/...command. Per-group overrides live intelegram.groupsif you want always-on behavior; iftelegram.groupsis set, add"*"to keep existing allow-all behavior.
Reply tags
To request a threaded reply, the model can include one tag in its output:
[[reply_to_current]]— reply to the triggering Telegram message.[[reply_to:<id>]]— reply to a specific message id from context. Current message ids are appended to prompts as[message_id: …]; reply context includesid:when available.
Behavior is controlled by telegram.replyToMode:
off: ignore tags.first: only the first outbound chunk/attachment is a reply.all: every outbound chunk/attachment is a reply.
Roadmap
- ✅ Design and defaults (this doc)
- ✅ grammY long-poll gateway + text/media send
- ✅ Proxy + webhook helpers (setWebhook/deleteWebhook, health endpoint, optional public URL)
- ⏳ Add more grammY coverage (webhook payloads, media edge cases)
Safety & ops
- Treat the bot token as a secret (equivalent to account control); prefer
TELEGRAM_BOT_TOKENor a locked-down config file (chmod 600 ~/.clawdbot/clawdbot.json). - Respect Telegram rate limits (429s); grammY throttling is enabled by default.
- Use a test bot for development to avoid hitting production chats.