@cobia/pi-wecom-aibot0.4.0
WeCom (Enterprise WeChat) smart robot for pi over a long connection: BotID + Secret, no public callback URL; task status, result notifications, images, files and proactive push.
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
🤖 pi-wecom-aibot
在企业微信里给 pi 发任务,用卡片查看结果、切换模型和中止任务。采用长连接,无需公网回调地址
📦 安装
pi install npm:@cobia/pi-wecom-aibot
安装后重新打开 pi,或执行 /reload,再输入 /wecom-aibot 检查插件是否加载
🔌 连接机器人
1. 创建机器人
- 登录 企业微信管理后台,创建或打开一个「智能机器人」
- 开启「API 模式」,连接方式选「长连接」
- 记下 BotID 和 Secret
2. 配置并接入
在 pi 中执行:
/wecom-aibot config edit
- 填入 BotID 和 Secret
- 「默认推送目标」选「发验证码识别」,在接收通知的聊天里把 pi 显示的 6 位验证码发给机器人,群聊需 @机器人
- 确认识别到的聊天并保存。知道 userid/chatid 时也可以选「手动填写」
识别只会临时连接,不接收任务。保存后正式接入并测试:
/wecom-aibot connect
/wecom-aibot test
收到「🧪 部署测试」控制卡后,点「刷新卡片」验证按钮回调
每个会话都要手动 connect,新建、恢复、分叉和 /reload 后也一样。修改配置不会自动接入;退出或切换会话时自动断开
同一个机器人同一时间只能在一台电脑、一个系统用户下连接。多个 pi 会话共用网关,无需单独启动;最后一个 pi 断开后,网关约 1.5 秒自动退出
🔐 设置白名单
[!CAUTION] 不设置
allowedUserIds或留空时,任何能给机器人发消息的人都能让 pi 读写文件、执行命令。强烈建议只允许自己和信任的同事
- 用
/wecom-aibot config whoami识别 userid:让本人把 pi 显示的验证码发给机器人。未指定--scope时不修改默认推送目标 - 在全局配置文件中添加
"allowedUserIds": ["你的 userid", "同事的 userid"]。此字段只能写在全局配置中,首次设置需手动编辑 - 在每个已接入的 pi 窗口执行
/wecom-aibot connect,新名单才会生效;未重新接入的窗口仍按旧名单放行
识别不受白名单限制,也不等于授权。已有名单时,whoami 识别到新成员会询问是否加入。userid 以识别结果为准,可能与通讯录账号不同
💬 日常使用
发送任务
在单聊里直接发消息,群聊先 @机器人:
- 普通消息:机器人询问「这条消息发给哪个会话?」,选好后点「确认发送」。只有一个会话在线也要确认;不改下拉框就确认,会发给第一个候选
- 引用文字消息:引用开头带
🆔 session: <ID>的机器人文字回复,可以直接发给那个会话;会话已离线时重新询问目标 - 引用卡片、图片或文件:无法定位会话,仍需选择。企业微信不会把被引用卡片的内容传给机器人
选择只对当前消息有效,不会记住上一次的目标。选择卡有效期为 4 分钟;同一人在同一聊天又发一条需要选择目标的消息时,上一条待选消息取消。群聊里只有发送者能确认
运行期间不发送「执行中…」状态消息,完成后发一张新的结果卡;消息未能执行时会回复原因。想继续,可在结果卡上点「发提示词」,或重新发消息并选择会话
| 发送内容 | pi 收到的内容 |
|---|---|
| 文字 | 消息正文 |
| 语音 | 转写后的文字 |
| 图片 | 图片本身,需要模型支持看图 |
| 文件、视频 | 保存到项目的 .pi-wecom-aibot-files/,通过 [attachments] 告知文件位置 |
| 引用消息 | 被引用的文字放在 [quote] 中;引用的图片、文件不会附带 |
模型只收到上表里的内容,不知道是谁发的、从哪个聊天发的。只有一个 @ 没有文字也没有图片的群消息,模型收到「(空消息)」。来源只显示在 pi 终端里:每条企微消息上方有一行暗色的 [wecom|from:<userid>|chat:单聊],群聊写 chat:群聊,不写聊天的 chatid。这行记在会话里,重新打开会话也看得到,但不发给模型,也不占上下文。「发提示词」发出的任务没有这一行。这一轮的系统提示里还会加一段说明:结果会以控制卡发回这个聊天、在手机上看、不要写密钥、怎样给出下一步
语音、图片、文件和视频仅支持单聊,单个文件不超过 50 MB。附件目录不会自动清理,也不会被提交到 Git。每个 pi 最多排队 50 条任务,大量图片请分批发送
每个 session 的控制卡
控制卡显示工作目录、模型、完整 session ID、正文摘要或文档入口,以及最近一次操作的结果:
| 按钮 | 作用 |
|---|---|
| 刷新卡片 | 读取终端当前画面;启用文档时同步更新会话文档,不调用模型 |
| 发提示词 | 从本卡的下一步或 controlPrompts 中选择,确认后发送;忙时排队,无候选时提示先配置 |
| 查看全文 | 仅限带正文的 inline 卡:将本卡对应的 Markdown 正文发到当前聊天,超长分段 |
| 查看图片 | 仅限带正文的 inline 卡:将同一份正文在本机渲染成长图,再发到当前聊天;不是终端截图 |
| 切换模型 | 选择并确认,仅影响当前会话的后续运行,不修改 pi 默认模型;模型多时可翻页 |
| 中止任务 | 由同一人在 60 秒内确认;有排队时还可选「全部中止」或「清空排队」 |
- 切换会话:在下拉框选另一个会话,再点任一按钮。这次只切换卡片,不执行按钮动作;确认会话后再操作
- 找回控制卡:在企微发
/wa s,选会话后点「打开会话」。列表每页 5 个,可刷新和翻页;当天首次进入机器人单聊时也会收到这张列表,只显示白名单允许访问的会话 - 候选太多:任务选择卡最多列最近使用的 10 个会话。需要的会话不在其中时,先用
/wa s打开它的控制卡,再重新发送任务;打开控制卡不会自动定向后续消息 - 发送与刷新:每次
connect、任务完成和通知都发新卡,旧卡不撤回。网络重连、网关替换不重发;卡片内容是快照,不会自动刷新,新接入的会话也要点按钮才出现在旧卡列表里
结果可以在末尾附上 <!-- wecom_next ["运行测试", "提交改动"] -->,作为本卡「发提示词」的优先候选,最多 10 条、每条最多 500 字。注释不会出现在企业微信正文或长图中。下一步、正文摘要和可查看的正文快照仅在当前接入期间保留最近 50 张卡,断开或重启后不保留;配置的 controlPrompts 不受影响
按需阅读全文(inline)
默认 contentDisplay=inline:卡片引用区显示正文开头的纯文本摘要,手机最多三行,引用区本身不能点击展开。带正文的新卡额外提供「查看全文」「查看图片」,不需要文档授权或网页服务,也不调用模型:
- 查看全文:发送本卡的 Markdown 正文,保留代码等格式,按企微每条 20480 个 UTF-8 字节的限制分段;每段带原会话和模型标识,可以引用文字消息继续发任务
- 查看图片:使用与「查看全文」相同的正文,渲染为 1600 像素宽、随内容增高的 PNG;超过单张行数时按顺序分图,不只保留开头或末尾。外链图片不下载或嵌入,HTML 不执行
- 内容绑定本卡:新回复、刷新或切换模型不会改变旧卡对应的正文。纯控制卡没有回复快照,不提供这两个按钮;正文过期后会提示,绝不改取最新回复。正文快照上限为 256 KiB,超过会明确标记截断
- 点击才发送:先在卡片记录请求,再把正文或图片发到点击所在的聊天;群聊里所有人都能看到发送的内容。每个接入会话同一时间只处理一次全文/长图发送;断开会取消后续发送,失败或送达未确认时不自动重发
- 长图限制:一次最多 20 张,每张不超过 10 MiB;无法生成时提示原因,可改点「查看全文」。只读取可见回复,不读取终端、输入草稿、思考过程或工具输出;沿用已知凭据脱敏,临时 PNG 在发送结束后清理
长图使用系统字体:Windows 为微软雅黑,macOS 为苹方;Linux 需有中文字体,例如 Debian/Ubuntu 的 fonts-noto-cjk 和 fontconfig。缺少字体会提示安装,不自动下载字体;部分 emoji 的显示取决于系统字体
两个按钮只对 inline 生效。linked 不提供这两个入口,也不会自动回退为摘要或全文消息;切换为 linked 后,旧卡上的查看按钮也会拒绝发送
会话文档
希望点击引用区打开会话文档时,可以启用 linked:
- 在企业微信「工作台 → 智能机器人 → 找到机器人 → 编辑 → 可使用权限」授权「文档」,点「查看使用方式」,复制 streamableHTTP URL,不是 JSON Config
- 在 pi 中执行
/wecom-aibot config edit,选「会话文档」并粘贴地址。地址必须为https://…qq.com/…,含 apikey,需像密码一样保管 - 将「正文展示方式」设为
linked,再执行/wecom-aibot connect;页面写入成功后,卡片引用区可打开会话文档
也可以只为当前会话启用:
/wecom-aibot config --scope session set contentDisplay=linked
- 每台电脑、每个机器人一份文档,每个 session 一页,保留最近 3 轮提问与回复、最近 3 条带正文的
wecom_send通知。长内容会截断,不是永久归档;正文不包含终端画面或附件 - 只配置
docMcpUrl不会启用文档。linked不回退到卡片正文摘要:未配置地址、写入失败或超时时,引用区显示原因和处理提示,不显示正文或终端内容,不保留失效链接 - 授权失效或权限不足:引用区提示「文档权限不足或授权已到期」,并提示到「工作台 → 智能机器人 → 可使用权限」重新授权。网络、超时等错误不冒充权限到期;修复后点「刷新卡片」,成功写入即可恢复文档入口,旧卡不自动更新
- 文档默认企业内需申请、企业外拒绝。默认目标为单聊时,该用户会加入只读成员;第一次点「刷新卡片」的人也会加入。群里其他人需要申请访问
- 授权有效期为 7 天,过期后重新授权;地址变更时重新填写。新建页面时清理 7 天未刷新的页面,
reset删除本机登记的全部页面;文档本身需在企业微信里手动删除
完成后通知
- 企业微信发起的任务:结果以一张结果卡发回原聊天,不回复原消息;模型拿到的是用户正文和图片/文件说明,不带发送人和 chatid;发送人只显示在 pi 终端的来源行里
- 电脑上布置的任务:当前会话接入后,告诉 pi「完成后发企业微信通知我」,推送到默认目标。希望每轮都通知,可设置
notificationScope=all-runs - 指定目标:告诉 pi 对方的 userid 或群 chatid。
wecom_send未指定目标时,企微任务优先回来源聊天,本地任务使用接入时采用的默认目标
主动推送要求对方先给机器人发过消息;wecom_send 不接受任意图片或文件附件,长图只通过 inline 卡的「查看图片」生成。通知正文按 contentDisplay 展示;wecom_send 自定义正文的第一行用作标题,重要结论应放在开头
确定尚未发送的结果和完成通知会在断线恢复后补发;已被服务端拒绝或发送结果未知时,不自动重复发送。inline 卡片明确被拒收时,任务结果和通知会改发 Markdown 正文;linked 不回退:文档失败在卡片引用区提示原因,卡片本身无法生成或被拒收则报告发送失败,不另发正文。断开或退出当前 pi 会清除待发通知
pi 状态栏
首次连接成功后,底部显示 wecom-aibot:默认主题下绿色表示正常,黄色表示正在重连,红色表示需处理;自定义主题颜色可能不同。首次连接未就绪前不显示,断开后隐藏
出现「待重新接入」说明接入配置已变更,需要运行 /wecom-aibot connect。详细原因用 status 或 log 查看;RPC、JSON、print 模式不显示状态栏
📝 配置文件
用 /wecom-aibot config 打开菜单,或直接执行:
/wecom-aibot config show # 查看合并结果及每项来源
/wecom-aibot config edit # 交互编辑全局配置
/wecom-aibot config --scope project set defaultChatId=your-group-chatid defaultChatType=2
/wecom-aibot config --scope session set controlPrompts=继续,运行测试
/wecom-aibot config set controlPrompts+=部署到测试环境
/wecom-aibot config set controlPrompts-=运行测试
/wecom-aibot config --scope session unset controlPrompts # 删除覆盖,恢复继承
/wecom-aibot config --scope global whoami # 识别并保存默认推送目标
作用域与位置
优先级:内置默认值 < 全局 < 项目 < session
| 作用域 | 适用范围 | 配置文件 |
|---|---|---|
global |
同一系统用户下的所有 pi | <agent-dir>/wecom-aibot/config.json |
project |
启动 pi 的工作目录,同目录会话共用 | <工作目录>/.pi/wecom-aibot/config.json |
session |
当前会话 | <agent-dir>/wecom-aibot/sessions/<session ID>.json |
全局和项目配置使用相同的相对路径 wecom-aibot/config.json,只按作用域选择不同的根目录
项目配置放在项目内,随项目一起复制、移动或重命名。只读取启动 pi 的工作目录,不向父目录查找,也不按 Git 根目录推断。命令会按需创建 .pi/wecom-aibot/config.json,不修改 .pi/settings.json、已有目录权限或 .gitignore。标准 pi 使用 .pi,其他发行版跟随其 CONFIG_DIR_NAME
全局和 session 配置仍放在用户侧插件目录:
- Linux / macOS:
~/.pi/agent/wecom-aibot/ - Windows:
C:\Users\你的用户名\.pi\agent\wecom-aibot\
实际位置以 /wecom-aibot status 或 config --scope project show 为准。PI_CODING_AGENT_DIR 只移动用户侧目录,不改变项目配置的位置。项目和 session 只保存显式覆盖的字段;分叉会话首次启动时复制父会话的覆盖,之后各自独立
插件遵从 pi 当前会话的项目可信状态:未信任时不读取项目配置,显式的项目配置命令会拒绝操作。检查项目内容后,可用 pi 的 /trust 授权并重新加载
--scope写在动作前。不写时:edit、set、unset改全局,show显示合并结果,whoami只识别不保存目标;指定作用域后,只查看或修改那一层set支持一次修改多个字段,全部校验通过才保存。unset删除本层设置,恢复继承值- BotID 与 Secret、默认目标与类型各自成组,不能跨层拼接
- BotID、Secret、
docMcpUrl只能通过edit或直接编辑文件填写,不能用会留在输入历史里的set。没有交互界面时请直接编辑文件
项目配置示例
<项目>/.pi/wecom-aibot/config.json:
{
"contentDisplay": "inline",
"controlPrompts": ["运行测试", "总结改动"]
}
未设置的凭据、推送目标等继续继承全局配置。项目可设置的字段范围不变,docMcpUrl、allowedUserIds 仍仅限全局。建议只把可共享、不含秘密的项目配置纳入版本控制;如果在项目层覆盖 BotID 和 Secret,不要提交该文件
全局配置示例
{
"$schema": "https://raw.githubusercontent.com/cobia68/pi-wecom-aibot/main/config.schema.json",
"botId": "your-bot-id",
"secret": "your-secret",
"defaultChatId": "your-userid",
"defaultChatType": 1,
"notificationScope": "wecom-tasks",
"allowedUserIds": ["your-userid"]
}
$schema 用于编辑器补全和校验;实际是否可用以 config show 为准
| 字段 | 含义 |
|---|---|
botId / secret |
机器人凭据 |
defaultChatId / defaultChatType |
默认目标:userid + 1 单聊,群 chatid + 2 群聊;省略类型时为单聊 |
notificationScope |
wecom-tasks(默认)只自动回传企微任务;all-runs 也通知本地运行结果 |
contentDisplay |
inline(默认)显示摘要,可按需查看全文/长图;linked 仅使用会话文档,不可用时在引用区提示原因,不回退正文 |
controlPrompts |
「发提示词」候选,默认空,最多 10 条、每条最多 500 字 |
docMcpUrl |
会话文档的 streamableHTTP URL,仅限全局,含密钥 |
allowedUserIds |
用户白名单,仅限全局;不写或留空表示不限制 |
controlPrompts 用英文逗号分隔,= 替换整份,+= 追加,-= 按原文删除。含空格或英文逗号的提示词用 edit 一行一条填写。项目或 session 首次用 +=、-= 时会复制继承来的列表,此后不再跟随上层变化,unset 后恢复继承
修改何时生效
notificationScope、contentDisplay、controlPrompts、docMcpUrl:下次使用时生效,无需重连;已经生成的待发通知保留原快照- 凭据、默认目标、白名单:各窗口重新
connect后生效,此前继续用旧配置。切换会清除当前接入的排队任务和待发通知;已开始的任务继续运行,但结果不再回传。没有交互界面且有待处理工作时拒绝切换 - 未知字段或无效值会报错,不会静默忽略;已接入的会话继续使用上一次有效配置
Secret 以明文保存,编辑时也会显示在屏幕上,请勿分享或提交到仓库。项目配置随项目目录一起删除;删除 pi 会话不会清理用户目录里的 session 覆盖,不需要时手动删除 sessions/ 中的对应文件
🧰 命令速查
企业微信
| 完整命令 | 缩写 | 作用 |
|---|---|---|
/wecom-aibot sessions |
/wa s |
打开在线会话卡 |
/wecom-aibot --help |
/wa -h |
显示全部用法 |
不能只发命令前缀,必须指定子命令或帮助选项。前缀、子命令和帮助选项可分别缩写,也可混用,例如 /wa sessions、/wecom-aibot -h;全部区分大小写。sessions 不接受任何后续参数,不再支持 sessions --help;多余参数会报错,不执行也不转交模型
pi 终端
以下命令在 pi 终端执行,不支持上述企微缩写;命令、选项、字段名和取值均区分大小写
| 命令 | 作用 |
|---|---|
/wecom-aibot |
打开子命令菜单 |
/wecom-aibot status |
查看连接状态、默认目标和配置位置 |
/wecom-aibot config |
查看、编辑配置或识别聊天,详见上节 |
/wecom-aibot connect |
接入当前会话,或确认切换接入配置 |
/wecom-aibot disconnect |
断开当前会话,不影响其他 pi |
/wecom-aibot test |
向默认目标发部署测试卡 |
/wecom-aibot log |
查看最近 20 条日志 |
/wecom-aibot reset |
确认后删除全局配置和本机登记的文档页,断开当前会话 |
/wecom-aibot --help |
查看完整用法;配置帮助用 config --help |
disconnect 不修改配置,会取消当前会话的排队任务和待发通知;已开始的任务继续在电脑上运行,但不再回传结果
reset 需要交互确认,不会删除项目级和 session 覆盖,也不会停止其他已接入的 pi。文档本身需手动删除;若提示删除失败,检查文件权限后重试,凭据可能仍在磁盘
🔄 升级与卸载
升级
pi update npm:@cobia/pi-wecom-aibot
更新后关闭所有使用这个机器人的 pi 窗口,等共享网关退出,再重新打开并逐个 connect。仅 /reload 无法替换已运行的网关。0.4.0 的长图传输与文档专用投递使用新版网关协议,不能与旧版本混用;旧卡没有保存全文快照,需使用升级后新发的正文卡。从 0.4.0 起,linked 不再回退正文;希望在聊天中按需阅读全文,请显式切换为 inline
用 pi install npm:@cobia/pi-wecom-aibot@版本号 固定版本后,pi update 不会更新它;换版本需重新 install。旧配置、命令和卡片不自动迁移:遇到未知字段按 config --help 调整,旧卡失效时重新 connect 或在企微发 /wa s 打开新卡
0.5.0 项目配置路径变更:不再从用户目录的 wecom-aibot/projects/<目录编码>.json 加载项目覆盖,改读 <项目>/.pi/wecom-aibot/config.json
- 新位置尚无文件、旧位置却有对应文件时,会报错并列出新旧路径,阻止静默套用全局的机器人或推送目标
- 先核对旧文件确实属于当前项目,再将需要的字段迁移到新文件;旧编码可能重名,旧文件也可能含 Secret,因此不会自动复制进仓库或自动删除
- 新文件存在后只使用新文件,空对象
{}表示没有项目覆盖,也不会回读旧配置。若不再需要旧覆盖,可在新位置写入{}或手动移除旧文件
卸载
- 在 pi 执行
/wecom-aibot reset;其他已接入窗口也要断开。若项目或 session 中存过凭据,清理各项目的.pi/wecom-aibot/config.json、用户侧插件目录的sessions/,以及旧版遗留的projects/ - 执行
pi remove npm:@cobia/pi-wecom-aibot - 按需清理项目中的
.pi-wecom-aibot-files/、插件目录中的gateway/和session-doc.json;在企业微信撤销「文档」授权并删除会话文档
❓ 常见问题
发消息没有反应?
用 status 确认当前会话已接入,再检查群聊是否 @机器人、发送者是否在白名单。普通消息需要在选择卡上确认。用 log 查看错误;gateway launch failed 或 gateway process exited 时检查 Node.js 是否在 PATH 中、插件是否安装完整
提示连接被其他机器或旧客户端接管?
同一机器人只能在一处连接。关闭另一台电脑或另一系统用户下的连接,再执行 connect
凭据错误,或改了配置仍不生效?
用 config show 查看生效值及其来源,在对应作用域执行 config edit。确认机器人仍是「API 模式」+「长连接」,然后在各窗口重新 connect
收不到主动推送?
确认对方先给机器人发过消息,用 config --scope global whoami 设置默认目标并重新 connect。企业微信限制每个聊天每分钟 30 条、每小时 1000 条消息,卡片更新也计入;具体原因看 log
日志里经常出现 WebSocket closed?
网关会自动重连,超过 30 秒未恢复会提醒。1006 只表示异常断开,无法据此判断是服务端还是网络问题。接收任务和卡片点击需要保持长连接,要暂停请用 disconnect