Feishu (飞书) ↔ OpenCode 双向网关。通过飞书个人消息与 OpenCode AI 编程助手实时交互。
- 流式卡片输出 — AI 回复通过飞书消息卡片实时流式展示(动态 PATCH 更新)
- 双向问答 — OpenCode 的
question工具提问直接转发到飞书,用户回复数字选择 - 权限审批 — 文件写入、命令执行等权限请求推送到飞书,用户远程批准/拒绝
- 错误通知 — session 错误实时推送
- 命令转发 — 飞书发送
/xxx命令直接转发给 OpenCode 执行 - Session 管理 —
/bind、/sessions、/status等控制命令
┌──────────┐ lark-cli event consume ┌─────────────┐ HTTP API ┌──────────────┐
│ Feishu │ ─────────────────────────────▶ │ Gateway │ ──────────────▶ │ OpenCode │
│ User │ ◀───────────────────────────── │ (asyncio) │ ◀────────────── │ Serve │
└──────────┘ lark-cli im +messages-send └─────────────┘ SSE /event └──────────────┘
消息流:
- 用户在飞书发消息 →
lark-cli event consume接收 NDJSON - Gateway 路由:控制命令本地处理,普通消息转发到 OpenCode
- OpenCode SSE 事件流 → Gateway 实时处理:
message.part.delta→ 流式 PATCH 更新卡片question.asked→ 转发选择题到飞书permission.asked→ 转发权限请求到飞书session.error→ 推送错误通知
- Python 3.11+
- OpenCode 已安装并可运行
opencode serve - lark-cli 已配置并登录(bot 身份)
- 飞书企业自建应用,开启机器人功能,订阅
im.message.receive_v1事件
git clone https://github.com/sudashannon/opencode-gateway.git
cd opencode-gateway
# 安装依赖
pip install -e .
# 编辑配置
cp config.yaml config.yaml # 修改 feishu.user_id 为你的 open_idconfig.yaml:
opencode:
host: 127.0.0.1
port: 4096
feishu:
user_id: ou_xxx # 你的飞书 open_id(只响应此用户的消息)
bot_identity: bot
session:
state_file: ~/.local/share/opencode-gateway/state.json
queue:
max_size: 100# 先启动 opencode serve
opencode serve --port 4096
# 启动 gateway
python -m gateway.main# 安装服务(会 enable + start)
chmod +x install.sh
./install.sh
# 查看状态
systemctl --user status opencode-gateway
systemctl --user status opencode-serve
# 查看日志
journalctl --user -u opencode-gateway -f在飞书中向机器人发消息:
| 命令 | 说明 |
|---|---|
/bind <session_id> |
绑定到指定 OpenCode session |
/sessions |
列出可用 session |
/status |
查看当前状态 |
/abort |
中止当前执行 |
/help |
显示帮助 |
/new [title] |
新建 session |
/xxx ... |
其他命令转发给 OpenCode |
- 发送
/sessions查看可用 session - 发送
/bind ses_xxx绑定 - 直接发消息与 AI 对话
- AI 回复通过流式卡片展示
- 遇到选择题/权限请求时回复数字
AI 提问时:
❓ 选择框架
【1】React — SPA 框架
【2】Next.js — 全栈框架
【3】Vue — 渐进式框架
回复数字选择,或直接输入自定义答案
回复 /skip 跳过
→ 回复 2 选择 Next.js
权限请求时:
🔒 权限请求
操作: file.write
路径: src/app.ts
【1】✅ 允许(本次)
【2】✅ 始终允许
【3】❌ 拒绝
→ 回复 1 允许本次
- 流式卡片:利用飞书消息卡片支持 PATCH 更新的特性,每 500ms 或累积 300 字触发一次更新
- 节流保护:避免触发飞书 API 限流(~5 QPS)
- 异常隔离:单条消息/事件处理失败不会影响整体服务
- 事件去重:SSE 重连后事件重放不会导致重复操作
- Graceful fallback:卡片创建失败时自动降级为纯文本消息
gateway/
├── main.py # 主入口,Gateway 类,事件分发与流式处理
├── config.py # 配置加载 + 状态持久化
├── opencode.py # OpenCode HTTP/SSE 客户端
├── feishu.py # 飞书消息收发(lark-cli 封装)
├── router.py # 消息路由(控制/转发/问答/权限)
├── formatter.py # Markdown → 飞书富文本格式转换
└── sessions.py # Session 列表(直查 SQLite)
MIT