An opencode plugin that connects instant messaging bots to opencode AI via a unified multi-channel architecture.
Currently supported: Feishu (Lark) via WebSocket long connection — no public IP required.
Skeleton ready: WeCom (企业微信) — see src/channels/wecom/index.ts.
User sends message (Feishu / WeCom / ...)
↓ Channel adapter (WebSocket / HTTP callback / ...)
chat-channel plugin (this repo)
↓ client.session.prompt()
opencode AI (Sisyphus)
↓ text reply
User receives reply
- Each user (
open_id/ user ID) gets their own persistent opencode session - Sessions expire after 2 hours of inactivity (auto-cleanup)
- Replies longer than 4000 characters are automatically split
Since this is an opencode plugin, opencode handles installation automatically via npm. No scripts needed.
Edit the opencode config file and add the plugin:
| Platform | Path |
|---|---|
| macOS / Linux | ~/.config/opencode/opencode.json |
| Windows | %APPDATA%\opencode\opencode.json |
{
"plugin": [
"opencode-chat-channel@latest"
]
}opencode will pull and install the package automatically on next startup.
Add CHAT_CHANNELS to your opencode .env file to control which channels are active:
| Platform | Path |
|---|---|
| macOS / Linux | ~/.config/opencode/.env |
| Windows | %APPDATA%\opencode\.env |
# ~/.config/opencode/.env
# Enable Feishu only (recommended to start)
CHAT_CHANNELS=feishu
# Enable multiple channels at once
# CHAT_CHANNELS=feishu,wecom
# Leave unset or empty = auto mode: any channel with valid credentials starts automatically
# CHAT_CHANNELS=Then configure credentials for each enabled channel (see sections below).
See the Feishu Configuration section below.
- Visit Feishu Open Platform and create a self-built app
- Note your App ID and App Secret
- Under "Add App Capabilities", enable Bot
- Under "Permissions", add:
im:message(read/send messages)im:message.group_at_msg(receive group @ messages, optional)
- Under "Event Subscriptions":
- Select "Use long connection to receive events" (no webhook URL needed)
- Add event:
Receive Message v2.0(im.message.receive_v1)
- Publish the app version
App ID (non-sensitive, store in .env):
# macOS / Linux: ~/.config/opencode/.env
# Windows: %APPDATA%\opencode\.env
FEISHU_APP_ID=cli_xxxxxxxxxxxxxxxx
# Optional: custom opencode API URL (default: http://localhost:4321)
# OPENCODE_BASE_URL=http://localhost:4321App Secret — choose the method for your platform:
| Platform | Method | Command / Location |
|---|---|---|
| macOS | Keychain (recommended) | security add-generic-password -a chat-channel -s opencode-chat-channel -w <secret> -U |
| Windows | .env file |
Add FEISHU_APP_SECRET=<secret> to %APPDATA%\opencode\.env |
| Linux | .env file |
Add FEISHU_APP_SECRET=<secret> to ~/.config/opencode/.env |
| All platforms | Environment variable | Set FEISHU_APP_SECRET=<secret> before launching opencode |
Priority: environment variable → macOS Keychain →
.envfile value (already loaded as env var). The plugin tries each in order and uses the first one found.
⚠️ If you store the secret in.env, ensure the file has restricted permissions:
- macOS/Linux:
chmod 600 ~/.config/opencode/.env- Windows: right-click the file → Properties → Security → restrict to your user only
macOS Keychain (verify):
security find-generic-password -a chat-channel -s opencode-chat-channel -wopencodeYou should see in the logs:
[feishu] 飞书机器人已启动(长连接模式),appId=cli_xxx***
chat-channel 已启动,活跃渠道: feishu
The plugin uses a ChatChannel interface. To add a new channel:
- Create
src/channels/<name>/index.tsimplementingChatChanneland exporting aChannelFactory - Register the factory in
src/index.ts→CHANNEL_FACTORIESarray
// src/channels/myapp/index.ts
import type { ChatChannel, ChannelFactory } from "../../types.js";
class MyAppChannel implements ChatChannel {
readonly name = "myapp";
async start(onMessage) { /* connect, call onMessage on each msg */ }
async send(target, text) { /* send reply */ }
}
export const myappChannelFactory: ChannelFactory = async (client) => {
// read credentials, return null if not configured
return new MyAppChannel(...);
};// src/index.ts — add to CHANNEL_FACTORIES
import { myappChannelFactory } from "./channels/myapp/index.js";
const CHANNEL_FACTORIES: ChannelFactory[] = [
feishuChannelFactory,
myappChannelFactory, // ← add here
];Q: Plugin starts but bot receives no messages
- Ensure event subscription is set to "long connection", not "HTTP callback URL"
- Ensure the app version is published and online
- Verify App ID / Secret are correct
Q: Replies are slow
- AI processing takes time; complex tasks may need 10–30 seconds
- Simple conversations typically 3–8 seconds
Q: How to reset conversation history
- Restart opencode (sessions follow process lifecycle)
- Or wait 2 hours for session TTL to expire
用户发消息(飞书 / 企业微信 / ...)
↓ 渠道适配器(WebSocket 长连接 / HTTP 回调 / ...)
chat-channel 插件(本仓库)
↓ client.session.prompt()
opencode AI (Sisyphus)
↓ 回复文本
用户收到回复
- 每个用户独享一个 opencode session,对话历史持久保留
- session 闲置 2 小时后自动回收,下次对话开新 session
- AI 回复超过 4000 字时自动分段发送
本项目是 opencode 插件,opencode 通过 npm 自动管理安装,无需额外脚本。
编辑 opencode 配置文件,在 plugin 数组中添加:
| 平台 | 路径 |
|---|---|
| macOS / Linux | ~/.config/opencode/opencode.json |
| Windows | %APPDATA%\opencode\opencode.json |
{
"plugin": [
"opencode-chat-channel@latest"
]
}下次启动 opencode 时会自动拉取并安装。
在 opencode 的 .env 文件中配置 CHAT_CHANNELS,指定要开启哪些渠道:
| 平台 | 路径 |
|---|---|
| macOS / Linux | ~/.config/opencode/.env |
| Windows | %APPDATA%\opencode\.env |
# ~/.config/opencode/.env
# 只开启飞书(初始推荐)
CHAT_CHANNELS=feishu
# 同时开启多个渠道
# CHAT_CHANNELS=feishu,wecom
# 留空或不配置 = 自动模式:凭证存在的渠道自动启用
# CHAT_CHANNELS=然后配置对应渠道的凭证(见下方各渠道配置说明)。
参见下方各渠道的配置说明。
- 访问 飞书开放平台,新建企业自建应用
- 记录 App ID 和 App Secret
- 在「添加应用能力」中开启机器人
- 在「权限管理」中添加以下权限:
im:message(读取/发送消息)im:message.group_at_msg(接收群组 @ 消息,按需)
- 在「事件订阅」中:
- 选择使用长连接接收事件(无需填写请求地址)
- 添加事件:
接收消息 v2.0(即im.message.receive_v1)
- 发布应用版本
App ID(非敏感,明文存 .env):
# macOS / Linux: ~/.config/opencode/.env
# Windows: %APPDATA%\opencode\.env
FEISHU_APP_ID=cli_xxxxxxxxxxxxxxxx
# 可选:自定义 opencode API 地址(默认:http://localhost:4321)
# OPENCODE_BASE_URL=http://localhost:4321App Secret—按使用的平台选择存储方式:
| 平台 | 方式 | 命令 / 路径 |
|---|---|---|
| macOS | 钥匙串(推荐,不落盘明文) | security add-generic-password -a chat-channel -s opencode-chat-channel -w <secret> -U |
| Windows | 写入 .env 文件 |
在 %APPDATA%\opencode\.env 中添加 FEISHU_APP_SECRET=<secret> |
| Linux | 写入 .env 文件 |
在 ~/.config/opencode/.env 中添加 FEISHU_APP_SECRET=<secret> |
| 所有平台 | 环境变量 | 启动 opencode 前设置 FEISHU_APP_SECRET=<secret> |
读取优先级:环境变量 → macOS 钥匙串 →
.env文件(已在插件启动时自动读入环境变量)。 插件依次尝试,找到第一个有效值即停止。
⚠️ 如果将 Secret 写入.env,建议限制文件权限:
- macOS/Linux:
chmod 600 ~/.config/opencode/.env- Windows:右键文件 → 属性 → 安全,限制为仅当前用户可读
macOS 钥匙串验证:
security find-generic-password -a chat-channel -s opencode-chat-channel -wopencode启动后日志中会看到:
[feishu] 飞书机器人已启动(长连接模式),appId=cli_xxx***
chat-channel 已启动,活跃渠道: feishu
插件基于 ChatChannel 接口设计,新增渠道步骤:
- 新建
src/channels/<渠道名>/index.ts,实现ChatChannel接口并导出ChannelFactory - 在
src/index.ts的CHANNEL_FACTORIES数组中注册工厂函数
参见 src/channels/wecom/index.ts — 企业微信骨架,含详细的实现 TODO 注释。
src/
├── index.ts # 插件入口,注册所有渠道
├── types.ts # ChatChannel 接口 & 公共类型
├── session-manager.ts # opencode session 管理 & 工具函数
└── channels/
├── feishu/
│ └── index.ts # 飞书渠道实现(已完成)
└── wecom/
└── index.ts # 企业微信渠道骨架(待实现)
Q: 插件启动后收不到消息
- 确认飞书应用事件订阅选择的是「长连接」而非「HTTP 请求地址」
- 确认应用已发布且版本已上线
- 确认 App ID/Secret 正确
Q: 回复很慢
- AI 处理需要时间,复杂问题可能需要 10-30 秒
- 简单对话通常 3-8 秒
Q: 想重置对话历史
- 关闭 opencode 重启即可(session 随进程生命周期)
- 或等待 2 小时 session 超时自动重置
MIT