sophhub 0.4.62 → 0.4.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sophhub",
3
- "version": "0.4.62",
3
+ "version": "0.4.64",
4
4
  "description": "SophHub CLI - Manage and download AI Agent skills and agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,10 +1,24 @@
1
1
  {
2
2
  "name": "claw-agent-get-send",
3
- "version": "1.2.0",
3
+ "version": "2.0.0",
4
4
  "types": ["store"],
5
- "displayName": "Claw Agent Get/Send",
6
- "description": "Appia(IM 即时通讯)侧 claw.agent.groups.get / claw.agent.message.send:查询机器人在哪些群聊、向群发纯文本或 Markdown、发送文件附件;脚本封装 + HTTP/curl 参考(JWT、msg/md、错误码)",
5
+ "displayName": "Claw Agent 全量能力",
6
+ "description": "Appia(IM)Claw Agent 全量能力:群聊收发/读历史/公告/撤回/退群,扩展(scopes/搜人/通知/待办/搜频道/纪要/总览/建群/改待办);脚本封装 + HTTP/curl 参考",
7
7
  "changelog": [
8
+ {
9
+ "version": "2.0.0",
10
+ "date": "2026-07-23",
11
+ "changes": [
12
+ "appia_claw.py:新增 get-messages / get-announcements / fetch-file / recall / leave 五个入群子命令(既有 groups/verify-target/send/send-md/send-file 不变)",
13
+ "appia_claw.py:send / send-md 新增 --mention(-m),经 agent.users.search 把显示名解析为 @username 前置到正文,可选按频道成员校验是否在群",
14
+ "新增 appia_common.py:共享凭证 + JWT + 通用 GET/POST/multipart/raw helper",
15
+ "新增 appia_extensions.py:scopes/scopes-request/users-search/notifications/todos/unread/channels-search/channel-info/channel-messages/channel-messages-search/channel-members/channel-attachments/channel-announcements/file-metadata/meeting-minutes/meeting-minutes-ingest/overview-resolve/overview-links/todos-update/channels-create/tool-invoke(21 子命令)",
16
+ "新增 references/ 目录:auth/creator-delegate-api/query-api/write-api/rooms-api/overview-api/session-flow",
17
+ "reference-http.md:追加 messages.get/announcements.get/file.fetch/recall/group.leave 章节与 references 指引",
18
+ "SKILL.md:重写为全量能力用法(入群/扩展)+ 文档地图 + --mention 说明;description 扩触发词",
19
+ "skill.json / pyproject.toml:bump 2.0.0;displayName 改为「Claw Agent 全量能力」"
20
+ ]
21
+ },
8
22
  {
9
23
  "version": "1.2.0",
10
24
  "date": "2026-07-06",
@@ -49,5 +63,5 @@
49
63
  }
50
64
  ],
51
65
  "createdAt": "2026-04-28",
52
- "updatedAt": "2026-07-06"
66
+ "updatedAt": "2026-07-23"
53
67
  }
@@ -1,49 +1,125 @@
1
1
  ---
2
2
  name: claw-agent-get-send
3
- description: On Appia (an IM / team chat platform), list which group chats the bot agent is in (rid + name), or send plaintext or Markdown to a group via Appia Claw. Use when the user asks for group list / 群列表 / Appia 群聊 / rid, or to message a group / 向群发消息 / IM 通知;claw、agent.groups.get、agent.message.send。
3
+ description: AppiaIMClaw Agent 全量能力:群聊收发/读历史/公告/撤回/退群,扩展(scopes/搜人/通知/待办/搜频道/纪要/总览/建群/改待办)。当用户要求 Appia/Claw 群聊收发、查历史公告、撤回、搜人/频道、待办通知、建群、scopes 授权时使用。
4
4
  ---
5
5
 
6
- # Appia 即时通讯(IM)· Claw 群列表与发消息
6
+ # Appia 即时通讯(IM)· Claw Agent 全量能力
7
7
 
