@xgjktech/xg_cwork_im
v1.12.3
Published
XG CWork IM channel plugin for OpenClaw
Downloads
1,385
Maintainers
Readme
XG CWork IM Channel for OpenClaw
工作说说 IM 机器人 Channel 插件,通过 WebSocket 长连接接收 @ 消息,由 OpenClaw AI 处理后自动回复。
工作原理
IM 系统 → WebSocket → 插件(本项目) → OpenClaw AI → IM 发送接口 → IM 系统- 插件启动时用
robotKey(兼容旧字段appKey)换取access_token和userId - 建立 WebSocket 长连接,接收带业务
params的推送(当前代码会处理robotMention与groupMessage,条件:parsed.params存在且cmd为上述二者之一) - 将收到的消息转发给 OpenClaw 处理
- OpenClaw AI 回复后,插件:
- 先通过 WebSocket
START让 IM 端显示一条「思考中」占位消息; - 当 AI 产出第一条完整回复时,用 HTTP
/im/message/send覆盖这条占位消息; - 若有多条回复,则后续每条都通过 HTTP 作为独立消息发送;
- 首条回复若在配置的超时时间内一直未产生,会自动将占位消息更新为「当前请求处理超时,请稍后重试」。
- 先通过 WebSocket
前置条件
- 已安装 OpenClaw (
>=2026.2.13) - 已在 IM 后台注册机器人,获取到
robotKey(旧配置中的appKey仍兼容)
安装
推荐同事通过 npm 安装,无需访问内部 Git;需要改源码时再从内部仓库克隆(方法 B)。
方法 A:通过 npm 包安装(推荐)
一条命令完成安装,依赖由 OpenClaw 自动处理:
openclaw plugins install @xgjktech/xg_cwork_im运行 openclaw plugins list 确认列表中有 xg_cwork_im 即可。
体积说明:扩展目录只需安装本插件 4 个运行时依赖(约十余 MB)。请勿在
~/.openclaw/extensions/xg_cwork_im内执行裸npm install把 openclaw 网关再装一遍(会膨胀到数百 MB)。若已误装,删除该目录下node_modules后执行npm install --omit=dev即可。
方法 B:通过本地源码安装
如需二次开发或无法使用 npm 安装时,可从内部 Git 克隆后以链接模式安装:
git clone http://192.168.3.200/openclaw/openclaw-channel-xg-cwork-im.git
cd openclaw-channel-xg-cwork-im
npm install # 开发:含 TypeScript、openclaw(仅 dev,用于编译);扩展目录生产安装请用 --omit=dev
npm run build
openclaw plugins install -l .方法 C:手动安装
- 将本仓库下载或复制到
~/.openclaw/extensions/xg_cwork_im(Windows 为%USERPROFILE%\.openclaw\extensions\xg_cwork_im)。 - 确保目录内包含
index.ts、openclaw.plugin.json、package.json。 - 在该目录执行
npm install --omit=dev或npm run install:prod安装依赖(仅 axios/ws/zod 等,勿在插件目录重复安装 openclaw 网关)。 - 运行
openclaw plugins list确认xg_cwork_im已显示。
方法 D:国内网络环境(npm 镜像源)
若执行 openclaw plugins install @xgjktech/xg_cwork_im 时卡在「Installing plugin dependencies...」或出现 npm install failed,可临时指定国内镜像源:
NPM_CONFIG_REGISTRY=https://registry.npmmirror.com openclaw plugins install @xgjktech/xg_cwork_im若插件已半安装(扩展目录存在但依赖未装全),可进入插件目录手动补装:
cd ~/.openclaw/extensions/xg_cwork_im
# Windows: cd %USERPROFILE%\.openclaw\extensions\xg_cwork_im
rm -rf node_modules package-lock.json
NPM_CONFIG_REGISTRY=https://registry.npmmirror.com npm install --omit=dev更新已安装的插件
当插件发布新版本后,已安装的用户可按以下方式更新。
通过 npm 安装的(方法 A)
使用插件 id(不是 npm 包名)执行更新:
openclaw plugins update xg_cwork_im更新完成后执行 openclaw gateway restart 使新版本生效。
国内网络可临时指定镜像源后再更新:
NPM_CONFIG_REGISTRY=https://registry.npmmirror.com openclaw plugins update xg_cwork_im通过本地源码 / 链接安装的(方法 B)
在插件目录拉取最新代码后重启网关:
cd openclaw-channel-xg-cwork-im # 进入当时克隆的目录
git pull
npm install
npm run build
openclaw gateway restart手动安装的(方法 C)
重新从内部 Git 下载或复制最新代码到 ~/.openclaw/extensions/xg_cwork_im,在该目录执行 npm install --omit=dev 或 npm run install:prod,再执行 openclaw gateway restart。
配置
步骤 1:启用并信任插件
执行以下命令,将 xg_cwork_im 插件添加到 OpenClaw 的信任白名单中:
openclaw plugins enable xg_cwork_im步骤 2:配置 Channel 账户信息
编辑 ~/.openclaw/openclaw.json,添加以下配置(推荐 accounts 使用对象 map,key 即 accountId):
{
"channels": {
"xg_cwork_im": {
"baseUrl": "https://cwork-web-test.xgjktech.com.cn",
"wsBaseUrl": "wss://cwork-web-test.xgjktech.com.cn",
"accounts": {
"main": { "robotKey": "你的机器人 robotKey", "agentId": "main", "name": "个人助手" }
}
}
}
}多账户:如有多个机器人,在
accounts中继续追加即可(对象 map:key 为accountId)。每个账户可指定不同的agentId对应不同的 OpenClaw Agent。
accounts.default(可选):OpenClaw 的
doctor --fix可能会自动生成accounts.default,用于存放默认项(例如groupPolicy等)。本插件会把accounts.default作为“默认覆盖”合并到每个真实账号上,但 不会把它当作一个需要启动连接的账号。
步骤 3:重启 Gateway
配置完成后,重启网关使配置生效:
openclaw gateway restart完整配置参考
~/.openclaw/openclaw.json 参考结构(示例使用 CWork 测试/生产域名,详细请参考 docs/im服务接口说明.md):
{
"plugins": {
"enabled": true,
"allow": ["xg_cwork_im"]
},
"channels": {
"xg_cwork_im": {
"baseUrl": "https://cwork-web-test.xgjktech.com.cn",
"wsBaseUrl": "wss://cwork-web-test.xgjktech.com.cn",
"groupPolicy": "mention",
"debug": false,
// 可选:首条 AI 回复超时时间(毫秒),默认 30 分钟
// 未配置时:30 * 60_000 = 1800000
"firstReplyTimeoutMs": 1800000,
// 可选:入站附件先下载到当前 Agent workspace 下该子目录,MediaPath 为相对路径或 /workspace/...(见下)
"inboundMediaWorkspaceSubdir": "xg_im_inbound",
// 沙箱 Agent 建议加:MediaPath 使用 /workspace/... 而不是 ./...(避免 read 按 cwd 解析失败)
"inboundMediaSandboxRootPrefix": "/workspace",
"accounts": {
"main": { "robotKey": "robotKey_机器人A", "agentId": "main", "name": "个人助手" },
"sales": { "robotKey": "robotKey_机器人B", "agentId": "sales", "name": "销售助手" }
}
}
},
"bindings": [
{ "type": "route", "agentId": "main", "match": { "channel": "xg_cwork_im", "accountId": "main" } },
{ "type": "route", "agentId": "sales", "match": { "channel": "xg_cwork_im", "accountId": "sales" } }
]
}生产环境配置示例
{
"channels": {
"xg_cwork_im": {
"baseUrl": "https://sg-al-cwork-web.mediportal.com.cn",
"wsBaseUrl": "wss://sg-al-cwork-web.mediportal.com.cn",
"groupPolicy": "mention",
"debug": false,
"maxConnectionAttempts": 200,
"maxReconnectDelay": 120000,
// 生产环境可根据需要调整首回复超时时间(毫秒)
"firstReplyTimeoutMs": 300000,
// 按需启用:入站附件落盘到 workspace,见配置表 inboundMediaWorkspaceSubdir
// "inboundMediaWorkspaceSubdir": "xg_im_inbound",
"accounts": {
"main": { "robotKey": "你的生产 robotKey", "agentId": "main", "name": "个人助手" }
}
}
}
}配置项说明
顶层配置(channels.xg_cwork_im)
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| baseUrl | string | 必填 | IM 服务域名(API 接口地址) |
| wsBaseUrl | string | — | 可选。WebSocket 独立域名。若不填,插件将尝试自动映射。 |
| groupPolicy | string | "mention" | 用于 OpenClaw groups.resolveRequireMention:"open" 时返回「不必强制仅 @ 才参与提及策略」;"mention" 时返回「需要 @」。注意:网关 handleMessage 是否把消息交给 AI 仅取决于 actuallyMentioned(mentions 含机器人 userId 或 "all",或旧版正文匹配 @机器人名)。groupPolicy: open 不会变成「群里任意发言都自动触发 AI」;未 @ 时仍会 recordInboundSession 记记忆,但不走 dispatchMentionedReply。 |
| enabled | boolean | true | 是否启用 |
| debug | boolean | false | 开启调试日志 |
| maxConnectionAttempts | number | 见下 | Channel 配置经 Zod 校验时默认 10(channel.ts 中 XgImConfigSchema)。connection.ts 读取配置时若该字段仍为 undefined,则回退为 200。建议在 openclaw.json 中显式填写以避免与直觉不一致。 |
| initialReconnectDelay | number | 1000 | 初始重连延迟(ms) |
| maxReconnectDelay | number | 60000 | 最大重连延迟(ms) |
| reconnectJitter | number | 0.3 | 重连抖动因子(0-1) |
| firstReplyTimeoutMs | number | 1800000(30 分钟) | 首条 AI 回复超时时间(毫秒)。未配置时代码使用 30 * 60_000(channel.ts 中 dispatchMentionedReply)。超时后通过 HTTP 将占位更新为超时提示。该键目前未写入 XgImConfigSchema,仅作为运行时字段生效(types.ts 中有类型说明)。 |
| inboundMediaWorkspaceSubdir | string | — | 可选。非空时,将入站附件先下载到当前 Agent workspace 下该相对子目录(如 xg_im_inbound),路径约定:{子目录}/{发送者 userId}/{YYYY-MM-DD}/{文件名}_{HHmmssmmm}.ext(时间为本机写入时刻),再向 OpenClaw 传入 MediaPath;默认使用 workspace 相对路径(如 ./xg_im_inbound/...),便于 沙箱 将 /workspace 映射到同一套目录树;未配置则仍使用 IM 返回的 URL。需 runtime 提供 resolveAgentWorkspaceDir。 |
| inboundMediaOpenClawPath | string | workspaceRelative(默认) | workspaceRelative:入站落盘后 MediaPath 为 ./子目录/...(若配置了 inboundMediaSandboxRootPrefix 则为该前缀 + 相对路径,如 /workspace/xg_im_inbound/...);absoluteFileUrl:宿主机 file://...(仅适合无沙箱、网关与 Agent 同盘场景)。 |
| inboundMediaSandboxRootPrefix | string | — | 可选。沙箱内 workspace 挂载根,填 /workspace 时,在 workspaceRelative 模式下 MediaPath 为 /workspace/xg_im_inbound/...,避免 ./ 被 read 等工具按进程 cwd解析导致「不可访问」。须以 / 开头。 |
| syncServiceBaseUrl | string | — | 可选。openclaw-xgkb-sync 管理 API 根地址(如 http://127.0.0.1:9090)。配置后插件可处理 IM 下发的 openclawApplySyncMapping 信令并登记目录映射。详见 docs/im服务接口说明.md。 |
账户配置(accounts.<accountId>,对象 map)
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| robotKey | string | 必填 | 机器人标识(IM 后台注册获取);旧字段 appKey 仍兼容 |
| agentId | string | "main" | 对应的 OpenClaw Agent ID |
| name | string | — | 账户显示名称(仅用于日志标识) |
| groupPolicy | string | 继承顶层 | 可覆盖顶层的 groupPolicy |
| inboundMediaWorkspaceSubdir | string | 继承顶层 | 可覆盖顶层的入站附件落盘子目录 |
| inboundMediaOpenClawPath | string | 继承顶层 | 可覆盖顶层的 MediaPath 形式(相对路径 vs file://) |
| inboundMediaSandboxRootPrefix | string | 继承顶层 | 可覆盖沙箱根前缀(如 /workspace) |
| syncServiceBaseUrl | string | 继承顶层 | 可覆盖同步服务管理 API 地址 |
Agent 工具(optional: true)
xg_cwork_im_get_group_chat_history 与 xg_cwork_im_send_group_message 在 index.ts 中以 api.registerTool(..., { optional: true }) 注册。需在对应 Agent 的 tools.allow(或你们环境中的工具白名单配置)中显式加入上述工具名后,模型才会在运行时获得它们。
故障排除
收不到消息
- 确认
robotKey正确(或旧字段appKey正确),且机器人已在 IM 后台激活 - 查看 OpenClaw 日志,确认 WebSocket 连接成功(
WebSocket connected successfully) - 群聊中确认已
@机器人
WebSocket 频繁断连
- 检查网络稳定性
- 适当增大
maxConnectionAttempts和maxReconnectDelay - 开启
debug: true查看详细日志
token 相关报错
- 确认
baseUrl域名可达 - 确认
robotKey有效(或旧字段appKey有效,可在 IM 后台查看机器人状态)
网关报 plugin must declare contracts.tools before registering agent tools
OpenClaw 2026+ 要求:在 register() 里调用 api.registerTool(...) 的工具名,必须预先写在 openclaw.plugin.json 的 contracts.tools 中(与工具对象的 name 一致)。本仓库已列出 xg_cwork_im_get_group_chat_history、xg_cwork_im_send_group_message。若你以后新增工具,请同步扩展 manifest。
占位消息后变「AI 未响应」、网关日志 invoke=0、但网页客户端有助手回复(OpenClaw 2026.x)
原因:默认群聊在未配置 messages.visibleReplies/messages.groupChat.visibleReplies = automatic 时,OpenClaw 会启用 message_tool_only(只通过 message 类工具对用户可见),从而 不向 Channel 插件的 deliver 投递,模型仍会写入会话网页可见,但 本插件不会 POST /im/message/send,msgId 合并也不会发生。
当前插件已在 dispatchMentionedReply 中对本轮强制 replyOptions.sourceReplyDeliveryMode: "automatic",一般无需再在 openclaw.json 里改该项;若你仍遇到问题,可把 messages.groupChat.visibleReplies 设为 "automatic" 做一次全局对齐。
项目结构
openclaw-channel-xg-cwork-im/
├── index.ts # 插件入口
├── src/
│ ├── types.ts # 类型定义
│ ├── auth.ts # 认证(robotKey/appKey → token)
│ ├── connection.ts # WebSocket 连接管理
│ ├── send-service.ts # IM 消息发送
│ ├── group-history-tool.ts # 拉取群消息历史的 Agent Tool
│ ├── send-group-message-tool.ts # 发送群消息的 Agent Tool
│ ├── inbound-media-local.ts # 可选:入站附件落盘到 workspace 子目录
│ ├── channel.ts # Channel 组装(meta / config / outbound / gateway)
│ ├── channel-config.ts # Zod schema、getXgImConfig、GroupSystemPrompt、命令门控
│ ├── channel-log.ts # toLogger 适配
│ ├── inbound-display.ts # 入站正文、@ 判定、MediaPath(s)、UntrustedContext
│ ├── dispatch-mentioned-reply.ts # OpenClaw 派发 + 流式 + HTTP deliver
│ ├── gateway-session-queue.ts # 按 session 排队与 /stop 清队列
├── package.json
├── tsconfig.json
├── openclaw.plugin.json
└── README.md代码仓库与发布流程说明
- 代码仓库:本项目在内部 Git 管理,地址:
http://192.168.3.200/openclaw/openclaw-channel-xg-cwork-im,不推送到 GitHub。 - 安装方式:同事安装请优先使用 npm(方法 A);需要改源码时从内部 Git 克隆(方法 B)。
- 发布流程:在内部 Git 上开发、提交后,由维护者发布到 npm;同事通过
openclaw plugins install @xgjktech/xg_cwork_im安装,无需访问 Git。
维护者:如何发布到 npm(详细步骤)
代码在内部 Git 上维护,发布到 npm 后同事即可一条命令安装。按下列步骤操作。
步骤 1:在 npm 注册 / 登录(仅本次发布走官方)
你可以保留系统默认镜像不变;只在本项目发布时显式指定官方 registry。
- 无 npm 账号:打开 https://www.npmjs.com/signup 注册。
- 在项目根目录执行(不会改全局配置):
npm login --registry=https://registry.npmjs.org/- 登录成功后校验当前身份(同样只看官方 registry):
npm whoami --registry=https://registry.npmjs.org/- 若账号开启了双因素认证(2FA),发布时必须使用:
- 在 npm 网站 Access Tokens 里创建 Granular Access Token,勾选 Publish packages,并勾选 Bypass 2FA;或
- 在发布时输入 OTP(一次性密码)。
否则会报错:Two-factor authentication or granular access token with bypass 2fa enabled is required to publish packages。
步骤 2:确认 scope 与权限
- 包名为
@xgjktech/xg_cwork_im,属于 scope@xgjktech。 - 在 npm 官网 登录 → Organizations → Create,创建组织名为 xgjktech,确保你的账号有该组织的发布权限。
- 若改用个人 scope(如
@你的用户名/xg_cwork_im),需修改package.json的"name"并同步改 README 中的安装命令。
步骤 3:发布前检查
在项目根目录执行:
npm pack --dry-run确认列出的文件无敏感内容(如 .env、密钥)。发布内容由 package.json 的 "files" 控制。
步骤 4:执行发布(强制官方 registry)
scoped 包必须加 --access public,否则会按私有包计费并可能报 402:
npm publish --access public --registry=https://registry.npmjs.org/成功后可在此查看:
https://www.npmjs.com/package/@xgjktech/xg_cwork_im
步骤 5:后续更新(重新推送到 npm)
每次发新版本都按下面做一遍即可:
- 在内部 Git 上改代码、提交、推送。
- 在 package.json 里把 version 升高(如
1.0.0→1.0.1),保存。 - 在项目根目录执行:
npm publish --access public --registry=https://registry.npmjs.org/- 通知同事执行 更新已安装的插件(见上文「更新已安装的插件」),例如:
openclaw plugins update xg_cwork_im→openclaw gateway restart。
(若该 scope 已发过公开包,有时可只执行 npm publish,建议仍带 --access public 避免误发成私有。)
常见问题
| 报错或现象 | 原因 | 处理 |
|-----------|------|------|
| 403 Forbidden,且提示需 2FA 或 token | 账号开启 2FA 后,普通登录无法发布 | 使用 Granular Access Token(勾选 Publish + Bypass 2FA),或在发布时提供 OTP |
| 403 Forbidden,无 2FA 提示 | 当前账号无 @xgjktech 发布权限 | 在 npm 创建/加入组织 xgjktech,或将包名改为个人 scope |
| 402 Payment Required | 未加 --access public,scoped 包被视为私有 | 执行 npm publish --access public |
| 国内网络登录/发布慢或超时 | 默认 registry 在国外 | 登录:npm login --registry=https://registry.npmjs.org/;发布时也可加 --registry=https://registry.npmjs.org/,不推荐长期用第三方镜像发布 |
