Appearance
OpenCode 通知系统:Bun + Telegram Bot 集成研究
执行摘要
本研究探讨了为 OpenCode 实现一个基于 Telegram 的实时通知系统。当 OpenCode 执行完成、失败或需要用户确认时,通过 Telegram Bot 发送即时通知。建议的方案采用 Bun 作为运行时(得益于其高性能和 WebSocket 能力),结合 Telegram Bot API 实现可靠的跨平台消息传递。该架构提供了清晰的关注点分离,允许 OpenCode 发出事件,由独立的通知服务处理消息传递,实现了松耦合、高可扩展的通知系统。
核心发现
- 架构设计:采用事件驱动架构,OpenCode 作为事件发射器,独立通知服务监听事件并发送 Telegram 消息
- 技术选型:Bun 作为运行时提供优异的性能和 WebSocket 支持,Telegram Bot API 提供可靠的消息传递
- 事件类型:支持任务开始、成功、失败、需要确认等核心事件
- 通信机制:支持本地 IPC、WebSocket、HTTP 等多种通信方式
可行性评估
技术可行性:高度可行(Highly Feasible)
- ✅ Bun 提供优异的性能和 WebSocket 支持
- ✅ Telegram Bot API 稳定可靠,文档完善
- ✅ 事件驱动架构松耦合,易于维护
- ✅ 支持多种通信机制,灵活适配
- ⚠️ 需要配置 Telegram Bot Token
- ⚠️ 需要管理用户 Chat ID
文档导航
- analysis.md - 完整分析报告:架构设计、技术方案、实现细节、代码示例
核心内容
1. 系统架构
┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐
│ OpenCode │────────▶│ Notification │────────▶│ Telegram │
│ (事件发射器) │ 事件 │ 服务 (Bun) │ HTTP │ Bot API │
└─────────────────┘ └──────────────────┘ └─────────────┘
│
▼
┌──────────────┐
│ 本地 IPC/ │
│ WebSocket │
└──────────────┘核心组件
- OpenCode:发出生命周期事件(开始、成功、失败、需要确认)
- 通知服务(Bun):订阅事件、格式化消息、调用 Telegram API
- Telegram Bot:向用户设备传递格式化的通知
2. 事件类型
| 事件名称 | 触发条件 | 载荷结构 |
|---|---|---|
opencode:start | 任务执行开始 | { taskId, command, timestamp } |
opencode:success | 任务成功完成 | { taskId, duration, outputSummary } |
opencode:failure | 任务失败 | { taskId, error, stackTrace, exitCode } |
opencode:confirm | 需要用户确认 | { taskId, message, options } |
3. 技术选型
Bun 运行时
优势:
- 极快的启动速度和运行时性能
- 原生 TypeScript 支持
- 内置 WebSocket 支持
- 轻量级 HTTP 服务器
- 兼容 Node.js API
性能对比:
- 启动速度:比 Node.js 快 3-4 倍
- HTTP 请求:比 Node.js 快 2-3 倍
- WebSocket:原生支持,性能优异
Telegram Bot API
优势:
- 完全免费,无消息限制
- 官方 API 稳定可靠
- 丰富的消息格式(文本、按钮、内联键盘)
- 支持文件传输
- 全平台支持(iOS、Android、Web、Desktop)
核心方法:
sendMessage:发送文本消息sendMessage+reply_markup:发送交互式按钮answerCallbackQuery:响应按钮点击editMessageText:编辑已发送的消息
4. 通信机制
方案 1:本地 IPC (推荐)
typescript
// OpenCode 侧
import { send } from "./ipc"
send("opencode:success", {
taskId: "task-123",
duration: 5000,
outputSummary: "Successfully completed"
})
// 通知服务侧
import { listen } from "./ipc"
listen("opencode:success", async (payload) => {
await sendTelegramMessage(payload)
})优势:
- 低延迟
- 简单可靠
- 无需网络配置
方案 2:WebSocket
typescript
// 通知服务(Bun WebSocket 服务器)
Bun.serve({
port: 3000,
fetch(req, server) {
if (server.upgrade(req)) return
return new Response("Upgrade failed", { status: 500 })
},
websocket: {
message(ws, message) {
const event = JSON.parse(message)
handleEvent(event)
}
}
})
// OpenCode 侧
const ws = new WebSocket("ws://localhost:3000")
ws.send(JSON.stringify({
type: "opencode:success",
payload: { taskId, duration, outputSummary }
}))优势:
- 双向通信
- 实时性强
- 支持远程部署
方案 3:HTTP Webhook
typescript
// 通知服务(HTTP 服务器)
Bun.serve({
port: 3000,
async fetch(req) {
const event = await req.json()
await handleEvent(event)
return new Response("OK")
}
})
// OpenCode 侧
await fetch("http://localhost:3000/webhook", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
type: "opencode:success",
payload: { taskId, duration, outputSummary }
})
})优势:
- 简单直接
- 易于调试
- 支持负载均衡
5. 实现示例
通知服务核心代码(Bun)
typescript
// notification-service.ts
const BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN
const CHAT_ID = process.env.TELEGRAM_CHAT_ID
async function sendTelegramMessage(text: string, buttons?: any) {
const url = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`
const payload = {
chat_id: CHAT_ID,
text,
parse_mode: "Markdown",
...(buttons && { reply_markup: buttons })
}
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
})
return response.json()
}
// 事件处理器
async function handleSuccess(payload: any) {
const message = `
✅ *OpenCode Task Completed*
Task ID: \`${payload.taskId}\`
Duration: ${payload.duration}ms
Output: ${payload.outputSummary}
`
await sendTelegramMessage(message)
}
async function handleFailure(payload: any) {
const message = `
❌ *OpenCode Task Failed*
Task ID: \`${payload.taskId}\`
Error: \`${payload.error}\`
Exit Code: ${payload.exitCode}
`
await sendTelegramMessage(message)
}
async function handleConfirm(payload: any) {
const message = `
🔔 *OpenCode Needs Your Confirmation*
${payload.message}
`
const buttons = {
inline_keyboard: [[
{ text: "✅ Approve", callback_data: `approve:${payload.taskId}` },
{ text: "❌ Reject", callback_data: `reject:${payload.taskId}` }
]]
}
await sendTelegramMessage(message, buttons)
}OpenCode 插件集成
typescript
// opencode-notification-plugin.ts
import type { Plugin } from "@opencode-ai/plugin"
export const NotificationPlugin: Plugin = async (ctx) => {
const notifyService = await connectToNotificationService()
return {
"session.created": async (input, output) => {
await notifyService.emit("opencode:start", {
taskId: output.sessionID,
command: input.prompt,
timestamp: Date.now()
})
},
"session.completed": async (input, output) => {
await notifyService.emit("opencode:success", {
taskId: output.sessionID,
duration: output.duration,
outputSummary: output.summary
})
},
"session.failed": async (input, output) => {
await notifyService.emit("opencode:failure", {
taskId: output.sessionID,
error: output.error,
stackTrace: output.stackTrace,
exitCode: output.exitCode
})
},
"permission.requested": async (input, output) => {
await notifyService.emit("opencode:confirm", {
taskId: output.sessionID,
message: input.message,
options: input.options
})
}
}
}部署与配置
1. 创建 Telegram Bot
bash
# 1. 在 Telegram 中找到 @BotFather
# 2. 发送 /newbot 创建新机器人
# 3. 获取 Bot Token
# 4. 发送消息到机器人获取 Chat ID2. 配置环境变量
bash
# .env
TELEGRAM_BOT_TOKEN=your_bot_token_here
TELEGRAM_CHAT_ID=your_chat_id_here3. 安装依赖
bash
# 安装 Bun
curl -fsSL https://bun.sh/install | bash
# 安装项目依赖
bun install4. 启动服务
bash
# 启动通知服务
bun run notification-service.ts
# 在 OpenCode 中启用插件
# 编辑 opencode.config.ts
import { NotificationPlugin } from "./opencode-notification-plugin"
export default {
plugins: [NotificationPlugin]
}最佳实践
1. 消息格式设计
- 使用 Markdown 格式化消息
- 添加清晰的状态指示器(✅❌🔔)
- 包含关键信息(Task ID、时间、错误等)
- 保持消息简洁,避免过长
2. 错误处理
- 实现重试机制(网络失败时)
- 记录失败的通知以便后续处理
- 提供降级方案(如日志文件)
- 监控通知服务健康状态
3. 性能优化
- 使用消息队列处理高并发
- 批量发送非紧急通知
- 实现消息去重
- 限制消息发送频率
4. 安全考虑
- 保护 Bot Token 和 Chat ID
- 验证事件来源
- 限制 API 访问(白名单)
- 加密敏感信息
扩展方向
1. 多用户支持
- 支持多个用户订阅通知
- 基于用户偏好过滤事件
- 用户权限管理
2. 丰富的消息类型
- 发送代码片段(使用 Telegram 代码格式)
- 发送文件(日志、报告等)
- 发送图片(图表、截图等)
3. 交互式功能
- 通过 Telegram 控制 OpenCode
- 远程批准/拒绝操作
- 查询任务状态
- 取消正在运行的任务
4. 集成其他通知渠道
- Slack
- Discord
- 企业微信/钉钉
适用场景
适合使用的场景
- 长时间运行的 OpenCode 任务
- 需要远程监控的自动化流程
- 团队协作开发环境
- CI/CD 集成场景
- 需要即时反馈的交互式任务
不适合使用的场景
- 短时间完成的简单任务
- 本地开发的轻量级使用
- 不希望依赖外部服务的场景
- 对隐私有严格要求的环境(需自建服务)
核心参考资料
官方文档
- Bun Documentation - Bun 运行时官方文档
- Telegram Bot API - Telegram Bot API 官方文档
- OpenCode Plugin API - OpenCode 插件开发文档
技术资源
- Telegram Bot Examples - Telegram Bot 示例代码
- Bun WebSocket Guide - Bun WebSocket 使用指南
- OpenCode Event Hooks - OpenCode 事件钩子文档
相关研究
- OpenCode Deep Dive - OpenCode 深度研究
- oh-my-opencode Analysis - oh-my-opencode 分析
研究日期:2026-01-19
技术栈:Bun + Telegram Bot API
研究类型:技术方案研究
文档版本:1.0