8
- Appia 为 IM(即时通讯)工具中的群聊/会话场景。脚本 `{baseDir}/scripts/appia_claw.py` 通过 Claw HTTP API 拉取机器人所在群并发消息。`{baseDir}` 与本 `SKILL.md` 同级(安装根下一般有 `scripts/`)。
8
+ Appia 为 IM(即时通讯)工具中的群聊/会话场景。操作者始终是机器人,凭证只有 JWT + `agentId` + 创建者 `userId`(JWT `sub` 须等于 `userId`);用户 `authToken` 永不给 Agent,写权限通过 scopes 授权。
9
9
 
10
- ## 用法
10
+ 脚本位于 `{baseDir}/scripts/`,用 `uv run` 启动。`{baseDir}` 与本 `SKILL.md` 同级。
11
+
12
+ ## 鉴权与授权
13
+
14
+ - 凭证:`--cred-file /path/to.cred.json`(或 `-c`)JSON 文件,非空字段优先于环境变量;不用凭证文件时设 `CLAW_JWT`、`APP_AGENT_ID`、`CLAW_USER_ID`(新脚本也接受 `MCP_JWT`)。
15
+ - 缺写权限:服务端返回 `SCOPE_DENIED` → `appia_extensions.py scopes-request` → 用户在 myAgent 点「授权」→ `scopes` 或重试。不要向用户要 authToken。
16
+ - 详情:[auth.md](references/auth.md) · [session-flow.md](references/session-flow.md)
17
+
18
+ ## 1. 入群能力(bot 须在频道)— `appia_claw.py`
19
+
20
+ 子命令前可加 `--cred-file /path/to.cred.json`(或 `-c`)、`--timeout 秒`。查群与收发:
21
+
22
+ ```bash
23
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json groups
24
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json groups --json
25
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json verify-target
26
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send --text "正文" --rid "<rid>"
27
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send --text "正文" --rid "<rid>" --mention "黄志举,李迅"
28
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send --file /tmp/body.txt --rid "<rid>"
29
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send-md --text "正文" --rid "<rid>"
30
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send-md --text "正文" --rid "<rid>" --mention "黄志举"
31
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send-md --md-file /tmp/md.json --rid "<rid>"
32
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json send-file report.pdf --rid "<rid>" --text "请查收"
33
+ ```
34
+
35
+ 读历史/公告、下载附件、撤回、退群:
36
+
37
+ ```bash
38
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json get-messages --rid "<rid>" --count 20
39
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json get-messages --rid "<rid>" --latest "<nextLatest>"
40
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json get-announcements --rid "<rid>"
41
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json fetch-file --file-id "<fid>" --rid "<rid>" -o ./attachment.pdf
42
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json recall --message-id "<msgId>"
43
+ uv run {baseDir}/scripts/appia_claw.py -c /path/to.cred.json leave --rid "<rid>"
44
+ ```
45
+
46
+ ## 2. 扩展能力(同一机器人 + scopes)— `appia_extensions.py`
47
+
48
+ 授权与人员/通知/待办:
49
+
50
+ ```bash
51
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json scopes
52
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json scopes-request --scopes "channels:write" --reason "建群"
53
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json users-search --q "张三" --limit 20
54
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json notifications --limit 20
55
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json todos --limit 20
56
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json unread
57
+ ```
58
+
59
+ 频道发现与消息:
11
60
 
12
61
  ```bash
13
- # 子命令前可加:--cred-file /path/to.cred.json(或 -c)、--timeout 秒;凭证与路径示例见 docs/claw-agent-get-send.md
62
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channels-search --name "产品周会"
63
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channel-info --rid "<rid>"
64
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channel-messages --rid "<rid>" --limit 20
65
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channel-messages-search --rid "<rid>" --keyword "上线"
66
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channel-members --rid "<rid>"
67
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channel-attachments --rid "<rid>"
68
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channel-announcements --rid "<rid>"
69
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json file-metadata --file-id "<fid>"
70
+ ```
14
71
 
15
- # 1. 列出当前 agent 已加入的群(rid、群名)
16
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json groups
72
+ 会议纪要 / 总览元数据:
17
73
 
