opencode-feishu-bot
v0.1.2
Published
飞书机器人,用于与 OpenCode AI 编程助手交互
Maintainers
Readme
OpenCode 飞书机器人
一个飞书聊天机器人,用于与 OpenCode AI 编程助手集成,让你可以通过飞书与 OpenCode 进行交互。
功能特性
- 会话群模式:每个会话创建独立群组,群内无需 @机器人 即可对话
- 自动标题:首条消息自动设置群组标题,格式
o{会话ID}-{标题} - 会话隔离:多个会话群互不干扰,用户退出或解散群时自动清理
- 开箱即用:默认所有用户可用,无需配置白名单
- 菜单系统:支持飞书应用菜单,快速创建会话、切换项目等
- 自动启动:OpenCode 服务器随机器人自动启动,无需手动配置
- 流式响应:实时卡片更新,具有打字效果
- 消息撤回:用户撤回消息时自动中止任务并撤回 AI 响应
- 项目切换:支持预配置项目列表,快速切换
- 模型切换:动态切换 AI 模型
- 可选白名单:支持启用白名单模式限制访问
- 命令系统:内置常用操作命令
环境要求
安装
作为 npm 包安装
# 全局安装
npm install -g opencode-feishu-bot
# 或使用 bun
bun add -g opencode-feishu-bot从源码安装
# 克隆仓库
git clone https://github.com/kylin1020/opencode-feishu-bot.git
cd opencode-feishu-bot
# 安装依赖
bun install配置
创建配置文件 ~/.config/opencode-feishu-bot/config.toml:
mkdir -p ~/.config/opencode-feishu-bot
cp config.toml.example ~/.config/opencode-feishu-bot/config.toml配置文件示例
[feishu]
app_id = "cli_xxxxxxxxxxxx"
app_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
[admin]
user_ids = ["ou_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"]
allow_all_users = true
[database]
# path = "~/.config/opencode-feishu-bot/bot.db"
[logging]
level = "info"
[[projects]]
path = "/home/user/project-a"
name = "项目A"
[[projects]]
path = "/home/user/project-b"
name = "项目B"
[models]
default = "anthropic/claude-sonnet-4-20250514"
[[models.available]]
id = "anthropic/claude-sonnet-4-20250514"
name = "Claude Sonnet"配置项说明
| 配置项 | 说明 | 必填 |
|--------|------|------|
| feishu.app_id | 飞书开放平台的应用 ID | 是 |
| feishu.app_secret | 飞书应用密钥 | 是 |
| admin.user_ids | 管理员 open_id 列表 | 否 |
| admin.allow_all_users | 是否允许所有用户(默认 true) | 否 |
| database.path | SQLite 数据库路径 | 否 |
| logging.level | 日志级别(debug/info/warn/error) | 否 |
| projects | 预配置项目列表 | 否 |
| models.default | 默认模型 | 否 |
| models.available | 可用模型列表(留空显示全部) | 否 |
环境变量
环境变量可覆盖配置文件中的对应项:
| 变量 | 覆盖配置项 |
|------|------------|
| FEISHU_APP_ID | feishu.app_id |
| FEISHU_APP_SECRET | feishu.app_secret |
| DATABASE_PATH | database.path |
| LOG_LEVEL | logging.level |
| DEFAULT_MODEL | models.default |
注意:OpenCode 服务器会随机器人自动启动(随机端口),无需手动配置。 默认项目目录为机器人启动时的当前工作目录。
使用方法
启动机器人
# 在你的项目目录中启动
cd /path/to/your/project
opencode-feishu-bot
# 从源码运行 - 生产模式
bun run start
# 从源码运行 - 开发模式(热重载)
bun run devCLI 参数
| 参数 | 简写 | 说明 |
|------|------|------|
| --model <id> | -m | 设置默认模型(格式:provider/model) |
| --project <path> | -p | 设置默认项目目录 |
| --log-level <level> | -l | 日志级别(debug/info/warn/error) |
| --list-models | | 列出所有可用模型并退出 |
| --help | -h | 显示帮助信息 |
| --version | -v | 显示版本号 |
示例:
# 使用指定模型启动
opencode-feishu-bot --model anthropic/claude-sonnet-4-20250514
# 指定项目目录启动
opencode-feishu-bot -p /path/to/project
# 列出所有可用模型
opencode-feishu-bot --list-models
# 组合使用
opencode-feishu-bot -m anthropic/claude-sonnet-4-20250514 -p /path/to/project -l debug可用命令
| 命令 | 说明 | 仅管理员 |
|------|------|----------|
| /help | 显示可用命令 | 否 |
| /new <编号> | 创建新会话群(私聊)/ 切换项目(会话群内) | 否 |
| /model <编号或ID> | 切换 AI 模型 | 否 |
| /compact | 压缩当前会话上下文 | 否 |
| /clear | 清除历史,创建新会话 | 否 |
| /new_session | 创建新的 OpenCode 会话 | 否 |
| /switch_project <路径> | 切换到不同的项目 | 否 |
| /abort | 中止当前运行的任务 | 否 |
| /status | 显示会话状态 | 否 |
| /whitelist_add <用户ID> | 将用户添加到白名单 | 是 |
| /whitelist_remove <用户ID> | 从白名单移除用户 | 是 |
| /whitelist_list | 列出所有白名单用户 | 是 |
与 OpenCode 交互
会话群模式(推荐):
- 在私聊中向机器人发送
/new <项目编号>创建新会话群 - 机器人创建群组并拉你进群
- 在群内直接发送消息与 AI 对话,无需 @机器人
- 首条消息会自动设置群组标题(如
o1a2b3c-实现登录功能) - 退出群组或解散群时自动清理会话数据
私聊模式:
直接在私聊中向机器人发送消息,机器人会自动创建或复用会话。
消息撤回:如果在 AI 生成响应过程中撤回消息,机器人会自动中止任务并撤回已发送的响应。
开发
运行测试
bun test项目结构
src/
├── index.ts # 应用入口
├── config.ts # 配置管理
├── cli.ts # CLI 参数解析
├── database/ # SQLite 数据库层
├── feishu/ # 飞书 SDK 集成
│ ├── client.ts # 飞书客户端封装
│ ├── formatter.ts # 消息格式化
│ ├── streamer.ts # 流式卡片更新
│ ├── welcome.ts # 欢迎卡片生成
│ └── menu.ts # 菜单交互卡片
├── events/ # 事件处理
│ └── handler.ts # 机器人进群、消息撤回、菜单点击等事件
├── opencode/ # OpenCode SDK 集成(自动启动服务器)
├── session/ # 会话管理
├── commands/ # 命令系统
├── auth/ # 认证/授权
├── utils/ # 工具函数(日志、重连)
└── __tests__/ # 测试文件架构
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 飞书客户端 │────▶│ 会话管理器 │────▶│ OpenCode客户端 │
│ (WebSocket) │ │ │ │ (自动启动服务) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 消息处理器 │ │ 数据库 │ │ 事件流 │
│ │ │ (SQLite) │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ 命令处理器 │ │ 卡片流式器 │
│ │ │ │
└─────────────────┘ └─────────────────┘飞书应用配置
- 访问飞书开放平台
- 创建新的企业应用
权限配置
进入 开发配置 > 权限管理,开通以下权限:
消息权限
| 权限名称 | 权限标识 | 用途 | 必需 |
|---------|---------|------|------|
| 获取与发送单聊、群组消息 | im:message | 发送消息、更新卡片 | ✅ |
| 获取用户发给机器人的单聊消息 | im:message.p2p_msg:readonly | 接收私聊消息 | ✅ |
| 获取群组中所有消息 | im:message.group_msg:readonly | 接收群聊消息 | ✅ |
| 获取与上传图片或文件资源 | im:resource | 获取用户发送的图片 | ✅ |
群组权限
| 权限名称 | 权限标识 | 用途 | 必需 |
|---------|---------|------|------|
| 获取与更新群组信息 | im:chat | 创建群聊、更新群名、解散群 | ✅ |
| 获取群组信息 | im:chat:readonly | 获取群信息 | ✅ |
| 更新群置顶 | im:chat.top_notice:write | 置顶状态卡片 | 可选 |
用户权限
| 权限名称 | 权限标识 | 用途 | 必需 |
|---------|---------|------|------|
| 通过手机号或邮箱获取用户 ID | contact:user.id:readonly | 白名单功能(通过用户 ID 识别) | 可选 |
事件订阅
进入 开发配置 > 事件订阅:
- 选择 长连接 模式(无需配置服务器地址)
- 添加以下事件:
| 事件名称 | 事件标识 | 用途 | 必需 |
|---------|---------|------|------|
| 接收消息 | im.message.receive_v1 | 接收用户消息 | ✅ |
| 机器人进群 | im.chat.member.bot.added_v1 | 发送欢迎卡片 | ✅ |
| 机器人被移出群 | im.chat.member.bot.deleted_v1 | 清理会话数据 | ✅ |
| 用户退群 | im.chat.member.user.deleted_v1 | 会话群自动清理 | ✅ |
| 群解散 | im.chat.disbanded_v1 | 会话群自动清理 | ✅ |
| 消息撤回 | im.message.recalled_v1 | 自动中止任务、撤回响应 | ✅ |
| 机器人菜单点击 | application.bot.menu_v6 | 菜单功能 | 可选 |
| 卡片回传交互 | card.action.trigger | 卡片按钮点击(模型切换等) | ✅ |
机器人菜单(可选)
进入 应用功能 > 机器人 > 机器人菜单,添加以下菜单项:
| 菜单名称 | event_key |
|---------|-----------|
| 新建会话 | new_session |
| 切换模型 | switch_model |
| 压缩上下文 | compact |
| 清除历史 | clear_history |
| 查看状态 | show_status |
发布应用
完成以上配置后:
- 进入 应用发布 > 版本管理与发布
- 创建新版本,提交审核
- 审核通过后发布应用
- 将机器人添加到你的飞书工作区
故障排除
机器人收不到消息
无法创建会话群
- 确认已授予
im:chat权限 - 确认应用已发布并通过审核
- 检查机器人是否有创建群聊的能力
会话群内消息无响应
- 确认群组是通过
/new命令创建的会话群 - 普通群组需要 @机器人 才能触发响应
- 检查数据库中是否有该群的会话记录
权限被拒绝(白名单模式)
- 确认
ALLOW_ALL_USERS是否设为false - 验证用户是管理员或已加入白名单
- 作为管理员使用
/whitelist_add <用户ID>授予访问权限
消息撤回不生效
- 确认已订阅
im.message.recalled_v1事件 - 机器人只能撤回 24 小时内发送的消息
卡片按钮点击无响应
- 确认已订阅
card.action.trigger事件 - 检查日志中是否有卡片交互相关的错误
无法获取用户发送的图片
- 确认已授予
im:resource权限 - 检查图片是否已过期(飞书图片有有效期)
无法置顶消息
- 确认已授予
im:chat.top_notice:write权限 - 机器人需要是群管理员才能置顶消息
许可证
MIT
