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.
- Issue created - Title, description, status, priority, assignee, project fields, and a "View Issue" link
- Issue done - Completion confirmation with status fields
- Approval requested - Interactive Approve and Reject inline buttons. Click to act without leaving Telegram.
- Agent error - Error message with warning indicator
- Agent run started/finished - Lifecycle notifications
- Approve/reject inline buttons on every approval notification
- Clicking a button calls the Paperclip API and updates the Telegram message inline
- Callback query acknowledgment with result text
approvalsChatId- Dedicated chat for approval notificationserrorsChatId- Dedicated chat for agent errorsescalationChatId- Dedicated chat for agent escalations- Falls back to
defaultChatIdwhen per-type chats aren't configured - Per-company overrides via
/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>- Map a forum topic to a Paperclip project/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 command
- Agents call
escalate_to_humantool when stuck (low confidence, user request, policy violation, unknown intent) - Escalation posted to dedicated channel with conversation context, suggested reply, and confidence score
- Inline buttons: Send Suggested Reply, Reply, Override, Dismiss
- Configurable timeout with default actions (
defer,auto_reply,close) - Hold message sent to customer while waiting for human response
- Reply routing back to originating chat via native or ACP transport
- Multiple agents per thread (up to 5 configurable via
maxAgentsPerThread) @mentionrouting: address a specific agent by name in a multi-agent thread- Reply-to routing: reply to an agent's message to route to that agent
- Fallback routing: most recently active agent receives unaddressed messages
- Handoff: agents call
handoff_to_agenttool to transfer work, with optional human approval gate - Discuss: agents call
discuss_with_agenttool to start back-and-forth conversation loops - Conversation loops with configurable max turns and human checkpoint pauses
- Stale loop detection (auto-pause when output repeats)
- Output sequencing so multi-agent responses don't interleave
- Native-first spawning: tries Paperclip agent sessions before falling back to ACP
- Auto-spawn on handoff/discuss if target agent isn't already in the thread
- Voice messages, audio, video notes, documents, and photos routed to agents
- Voice/audio transcription via Whisper API with transcription preview posted back
- Brief Agent: media sent to intake channels is forwarded to a configurable Brief Agent for triage
- Media in active agent threads is routed to the active session (native or ACP)
/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- Custom commands invocable directly as
/<name>(cannot override built-ins) - Workflow step types:
fetch_issue,invoke_agent,http_request,send_message,create_issue,wait_approval,set_state - Template interpolation:
{{arg0}},{{args}},{{prev.result}},{{step_id.result}} - Per-company command registry
- Agents call
register_watchtool to set up condition-based monitors - Watch conditions:
gt,lt,eq,ne,contains,existsoperators on entity fields - Watches evaluate against issues, agents, or custom state-stored data
- Built-in templates:
invoice-overdue,lead-stale - Custom templates with
{{field}}placeholder interpolation - Rate limiting: configurable max suggestions per hour per company
- Deduplication: same watch+entity won't re-fire within a configurable window (default 24h)
- Scheduled job checks all watches periodically
- Reply to any bot notification to route your message back to Paperclip
- Replies to issue notifications create issue comments automatically
- Replies to escalation notifications resolve the escalation as a human reply
- Enable/disable with
enableInboundconfig toggle (default: true)
- Configurable digest summaries posted to your Telegram chats
- Modes:
daily(once),bidaily(twice),tridaily(three times per day) - Configure via the
digestModeconfig setting - Includes: tasks completed/created, active agents, in-progress/review/blocked issues
- Map Telegram forum topics to Paperclip projects via
/connect-topic - Notifications for a project are routed to its mapped topic
- Requires a group with forum topics enabled
npm install paperclip-plugin-telegramOr 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"}'- Open Telegram and chat with @BotFather
- Run
/newbotand 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 thechat.idfield - In Paperclip, go to Settings -> Secrets -> Create new secret, paste your bot token as the secret value, and copy the resulting UUID
- Configure the plugin with the secret UUID in
telegramBotTokenRefand your chat ID indefaultChatId
| Setting | Required | Description |
|---|---|---|
telegramBotTokenRef |
Yes | Secret UUID for your bot token |
defaultChatId |
No | Fallback chat ID for notifications |
approvalsChatId |
No | Separate chat for approvals |
errorsChatId |
No | Separate chat for errors |
escalationChatId |
No | Dedicated chat for agent escalations |
paperclipBaseUrl |
No | Internal Paperclip API URL (default: http://localhost:3100) |
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) |
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) |
| 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, /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 your raw bot token in the field, follow these steps to migrate:
- Go to Settings -> Secrets -> Create new secret
- Paste your Telegram bot token as the secret value and save
- Copy the resulting UUID
- Open Plugin Settings for Telegram Bot and paste the UUID into "Telegram Bot Token"
- Save and restart the plugin
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