18
- # 2. 同上,输出接口原始 JSON(便于复制 rid)
19
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json groups --json
74
+ ```bash
75
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json meeting-minutes --limit 20
76
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json meeting-minutes-ingest --limit 20
77
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json overview-resolve --url "https://projects.appia.vip/<id>?doc=<docKey>"
78
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json overview-links --rid "<rid>"
79
+ ```
80
+
81
+ 写操作(需对应 `:write` scope,缺则 `scopes-request`)与聚合调用:
20
82
 
21
- # 3. 双因子校验:凭证或环境里已配置 TARGET_RID、TARGET_GROUP_NAME
22
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json verify-target
83
+ ```bash
84
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json todos-update --id "<todoId>" --status "done"
85
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json channels-create --name "产品周会群" --members-json '["zhangsan","lisi"]'
86
+ uv run {baseDir}/scripts/appia_extensions.py -c cred.json tool-invoke --tool "appia.todos.list" --args-json '{"limit":5}'
87
+ ```
23
88
 
24
- # 4. 向指定 rid 发纯文本(--rid 可换成本地凭证里的 target_rid)
25
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json send --text "正文" --rid "<rid>"
89
+ ## 文档地图
26
90
 
27
- # 5. 长文本从 UTF-8 文件发送
28
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json send --file /tmp/body.txt --rid "<rid>"
91
+ | 文件 | 内容 |
92
+ |------|------|
93
+ | [reference-http.md](reference-http.md) | 入群端点 curl 参考(groups/messages/announcements/file.fetch/upload/send/recall/leave) |
94
+ | [references/auth.md](references/auth.md) | 鉴权 + scopes 授权 |
95
+ | [references/creator-delegate-api.md](references/creator-delegate-api.md) | 扩展能力端点表 |
96
+ | [references/query-api.md](references/query-api.md) / [write-api.md](references/write-api.md) | 读 / 写补充 |
97
+ | [references/rooms-api.md](references/rooms-api.md) | 建频道 |
98
+ | [references/overview-api.md](references/overview-api.md) | 总览 |
99
+ | [references/session-flow.md](references/session-flow.md) | 启动与轮询 |
29
100
 
30
- # 6. 发 Markdown AST:一段纯文本自动包成 md
31
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json send-md --text "正文" --rid "<rid>"
101
+ ## @提及(--mention)
32
102
 
33
- # 7. JSON 文件读 md 数组
34
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json send-md --md-file /tmp/md.json --rid "<rid>"
103
+ `send` 和 `send-md` 均支持 `--mention`(`-m`),接收显示名称或 username,逗号分隔。脚本会先通过 `agent.users.search` API 查询用户名,精确匹配 name/username 优先,否则取搜索结果第一条,再拼成 `@username` 前缀。
35
104
 
36
- # 8. 发送文件到群聊(一步到位:内部自动 upload + send,支持一个或多个文件)
37
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json send-file report.pdf --rid "<rid>" --text "请查收附件"
38
- # 多文件 + 无正文:
39
- uv run {baseDir}/scripts/appia_claw.py --cred-file /path/to.cred.json send-file a.pdf b.pdf --rid "<rid>"
105
+ ```bash
106
+ # 单个 @
107
+ uv run {baseDir}/scripts/appia_claw.py -c cred.json send --text "请查收" --rid "<rid>" --mention "黄志举"
108
+ # 多个 @
109
+ uv run {baseDir}/scripts/appia_claw.py -c cred.json send --text "开会了" --rid "<rid>" --mention "黄志举,李迅"
110
+ # 也可直接用 username
111
+ uv run {baseDir}/scripts/appia_claw.py -c cred.json send-md --text "请确认" --rid "<rid>" --mention "zhiju.huang"
40
112
  ```
41
113
 
42
- 不用凭证文件时,可在环境中设置 `CLAW_JWT`、`APP_AGENT_ID`、`CLAW_USER_ID`(及场景需要的 `TARGET_RID` 等),命令相同,省略 `--cred-file …` 即可。
114
+ ⚠️ 必须先查用户再 @,不要猜测 username。
43
115
 
44
116
  ## 注意事项
45
117
 
