下载地址
https://www.zhengdianxue.com/wp-content/uploads/skills/org-vsc9dz4y--weaver-e10-yimiaoban.zip将提示词发送给你的 AI 安装该 skills
请根据 https://skillhub.cn/install/skillhub.md,安装 @org-vsc9dz4y/weaver-e10-yimiaoban。泛微E10易秒办即时通讯。即时通讯又可以称之为工作消息,聊天消息。包含消息功能、群组功能、会话功能。消息功能包含:发送单聊消息、发送群聊消息、拉取单聊消息、拉取群聊消息、消息撤回、拉取系统消息。群组功能包含:搜索群聊、创建群、群加人、群踢人、退群、群解散。会话功能包含:拉取会话列表。
阅读全文 (展开查看完整说明)
概述
⚠️ 铁律:模糊性拦截(执行任何脚本前的强制门禁,优先级最高)
本 Skill 接口众多,且部分接口有副作用(发消息 / 必达 / 建群 / 加人 / 踢人 / 退群 / 解散等)。为避免「猜谜式」调用——即靠反复调接口去"验证"用户到底想要什么——执行任何脚本前,必须先完成下面的「需求完整性评估」,任一不通过即禁止调用脚本。
IM 交互铁律(第一性原理,覆盖默认推理)
本 Skill 运行在即时通讯(IM)环境,交互单位是「消息轮次(Round)」。IM 下用户对首字延迟(TTFT)极敏感,但对多轮交互高度容忍——一次秒回的反问,体验远好于一次 8 秒的"正在输入…"。因此禁止把 IM 当 RESTful API 用(试图在一个回复周期内把所有参数补全)。
- 规则 A · 首轮零调用:对用户的第一条消息,只要参数完整度 < 100%,本轮禁止生成任何脚本调用,输出必须仅为一句话的反问。
- 规则 B · 零容忍缺失:本 Skill 的必填参数不存在"默认值 / 自动补全"概念。缺任一必填字段(对象 id / 姓名 / 群 id / 时间范围 / 动作)即视为非法请求,禁止发起任何接口调用去"试默认值"(如把"最近"自行映射成某个日期去试探)。
- 规则 C · 上下文断裂:IM 消息是碎片化、间断的。严禁根据上一条消息的"言外之意"补全下一条的参数——默认用户只提供了显式文本。多句合并:用户上一句"查订单"、下一句"昨天的",必须合并后重新提取参数,合并完整才允许调用;严禁只凭"昨天的"就触发调用。
- 规则 D · 禁止连锁推理:反问用户的同时,禁止在后台准备 / 预演第二个接口调用;输出反问后立即 Stop,等待用户下一轮显式输入。
- 规则 E · 延迟响应(Deferred Response):仅当参数 100% 齐全时,才允许调用脚本;且调用前先输出一句话告知正在执行(如「正在查询 XX(时间范围:今天),请稍候…」),再发起调用。
第一步:意图分类(先判断,再决定动不动)
将用户需求映射为三类之一:
| 分类 | 判定标准 | 行动 |
|---|---|---|
| ✅ 明确指令 | 对象(发给谁 / 哪个群 / 哪个会话)+ 动作 + 关键参数均齐备 | 进入正常流程,执行对应脚本 |
| ⚠️ 模糊意图 | 对象、范围、动作或关键参数有缺失或多义(如「全部群」「所有消息」「支持群」等无明确筛选条件) | 阈值 = 0:零次脚本调用,只输出澄清问题,立即停止推理 |
| 💬 无关闲聊 | 与本 Skill 能力无关 | 正常对话回应,不调用脚本 |
第二步:需求完整性评估(调用任何脚本前自问)
- 对象确定吗? 发给谁 / 哪个群 / 哪个会话,是否已解析到明确的 id 或唯一名称?
- 范围确定吗? 时间、数量、筛选条件(名称 / 类型 / 创建时间)是否明确?含「全部 / 所有 / 每个 / 批量」且无筛选条件 → 不通过。
- 动作确定吗? 用户要的是 查 / 发 / 建 / 加 / 踢 / 退 / 解散 中的哪一个?存在多义 → 不通过。
任一不通过 → 禁止调用脚本;禁止「先调接口验证再决定」;禁止枚举式探测(反复试 --type / --name / --members 等去猜用户意图)。只输出 1 个澄清问题(最多列 2-3 个关键缺失点),立即停止,等待用户答复后再进入正常流程。
澄清提问规范
- 单条消息一次性列全所有缺失字段(禁止分多条消息连环追问),并给出输入示例(如「请补充时间范围,格式:2026-09-01」)。
- 枚举类字段(群类型、状态、时间口径等)反问时,给出 2-3 个候选快捷选项(即使用 AskUserQuestion 的 option,或纯文本列出「A / B / C」),让用户点选而非手打。
- 用 AskUserQuestion 给选项时,必须带范围 / 数量提示(如「名称含『易秒办』的 12 个群」vs「名称含『支持』的 122 个群」vs「我所在的全部群」),让用户一看便知代价。
- 能用本对话上下文消歧的(已拉过的会话列表、已解析过的人员)直接复用,不再追问。
- 反问发出后立即 Stop,不要在脑内预演"用户选 A 我该调哪个接口"。
正反例对照
| 场景 | ✅ 正确 | ❌ 错误 |
|---|---|---|
| 「获取易秒办支持群的成员」 | 先问:是「含易秒办的 12 个群」「含支持的 122 个群」还是「我所在全部群」?确认后再拉 | 连试 --type 1/6/7、--name 易秒办、--name 支持 反复探测,最后才问 |
| 「给张三发消息」 | 先 resolveUser 解析 → 无匹配则停下让用户确认姓名 | 猜同音字、翻历史会话去"找"这个人 |
| 「拉一下最近的消息」 | 明确时间/范围后执行一次 | 拉不到就反复换参数试探 |
高频命令速查
| 操作 | 命令 |
|---|---|
| 查人员 IM uid/cid | node scripts/resolveUser.js --name <姓名> |
| 发单聊消息 | node scripts/sendSingleMsg.js --to-uid <uid> --to-cid <cid> --txt <内容>(图片/文件:--img / --file <本地路径>) |
| 发群消息 | node scripts/sendGroupMsg.js --group-id <群id> --txt <内容>(图片/文件:--img <路径> / --file <路径>) |
| 发送必达消息 | node scripts/sendDing.js --group-id <群id> --txt <内容>(群发)/ --to-uid <对方uid> --txt <内容>(单聊);--convert-msgid <消息id> 已有消息转必达(群聊可 --unread-only 只发未读人员、--to-uids 指定人员;未读为 0 时提示用户确认,不自动回退);--send-msg 0|1 发短信(默认 1=发,用户主动说不发才 0)、--show-type 0|1 可见范围 |
| 上传文件(取文件 id) | node scripts/uploadFile.js --file <本地路径> [--share-group <群id>] |
| 生成/下载图片预览 | node scripts/previewImg.js --file-id <文件id> --msgid <消息id> --group-id <群id> [--save <目录>] |
| 生成/下载视频预览 | node scripts/previewVideo.js --file-id <文件id> --msgid <消息id> --group-id <群id> [--save <目录>] |
| 搜群 | node scripts/searchGroup.js --creator/--owner/--members/--today/--yesterday |
E10 工作消息
本 Skill 封装 工作消息模块内部 HTTP 接口,用于 Agent 在对话中完成消息和群组的功能。
前置依赖
本 Skill 依赖以下外部 skill,使用前需确保已安装并可用:
| 依赖 skill | 用途 | 何时需要 | 数据流向(产出 → 消费方) |
|---|---|---|---|
weaver-e10-login | 认证(access_token、签名)、完整 URL 拼接、提供 base_url/tenant_key/operator/cid/uid | 所有操作 | 输出登录会话(baseUrl / cookies.raw / eteamsid / User-Agent)→ common.js authHeaders() 组装请求头 |
weaver-e10-hrm | 泛微HRM人事管理,帮您处理 HRM 人事日常事宜:[员工]-按工号/姓名/手机/邮箱查询员工,查某员工的所有/直接/间接下属,按人员 id 取员工详情资料名片(头像/是否管理员/在线状态);[组织]-按名称/编号/多级路径查询分部与部门。员工与组织走 E10 会话,完整接口地址与认证由 weaver-e10-login 提供 | 解析人员姓名↔uid/cid、批量取姓名、成员/发送者姓名解析 | 输出 uid/cid/姓名 → resolveUser / resolveUserByIds / fetchUsersByIds(common.js 内 runHrmCli)消费 |
工作流程
- 先执行顶部「模糊性拦截」铁律:意图分类 + 需求完整性评估,任一不通过则禁止调用脚本,只输出澄清问题
- 校验登录状态(分步检查,任一步失败即停下告知用户,禁止猜测状态):
- 用
weaver-e10-login检查当前是否有有效会话(e10-login status);未登录 / 凭证失效 → 先登录(e10-login oidc --base-url <url>),登录失败 → 停止并如实告知,不臆测原因 - 确认当前激活环境(profile / baseUrl),一切操作以当前环境为准(见红线「禁止擅自切换使用环境」)
- 用
- 归类用户意图:对照下方「用户视角能力目录」,确定用户要的是哪类操作(查聊天记录 / 发消息 / 会话列表 / 人员 / 群管理 / 系统消息),以用户原话为准,不自行升级或降级意图(如「看看聊天」= 查消息,不是发消息);意图落在能力边界外 → 直接告知不适用(见「适用 / 不适用边界」)
- 解析目标实体:把用户说的人名 / 群名 / 系统会话名解析为 id(见「字段值解析」),优先复用本对话已出现的实体与会话列表;解析失败(未匹配)→ 立即停止并告知,不猜测
- 执行对应脚本完成业务处理,展示结果时说明本次默认口径(见「默认行为与展示说明」);脚本报错 / 返回异常 → 按「错误处理」表处理,禁止静默失败或自动换接口
读取顺序
- 本文件已包含能力概览和解析策略速览,大多数场景可直接据此操作
- 用户意图归类先看「用户视角能力目录」,具体脚本用法见「可用能力与脚本」章节
- 如需了解完整接口列表,读取
references/catalog.md - 需自定义请求参数时,再读取对应的单接口文档,确认参数结构和约束
用户视角能力目录(需求分析第一优先)
接到用户需求先归类到下面某一类,再查「可用能力与脚本」选具体脚本。归类以用户原话为准。
适用 / 不适用边界(先判断,再归类):本 Skill 只处理 E10 工作消息(易秒办 IM) 域内的消息 / 群组 / 会话 / 人员解析。以下情况不属于本 Skill 能力范围,直接说明不适用、不做变通硬凑:非 IM 的业务数据(订单、客户、审批表单内容等)、跨平台 IM(企业微信 / 钉钉 / 邮件)、对消息做统计分析 / 报表、定时推送 / 机器人托管。落在边界外 → 明确告知,可建议对应 skill(企业微信用
wecom-unified、人事查询用weaver-e10-hrm),但不代为调用。
易混淆场景路由(先消歧,再归类)
当用户一句话可能对应多个能力时,按下表判定;判定不了就问一句「是 A 还是 B」,禁止两个都调或按猜的来。
| 易混淆点 | 判定规则 |
|---|---|
| 发普通消息 vs 发必达(Ding) | 用户明确说「必达 / 提醒务必看 / 催办 / 一定要回」→ 必达(sendDing);只说「发消息 / 说一声 / 通知」→ 普通消息。拿不准 → 问「普通消息还是必达消息?」 |
| 查群信息 vs 建群 | 出现「查 / 看 / 搜」+ 已有群名 → 查(searchGroup/queryGroupInfo);出现「建 / 新建 / 拉个群」→ 建(groupCreate) |
| 撤回消息 vs 删除/清空 | 撤回 = 自己发的消息可撤回(withdrawMsg,有时限);无「删除/清空消息」能力 → 直接告知不支持 |
| 系统消息 vs 群聊消息 | 「提醒 / 待办 / 流程 / 公文 / 新到达」→ 系统消息(searchSysMsgGroup+querySysMsgInfo);「某某群 / 群里说的」→ 群聊(syncGroupMsg) |
| 单聊 vs 群聊 | 对象是「人」→ 单聊;对象是「群」→ 群聊;说「通知大家」但未给群名 → 问群 |
A. 查聊天记录(单聊 / 群聊 / 系统会话)
- 常见说法:「看看我和张三聊了啥」「拉一下某某群的消息」「提醒里有什么消息」「最近说了什么」
- 默认行为:未说明时间 → 只拉当天(输出明确告知口径);用户明确要「最新消息」→ 加
--latest(起始 1970-01-01/msgid=0 不限下限,保证最近消息拉全);未说明数量 → 最新一页(≤20 条) - 对应脚本:单聊
syncSingleMsg/ 群聊syncGroupMsg/ 系统会话searchSysMsgGroup+querySysMsgInfo - 何时追问:拉取结果为空(当天无消息)→ 给快捷选项(最新消息 / 最近 20 条 / 最近一周);只笼统说「系统消息」→ 列出会话列表里的系统会话让用户选
B. 发消息
- 常见说法:「给张三发条消息」「在群里说一声」「通知大家」「把这张图发给张三」「把这个文件发到群里」
- 默认行为:文本消息;单聊还是群聊由对象决定
- 对应脚本:
sendSingleMsg/sendGroupMsg;图片/文件消息先走uploadFile(common.js已内置两段式上传)再组装img/file发送 - 何时追问:写操作确认——必须确认收件人 + 内容;没说发给谁 → 问收件人
C. 会话列表
- 常见说法:「看看有哪些会话」「我的未读」「最近会话」
- 默认行为:最新一页 20 条;更早的会话需
--continue - 对应脚本:
getSessionContext - 何时追问:要求「统计会话/消息总数」→ 按红线直接回复「无法统计总数,功能暂时不支持」,不提供变通
D. 人员
- 常见说法:「张三的工号/部门/手机号」「查一下这个人」
- 默认行为:姓名 → cid/uid;多结果按「字段值解析」消歧
- 对应脚本:
resolveUser/resolveUserByIds - 何时追问:模糊命中多个 → 带部门选项;没说查什么 → 默认给姓名 + 部门
E. 群管理
- 常见说法:「建个群」「把张三拉进群」「把张三踢了」「退群」「解散群」「申请加群」
- 对应脚本:
groupCreate/inviteGroupUsers/kickGroupUsers/exitGroup/destroyGroup/joinGroup/searchGroup/queryGroupInfo - 何时追问:写/破坏性操作确认——群对象 + 成员必须确认;群名模糊 → 带群 ID 选项
F. 系统消息(流程 / 待办 / 提醒)
- 常见说法:「提醒里有什么消息」「我的待办流程」「新到达流程的消息」
- 链路:会话名 →
searchSysMsgGroup(精确优先,与会话列表交叉验证)→querySysMsgInfo - 默认行为:未说明时间 → 当天
- 何时追问:只说「系统消息」→ 列出系统会话;数据对不上 → 按「数据对不上提问模板」
确认与追问原则(读写分离,显式):
- 读操作(查 / 拉 / 看 / 搜)默认直接执行,不追问;仅当遇到歧义(时间范围 / 对象 / 口径)时才追问。追问时两边都查、合并展示(例如「查张三」命中多个张三 → 把候选都列出来让用户选,而不是先猜一个)。
- 写 / 破坏性操作(发消息 / 发必达 / 建群 / 加人 / 踢人 / 退群 / 解散 / 撤回 / 改群信息)必须先确认对象 + 内容 / 成员后才执行,确认时只展示用户已提供的字段 + 自动填充的默认值,不追问未指定字段。
- 一次只问最关键的问题(最多 1-2 个),禁止连环追问;能用本对话上下文消歧的(刚拉过的会话列表、已解析过的人员)直接复用,不再问。
- 固定消歧话术(原文照用,禁止改写):命中对应歧义时直接使用——「要创建群还是加入群?」「普通消息还是必达消息?」「需要我查单聊还是群聊?」「你是要拉今天的还是最新的消息?」
- 候选列表数量上限:同名 / 歧义候选超过 4 个时,只取前 4 个展示,并提示「还有 N 个,请缩小范围(补充关键字 / 部门 / 群名)」。
认证与接口地址
- 🔴 登录强制(不可绕过):必须走
weaver-e10-loginskill 登录(e10-login oidc/set --base-url <url>),脚本只读取当前激活 profile 的登录会话;禁止通过脚本--base-url/--eteamsid/环境变量手动指定凭证,未登录或凭证失效时脚本直接报错提示。 - 单接口文档中的接口 URL 均为去域名路径和去除固定路径(如
/send/sendGroupMsg),实际调用地址为{域名}/api/em/msg/executeIm/{业务接口url},例如:https://weapp.xxxx/api/em/msg/executeIm/send/sendGroupMsg - 优先调用
scripts/下的脚本,认证(ETEAMSID 自动解密、cid/uid 自动解析)由scripts/common.js完成,无需手动处理 - 🔴 请求头强制(三条缺一不可):所有 API 请求必须携带 e10-login 返回的全部用户信息参数——① Cookie 完整原始串(
cookies.raw原样透传,禁止裁剪/去重/改写;无 raw 时回退ETEAMSID=<值>);② eteamsid(单独请求头);③ User-Agent(AgentType=<agentType>,IsAgent=true)。统一由common.js authHeaders()组装,禁止手工构造认证头;仅当需要自定义请求体时才参考单接口文档手工构造,生成请求参数时不包含认证字段 - 协议约定:所有接口请求体中
trans_id统一固定0、dev统一固定4(API 版);common.js已导出TRANS_ID/DEV_TYPE_API常量供引用 - 拉取消息约定:倒序拉取(从 id 大往 id 小方向);第一页
start固定9223372036854775807、end固定0,分页时start改为上次拉取的最小消息 id。common.js已导出MAX_MSG_ID常量供引用。 - 🔴 时间范围自动转 id 范围:当用户按时间范围(如「最近一周」「昨天」)拉取消息时,脚本自动用
MakeMinAndMaxIdByTm把时间换算成消息 id 的起止范围(--from→最小 id、--to→最大 id),再按 id 范围向接口请求;上层(agent)只传时间,无需手动拼接 id 范围。common.js的makeMinMaxIdByTm/parseTimeToSec已封装该转换。 - 🔴 成功判定约定(接口返回即成功,禁止二次验证):任何写操作(发消息/发必达/建群/加人/上传等),接口返回成功(code=200 / actionMsg.code=0)即视为操作成功,以本次回包为准向用户汇报;禁止再通过其他接口(如拉取消息/查群列表)去验证是否成功——回包已含结果(如必达 id、消息 id),无需也不应二次拉取核验,避免多余请求与误判(如拉取接口的时序/缓存问题可能造成假失败)。
可用能力与脚本
优先调用
scripts/下的现成脚本执行,禁止自己手写 HTTP 请求或解密认证逻辑。 脚本会自动完成认证(ETEAMSID 解密、cid/uid 解析),时间戳按当前系统时区展示。
🔴 本 Skill 所有接口均需明确参数,不支持模糊检索 / 探测式调用(负向约束):下表每个脚本的必填参数(对象 id / 姓名 / 群 id / 时间范围 / 具体动作等)缺失时,必须先向用户询问补齐,严禁自行构造、遍历枚举或换参数反复试探——判定与提问规范见顶部「模糊性拦截」铁律。高危接口特别提醒:
searchGroup:需明确关键字(--name)或类型(--type)或归属(--owner/--creator/--members),裸的"查群/支持群/所有群"先问范围,禁止逐 type/逐 name 试;getGroupUsers:需确定的--group-id;批量拉多群成员前先确认群数量与范围;resolveUser:姓名需用户提供,未匹配(total=0)立即停止,禁止猜同音字/翻历史;querySysMsgInfo:需明确--group(及可选--type),只说"系统消息"先列会话让用户选。
| 用户意图 | 执行命令 | 对应接口 |
|---|---|---|
| 获取人员 IM cid/uid(姓名 → 身份) | node scripts/resolveUser.js --name <姓名> | hrm 员工浏览 |
| 按人员 uid 列表获取人员信息(走 hrm) | node scripts/resolveUserByIds.js --ids <uid1,uid2,...> | hrm profile(并发批量) |
| 给某人发消息 | node scripts/sendSingleMsg.js --to-uid <uid> --to-cid <cid> --txt 你好(发图片/文件:--img ./a.jpg / --file ./d.pdf) | sendSingleMsg |
| 在某个群里发消息 | node scripts/sendGroupMsg.js --group-id <群id> --txt 大家好(发图片/文件:--img ./a.jpg / --file ./d.pdf) | sendGroupMsg |
| 上传消息文件(取文件 id) | node scripts/uploadFile.js --file <本地路径> [--share-group <群id>] | preUploadCheck + valid/upload |
| 生成/下载图片预览 | node scripts/previewImg.js --file-id <文件id> --msgid <消息id> (--group-id <群id> | --to-uid <uid> --to-cid <cid>) [--img-format small|large|original] [--save <目录>] | file/preview |
| 生成/下载视频预览 | node scripts/previewVideo.js --file-id <文件id> --msgid <消息id> (--group-id <群id> | --to-uid <uid> --to-cid <cid>) [--save <目录>] | file/preview |
| 撤回单聊消息 | node scripts/withdrawMsg.js --type single --to-uid <对方uid> --to-cid <对方cid> --msgid <消息id> | makeMsgWithdraw |
| 撤回群聊消息 | node scripts/withdrawMsg.js --type group --group-id <群id> --msgid <消息id> | makeMsgWithdraw |
| 搜索群信息 | node scripts/searchGroup.js ... | searchGroup |
| 按群 id 查群信息 | node scripts/queryGroupInfo.js --group-id <群id> | queryGroupInfo |
| 获取单聊消息(含媒体按钮) | node scripts/syncSingleMsg.js --from-uid <uid> --from-cid <cid> [--num <N>] [--continue] [--from <时间>] [--to <时间>] [--save-preview <目录>] [--img-format small|large|original] | syncSingleMsg |
| 获取群聊消息(含媒体按钮) | node scripts/syncGroupMsg.js --group-id <群id> [--num <N>] [--continue] [--from <时间>] [--to <时间>] [--save-preview <目录>] [--img-format small|large|original] | syncChatGroupMsg |
| 创建群(仅普通群) | node scripts/groupCreate.js --users <uid1,uid2,...> [--name <群名>] [--names <姓名1,姓名2,...>] [--admins ...] | groupCreate |
| 邀请人员进群 | node scripts/inviteGroupUsers.js --group-id <群id> --users <uid1,...> | inviteGroupUsers |
| 申请加入群聊(不在群里时) | node scripts/joinGroup.js --group-id <群id> [--mark <理由>] | joinGroup |
| 搜索系统消息分组配置 | node scripts/searchSysMsgGroup.js --name <分组名> | searchSysMsgGroup |
| 拉取系统分组/type 配置 | node scripts/syncGroupType.js --gids <gid1,...> [--tids ...] | syncGroupType |
| 拉取系统消息(流程/任务/公文) | node scripts/querySysMsgInfo.js --group <gid> [--type <tid>] [--deal 0|1|2] [--flag 0|1|2] [--num N] | querySysMsgInfo |
| 拉取会话列表(单聊/群聊/系统会话) | node scripts/getSessionContext.js [--type <会话类型>] [--num N] [--continue] | getSessionContext |
| 拉取某时间附近的会话 | node scripts/getSessionContext.js --msgid <锚点id> --around [--num N](附近 = down+up 两个方向,每方向 page_size/2 个) | getSessionContext |
| 翻译国际化标签 id(内部能力) | node scripts/i18nLabel.js --ids <id1,id2,...> | getHtmlLabelNames(内部) |
| 踢出群成员 | node scripts/kickGroupUsers.js --group-id <群id> --users <uid1,...> | kickGroupUsers |
| 解散群聊 | node scripts/destroyGroup.js --group-id <群id> | destroyGroup |
| 退出群聊 | node scripts/exitGroup.js --group-id <群id> | exitGroup |
| 修改群信息(群属性) | node scripts/modGroupInfo.js --group-id <群id> [--num <最大人数>] [--switchs <flag:on_off,...>] [--rsonoff 0|1] [--history <范围>] [--admins <uid,...>] [--creator <uid>](--switchs 1:1=开启匿名、2:1=搜索、3:1=申请加入;🔴 元素字段名须为 on_off) | batModGroupInfo |
| 修改群名 | node scripts/modifyGroupInfo.js --group-id <群id> --name <群名> | --history <n> | --host <uid>(一次只改一项;🔴 禁止 –type/–state/–announce,群公告用 modGroupAnnounce.js) | modifyGroupInfo |
| 新增/修改/删除群公告 | node scripts/modGroupAnnounce.js --group-id <群id> --annouce <内容> [--aid <id>] [--notice 0|1|2] [--fmark 0|1](--del --aid <id> 删除) | modifyAnnouce |
| 获取群公告(最新/指定) | node scripts/getGroupAnnounce.js --group-id <群id> [--aid <公告id>] | getAnnouce |
| 获取群公告列表 | node scripts/getGroupAnnounceList.js --group-id <群id> [--aid <分页起始id>] [--page-size <N>] | getAnnouceList |
| 获取群成员列表 | node scripts/getGroupUsers.js --group-id <群id> [--mask <位掩码>] [--sync-type 0|1] [--client-uc <uc>] | getGroupUsers |
| 群消息置顶 / 取消置顶 | node scripts/setGroupTopMsg.js --group-id <群id> --msgid <消息id> [--type 1|2](--cancel 等价 --type 2) | setGroupTopMsg |
| 同步/拉取群置顶消息 | node scripts/syncGroupTopMsg.js --group-id <群id> [--msgids <id,...>] | syncGroupTopMsg |
| 拉取群消息阅读状态(未读总数) | node scripts/getGroupMsgReadStatus.js --group-id <群id> --msgids <自己发的id,...> | --recv-msgids <别人发的id,...> | getGroupMsgReadStatus |
| 同步群消息阅读状态详情(谁已读) | node scripts/syncGroupReadStatus.js --group-id <群id> --msgid <消息id> [--page-size <N>] [--page-num <N>](替代已删除的 getGroupMsgReadDetail) | syncGroupReadStatus |
| 查询单聊消息已读状态 | node scripts/getSingleMsgReadStatus.js --to-uid <对方uid> --to-cid <对方cid> --msgids <自己发的id,...> | --recv-msgids <自己接收的id,...> | getSingleMsgReadStatus |
| 拉取人员状态 | node scripts/syncUserState.js --users <uid1,uid2,...> [--dev-type <n>] [--mask <n>] | syncUserState |
| 批量获取群管理员 | node scripts/getGroupAdminBatch.js --group-ids <群id1,...> [--mask <n>](mask 位1=群主 位2=管理员) | getGroupAdminBatch |
| 判断群是否存在 | node scripts/checkGroupExist.js --group-ids <群id1,...>(ret=0 存在,1209=不存在) | checkGroupExist |
| 检查用户是否在群中 | node scripts/checkGroupUserExist.js --group-id <群id> --users <uid1,...> | checkGroupUserExist |
✅ 以上 5 个新接口已在 yunteams 环境(2026-08-31)实测通过:modGroupInfo(num 可逆修改、admins 走 hrm 解析)、setGroupTopMsg(置顶/取消均生效)、getGroupMsgReadStatus(未读总数)、getGroupMsgReadDetail(详情+分页)、syncUserState(人员状态)。⚠️ 阅读状态两接口
trans_id为必填(缺失后端报code=1014),脚本已固定传 0;msgids/msgid必须按字符串传输(19 位 uint64 防精度丢失)。syncGroupTopMsg(拉置顶消息)已部署可用。setGroupTopMsg 用法:--type 1|2或--cancel(旧版只认 –cancel,–type 曾因参数被忽略而误判"取消不生效",已修复)。详见references/im-*.md。
群与消息能力的参数、业务限制详见
references/下各独立接口文档:im-syncSingleMsg.md、im-syncGroupMsg.md、im-withdrawMsg.md(撤回消息)、im-groupCreate.md、im-inviteGroupUsers.md、im-joinGroup.md、im-kickGroupUsers.md、im-destroyGroup.md、im-exitGroup.md、im-searchSysMsgGroup.md、im-syncGroupType.md、im-querySysMsgInfo.md(系统消息三接口)、im-sysmsg-fields.md(系统 group/type 字段说明)、im-getSessionContext.md(会话列表)、im-i18nLabel.md(国际化标签翻译,内部接口)、im-resolveUserByIds.md(按人员 id 列表查人员信息,走 weaver-e10-hrm)、im-modGroupInfo.md(群属性修改,含--switchs)、im-group-onoff-bits.md(on_off 通用开关 27 位定义表)、im-modifyGroupInfo.md(改群名;🔴 群公告不生效)、im-modGroupAnnounce.md、im-getGroupAnnounce.md、im-getGroupAnnounceList.md(群公告三接口,唯一群公告入口)、im-getGroupUsers.md(群成员列表)、im-getGroupAdminBatch.md(批量管理员)、im-checkGroupExist.md(群存在)、im-checkGroupUserExist.md(成员在群检查)、im-setGroupTopMsg.md、im-syncGroupTopMsg.md、im-getGroupMsgReadStatus.md、im-syncGroupReadStatus.md(阅读详情,替代已删除的 getGroupMsgReadDetail)、im-getSingleMsgReadStatus.md(单聊已读)、im-syncUserState.md、im-sendDing.md(发送必达消息:createDing,路径无 executeIm 前缀,msgEntity/msgTitle 中 tf:"1" 必达标记;群发/单聊/消息转必达)、im-msg-kind-mkind.md(消息 kind/mkind 类型定义:kind 具体类型 1001~9002,mkind 按位掩码 1<<0~1<<18,mkindToKindList 转换)、im-file-upload.md(消息图片/文件两段式上传:preUploadCheck → valid/upload,文件 id → img.src/file.id 映射)、im-img-preview.md(媒体预览(图片/视频):file/preview + weappAuthStr 构造,图片 type=imgs/tag=0、视频 type=video/tag=1,🔴 需登录态否则 401);接口报错原因参考references/error-codes.md。
撤回消息约定(withdrawMsg.js,PathMakeMsgWithdraw):只支持撤回自己发送的消息(错误码 1506=不是自己撤回、1505=撤回超时、1507=编辑撤回超时)。写操作需用户确认后执行;撤回需提供消息 id(拉取消息时展示的编号即 ser_msgid)与消息来源:单聊=对方 cid/uid(--to-uid/--to-cid)、群聊=群 id(--group-id)。撤回后自动生成新消息内容「XX撤回了一条消息」(type=10,id18n=103838,%NAME%=撤回者姓名),msg/title 自动构造;dev=5、trans_id=秒级时间戳(该接口区别于通用约定,详见 im-withdrawMsg.md)。
人员信息获取红线:人员信息(名称搜索 resolveUser.js、按 id 查询 resolveUserByIds.js/fetchUsersByIds)全部由 weaver-e10-hrm 负责数据采集——im 侧仅 spawn hrm-cli.mjs(emp / profile),不自实现任何 hrm 域 HTTP 请求;common.js runHrmCli 自动注入 E10_LOGIN_ENTRY(全局安装的 e10-login 优先,回退 hrm skill 本地安装)。hrm skill 定位按名称动态扫描(findHrmSkillDirs:扫描 ~/.workbuddy/skills/ 下 weaver-e10-hrm* 前缀的有效安装目录(含 scripts/hrm-cli.mjs),兼容 __skillhub 等后缀,不依赖具体文件夹路径,迁移/重装自动命中;~/.workbuddy-ai/skills/hrm 为历史兜底)。若存在多个同名(不同文件夹)安装,按版本从高到低排序、高版本优先(版本取 _skillhub_meta.json/_meta.json/manifest.json/SKILL.md frontmatter 中的最大值,去 v 前缀比较)。按 uid 列表解析姓名优先走 hrm-cli.mjs emp-by-ids(未来版本新增的批量子命令,一次返回多 id);不存在/失败时退化为 hrm-cli.mjs profile <uid> --json 并发批量(一次最多 100 人、并发受限 8,由 common.js fetchUsersByIds 保证),未命中回退 uid。🔴 禁止使用 IM 接口 getGroupUserName 获取群成员姓名映射:群聊/群成员场景的人员姓名(发送者 from_uid、群成员列表)一律走 hrm(fetchUsersByIds)解析,不得用 getGroupUsers 返回的 name 字段展示姓名。getSessionContext 单聊姓名解析 = 名称缓存 → fetchUsersByIds(优先 emp-by-ids,缺失则 profile 并发)→ 回退 uid(不拉全量员工)。
i18n 翻译约定:消息/会话展示时自动收集 id18n 标签 → getHtmlLabelNames 批量翻译(带缓存,过期条件:超 7 天 或 登录 eteamsid 变化)→ 配合 kvs/jvs 替换 %KEY% 占位符(kvs key 可带/不带 %);占位符值为人员对象/数组时,用人员名称替换(collectPersonIds 收集 uid → fetchUsersByIds(weaver-e10-hrm)批量解析姓名,未命中回退 uid);@ 提及还原:消息文本里的 :@<uid>; 占位符必须还原为 @姓名——优先用消息自带 txt.aus({id, nm})里的姓名,缺失时回退 nameMap/hrm,最后回退 uid(replaceMentions,extractTxt/parseContent 统一处理);querySysMsgInfo/syncGroupMsg/syncSingleMsg/getSessionContext 均已集成。
会话列表展示约定(getSessionContext):会话类型 1=单聊、2=群聊、4=系统消息(详见 im-getSessionContext.md);请求约定 view/sview/reminder 固定 0、top 固定 1;🔴 默认只拉 down 方向(更旧会话),up 方向(更新)除非用户显式 --flag 指定,否则一概不查(默认 flag=2;--continue 亦只拉 down)。展示:全部会话用 markdown 表格输出(| # | 会话类型 | 名称 | 未读数 | 时间 | 副标题 |),时间列取自会话信息里的更新时间戳 update_tm(格式 YYYY/MM/DD HH:MM:SS),按会话最新消息 id(last_msgid)从大到小排序展示(最新在前);名称解析成功只显示名称、失败才显示 id:单聊=对方姓名(hrm 名称缓存 / title 消息 sname,hrm 按 uid 走 profile 并发批量,失败回退 uid)、群聊=queryGroupInfo 批量群名、系统=syncGroupType 批量分组名;副标题 = title 里的发送者:消息内容(id18n 翻译 + %KEY%/@提及 占位符均按「i18n 翻译约定」还原成姓名/文案,消息内容完整展示,不做截断);🔴 媒体消息(图片/文件/视频)副标题显示为 [类型]文件名称(如 [图片]aaa.png、[文件]xxx.pdf、[视频]xxx.mp4),必达消息保留 [必达] 前缀(如 [必达][图片]aaa.png)。具体消息按类型拉取(单聊/群聊/系统)。默认只拉第一页(最新一页,默认 20 条,--num 上限 50 条,超过会被截断),需要更早的会话必须由用户主动询问后再用 --continue 拉下一页(数据未拉完时脚本会输出「是否继续」提示)。
系统消息拉取流程(流程/任务/公文等模块推送到 IM 的消息;每条含 group=系统会话id、type=消息类型):
- 先
searchSysMsgGroup.js --name <模块名>搜索分组配置(如「新到达流程」→groupId=125);命中多个同名/相似分组时,优先选enable=0(启用)且state=0(正常)的条目(enable:0 启用/1 不启用;state:0 正常/1 已删除); - 系统消息里有
type时用syncGroupType.js --gids <gid>(或--tids <tid>)拉 type 配置; querySysMsgInfo.js --group <gid> [--type <tid>]拉消息,--deal 1=未处理、--deal 2=已处理、--flag 1/2=已读/未读;未说明时间范围时脚本默认只拉当天(内置限定今天 00:00:00~23:59:59);- 逐条展示
发送人 | 发送时间 | 内容 | 已读/未读 | 已处理/未处理,不折叠,按消息 id 从大到小排序展示(最新在前)。 - group/type 各字段完整含义(
sunread/enable/state/top/mark/defmark/terminal/location等)见references/im-sysmsg-fields.md(官方文档整理)。
searchGroup.js 常用参数(组合使用,满足即「与」关系):
| 参数 | 含义 |
|---|---|
--name <名称> [--precise] | 按群名称搜索(--precise 精确匹配) |
--members | 列出我所在的所有群 |
--owner | 列出我是群主的群 |
--creator | 列出我创建的群 |
--today | 查询今天创建的群 |
--yesterday | 查询昨天创建的群 |
--type <n> | 按群类型筛选(6=部门群,7=全员群,1=普通群) |
--create-begin <ts> --create-end <ts> | 按创建时间戳范围(秒) |
示例:node scripts/searchGroup.js --creator --yesterday 即「查询我昨天创建的群」。
群信息查询约定:searchGroup(按名称/条件搜索)与 queryGroupInfo(按群 id 查)互相补充——当已有明确的群 id 时,优先使用 queryGroupInfo.js --group-id <群id> 直接查群信息(支持批量 --group-ids);只有群 id 未知时才用 searchGroup 搜索定位。
syncSingleMsg.js / syncGroupMsg.js 拉取消息约定(单聊/群聊通用):
| 用户说法 | 执行方式 |
|---|---|
| 「拉取消息」(未说明时间范围) | 脚本默认只拉当天的消息(未传 --from/--to/--start/--end/--latest 时自动限定今天 00:00:00~23:59:59,输出会明确告知"当天 YYYY-MM-DD"),Agent 无需手动加时间参数 |
| 「拉最新消息」(用户明确要最新/最近的消息) | 加 --latest:起始时间 1970-01-01(msgid=0,end=0 不限下限,start=int64 最大值),近期消息不足一页自动往旧拉全,保证最近消息拉取完整 |
| 「拉取昨天/某日期的消息」 | 加 --from 2026-08-19 --to 2026-08-19(日期由 Agent 按当前时间换算),脚本按 MakeMinAndMaxIdByTm 把时间转成消息 id 范围 |
| 指定具体时间 | --from 2026-08-19 10:00:00 --to 2026-08-19 18:00:00(支持 unix 秒) |
| 「继续拉取」 | 加 --continue,从上一次拉取位置(scripts/.msg-cursor.json 游标)继续拉更旧的消息(未指定时间范围时游标范围保持 0=不限,持续往旧拉) |
拉完时的提示口径(消除歧义):脚本在范围内拉完时,明确区分「本时间范围内消息已拉取完(如需更早请显式指定日期)」与「已拉取到最早消息(无更多历史)」;会话列表拉完时提示「本页为最新会话列表 N 条,如需更旧会话可加 –continue 尝试」,不再笼统提示"已拉取完所有/全部"。
当天无消息时:必须提示用户「当天(YYYY-MM-DD)无消息」,并给快捷选择——「拉最新消息」(--latest,起始 1970-01-01/msgid=0 不限下限)、「拉最近的 20 条」、「拉最近一周的消息」(分别对应 --latest --num 20 / --from 一周前 --to 今天),由用户选择后执行。
分页限制(单聊/群聊/系统/会话列表通用):🔴 每次接口调用只允许拉一页,禁止自动重复翻页把时间范围内的数据一次性拉完:
- 分页大小统一约定:默认每页 20 条(
DEFAULT_PAGE_SIZE),单次请求最多 50 条(MAX_PAGE_SIZE);--num仅作为单页数量上限,超过 50 会被脚本自动截断并打印警告,不得靠--num拉取超过一页的数据。 - 时间范围 ≠ 全量:当用户要求「拉取一周/某天的消息」时,脚本只拉该范围内的最新一页(如一周内的前 20 条),不会循环翻页把整周消息拉完;即使范围内还有更多数据,也只拉一页后停止。
- 未拉完必须停下并报告(红线:禁止一切循环拉取):当本页数据未拉完(本页拉满且区间内仍有更旧消息)时,脚本会输出
⚠️ ...是否继续?加 --continue 参数可拉取下一页;agent 拉完一页后必须停止,向用户报告「本次已拉 N 条、预计剩余约 M 页/条」,由用户再次明确指示后才执行下一页;同一轮内严禁连续多次调用--continue(哪怕用户上一句说了「全部」「拉完」)。若用户说「不用了/只看这么多」,立即结束。 - 「全部/全部消息」/数量要求 ≠ 循环授权:即使用户明确要求「拉取全部消息」,agent 不得一次性循环拉完——每次只拉一页,停下报告并等待用户下一步明确指示(用户说「继续」才拉下一页);宁可通过多轮对话逐页完成,也禁止任何形式的自动循环。
创建群群名规则(groupCreate.js):
- 群名可自定义(
--name <群名>),也可用默认名称。 - 默认名称 = 自己的姓名 + 另外最多四个人的姓名,中间用中文顿号「、」分割,自己姓名排在第一位。例:初四十六、初三、初四、初五十、初十九。
- 用默认名称时:调用前通过
resolveUser.js已拿到成员姓名,传--names <姓名1,姓名2,...>(与--users顺序一一对应),脚本自动拼接;成员超过 5 人时只取自己 + 前 4 人姓名。 - 未传
--name且未传--names时脚本报错,必须二选一。
游标按会话隔离:单聊 key=
single:<对方uid>、群聊 key=group:<群id>;拉到底时不保存游标并提示「已拉取到最早消息」。
标识展示约定(群/人员/会话等 id 展示):
- 尽量不向用户暴露 id(如群聊 id、人员 uid/cid、消息 id 等),优先使用群名称和人员姓名;
- 仅当出现同名无法区分、或拉取群名称/人员名称失败时,才展示 id 辅助区分;
- 用户主动要求展示/复制 id、或脚本参数需要 id 的场景除外。
- ID 类字段穷举黑名单(默认不外露):群聊
group-id、人员uid/cid、消息ser_msgid/msgid、文件file-id、系统会话gid/tid——以上 id 默认不对用户展示,仅作为脚本内部参数。用户索要 id 时的应对话术:「群 id 一般无需关注,我用群名『XX』替你操作即可;如确需复制 id 请告诉我用途」。不因用户反复索要而放宽展示。
消息展示约定(拉取到消息后):全部消息用 markdown 表格展示(内容超 100 字符截断、| 转义;时间按系统时区;多行内容换行显示 ⏎),按消息 id 从大到小排序展示(最新在前)。
- 单聊 / 群聊:
| # | 发送者 | 发送时间 | 消息类型 | 内容 |(发送者:自己「我」,他人姓名,优先消息 sname、群聊回退群成员映射;消息类型:文本/图片/文件/语音等,取自消息 type 解析,未知显示-);- 文件 / 图片 / 视频消息:内容列展示为
[文件名称/图片名称](方括号包裹名称),不使用-占位;预览/下载必须保留为可点击的 Markdown 链接原样展示,禁止省略、压缩或替换为描述性文字——图片/视频 =[名称] [预览](URL) [下载](URL),文件 =[名称] [下载](URL)(文件无预览接口,仅下载;预览/下载 URL 需登录态浏览器打开); - 富文本消息:指包含多种类型消息的组合,展示时将多个消息拼接在一起展示,例如
[xxx.png]你好[xxx.pdf]; - 必达消息:消息体
tf字段按位包含0x01(如tf:"1")即必达消息,内容列加[必达]前缀(如[必达]222222);msgParser.parseContent()已自动识别(返回must字段);
- 文件 / 图片 / 视频消息:内容列展示为
- 系统消息:
| # | 发送者 | 发送时间 | 内容 | 阅读状态/处理状态 |——状态列取决于系统分组配置的sunread(角标计算逻辑):sunread=0(SYSMSG_GROUP_SUNREAD_READ_STATUS)→ 展示阅读状态(已读/未读);sunread=1(SYSMSG_GROUP_SUNREAD_DEAL_STATUS)→ 展示处理状态(已处理/未处理)。脚本展示前调syncGroupType取分组sunread判定模式(默认 0=阅读状态)。内容列:标题第一行、内容第二行(<br>换行)——标题优先sys.id18n翻译(如【流程:提交】),无则用sys.et.nm(事项名称,如「出勤」)。
默认行为与展示说明
每次展示查询结果时,必须向用户明示本次默认口径,并给快捷调整选项,减少「数据对不上」的困惑。
- 时间范围:未说明时默认当天——回复里明确写明(如「默认拉了今天 2026-09-01 的消息」);用户要最新消息时用
--latest(起始 1970-01-01/msgid=0 不限下限,保证最近消息拉全);当天无消息时按「当天无消息」约定给快捷选项(最新消息 / 最近 20 条 / 最近一周); - 数量/页码:默认「最新一页(≤20 条)」——回复里写明(如「最新 20 条,更早可加 –continue」),不静默翻页;
- 数据来源:写明本次是单聊 / 群聊 / 哪个系统会话,避免与其它来源混淆;
- 快捷选项固定话术:「需要更早/更多,可以:① 拉最近的 20 条 ② 拉最近一周 ③ 继续拉下一页」。
字段值解析
仅解析用户明确提供的字段值,未提及的字段不主动解析(请求体构造见「调用规则」)。
解析优先级:① 本对话已出现的实体直接复用(已解析的 cid/uid、已拉取的会话列表中的 group id);② 精确匹配(名称缓存、searchSysMsgGroup/searchGroup 精确名);③ 模糊搜索 + 消歧。禁止跳过前两步直接做全量模糊搜索。
当用户以用户名称描述关联字段(如"张三")时,必须先解析为 ID 再传入接口。用 node scripts/resolveUser.js --name 姓名 获取 IM cid/uid(走 hrm-employee-query,姓名模糊匹配,id→IM uid、cid→IM cid);详见 references/im-resolveUserCidUid.md。
cid/uid 必须成对使用:发送人的 cid 与接收人的 cid 可能不同,解析用户时必须同时拿到 cid 和 uid;发单聊消息时
reciver的 cid/uid 都用接收人自己的值,不要用发送人 cid 顶替。
当用户以群聊名称描述关联字段(如"群聊项目攻坚群")时,必须先解析为 ID 再传入接口。
系统会话名 → groupId:用户提到会话列表里的系统会话名(如「提醒」「新到达流程」「待办流程」)时:
- 优先查本对话最近的
getSessionContext结果,能对应到会话的group直接复用,不再搜索; - 没有会话列表时用
searchSysMsgGroup --name <会话名>定位——该接口是模糊匹配,可能返回多条配置(如「提醒」会命中多条),必须选名称与用户说法一致的条目(名称精确相等优先,并尽量与会话列表交叉验证),禁止直接取第一条; - 仍不唯一时让用户选择,选项带名称 + groupId。
拿到 groupId 后走 querySysMsgInfo 拉消息。
同名消歧(人员/群聊):当解析结果存在多个同名项时,必须先让用户选择确认,不可猜测。选择项必须带区分信息——人员同名带所属部门(如"张三(技术部)"),群聊同名带群 ID(如"测试群2(1787129175701000001)")。候选数量上限:超过 4 个只展示前 4 个 + 提示缩小范围(补充部门 / 群名关键字)。
模糊姓名消歧:多个匹配时,候选先按「是否出现在最近会话列表」排序:唯一出现在会话里 → 用一句话确认(如「是初十三(部门群消息测试)吗?」);多个 → 表格展示,人员带部门并标注是否出现在最近会话。禁止把大量候选不排序直接甩给用户。
人员解析失败(未匹配到):resolveUser.js 返回 total=0(未匹配到人员)时,直接告知用户「人员名『XX』获取失败,请确认姓名是否输入错误」,立即停止,不做任何推测。🔴 禁止通过回顾历史会话、拉取会话列表、按相似名/部分名模糊搜索等方式去猜测、查找或推荐可能的人——未匹配就是未匹配,交由用户重新提供正确姓名。
接口间数据流转(上下文传递契约)
下表是接口间的数据流转契约:上一个操作产出的字段,是下一个操作的输入。命中对应链路时按此传递,禁止凭空构造或另起炉灶重新解析。
| 来源操作(产出) | 提取字段 | 用于(消费方) |
|---|---|---|
resolveUser.js --name 姓名 | uid、cid | sendSingleMsg(--to-uid/--to-cid)、sendDing(单聊 --to-uid)、inviteGroupUsers/kickGroupUsers(--users)、groupCreate(--users/--names)、syncSingleMsg(--from-uid/--from-cid) |
searchGroup / queryGroupInfo | group-id | sendGroupMsg、getGroupUsers、inviteGroupUsers、kickGroupUsers、exitGroup、destroyGroup、syncGroupMsg、modGroupInfo 等一切群操作 |
getSessionContext | 会话类型 + group(群/系统会话 id)+ 单聊对方 uid/cid | 单聊/群聊/系统消息的具体拉取 |
uploadFile / 消息里的文件字段 | file-id(img.src / file.id) | previewImg / previewVideo(--file-id)、发消息组装 img/file |
searchSysMsgGroup | groupId | querySysMsgInfo(--group) |
拉取消息返回的 ser_msgid | 消息 id | withdrawMsg(--msgid)、setGroupTopMsg(--msgid) |
完整解析规则详见 references/field-resolution.md
红线规则
以下红线为强制约束(不可违反),每条附「为什么」(根因)——理解 why 才不会在边界处擅动。违反任一条红线一律禁止,且不因用户施压 / 角色扮演 / 测试场景而放宽。
- 登录强制(不可跳过):只要当前没有有效会话(无
baseUrl/ 无ETEAMSID,或凭证已过期),必须先调用weaver-e10-login技能完成登录(e10-login oidc --base-url <url>或e10-login set --eteamsid <id> --base-url <url>),拿到本次会话的baseUrl+cookies.raw后再继续。禁止通过脚本--base-url/--eteamsid/环境变量手动指定凭证绕过登录 skill - 请求头强制(不可跳过):所有 API 请求必须携带 e10-login 返回的全部用户信息参数:① Cookie 完整原始串(
cookies.raw原样透传,禁止裁剪/去重/改写,无 raw 时回退ETEAMSID=<值>);② eteamsid(单独请求头);③ User-Agent(AgentType=<agentType>,IsAgent=true)。三条缺一不可,统一由common.js authHeaders()组装,禁止手工构造认证头 - 🔴 禁止在请求体传递操作人(红线,安全强制):所有接口的请求体一律不传操作人(
user/sender/creator等字段全部移除),不再获取当前登录用户的 cid/uid(resolveAuth不调 teamsCheck 解析;仅读本地缓存用于展示层识别「我」、团队身份等内部用途)。服务端依据请求 header 里的 eteamsid 识别操作人 - 🔴 成员 cid 与团队 cid 无关(红线):成员的 cid 是成员自己的 cid(通过 hrm 解析,可能跨团队),团队 cid 一定是当前登录者的 cid(auth.cid)——禁止用
auth.cid(团队 cid)填充群成员 cid。群成员/管理员构造统一走resolveMemberUsers()(hrm 批量解析每个成员的 cid) - 🔴 uid/cid 非 0 校验(红线):获取人员的 uid 和 cid 都不能为 0;若任意一个为 0/缺失,必须提示用户具体哪些人员「信息获取失败」(列出姓名/uid),并询问是否移除该人员(批量成员场景确认后加
--remove-failed重试)。禁止使用cid: auth.cid || "0"之类的 0 值兜底兼容;也禁止提示「重新登录」——登录态与人员信息查询(hrm 接口)是两回事,hrm 查询失败时用户仍是登录状态 - 所有业务逻辑,操作者或发送人必须是的当前e10登录用户,不允许指定操作人或者发送人
- 禁止猜测或编造不存在的用户名称、群聊名称等。若无匹配项,你必须直接回复:“未找到该用户或者群聊,请检查名称是否正确”;🔴 禁止通过回顾历史会话、拉取会话列表、按相似名/部分名模糊搜索等方式去猜测、查找或推荐可能的人——未匹配就是未匹配,交由用户重新提供正确名称
- 除了前置依赖里涉及到的skill,不允许去其他skill里探测
- 只记忆缓存自己的信息(如操作者自身的 cid/uid),不缓存他人的人员/群聊信息
- 优先调用
scripts/下的现成脚本,禁止自己手写 HTTP 请求或解密认证逻辑 - 禁止发送空白消息:消息内容(
txt)为空或全空白时不允许发送,需提示用户提供非空内容 - 超时即失败:HTTP 请求超过 15 秒即视为调用失败,不再重试,向用户提示失败原因
- 禁止在没有会话时自行猜测环境地址(域名/IP/端口)、从历史对话或记忆推断拼接地址、或凭空拼接口 URL——一切完整地址与凭证只能来源于
weaver-e10-login的会话输出。 - 禁止擅自切换使用环境(红线):一切操作完全以当前登录环境为准(
weaver-e10-login当前激活的 profile / baseUrl)。严禁擅自修改~/.e10-cli/profile、恢复/改写~/.e10-cli/profiles/<name>/auth、或通过--base-url/--cid/--uid等参数强制指定其他环境身份。环境切换必须由用户明确要求,并交由weaver-e10-login完成。 - 禁止拉全量获取数量(红线):不允许通过拉取全部数据的方式来获取数量——例如获取单聊/群聊的消息总条数、获取会话总数量等。一旦触发此类请求(如用户要求统计消息总数/会话总数),必须立即回复「无法统计总数,功能暂时不支持」,不得再询问用户替代方案、不得提供逐页拉全量等变通选项。数量展示只能基于当页已拉取的数据(如本页
total=N)。 - 禁止擅自修饰数据(红线):拉取到的数据(消息内容、代码文本、链接、文件内容等)必须原样展示,不允许擅自概括、改写、润色、替换为描述性文字(例如把拉取到的代码文本概括为「代码片段」、把链接描述成「gitlab 链接」)。只允许展示层既定处理:
|转义、多行换行显示 ⏎(消息内容一律完整展示,不做长度截断)。展示必须忠实于接口返回的原始内容。 - 禁止拉取后本地过滤(红线):当用户需要对数据做过滤(如按免打扰、按未读、按发送人等条件筛选)时,如果接口参数不支持该过滤,必须直接告知用户「该过滤条件接口不支持」;严禁先拉取数据、再在本地对结果做过滤/筛选(例如拉全量会话后本地 filter 掉免打扰会话)。过滤只能依赖接口参数(如
--type、--deal、--flag等接口原生支持的条件),接口不支持的条件一律如实告知,不得变通。 - 数据对不上时不得自行猜测(红线):
- 需求明确时:即使接口返回与会话展示或用户描述不一致(例如系统消息接口返回 0 条但会话列表有未读、条数/字段对不上),禁止自行猜测原因、擅自换参数反复探测、换同类型接口或编造数据;必须如实报告「接口返回 X、与预期 Y 不一致」的具体差异与已确认事实,停止等待用户指示。
- 需求不明确时:发现数据对不上(如返回为空、条数不符、字段缺失),必须先与用户确认需求——确认要查询的范围、口径、数据来源等,确认后再执行;禁止自作主张选定参数或替用户决定口径。
- 报告差异时必须给出证据(接口返回码、条数、关键字段),明确区分「已确认事实」与「推测」,不得把推测当结论。
数据对不上提问模板(配合上方红线强制使用,先证据、后选项、不猜原因):
已确认事实:<接口返回码、条数、关键字段>(如「querySysMsgInfo group=110 返回 code=0,0 条」)
差异:接口返回 <X>,会话/预期显示 <Y>(如「会话列表显示未读 58 条」)
可能方向(需你选择,我不替你决定):A <方向1> B <方向2> C <方向3>调用规则
- 严禁凭空探测:如果你发现没有匹配用户需求的 Skill(技能)或接口文档,严禁自行发起任何形式的“接口探测”、“能力扫描”、“文档分析”或“模拟测试”。
- 立即终止并告知:当遇到“未找到群聊消息发送技能”或“相关接口为空”时,你必须在回复的第一句直接告知用户无法执行,并立即停止后续的所有思考和输出。
- 禁止编造步骤:绝不允许列出所谓的“探测步骤”(例如“步骤1:扫描端口;步骤2:尝试 GET /send”等),因为这些都是无实际代码支撑的幻觉内容。
- 技能不存在:提示用户无相关技能,不允许自行尝试
- 写操作确认:发送消息等有副作用的写操作,必须先获得用户明确确认后才可以执行。确认时只展示用户提供的字段和自动填充的默认值,不要追问未指定的字段
- 接口选择:同类型候选接口中,只选择最符合用户意图和接口约束的一个;当存在多个语义相近的操作且无法从用户意图中明确区分时,先询问用户选择哪个操作(非字段值)
- 请求体构造:仅传入必填字段、用户指定的字段、及需填充默认值的字段(默认值按接口文档静默填充)。非必填且无默认值的字段,用户未指定时不传入请求体。不主动追问缺失字段。
- 数据展示:向用户展示数据(查询结果、确认信息等)时,使用字段业务名称和可读值(如"张三"),不展示字段 key(如
task_name、manager)和关联字段的内部 ID(人员 ID、e-builder 关联 ID 等)。查询响应中关联类字段(人员、Ebuilder 关联、字典选项等)返回[{name, id}]数组,展示时取name值。数据记录本身的 ID 可展示供用户引用。 - 默认口径明示:展示查询结果时按「默认行为与展示说明」写明时间范围/数量/数据来源,并给快捷调整选项。
- 失败边界:接口调用失败后停止并说明失败原因,不自动切换到其他同类型接口;数据对不上(返回 0 条/条数不符/字段缺失)时,按上文「数据对不上时不得自行猜测」红线处理
- 链路组合:一个用户意图可以按业务链路调用多个不同职责接口(如先查询再创建)
错误处理(失败不静默,禁止静默换接口)
| 现象 | 应该做什么 | 禁止做什么 |
|---|---|---|
| 脚本报错 / 非 0 退出 | 停止,如实报告报错信息(退出码 / 关键报错行) | 静默失败、当作成功、自动重试 |
| 接口返回 code≠0 / 业务码异常 | 读 references/error-codes.md 对照原因,报告「接口返回 code=X(含义)」 | 猜原因、换参数反复探测 |
| 未匹配到人员/群(total=0 / 空) | 告知「未找到『XX』,请确认名称」,立即停止 | 猜同音字、翻历史、相似名模糊搜 |
| 数据对不上(返回 0 条/条数不符/字段缺失) | 按「数据对不上提问模板」先给证据再让用户选方向 | 自作主张选参数、替用户定口径 |
| 超时(>15s) | 视为失败,停止并告知 | 无限重试 |
| 无对应接口支持的需求 | 如实告知「不支持」,提供替代方案(若有) | 变通硬凑、编造步骤、声称能探测 |
已知限制(不支持的能力,集中声明)
遇到下列需求,直接告知不支持,不提供变通、不硬凑、不假装能做。避免 agent 为满足需求而调用错误接口或编造能力。
| 不支持的能力 | 替代方案 / 引导 |
|---|---|
| 统计消息总数 / 会话总数(全量计数) | 仅能基于当页数据展示 total=N;直接回复「无法统计总数,功能暂时不支持」 |
| 按接口不支持的字段做过滤(免打扰/未读/发送人等本地过滤) | 告知「该过滤条件接口不支持」,引导改用接口原生参数(--type/--deal/--flag) |
| 删除 / 清空消息、编辑已发消息 | 仅支持撤回自己发的消息(withdrawMsg,有时限) |
| 跨平台 IM(企业微信/钉钉/邮件) | 建议对应 skill(如 wecom-unified),不代为调用 |
| 定时推送 / 机器人托管 / 自动回复 | 不在本 Skill 范围 |
| 对消息做统计分析 / 报表 | 不在本 Skill 范围 |
| 建非普通群(部门群/全员群等) | groupCreate 仅支持普通群,其他类型需客户端操作 |
输出质量标准(正面标准 + 不可接受输出成对)
| 正面标准(必须做到) | 不可接受输出(红线反例) |
|---|---|
| 查询结果用 markdown 表格,按消息 id 从大到小(最新在前) | 纯文本堆砌、乱序、折叠关键字段 |
消息内容完整展示(不截断;| 转义、换行 ⏎ 除外) | 概括/改写/润色/替换为描述性文字(如把代码写成「代码片段」) |
媒体消息展示为 [名称],预览/下载保留可点击 Markdown 链接 | 省略/压缩链接、替换为「(附下载链接)」 |
| 时间/数量/来源明示默认口径,并给快捷调整选项 | 静默按默认值执行、不说明口径 |
| 姓名优先展示名称,失败才回退 id | 直接甩 id、暴露内部字段 key |
| 写操作完成后仅报告本次回包结果,不再二次核验 | 二次拉取验证、制造多余请求 |