OpenCode 飞书插件 — 通过飞书 WebSocket 长连接将飞书消息接入 OpenCode AI 对话。
在 ~/.config/opencode/opencode.json 中添加:
{
"plugin": ["opencode-feishu"]
}Windows 上 Bun 安装存在 EPERM 权限问题,建议使用项目绝对路径:
"plugin": ["D:/path/to/opencode-feishu"]
创建 ~/.config/opencode/plugins/feishu.json:
{
"appId": "cli_xxxxxxxxxxxx",
"appSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}也支持通过环境变量注入敏感值(适合容器部署):
{
"appId": "${FEISHU_APP_ID}",
"appSecret": "${FEISHU_APP_SECRET}"
}${VAR_NAME} 占位符会在启动时从 process.env 读取,未设置则报错。明文值直接使用。
在 飞书开放平台 创建自建应用,然后:
- 添加机器人能力
- 事件订阅 — 添加
im.message.receive_v1和im.chat.member.bot.added_v1 - 订阅方式 — 选择「使用长连接接收事件/回调」(不是 Webhook)
- 权限 — 开通
im:message、im:message:send_as_bot、im:chat、im:message:readonly、contact:user.base:readonly - 发布应用
opencode插件自动安装并连接飞书 WebSocket。
~/.config/opencode/plugins/feishu.json 完整配置:
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
appId |
string | 是 | — | 飞书应用 App ID |
appSecret |
string | 是 | — | 飞书应用 App Secret |
timeout |
number | 否 | 未设置 |
对话轮询总超时(毫秒);未配置时不设固定超时,持续等待直到响应稳定、检测到 SSE 错误或请求被中断 |
logLevel |
string | 否 | "info" |
日志级别:fatal/error/warn/info/debug/trace |
maxHistoryMessages |
number | 否 | 200 |
入群时最多摄入的历史消息条数(飞书接口按 50/页分页拉取) |
pollInterval |
number | 否 | 1000 |
轮询 AI 响应的间隔(毫秒) |
stablePolls |
number | 否 | 3 |
连续几次轮询内容不变视为回复完成 |
dedupTtl |
number | 否 | 600000 |
消息去重缓存过期时间(毫秒) |
maxResourceSize |
number | 否 | 524288000 |
单个资源最大下载大小(字节,默认 500MB) |
directory |
string | 否 | OpenCode 当前工作目录 |
默认工作目录,支持 ~ 和 ${ENV_VAR} 展开;若 OpenCode 未提供则为空字符串 |
nudge.enabled |
boolean | 否 | false |
启用 session.idle 催促;命中条件时向 OpenCode 发送 synthetic prompt,而不是直接向飞书新增可见消息 |
nudge.intervalSeconds |
number | 否 | 30 |
同一 session 连续催促的最小间隔(秒) |
nudge.maxIterations |
number | 否 | 3 |
同一 session 最大催促次数(用户新消息后重置) |
nudge.message |
string | 否 | "上一步操作已完成。请继续执行下一步,同步当前进度。如果全部完成,给出完整结果和结论。" |
发送给 OpenCode 的 synthetic prompt 内容 |
- CardKit 2.0 流式卡片 — AI 回复实时显示文本(markdown 渲染)和工具调用进度
- 交互式卡片 — 权限审批和问答通过按钮完成(card.action.trigger 回调)
- Agent 卡片工具 —
feishu_send_cardtool,AI 自主决定何时使用卡片展示结构化内容 - 运行时 prompt 分层 —
prompt.md仅注入飞书渠道事实和工具契约,SKILL.md负责维护与评审,不再用插件侧 skill 主动塑形会话 - 多媒体消息支持 — 图片、文件、音频、富文本(含内嵌图片)、卡片表格等,自动下载转换
- 用户名显示 — 群聊消息自动解析飞书用户名替代 open_id(24h 缓存)
- 消息引用解析 — 解析飞书回复/引用关系,将被引用消息内容作为上下文传给 AI
- 群聊静默监听 — 所有群消息作为上下文积累,仅 @提及时回复
- FIFO 消息队列 — P2P 和群聊统一串行队列,消息按顺序处理不互相中断
- 入群自动摄入历史消息
- session.idle 催促 — 仅在工具调用后停止时,按需向 OpenCode 注入 synthetic prompt 继续执行(可配置)
- Langfuse 用户关联 — 每条消息 fire-and-forget 发送 trace 到 Langfuse,关联 sessionId 和飞书 userId
- 代理支持 —
HTTPS_PROXY/HTTP_PROXY/ALL_PROXY - 消息去重 — 可配置 TTL(默认 10 分钟)
- Zod 配置验证 — 启动时结构化验证 feishu.json,拼写/类型错误立即报出
完整的产品行为契约(消息流程、责任分界、错误体验、不变量、配置如何影响行为)见 BEHAVIOR.md。
简表速查:
| 场景 | 发送到 OpenCode | AI 回复 | 飞书回复 |
|---|---|---|---|
| 单聊 | 是 | 是 | 是(流式卡片) |
| 群聊 + @bot | 是 | 是 | 是(流式卡片) |
| 群聊未 @bot | 是 | 否(静默积累上下文) | 否 |
| bot 入群 | 历史消息 | 否 | 否 |
支持的消息类型:text / image / 富文本 (post) / file / audio / 卡片 / quote。详见 BEHAVIOR.md §4.2。
npm install # 安装依赖
npm run build # 构建
npm run dev # 开发模式(监听变更)
npm run typecheck # 类型检查
npm run release # 交互式版本发布(bumpp:选版本 → commit → tag → push)
npm publish # 发布到 npm(自动先构建+类型检查)
npm publish --dry-run # 预览将要发布的内容# 启用调试日志(结构化 JSON 输出到 stderr)
FEISHU_DEBUG=1 opencode
# 过滤错误日志
FEISHU_DEBUG=1 opencode 2>&1 | grep '"level":"error"'
# 重定向到文件
FEISHU_DEBUG=1 opencode 2>feishu-debug.logMIT