Bidirectional Telegram bot plugin for Paperclip - push notifications, bot commands, inline approve/reject buttons, reply routing
TypeScript
96
181 commits
updated Sep 10, 2026
Bidirectional Telegram integration for Paperclip. Push agent notifications to Telegram, receive bot commands, approve requests with inline buttons, gather community signals, run multi-agent sessions in threads, process media attachments, register custom commands, and deploy proactive agent suggestions.
Built on the Paperclip plugin SDK and the domain event bridge (PR #909).
Multiple Paperclip users asked for notifications on the same day the plugin system shipped (2026-03-14):
"is there a way to have codex/claude check paperclip to see when tasks are done without me prompting it?" - @Choose Liberty, Discord #dev
"basically to have it 'let me know when its done'" - @Choose Liberty, Discord #dev
"can claude code check paperclip to see when tasks are done" - @Nascozz, Discord #dev
@dotta (maintainer) responded: "we're also adding issue-changed hooks for plugins so when that lands someone could [make notifications]." The event bridge (PR #909) shipped that same day. @Ryze said "Really excited by the plugins. I had developed a custom plugin bridge that I will now deprecate and migrate over to the new supported plugin system."
This is that plugin.
approvalsChatId - Dedicated chat for approval notificationsapprovalsTopicId - Dedicated forum topic for approval notificationserrorsChatId - Dedicated chat for agent errorserrorsTopicId - Dedicated forum topic for agent errorsdigestChatId - Dedicated chat for digest notificationsdigestTopicId - Dedicated forum topic for digest notificationsescalationChatId - Dedicated chat for agent escalationsdefaultChatId when per-type chats aren't configured/connect/status - Show active agents and recent completions/issues - List open issues/agents - List agents with status indicators/approve <id> - Approve a pending approval/help - Display all available commands/connect <company> - Link this chat to a Paperclip company/connect_topic <project-name> [topic-id] - Map a forum topic to an existing Paperclip project/topics list - Show forum topic mappings for this chat/topics remove <project-name> - Remove one forum topic mapping/topics clear - Remove all forum topic mappings for this chat/acp spawn <agent> - Start a new agent session in the current thread/acp status - Check ACP session status/acp cancel - Cancel a running ACP session/acp close - Close a completed ACP session/commands import <json> - Import a workflow command/commands list - List registered workflow commands/commands run <name> [args] - Execute a workflow command/commands delete <name> - Delete a workflow commandescalate_to_human tool when stuck (low confidence, user request, policy violation, unknown intent)defer, auto_reply, close)maxAgentsPerThread)@mention routing: address a specific agent by name in a multi-agent threadhandoff_to_agent tool to transfer work, with optional human approval gatediscuss_with_agent tool to start back-and-forth conversation loops/commands import <json> - import a multi-step workflow as a custom slash command/commands list - show all registered custom commands/commands run <name> [args] - execute a workflow/commands delete <name> - remove a custom command/<name> (cannot override built-ins)fetch_issue, invoke_agent, http_request, send_message, create_issue, wait_approval, set_state{{arg0}}, {{args}}, {{prev.result}}, {{step_id.result}}register_watch tool to set up condition-based monitorsgt, lt, eq, ne, contains, exists operators on entity fieldsinvoice-overdue, lead-stale{{field}} placeholder interpolationenableInbound config toggle (default: true)daily (once), bidaily (twice), tridaily (three times per day)digestMode config setting/connect_topic/topics list, /topics remove <project-name>, and /topics clearapprovalsTopicId routes approval notifications to a dedicated forum topic.errorsTopicId routes agent error notifications to a dedicated forum topic.digestTopicId routes daily/bidaily/tridaily digest notifications to a dedicated forum topic.onlyNotifyBoardApprovals can restrict approval notifications to request_board_approval approvals so internal CEO approvals stay inside Paperclip.npm install paperclip-plugin-telegram
Or register with your Paperclip instance directly:
curl -X POST http://127.0.0.1:3100/api/plugins/install \
-H "Content-Type: application/json" \
-d '{"packageName":"paperclip-plugin-telegram"}'
Before filing a bug, confirm which Paperclip host this plugin is actually talking to. Run paperclipai plugin target (#8575) — it prints the resolved API URL plus the server's status, version, deploymentMode, and deploymentExposure before anything is installed. A server version older than this plugin expects is the most common cause of activation failures and secret-resolution errors (e.g. telegramBotTokenRef not resolving) that look like plugin bugs but aren't. If the URL or version is wrong, point Paperclip at the right host — or update the server — before opening an issue.
Open Telegram and chat with @BotFather
Run /newbot and follow the prompts to create a bot
Save the bot token
Send a message to your bot, then run curl "https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates" and find the chat.id field
In Paperclip, create a company secret holding your bot token, by either:
telegram-bot-token) and the bot token as the value, then click Create / Seal. The secret is created at the company level (not bound to that agent — despite the agent-context UI) and the returned UUID can be used from any plugin in the company.POST /api/companies/{companyId}/secrets with body {"name": "telegram-bot-token", "value": "<your-bot-token>", "provider": "local_encrypted"}. The response contains the secret's UUID.Copy the resulting secret UUID — you'll paste it into telegramBotTokenRef in the next step.
Configure the plugin with the secret UUID in telegramBotTokenRef and your chat ID in defaultChatId
If your Paperclip deployment requires authenticated board mutations, open the plugin settings page from a company context and complete Board Access Connection. This stores a Paperclip board API token as a company secret and lets Telegram approval actions authenticate without pasting raw tokens into the plugin config.
| Setting | Required | Description |
|---|---|---|
telegramBotTokenRef | Yes | Secret UUID for your bot token |
defaultChatId | No | Fallback chat ID for notifications |
approvalsChatId | No | Separate chat for approvals |
approvalsTopicId | No | Forum topic ID for approvals inside the selected approvals/default chat |
errorsChatId | No | Separate chat for errors |
errorsTopicId | No | Forum topic ID for errors inside the selected errors/default chat |
digestChatId | No | Separate chat for digest notifications |
digestTopicId | No | Forum topic ID for digests inside the selected digest/company/default chat |
escalationChatId | No | Dedicated chat for agent escalations |
paperclipBaseUrl | No | Internal Paperclip API URL (default: http://localhost:3100) |
paperclipBoardApiTokenRef | No | Advanced/manual secret reference to a Paperclip board API token used by Telegram approval buttons and /approve commands. Prefer the Board Access Connection settings UI when available |
paperclipPublicUrl | No | Public URL for issue links in messages |
enableCommands | No | Enable bot commands (default: true) |
enableInbound | No | Route Telegram replies to issues (default: true) |
onlyNotifyBoardApprovals | No | When enabled, send Telegram approval notifications only for request_board_approval approvals |
notifyOnAgentError | No | Send agent failure notifications (default: true) |
notifyOnAgentRunStarted | No | Send agent run-start lifecycle notifications (default: false) |
notifyOnAgentRunFinished | No | Send agent run-finish lifecycle notifications (default: false) |
allowedTelegramUserIds | No | Optional allowlist of Telegram user IDs allowed to use commands, inbound replies, media intake, and inline buttons. Empty means any user is allowed |
allowedTelegramChatIds | No | Optional allowlist of Telegram chat IDs where commands, inbound replies, media intake, and inline buttons are accepted. Empty means any chat is allowed |
topicRouting | No | Map forum topics to projects (default: false) |
digestMode | No | Digest frequency: off, daily, bidaily, tridaily (default: off) |
dailyDigestTime | No | UTC time for digest, HH:MM (default: 09:00) |
bidailySecondTime | No | Second digest time for bidaily mode (default: 17:00) |
tridailyTimes | No | Comma-separated HH:MM times for tridaily (default: 07:00,13:00,19:00) |
escalationTimeoutMs | No | Timeout before default action fires (default: 900000 / 15 min) |
escalationDefaultAction | No | Action on timeout: defer, auto_reply, close (default: defer) |
escalationHoldMessage | No | Message sent to customer while waiting |
maxAgentsPerThread | No | Max concurrent agents per thread (default: 5) |
briefAgentId | No | Agent ID for media intake Brief Agent |
briefAgentChatIds | No | Chat IDs that act as media intake channels |
transcriptionApiKeyRef | No | Secret reference to OpenAI API key for Whisper |
maxSuggestionsPerHourPerCompany | No | Rate limit for proactive suggestions (default: 10) |
watchDeduplicationWindowMs | No | Suppress duplicate watch suggestions within this window (default: 86400000 / 24h) |
Telegram does not provide a BotFather setting to disable direct messages while still allowing group use. To safely enable enableCommands or enableInbound, configure one or both allowlists:
allowedTelegramUserIds: who may interact with the botallowedTelegramChatIds: where interactions are acceptedIf both allowlists are configured, both must match. For example, a user must be on the user allowlist and the message must come from an allowed DM or group chat.
The allowlists apply to:
Leave an allowlist empty only if that dimension should be unrestricted. After changing allowlists, save the plugin settings and restart the plugin if the new values are not picked up immediately.
Approval buttons and /approve <approval-id> call Paperclip approval APIs. Authenticated Paperclip deployments may require a board API token for those mutations.
Use Board Access Connection on the plugin settings page to connect board access:
The plugin stores the resulting board API token as a Paperclip company secret and keeps only the secret reference in plugin state. The advanced paperclipBoardApiTokenRef config field is still supported for manual setups.
| Tool | Phase | Description |
|---|---|---|
escalate_to_human | 1 | Escalate a conversation to a human when confidence is low |
handoff_to_agent | 2 | Hand off work to another agent in this thread |
discuss_with_agent | 2 | Start a back-and-forth conversation with another agent |
register_watch | 5 | Register a proactive watch that monitors entities and sends suggestions |
| Feature | PR #407 | This plugin |
|---|---|---|
| Push notifications | Yes | Yes |
| Receive messages | No | Yes |
| Bot commands | No | /status, /issues, /agents, /approve, /topics, /acp, /commands |
| Inline buttons | No | Approve/reject on approvals + escalations + handoffs |
| Reply routing | No | Replies become issue comments |
| Topic routing | No | Forum topic = project |
| Daily digest | No | Yes |
| HITL escalation | No | Dedicated channel with suggested replies + timeout |
| Multi-agent threads | No | Up to 5 agents per thread, @mention routing, handoff, discuss |
| Media pipeline | No | Voice transcription, Brief Agent intake |
| Custom commands | No | Importable multi-step workflows |
| Proactive suggestions | No | Watch conditions with built-in sales templates |
| Architecture | Monorepo example | Standalone npm package |
The telegramBotTokenRef and transcriptionApiKeyRef fields now require a Paperclip secret reference (a UUID), not the raw token value. If you previously entered a raw bot token in the field, follow these steps to migrate:
The plugin will fail to activate if a raw token (non-UUID) is entered in the field.
pnpm install
pnpm typecheck
pnpm test
pnpm build
~80 tests covering notifications, approvals, escalation, session registry, media pipeline, custom commands, proactive suggestions, MarkdownV2 formatting, and bot commands.
Issues and PRs welcome at github.com/mvanhorn/paperclip-plugin-telegram.
Auto-publishes to npm on push to main via OIDC trusted publishing.
@MatB57 - Escalation channel concept, "Chat OS" vision for turning chat plugins into bidirectional agent command centers, and the HITL suggested-reply flow.
@leeknowsai - Worker bootstrap patterns adapted from the Discord plugin.
Inspired by OpenClaw's Telegram integration (grammY, bidirectional messaging, inline buttons) and adapted for the Paperclip plugin SDK.
MIT
TypeScript
100.0%
Bidirectional Telegram bot plugin for Paperclip - push notifications, bot commands, inline approve/reject buttons, reply routing
TypeScript
96
181 commits
updated Sep 10, 2026
Bidirectional Telegram integration for Paperclip. Push agent notifications to Telegram, receive bot commands, approve requests with inline buttons, gather community signals, run multi-agent sessions in threads, process media attachments, register custom commands, and deploy proactive agent suggestions.
Built on the Paperclip plugin SDK and the domain event bridge (PR #909).
Multiple Paperclip users asked for notifications on the same day the plugin system shipped (2026-03-14):
"is there a way to have codex/claude check paperclip to see when tasks are done without me prompting it?" - @Choose Liberty, Discord #dev
"basically to have it 'let me know when its done'" - @Choose Liberty, Discord #dev
"can claude code check paperclip to see when tasks are done" - @Nascozz, Discord #dev
@dotta (maintainer) responded: "we're also adding issue-changed hooks for plugins so when that lands someone could [make notifications]." The event bridge (PR #909) shipped that same day. @Ryze said "Really excited by the plugins. I had developed a custom plugin bridge that I will now deprecate and migrate over to the new supported plugin system."
This is that plugin.
approvalsChatId - Dedicated chat for approval notificationsapprovalsTopicId - Dedicated forum topic for approval notificationserrorsChatId - Dedicated chat for agent errorserrorsTopicId - Dedicated forum topic for agent errorsdigestChatId - Dedicated chat for digest notificationsdigestTopicId - Dedicated forum topic for digest notificationsescalationChatId - Dedicated chat for agent escalationsdefaultChatId when per-type chats aren't configured/connect/status - Show active agents and recent completions/issues - List open issues/agents - List agents with status indicators/approve <id> - Approve a pending approval/help - Display all available commands/connect <company> - Link this chat to a Paperclip company/connect_topic <project-name> [topic-id] - Map a forum topic to an existing Paperclip project/topics list - Show forum topic mappings for this chat/topics remove <project-name> - Remove one forum topic mapping/topics clear - Remove all forum topic mappings for this chat/acp spawn <agent> - Start a new agent session in the current thread/acp status - Check ACP session status/acp cancel - Cancel a running ACP session/acp close - Close a completed ACP session/commands import <json> - Import a workflow command/commands list - List registered workflow commands/commands run <name> [args] - Execute a workflow command/commands delete <name> - Delete a workflow commandescalate_to_human tool when stuck (low confidence, user request, policy violation, unknown intent)defer, auto_reply, close)maxAgentsPerThread)@mention routing: address a specific agent by name in a multi-agent threadhandoff_to_agent tool to transfer work, with optional human approval gatediscuss_with_agent tool to start back-and-forth conversation loops/commands import <json> - import a multi-step workflow as a custom slash command/commands list - show all registered custom commands/commands run <name> [args] - execute a workflow/commands delete <name> - remove a custom command/<name> (cannot override built-ins)fetch_issue, invoke_agent, http_request, send_message, create_issue, wait_approval, set_state{{arg0}}, {{args}}, {{prev.result}}, {{step_id.result}}register_watch tool to set up condition-based monitorsgt, lt, eq, ne, contains, exists operators on entity fieldsinvoice-overdue, lead-stale{{field}} placeholder interpolationenableInbound config toggle (default: true)daily (once), bidaily (twice), tridaily (three times per day)digestMode config setting/connect_topic/topics list, /topics remove <project-name>, and /topics clearapprovalsTopicId routes approval notifications to a dedicated forum topic.errorsTopicId routes agent error notifications to a dedicated forum topic.digestTopicId routes daily/bidaily/tridaily digest notifications to a dedicated forum topic.onlyNotifyBoardApprovals can restrict approval notifications to request_board_approval approvals so internal CEO approvals stay inside Paperclip.npm install paperclip-plugin-telegram
Or register with your Paperclip instance directly:
curl -X POST http://127.0.0.1:3100/api/plugins/install \
-H "Content-Type: application/json" \
-d '{"packageName":"paperclip-plugin-telegram"}'
Before filing a bug, confirm which Paperclip host this plugin is actually talking to. Run paperclipai plugin target (#8575) — it prints the resolved API URL plus the server's status, version, deploymentMode, and deploymentExposure before anything is installed. A server version older than this plugin expects is the most common cause of activation failures and secret-resolution errors (e.g. telegramBotTokenRef not resolving) that look like plugin bugs but aren't. If the URL or version is wrong, point Paperclip at the right host — or update the server — before opening an issue.
Open Telegram and chat with @BotFather
Run /newbot and follow the prompts to create a bot
Save the bot token
Send a message to your bot, then run curl "https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates" and find the chat.id field
In Paperclip, create a company secret holding your bot token, by either:
telegram-bot-token) and the bot token as the value, then click Create / Seal. The secret is created at the company level (not bound to that agent — despite the agent-context UI) and the returned UUID can be used from any plugin in the company.POST /api/companies/{companyId}/secrets with body {"name": "telegram-bot-token", "value": "<your-bot-token>", "provider": "local_encrypted"}. The response contains the secret's UUID.Copy the resulting secret UUID — you'll paste it into telegramBotTokenRef in the next step.
Configure the plugin with the secret UUID in telegramBotTokenRef and your chat ID in defaultChatId
If your Paperclip deployment requires authenticated board mutations, open the plugin settings page from a company context and complete Board Access Connection. This stores a Paperclip board API token as a company secret and lets Telegram approval actions authenticate without pasting raw tokens into the plugin config.
| Setting | Required | Description |
|---|---|---|
telegramBotTokenRef | Yes | Secret UUID for your bot token |
defaultChatId | No | Fallback chat ID for notifications |
approvalsChatId | No | Separate chat for approvals |
approvalsTopicId | No | Forum topic ID for approvals inside the selected approvals/default chat |
errorsChatId | No | Separate chat for errors |
errorsTopicId | No | Forum topic ID for errors inside the selected errors/default chat |
digestChatId | No | Separate chat for digest notifications |
digestTopicId | No | Forum topic ID for digests inside the selected digest/company/default chat |
escalationChatId | No | Dedicated chat for agent escalations |
paperclipBaseUrl | No | Internal Paperclip API URL (default: http://localhost:3100) |
paperclipBoardApiTokenRef | No | Advanced/manual secret reference to a Paperclip board API token used by Telegram approval buttons and /approve commands. Prefer the Board Access Connection settings UI when available |
paperclipPublicUrl | No | Public URL for issue links in messages |
enableCommands | No | Enable bot commands (default: true) |
enableInbound | No | Route Telegram replies to issues (default: true) |
onlyNotifyBoardApprovals | No | When enabled, send Telegram approval notifications only for request_board_approval approvals |
notifyOnAgentError | No | Send agent failure notifications (default: true) |
notifyOnAgentRunStarted | No | Send agent run-start lifecycle notifications (default: false) |
notifyOnAgentRunFinished | No | Send agent run-finish lifecycle notifications (default: false) |
allowedTelegramUserIds | No | Optional allowlist of Telegram user IDs allowed to use commands, inbound replies, media intake, and inline buttons. Empty means any user is allowed |
allowedTelegramChatIds | No | Optional allowlist of Telegram chat IDs where commands, inbound replies, media intake, and inline buttons are accepted. Empty means any chat is allowed |
topicRouting | No | Map forum topics to projects (default: false) |
digestMode | No | Digest frequency: off, daily, bidaily, tridaily (default: off) |
dailyDigestTime | No | UTC time for digest, HH:MM (default: 09:00) |
bidailySecondTime | No | Second digest time for bidaily mode (default: 17:00) |
tridailyTimes | No | Comma-separated HH:MM times for tridaily (default: 07:00,13:00,19:00) |
escalationTimeoutMs | No | Timeout before default action fires (default: 900000 / 15 min) |
escalationDefaultAction | No | Action on timeout: defer, auto_reply, close (default: defer) |
escalationHoldMessage | No | Message sent to customer while waiting |
maxAgentsPerThread | No | Max concurrent agents per thread (default: 5) |
briefAgentId | No | Agent ID for media intake Brief Agent |
briefAgentChatIds | No | Chat IDs that act as media intake channels |
transcriptionApiKeyRef | No | Secret reference to OpenAI API key for Whisper |
maxSuggestionsPerHourPerCompany | No | Rate limit for proactive suggestions (default: 10) |
watchDeduplicationWindowMs | No | Suppress duplicate watch suggestions within this window (default: 86400000 / 24h) |
Telegram does not provide a BotFather setting to disable direct messages while still allowing group use. To safely enable enableCommands or enableInbound, configure one or both allowlists:
allowedTelegramUserIds: who may interact with the botallowedTelegramChatIds: where interactions are acceptedIf both allowlists are configured, both must match. For example, a user must be on the user allowlist and the message must come from an allowed DM or group chat.
The allowlists apply to:
Leave an allowlist empty only if that dimension should be unrestricted. After changing allowlists, save the plugin settings and restart the plugin if the new values are not picked up immediately.
Approval buttons and /approve <approval-id> call Paperclip approval APIs. Authenticated Paperclip deployments may require a board API token for those mutations.
Use Board Access Connection on the plugin settings page to connect board access:
The plugin stores the resulting board API token as a Paperclip company secret and keeps only the secret reference in plugin state. The advanced paperclipBoardApiTokenRef config field is still supported for manual setups.
| Tool | Phase | Description |
|---|---|---|
escalate_to_human | 1 | Escalate a conversation to a human when confidence is low |
handoff_to_agent | 2 | Hand off work to another agent in this thread |
discuss_with_agent | 2 | Start a back-and-forth conversation with another agent |
register_watch | 5 | Register a proactive watch that monitors entities and sends suggestions |
| Feature | PR #407 | This plugin |
|---|---|---|
| Push notifications | Yes | Yes |
| Receive messages | No | Yes |
| Bot commands | No | /status, /issues, /agents, /approve, /topics, /acp, /commands |
| Inline buttons | No | Approve/reject on approvals + escalations + handoffs |
| Reply routing | No | Replies become issue comments |
| Topic routing | No | Forum topic = project |
| Daily digest | No | Yes |
| HITL escalation | No | Dedicated channel with suggested replies + timeout |
| Multi-agent threads | No | Up to 5 agents per thread, @mention routing, handoff, discuss |
| Media pipeline | No | Voice transcription, Brief Agent intake |
| Custom commands | No | Importable multi-step workflows |
| Proactive suggestions | No | Watch conditions with built-in sales templates |
| Architecture | Monorepo example | Standalone npm package |
The telegramBotTokenRef and transcriptionApiKeyRef fields now require a Paperclip secret reference (a UUID), not the raw token value. If you previously entered a raw bot token in the field, follow these steps to migrate:
The plugin will fail to activate if a raw token (non-UUID) is entered in the field.
pnpm install
pnpm typecheck
pnpm test
pnpm build
~80 tests covering notifications, approvals, escalation, session registry, media pipeline, custom commands, proactive suggestions, MarkdownV2 formatting, and bot commands.
Issues and PRs welcome at github.com/mvanhorn/paperclip-plugin-telegram.
Auto-publishes to npm on push to main via OIDC trusted publishing.
@MatB57 - Escalation channel concept, "Chat OS" vision for turning chat plugins into bidirectional agent command centers, and the HITL suggested-reply flow.
@leeknowsai - Worker bootstrap patterns adapted from the Discord plugin.
Inspired by OpenClaw's Telegram integration (grammY, bidirectional messaging, inline buttons) and adapted for the Paperclip plugin SDK.
MIT
TypeScript
100.0%