46
- - 最小凭证字段(JSON 或环境变量):JWT、机器人 `agentId`、创建者 `userId`;勿将填好真实值的文件提交 Git。
118
+ - 最小凭证字段:JWT、机器人 `agentId`、创建者 `userId`;勿将填好真实值的凭证文件提交 Git。
47
119
  - 未设置 `APPIA_BASE_URL` 时,脚本默认 `https://sophgo.appia.cn`。
48
- - HTTP / curl / 错误码:技能根目录 **`../reference-http.md`**(相对本文件)。
49
- - 发送文件用 `send-file` 一步完成(内部自动 upload + send);不存在单独的 `upload` 子命令,避免"只上传不发消息"的失败。
120
+ - 入群能力须 bot 已在频道;扩展能力看 scopes。
121
+ - 不猜 rid / username:入群 `groups`;按名 `channels-search`;人名 `users-search`。
122
+ - 附件两步:`send-file` 一步完成(内部 upload → send);下载用 `fetch-file`。
123
+ - 建频道 `members` 用 username,不要默认把 Claw 创建者塞进去。
124
+ - 总览行数据未落地,只用 `overview-resolve` / `overview-links`,勿调 `overview.read`。
125
+ - 写操作先向用户确认。
@@ -1,5 +1,5 @@
1
1
  [project]
2
2
  name = "claw-agent-get-send"
3
- version = "1.0.1"
4
- description = "Appia Claw groups.get / message.send helper"
3
+ version = "2.0.0"
4
+ description = "Appia Claw Agent 全量能力:入群收发 + 扩展(scopes)"
5
5
  requires-python = ">=3.10"
@@ -0,0 +1,296 @@
1
+ # Claw HTTP API(curl 参考)
2
+
3
+ ---
4
+
5
+
6
+ ## `GET /api/v1/claw/agent.groups.get`
7
+
8
+ 用于按 `agentId` + `userId` 查询该机器人所在的所有群聊,返回 `rid` 和群名称。
9
+
10
+ ### 鉴权方式
11
+
12
+ 与 `mcpToDos` 一致:
13
+
14
+ - `authRequired: false`
15
+ - 通过请求头 `Authorization: Bearer <JWT>` 校验
16
+ - 校验规则受以下设置控制:
17
+ - `Appia_Antagent_JWT_Enable`
18
+ - `APPIA_JWT_SECRET`
19
+
20
+ ### 请求示例
21
+
22
+ ```bash
23
+ curl -sS -G 'https://YOUR_ROCKETCHAT_HOST/api/v1/claw/agent.groups.get' \
24
+ -H 'Authorization: Bearer YOUR_MCP_JWT_TOKEN' \
25
+ --data-urlencode 'agentId=AGENT_BOT_USER_ID' \
26
+ --data-urlencode 'userId=CREATOR_USER_ID'
27
+ ```
28
+
29
+ ### 参数
30
+
31
+ - `agentId`(query,必填):OpenClaw 侧 Agent ID(会映射到机器人用户)
32
+ - `userId`(query,必填):创建者 / 调用方用户 ID(脚本由凭证 `creator_user_id` 等提供)。缺失返回 `userId is required`。
33
+
34
+ ### 成功返回示例
35
+
36
+ ```json
37
+ {
38
+ "success": true,
39
+ "data": {
40
+ "agentId": "AGENT_BOT_USER_ID",
41
+ "groups": [
42
+ {
43
+ "rid": "ROOM_ID_1",
44
+ "name": "群聊A"
45
+ },
46
+ {
47
+ "rid": "ROOM_ID_2",
48
+ "name": "群聊B"
49
+ }
50
+ ],
51
+ "total": 2
52
+ }
53
+ }
54
+ ```
55
+
56
+ ### 常见失败
57
+
58
+ - `{"success":false,"message":"401"}`:JWT 无效或过期
59
+ - `{"success":false,"message":"agentId is required"}`:缺少 `agentId`
60
+ - `{"success":false,"message":"userId is required"}`:缺少 `userId`
61
+ - `{"success":false,"message":"agent not found by agentId"}`:找不到对应 agentId 的机器人
62
+
63
+ ---
64
+
65
+ ## `POST /api/v1/claw/agent.message.send`
66
+
67
+ 用于根据 **`userId` + `rid` + `agentId`** 向指定群聊发送消息。
68
+
69
+ 接口会校验:
70
+
71
+ 1. `rid` 对应房间存在
72
+ 2. `agentId` 对应用户存在、为 bot、且 active
73
+ 3. 该 `agentId` 确实在该 `rid` 的订阅列表里
74
+
75
+ 满足后,走后端正常发消息逻辑(`executeSendMessage`)。
76
+
77
+ ### 鉴权方式
78
+
79
+ 与 `mcpToDos` 一致:
80
+
81
+ - `authRequired: false`
82
+ - 通过请求头 `Authorization: Bearer <JWT>` 校验
83
+ - 校验规则受以下设置控制:
84
+ - `Appia_Antagent_JWT_Enable`
85
+ - `APPIA_JWT_SECRET`
86
+
87
+ ### 请求示例
88
+
89
+ #### 示例一:发送纯文本
90
+
91
+ ```bash
92
+ curl -sS -X POST 'https://YOUR_ROCKETCHAT_HOST/api/v1/claw/agent.message.send' \
93
+ -H 'Content-Type: application/json' \
94
+ -H 'Authorization: Bearer YOUR_MCP_JWT_TOKEN' \
95
+ -d '{
96
+ "userId": "CREATOR_USER_ID",
97
+ "rid": "TARGET_ROOM_RID",
98
+ "agentId": "AGENT_BOT_USER_ID",
99
+ "msg": "这是一条由 Claw 机器人发送的消息"
100
+ }'
101
+ ```
102
+
103
+ #### 示例二:发送 Markdown(`md`)
104
+
105
+ ```bash
106
+ curl -sS -X POST 'https://YOUR_ROCKETCHAT_HOST/api/v1/claw/agent.message.send' \
107
+ -H 'Content-Type: application/json' \
108
+ -H 'Authorization: Bearer YOUR_MCP_JWT_TOKEN' \
109
+ -d '{
110
+ "userId": "CREATOR_USER_ID",
111
+ "rid": "TARGET_ROOM_RID",
112
+ "agentId": "OPENCLAW_AGENT_ID",
113
+ "md": [
114
+ {
115
+ "type": "PARAGRAPH",
116
+ "value": [
117
+ { "type": "PLAIN_TEXT", "value": "这是一条 *Markdown* 消息" }
118
+ ]
119
+ }
120
+ ]
121
+ }'
122
+ ```
123
+
124
+ ### 参数
125
+
126
+ - `userId`(body,必填):创建者 / 调用方用户 ID(与 `agent.groups.get` 的 query `userId` 同源;脚本由凭证 `creator_user_id` 等提供)
127
+ - `rid`(body,必填):目标群聊房间 ID
128
+ - `agentId`(body,必填):OpenClaw 侧 Agent ID(会映射到机器人用户)
129
+ - `msg`(body,可选):消息文本
130
+ - `md`(body,可选):Markdown AST(Rocket.Chat `md` 结构)
131
+ - 约束:`msg` 和 `md` 至少提供一个
132
+
133
+ ### 成功返回示例
134
+
135
+ ```json
136
+ {
137
+ "success": true,
138
+ "data": {
139
+ "rid": "TARGET_ROOM_RID",
140
+ "agentId": "AGENT_BOT_USER_ID",
141
+ "status": "sent"
142
+ }
143
+ }
144
+ ```
145
+
146
+ ### 常见失败
147
+
148
+ - `{"success":false,"message":"401"}`:JWT 无效或过期
149
+ - `{"success":false,"message":"userId, rid and agentId are required, and either msg or md must be provided"}`:缺少 `userId`/`rid`/`agentId` 或未提供 `msg`/`md`
150
+ - `{"success":false,"message":"room not found"}`:房间不存在
151
+ - `{"success":false,"message":"agent not found by agentId"}`:找不到对应 agentId 的机器人
152
+ - `{"success":false,"message":"agent must be a bot user"}`:agent 不是 bot
153
+ - `{"success":false,"message":"agent is inactive"}`:机器人未激活
154
+ - `{"success":false,"message":"agent is not in this room"}`:机器人不在该群里
155
+
156
+ ### 带附件发送(`fileIds`)
157
+
158
+ 先上传文件拿到 `file._id`,再放入 `send` 的 `fileIds` 数组:
159
+
160
+ ```json
161
+ {
162
+ "userId": "CREATOR_USER_ID",
163
+ "rid": "TARGET_ROOM_RID",
164
+ "agentId": "AGENT_BOT_USER_ID",
165
+ "msg": "请查收附件",
166
+ "fileIds": ["uploaded-file-id"]
167
+ }
168
+ ```
169
+
170
+ ---
171
+
172
+ ## `POST /api/v1/claw/agent.file.upload`
173
+
174
+ 上传文件到 Appia 群聊(**不发消息**),返回 `file._id` 供 `agent.message.send` 的 `fileIds` 使用。
175
+
176
+ ### 请求示例
177
+
178
+ `multipart/form-data`,字段:
179
+
180
+ | 字段 | 必填 |
181
+ |------|------|
182
+ | userId | 是 |
183
+ | agentId | 是 |
184
+ | rid | 是 |
185
+ | file | 是 |
186
+
187
+ ```bash
188
+ curl -sS -X POST 'https://YOUR_ROCKETCHAT_HOST/api/v1/claw/agent.file.upload' \
189
+ -H 'Authorization: Bearer YOUR_MCP_JWT_TOKEN' \
190
+ -F "userId=CREATOR_USER_ID" \
191
+ -F "agentId=AGENT_BOT_USER_ID" \
192
+ -F "rid=TARGET_ROOM_RID" \
193
+ -F "file=@./report.pdf"
194
+ ```
195
+
196
+ ### 成功返回示例
197
+
198
+ ```json
199
+ {
200
+ "success": true,
201
+ "data": {
202
+ "file": {
203
+ "_id": "uploaded-file-id",
204
+ "name": "report.pdf",
205
+ "type": "application/pdf",
206
+ "size": 102400
207
+ }
208
+ }
209
+ }
210
+ ```
211
+
212
+ ### 常见失败
213
+
214
+ - `{"success":false,"message":"401"}`:JWT 无效或过期
215
+ - `{"success":false,"message":"agent is not in this room"}`:机器人不在该群里
216
+ - `{"success":false,"message":"file is required"}`:未上传文件
217
+
218
+ ---
219
+
220
+ ## `GET /api/v1/claw/agent.messages.get`
221
+
222
+ 读取频道历史消息(倒序),用响应 `nextLatest` 作为 `latest` 翻页。脚本:`appia_claw.py get-messages`。
223
+
224
+ ```bash
225
+ curl -H "Authorization: Bearer $MCP_JWT" \
226
+ "$SITE_URL/api/v1/claw/agent.messages.get?userId=$USER_ID&agentId=$AGENT_ID&rid=$RID&count=20"
227
+ ```
228
+
229
+ | 参数 | 必填 | 说明 |
230
+ |------|------|------|
231
+ | userId, agentId, rid | 是 | |
232
+ | count, offset | 否 | 分页 |
233
+ | latest | 否 | ISO 时间,返回此时间之前 |
234
+ | showThreadMessages | 否 | 默认 true |
235
+
236
+ ---
237
+
238
+ ## `GET /api/v1/claw/agent.announcements.get`
239
+
240
+ 读取频道公告,支持类型过滤。脚本:`appia_claw.py get-announcements`。类型:`0/normal` 普通公告、`1/meeting` 会议公告、`2/summary` 会议纪要。
241
+
242
+ ```bash
243
+ curl -H "Authorization: Bearer $MCP_JWT" \
244
+ "$SITE_URL/api/v1/claw/agent.announcements.get?userId=$USER_ID&agentId=$AGENT_ID&rid=$RID"
245
+ ```
246
+
247
+ ---
248
+
249
+ ## `GET /api/v1/claw/agent.file.fetch`
250
+
251
+ 下载频道附件(二进制流)。脚本:`appia_claw.py fetch-file`。
252
+
253
+ ```bash
254
+ curl -H "Authorization: Bearer $MCP_JWT" \
255
+ "$SITE_URL/api/v1/claw/agent.file.fetch?userId=$USER_ID&agentId=$AGENT_ID&fileId=$FILE_ID&rid=$RID" \
256
+ -o ./attachment.pdf
257
+ ```
258
+
259
+ | 参数 | 必填 | 说明 |
260
+ |------|------|------|
261
+ | userId, agentId, fileId | 是 | |
262
+ | rid | 否 | 建议传,校验文件属于该频道 |
263
+
264
+ ---
265
+
266
+ ## `POST /api/v1/claw/agent.message.recall`
267
+
268
+ 撤回 **bot 自己发送** 的消息。脚本:`appia_claw.py recall`。
269
+
270
+ ```bash
271
+ curl -X POST "$SITE_URL/api/v1/claw/agent.message.recall" \
272
+ -H "Authorization: Bearer $MCP_JWT" -H "Content-Type: application/json" \
273
+ -d '{"userId":"'"$USER_ID"'","agentId":"'"$AGENT_ID"'","messageId":"'"$MSG_ID"'"}'
274
+ ```
275
+
276
+ ---
277
+
278
+ ## `POST /api/v1/claw/agent.group.leave`
279
+
280
+ bot 退出指定群聊。脚本:`appia_claw.py leave`。
281
+
282
+ ```bash
283
+ curl -X POST "$SITE_URL/api/v1/claw/agent.group.leave" \
284
+ -H "Authorization: Bearer $MCP_JWT" -H "Content-Type: application/json" \
285
+ -d '{"userId":"'"$USER_ID"'","agentId":"'"$AGENT_ID"'","rid":"'"$RID"'"}'
286
+ ```
287
+
288
+ ---
289
+
290
+ ## 扩展能力 / 会议纪要 / 总览
291
+
292
+ `scopes.*`、`users.search`、`notifications/todos/unread`、`channels.*`、`channel.*`、`meeting.minutes.*`、`overview.*`、`tool.invoke` 的 curl 与工作流见 `references/` 目录:
293
+
294
+ - [auth.md](references/auth.md) · [creator-delegate-api.md](references/creator-delegate-api.md) · [query-api.md](references/query-api.md) · [write-api.md](references/write-api.md)
295
+ - [rooms-api.md](references/rooms-api.md)
296
+ - [overview-api.md](references/overview-api.md) · [session-flow.md](references/session-flow.md)
@@ -0,0 +1,115 @@
1
+ # 鉴权与授权
2
+
3
+ ## 三句话
4
+
5
+ 1. **干活的是机器人**(SophClaw),凭证只有 `MCP_JWT` + `userId` + `agentId`。
6
+ 2. **用户 `authToken` 永不给 Agent。**
7
+ 3. **「授权」** = 用户在 myAgent 点卡片,允许这个机器人使用某些 **scopes**;之后仍是机器人调接口,服务端查库校验。
8
+
9
+ 不是:换用户登录、下发 RC Token、或「创建者本人去操作」。
10
+
11
+ ---
12
+
13
+ ## 配置(USER.md)
14
+
15
+ | 项 | 含义 |
16
+ |----|------|
17
+ | `SITE_URL` | 如 `https://ssc.appia.cn` |
18
+ | `userId` | Agent 创建者 ID(归属校验,不是登录态) |
19
+ | `agentId` | OpenClaw agent ID |
20
+ | `MCP_JWT` | `Authorization: Bearer …` |
21
+
22
+ 企业识别码 → 地址(大小写不敏感):SSC → `ssc.appia.cn`;BITMAIN → `appia.cn`;SOPHGO → `sophgo.appia.cn`。
23
+
24
+ ### JWT 规则
25
+
26
+ - 开启 `Appia_Antagent_JWT_Enable` 时,Bearer JWT 必须有效且未过期。
27
+ - JWT 的 `sub`(或 `uid`)**必须等于**请求中的 `userId`。
28
+ - 入群、扩展均同一规则。
29
+
30
+ > **本 skill 脚本**:`appia_claw.py` 读 `CLAW_JWT`;`appia_extensions.py`(经 `appia_common.py`)同时接受 `CLAW_JWT` 与 `MCP_JWT`,任一非空即可;`APP_AGENT_ID` / `CLAW_USER_ID` 同理。
31
+
32
+ ---
33
+
34
+ ## 两类能力(都是机器人在调)
35
+
36
+ | | 入群 | 扩展(scopes) |
37
+ |--|------|----------------|
38
+ | 条件 | bot 已在频道 | 服务端 `appiaClawAgentScopes` 通过 |
39
+ | 例子 | 发消息、附件、撤回 | 待办、搜人、建群、总览元数据 |
40
+ | 凭证 | MCP JWT | MCP JWT(同一个) |
41
+
42
+ 扩展能力在服务端会按创建者可见范围执行业务,但对 Agent 而言**没有第二条登录线**。
43
+
44
+ 总览:**元数据**已落地(`overview.resolve`);**行数据**未落地,见 [overview-api.md](overview-api.md)。
45
+
46
+ ---
47
+
48
+ ## 授权(scopes)
49
+
50
+ ### 是什么
51
+
52
+ scopes = 服务端记在该 Agent 上的能力开关。
53
+ 创建时默认**只读**;建群 / 改待办等 **write** 要用户点一次卡片。
54
+
55
+ ### 流程
56
+
57
+ ```text
58
+ 1. 机器人调写接口(如 channels.create)
59
+ 2. 返回 SCOPE_DENIED + missingScope
60
+ 3. 机器人 POST claw/agent.scopes.request(说明要哪些 scopes、原因)
61
+ 4. 创建者 myAgent 出现卡片 → 用户点「授权」或「拒绝」
62
+ 5. 授权成功:服务端合并写入 appiaClawAgentScopes
63
+ 6. 机器人 scopes.get 确认,或直接重试原接口
64
+ (全程只有 MCP_JWT,没有 authToken)
65
+ ```
66
+
67
+ 对用户可以说:「请到 Appia 的 myAgent / 我的助手 里点一下授权卡片。」
68
+ 不要说:「请把登录密码/验证码/Token 发给我。」
69
+
70
+ ### 常用 scopes
71
+
72
+ | Scope | 含义 |
73
+ |-------|------|
74
+ | `users:read` | 搜人(默认有) |
75
+ | `channels:read` / `write` | 搜频道 / 建频道 |
76
+ | `todos:read` / `write` | 待办 |
77
+ | `notifications:read` | 通知 |
78
+ | `meetings:read` | 会议纪要 |
79
+ | `overview:read` | 总览元数据 |
80
+ | `files:read` | 文件元数据 |
81
+
82
+ 默认只读:`channels:read`, `todos:read`, `notifications:read`, `meetings:read`, `overview:read`, `files:read`, `users:read`。
83
+
84
+ ### 相关接口
85
+
86
+ | 方法 | 路径 | 作用 |
87
+ |------|------|------|
88
+ | GET | `claw/agent.scopes.get` | 查看当前 scopes |
89
+ | POST | `claw/agent.scopes.request` | 申请开权限(发卡片) |
90
+
91
+ 完整扩展 API 见 [creator-delegate-api.md](creator-delegate-api.md)。
92
+
93
+ ---
94
+
95
+ ## 调用示例
96
+
97
+ ```bash
98
+ # 查已授权 scopes
99
+ curl -H "Authorization: Bearer $MCP_JWT" \
100
+ "$SITE_URL/api/v1/claw/agent.scopes.get?userId=$USER_ID&agentId=$AGENT_ID"
101
+
102
+ # 申请写权限(用户去 myAgent 点授权)
103
+ curl -X POST "$SITE_URL/api/v1/claw/agent.scopes.request" \
104
+ -H "Authorization: Bearer $MCP_JWT" -H "Content-Type: application/json" \
105
+ -d '{"userId":"'"$USER_ID"'","agentId":"'"$AGENT_ID"'","scopes":["channels:write"],"reason":"建群"}'
106
+ ```
107
+
108
+ ---
109
+
110
+ ## 明确不做
111
+
112
+ - 向用户要 authToken / 短信码 / 密码
113
+ - 把授权说成「请用你的账号登录给 Agent」
114
+ - 用创建者 ID 冒充提问者读总览行(行接口本身也未落地)
115
+ - 调用不存在的 `agent.overview.read`