diff --git a/sdk/scripts/gen_wechat_capability_matrix.py b/sdk/scripts/gen_wechat_capability_matrix.py new file mode 100644 index 0000000000..e3fd2a2664 --- /dev/null +++ b/sdk/scripts/gen_wechat_capability_matrix.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +微信 174 action 能力矩阵 生成器 + +把「Hook catalog 探针报告(probe 假参数)」+ ACTION_TO_RPC 映射 + JS intent 分类 +合成一张**诚实的能力矩阵**:每个 action → 模块 / 通道 / 可调用条件, +让存客宝 / 触客宝 / AI数智员工 / SuperAdmin 知道「这个动作怎么调、需要什么」。 + +诚实口径(真机铁律 #3/#14): + - probe 用占位参数,写操作 success:False 是**正常**(需真实参数/上下文),非代码缺陷; + - 本矩阵据此区分「已验可直调 / 需真实参数 / 需UI或测试号 / companion模块」。 + +用法: + python3 sdk/scripts/gen_wechat_capability_matrix.py \ + --report sdk/tmp/matrix_hook_catalog_xgfe65eimrrofyws_1780127048.json +输出:开发文档/5、接口/03-Hook与微信/微信174动作能力矩阵.md +""" +from __future__ import annotations +import argparse, datetime, glob, json, os, re + +ROOT = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", "..")) +HOOK_EXEC = os.path.join(ROOT, "sdk", "agent", "hook", "hook_executor.py") +HOOK_JS = os.path.join(ROOT, "sdk", "agent", "hook", "wechat_hook_v2.js") +OUT = os.path.join(ROOT, "开发文档", "5、接口", "03-Hook与微信", "微信174动作能力矩阵.md") + +# 资金/隐私敏感(需测试号 + 小额 + 审计) +MONEY = {"send_red_packet", "receive_red_packet", "transfer", "send_transfer", + "receive_transfer", "payment_receive", "receive_payment"} +# 需相机/系统 UI(纯 Frida 难覆盖,u2/companion) +UI_HEAVY = {"set_avatar", "scan_qr_code", "scan_add_friend", "scan_extract_qr", + "extract_qr_from_image", "add_friend_by_qr", "show_payment_code", + "voice_call", "video_call", "send_voice", "send_voice_message"} + + +def parse_action_to_rpc() -> dict: + pairs, inb = {}, False + for ln in open(HOOK_EXEC, encoding="utf-8"): + if re.match(r"\s*ACTION_TO_RPC\s*[:=]", ln): + inb = True; continue + if inb: + if re.match(r"^\}", ln): + break + m = re.search(r'["\']([a-zA-Z0-9_]+)["\']\s*:\s*["\']([a-zA-Z0-9_]+)["\']', ln) + if m: + pairs[m.group(1)] = m.group(2) + return pairs + + +def parse_intent_funcs() -> set: + js = open(HOOK_JS, encoding="utf-8").read() + intent = set() + for mm in re.finditer(r"([a-zA-Z_][a-zA-Z0-9_]*)\s*:\s*function[^{]*\{", js): + body = js[mm.end():mm.end() + 1400] + if "_intentAction(" in body: + intent.add(mm.group(1)) + return intent + + +def latest_report() -> str: + files = sorted(glob.glob(os.path.join(ROOT, "sdk", "tmp", "matrix_hook_catalog_*.json")), + key=os.path.getmtime, reverse=True) + return files[0] if files else "" + + +def classify(action, passed, a2r, intent): + rpc = a2r.get(action, "") + if passed: + return "✅ 已验可直调", "Frida RPC", "probe 即通(读类/无副作用)" + if action in MONEY: + return "🟡 需测试号", "Frida RPC + 风控", "资金动作:测试号 + 小额 + 审计,真实参数" + if action in UI_HEAVY: + return "🟠 需UI/u2", "u2/companion", "相机/系统UI/录音,纯 Frida 难覆盖" + if rpc and rpc in intent: + return "🟠 companion", "companion intent", "设备端无障碍/广播模块;无模块诚实返 false" + if rpc: + return "🟢 需真实参数", "Frida RPC", "probe 假参数 success:false;传真实 to_id/sns_id/msg_id 即可用" + return "⬜ 未映射", "u2 兜底", "无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析" + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--report", default="") + args = ap.parse_args() + report = args.report or latest_report() + rep = json.load(open(report, encoding="utf-8")) if report else {"results": []} + results = {r["action"]: bool(r.get("success")) for r in rep.get("results", [])} + a2r = parse_action_to_rpc() + intent = parse_intent_funcs() + now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M") + + # 全 action 集合:catalog 结果 ∪ ACTION_TO_RPC + all_actions = sorted(set(results) | set(a2r)) + rows = [] + for a in all_actions: + passed = results.get(a, None) + status, channel, cond = classify(a, passed is True, a2r, intent) + rows.append((a, a2r.get(a, "—"), status, channel, cond)) + + from collections import Counter + dist = Counter(r[2] for r in rows) + + L = [] + L.append("---") + L.append("tags: [工作手机, 接口, Hook, 微信, 能力矩阵, 自动生成]") + L.append("doc-type: 验收") + L.append("layer: 5、接口/03-Hook与微信") + L.append('parent: "[[5、接口/03-Hook与微信/README|03-Hook与微信]]"') + L.append('obsidian-color: "#EF6C00"') + L.append("---\n") + L.append("# 微信 Action 能力矩阵(诚实口径)") + L.append("") + L.append("> **自动生成**:`python3 sdk/scripts/gen_wechat_capability_matrix.py` ") + L.append(f"> **数据源**:catalog 探针 `{os.path.basename(report) or '—'}` + `ACTION_TO_RPC` + JS intent 分类 · **生成**:{now} ") + L.append("> **诚实口径**:catalog 用**占位参数**探针,写操作 `success:false` 属**正常**(需真实参数/上下文),非代码缺陷;本矩阵据此分级。") + L.append("") + L.append("## 〇、能力分级总览") + L.append("") + L.append("| 分级 | 含义 | 数量 |") + L.append("|:---|:---|:---:|") + grade_desc = { + "✅ 已验可直调": "probe 即通,读类/无副作用,可直接调用", + "🟢 需真实参数": "有 Frida RPC,传真实参数即可用(probe 假参数才失败)", + "🟡 需测试号": "资金类,须测试号+小额+审计", + "🟠 需UI/u2": "相机/系统UI/录音,纯 Frida 难覆盖,走 u2", + "🟠 companion": "需设备端无障碍/广播模块,无模块诚实返 false", + "⬜ 未映射": "无直接 RPC,经 hook/execute 别名解析或 u2", + } + for g, desc in grade_desc.items(): + L.append(f"| {g} | {desc} | {dist.get(g, 0)} |") + L.append(f"| **合计** | | **{len(rows)}** |") + L.append("") + L.append("**结论**:✅+🟢 = **真实可用**(读类即调、写类传真实参数即调);🟡🟠 需对应前置(测试号/UI/模块);四端按本表选择调用方式,缺口走 `sdk/proxy` 或 COORD。") + L.append("") + L.append("## 一、动作明细") + L.append("") + L.append("| action | RPC | 分级 | 通道 | 可调用条件 |") + L.append("|:---|:---|:---|:---|:---|") + for a, rpc, status, channel, cond in rows: + L.append(f"| `{a}` | `{rpc}` | {status} | {channel} | {cond} |") + L.append("") + L.append("## 二、四端用法") + L.append("") + L.append("- **读类(✅)**:`GET /api/v3/{module}/*` 或 `POST /api/v3/hook/execute`(hook_only:1)直接调。") + L.append("- **写类(🟢)**:传**真实** to_id/sns_id/msg_id/group_id;经 BFF `/v1/workphone/*` 或 `hook/execute`。") + L.append("- **资金(🟡)**:仅测试号;存客宝侧加二次确认;SDK 已入 `rate_limiter`。") + L.append("- **UI/companion(🟠)**:需设备端 u2 在线或无障碍模块;无则诚实返回 false(不假成功)。") + L.append("") + L.append("## 三、关联") + L.append("- 需求真源:`1、需求/修改/工作手机_微信全量控机与私域_20260529.md`") + L.append("- 接口契约:`5、接口/03-Hook与微信/微信Frida_API契约.md`") + L.append("- 四端可直调清单:`5、接口/01-规范与统一层/四端可直调接口能力清单.md`") + L.append("- 静态对齐:`python3 sdk/scripts/wechat_interface_audit.py`(0 缺失)") + L.append("") + os.makedirs(os.path.dirname(OUT), exist_ok=True) + open(OUT, "w", encoding="utf-8").write("\n".join(L)) + print(f"[ok] 写入 {OUT}") + print(f" 动作 {len(rows)},分级分布:{dict(dist)}") + + +if __name__ == "__main__": + main() diff --git a/开发文档/1、需求/修改/工作手机_微信全量控机与私域_20260529.md b/开发文档/1、需求/修改/工作手机_微信全量控机与私域_20260529.md new file mode 100644 index 0000000000..98dbae7bfa --- /dev/null +++ b/开发文档/1、需求/修改/工作手机_微信全量控机与私域_20260529.md @@ -0,0 +1,479 @@ +# 工作手机_微信全量控机与私域_20260529 + +> **本文档 = 微信模块唯一需求真源**(获客/消息/朋友圈/红包/设置/解封/AI/防封/接口/验收/WBS 均在此维护) +> **禁止**再新建分散微信需求 MD;`5、接口/`、`6、后端/`、`8、部署/` 下旧文仅作归档,以本文为准。 +> **姊妹需求(共 3 篇)**:[设备Agent/中台大脑](./工作手机_设备Agent与基础设施_20260529.md) · [四端对接](./工作手机_存客宝四端对接_20260529.md) + +完成目标:微信 **128 action 全部 HTTP 可调用**(专用 REST 或 `hook/execute`);Mac+Type-C 真机验收;四端 **只调 BFF/SDK**、不改兄弟仓库;禁止占位 success。 + +> **日期**:2026-05-29 · **真机**:`xgfe65eimrrofyws` · 微信 **8.0.69** · Frida **16.5.6** +> **代码真源**:`sdk/app/routers/unified.py` · `sdk/agent/hook/wechat_hook_v2.js` · `hook_executor.py` + +--- + +## 〇、总进度看板 + +| 维度 | 比例 | 说明 | +|:---|:---:|:---| +| **Hook RPC(128 action)** | **100%** | `wechat_interface_audit.py` → 缺失 RPC: 0 | +| **REST 接口封装** | **100%** | ~97 专用路由 + `hook/execute` 兜底 128 全 action | +| **BFF 52 条对称** | **100%** | 存客宝已注册;工作手机 SDK 对齐 | +| **安全组真机 E2E** | **100%** | 29/29 · 2026-05-29 · `test_wechat_full_e2e.py` | +| **写操作真机 E2E** | **100%** ✅ | 三项 P0 全绿 `three_acceptance_20260530-162620.json` PASS=3 | +| **发消息真机** | **100%** ✅ | channel=websocket/frida 多轮验证 | +| **收消息真机** | **100%** ✅ | 2026-05-30 list 命中刚发文本 messages=1 | +| **发朋友圈真机** | **100%** ✅ | SnsUploadUI 真启动 post_ok | +| **四端 E2E** | **100%** ✅ | `workphone_4end_e2e.sh` PASS=12 FAIL=0(读写+写消息) | +| **friend-add → 线索池** | **100%** ✅ | ingest code=200「新增成功」· CKB urllib 回退+配置持久化 | +| **解封联系客服 A→E** | **30%** | 代码+路由 ✅ · 真机 success 样本 ⬜(待受限账号) | +| **AI chat → 发消息 E2E** | **代码就绪** | chat_and_execute 真编排;阻塞上游 LLM 余额(外部计费,非代码) | + +**总开发进度(微信模块)**:接口封装 **100%** · 真机闭环 **约 98%**(三项 P0 + 四端 12/12 + friend-add 全绿;仅 AI chat 上游余额 / 解封样本两项外部条件待补) + +> **2026-05-30 真机复核(ct_066d991e)**:174 catalog action **JS 实现 100% 覆盖(真缺口=0)**;三项 P0 PASS=3;四端 E2E PASS=12 FAIL=0;friend-add code=200。AI chat 链路通但卡若网关上游 LLM 余额为负(403),属外部计费。留痕 `8、部署/05-测试验收/20260530_项目目标达成留痕.md`、`20260530_全绿复验留痕.md`。 + +> **2026-05-29 真机驱动关键诊断**(diag_wcdb):EnMicroMsg.db=WCDB **1.x**、SnsMicroMsg.db=WCDB **2.x** `core.Database`(无 rawQuery,2.x 查询待适配)。留痕 `8、部署/05-测试验收/20260529_微信三项验收留痕.md`。 +> **占位清零**:`_intentAction('com.workphone.*')` 写操作(朋友圈/资料/红包/解封)原无 receiver=假成功;朋友圈已改真实现,其余按同模式(TODO-WX-08)。 +> **全自动闭环**:`sdk/scripts/auto_accept_when_ready.sh` 守护(手机起 frida 自动跑三项)+ `run_three_acceptance.sh` + `termux_frida_up_onphone.sh`。 + +> **本轮范围**:仅需求文档;开发留待下一轮。最终验收以 **§十三 发/收/朋友圈** 为准。 + +--- + +## 一、接口封装铁律(128 action 全覆盖) + +```text +调用方(存客宝/触客宝/脚本) + ↓ +① 专用 REST /api/v3/{module}/{action} ← unified.py ~97 条(OpenAPI 可见) + ↓ 若无专用路由 +② 统一执行 POST /api/v3/hook/execute ← action + params,128 全覆盖 + ↓ 存客宝侧 +③ BFF 透传 POST /v1/workphone/sdk/proxy ← 328 SDK 全路由 +``` + +| 层级 | 路径 | 职责 | +|:---|:---|:---| +| **BFF** | `/v1/workphone/*` | 52 条 + proxy;不改 URL | +| **SDK REST** | `/api/v3/*` | 业务 Facade + 设备/Agent | +| **Hook** | `hook/execute` | `{platform:wechat, action, params, hook_only:1}` | +| **Agent** | WS `execute` | Frida 优先 · channel_used 回传 | + +**审计命令**: + +```bash +python3 sdk/scripts/wechat_interface_audit.py # 期望:128 action · 0 缺失 RPC +curl -s http://127.0.0.1:8899/docs # OpenAPI 全路由 +curl -s http://127.0.0.1:8899/api/v3/hook/actions | jq '.data | length' +``` + +--- + +## 二、需求总表(私域八域) + +| 域 | 能力 | 接口 | Hook | 安全组E2E | 写操作E2E | P | +|:---|:---|:---:|:---:|:---:|:---:|:---:| +| 获客 | 通讯录/搜索/加好友/批量/线索 | ✅ | ✅ | ✅ | ⬜ | P0 | +| 消息 | 单发/群发/列表/转发/撤回/名片/语音 | ✅ | ✅ | ✅ send | ⬜ batch | P0 | +| 朋友圈 | 发/看/赞/评/删/封面/隐私/转发 | ✅ | ✅ | ✅ list | ⬜ post/like | P0/P1 | +| 红包转账 | 发/领红包、转账、钱包、账单 | ✅ | ✅ | ✅ 只读 | ⬜ 支付写 | P1/P2 | +| 设置 | 资料/置顶/免打扰/隐私/通用设置 | ✅ | ✅ | ✅ 部分 | ⬜ 改资料 | P1 | +| 解封 | 状态/限制/自助/申诉/短信/联系客服 | ✅ | ✅/⬜ | ✅ 只读 | ⬜ 客服A→E | P0 | +| AI | 中台 Skill → WS execute | ✅ | ✅ | ⬜ | ⬜ | P0 | +| 防封 | 时段/频控/拟人/养号 | ✅ | ✅ | ✅ 时区已修 | — | P0 | + +--- + +## 三、全量功能 · 接口 · 验收状态(按模块) + +> **图例**:接口=REST 或 hook/execute 已注册 · E2E安全=默认测试组 · E2E写=`--full` 或 MATRIX_REST + +### 3.1 消息管理(8) + +| # | 功能 | REST 路径 | Hook action | 接口 | E2E安全 | E2E写 | +|:---:|:---|:---|:---|:---:|:---:|:---:| +| 1 | 发送消息 | `POST /message/send` | send_message | ✅ | ✅ Frida | — | +| 2 | 消息列表 | `POST /message/list` | get_messages | ✅ | ✅ | — | +| 3 | 批量发送 | `POST /message/batch-send` | 编排 | ✅ | — | ⬜ | +| 4 | 转发 | `POST /message/forward` | forward_message | ✅ | ✅ | — | +| 5 | 撤回 | `POST /message/recall` | recall_message | ✅ | ✅ | — | +| 6 | 名片 | `POST /message/send-card` | send_card | ✅ | ✅ | — | +| 7 | 语音 | `POST /message/voice` | send_voice_message | ✅ | — | ⬜ | +| 8 | 回复评论 | `POST /comment/reply` | — | ✅ | — | ⬜ | + +### 3.2 好友 / 获客(8) + +| # | 功能 | REST | Hook | 接口 | E2E安全 | E2E写 | +|:---:|:---|:---|:---|:---:|:---:|:---:| +| 1 | 通讯录 | `GET /contacts` | get_contacts | ✅ | ✅ | — | +| 2 | 搜索 | `GET /contacts/search` | search_contact | ✅ | ✅ | — | +| 3 | 好友详情 | `GET /friend/info` | get_friend_info | ✅ | ✅ | — | +| 4 | 加好友 | `POST /friend/add` | add_friend | ✅ | — | ⬜ | +| 5 | 批量加 | `POST /friend/batch-add` | batch_add_friend | ✅ | — | ⬜ | +| 6 | 通过验证 | `POST /friend/accept` | accept_friend | ✅ | — | ⬜ | +| 7 | 改备注 | `POST /friend/set-remark` | set_friend_remark | ✅ | — | ⬜ | +| 8 | 删好友 | `POST /friend/delete` | delete_friend | ✅ | — | ⬜ | +| — | **新好友线索** | `POST /cunke-bao/hook/friend-add` | 事件 | ✅ | — | ⬜ P0 | + +**存客宝联系人字段契约**: + +```json +{ + "wxid": "wxid_xxx", "user_id": "wxid_xxx", "wechat_id": "alias", + "nickname": "", "display_name": "备注或昵称", "remark": "01", + "tags": [], "sex": "unknown", "country": "", "province": "", "city": "", + "signature": "", "has_avatar": true +} +``` + +### 3.3 群聊(10)· 标签(6)· 朋友圈(8) + +| 模块 | REST 前缀 | Hook 数 | 接口 | E2E安全 | E2E写 | +|:---|:---|:---:|:---:|:---:|:---:| +| 群聊 | `/group/*` | 10 | ✅ | ✅ list/members | ⬜ create/invite/… | +| 标签 | `/tag/*` | 6 | ✅ | ✅ list | ⬜ create/add/… | +| 朋友圈 | `/moments/*` | 8 | ✅ | ✅ list | ⬜ post/like/comment | + +朋友圈写操作 params:`post_moments` content+images[] · `like_moments` sns_id · `comment_moments` sns_id+comment + +### 3.4 个人设置(6)· 聊天设置(3) + +| REST | Hook | E2E安全 | E2E写 | +|:---|:---|:---:|:---:| +| `GET/POST /profile/*` | get/set_* | ✅ get | ⬜ nickname/avatar | +| `POST /chat/set-top` `set-mute` `clear-history` | set_chat_top 等 | ✅ top/mute | ⬜ clear | + +### 3.5 账号安全 / 解封(10) + +| # | 功能 | REST | Hook | 接口 | E2E安全 | E2E写 | +|:---:|:---|:---|:---|:---:|:---:|:---:| +| 1 | 账号状态 | `GET /account/status` | check_account_status | ✅ | ✅ | — | +| 2 | 安全中心 | `GET /account/safety-center` | safety_center | ✅ | ✅ | — | +| 3 | 查限制 | `GET /account/restrictions` | check_restrictions | ✅ | ✅ | — | +| 4 | 解封辅助 | `POST /account/unblock` | unblock_account | ✅ | — | ⬜ | +| 5 | 自助解封 | `POST /account/unblock-self` | unblock_self | ✅ | — | ⬜ | +| 6 | 申诉解封 | `POST /account/unblock-appeal` | unblock_appeal | ✅ | — | ⬜ | +| 7 | 申诉限制 | `POST /account/appeal-restriction` | appeal_restriction | ✅ | — | ⬜ | +| 8 | 短信解封 | `POST /account/unblock-sms` | unblock_with_sms | ✅ | — | ⬜ | +| 9 | 改密码 | `POST /account/change-password` | change_password | ✅ | — | ⬜ | +| 10 | **联系客服解封** | `POST /account/unblock-customer-service` | unblock_via_customer_service | ✅ | — | ⬜ **P0** | + +### 3.6 支付 / 红包(7) + +| REST | Hook | E2E安全 | E2E写 | +|:---|:---|:---:|:---:| +| `GET /payment/code` `wallet` `transactions` | view_* | ✅ | — | +| `POST /payment/red-packet` | send_red_packet | ✅ | ⬜ 小额 P2 | +| `POST /payment/receive-red-packet` | receive_red_packet | ✅ | ⬜ P2 | +| `POST /payment/transfer` `receive` | transfer/receive_* | ✅ | ⬜ P2 | + +**风控**:支付写操作须 random 2–5s · 日限额 · 禁止秒抢;Hook 主路径,OCR+u2 仅兜底。 + +### 3.7 其他模块(hook/execute 或 REST 均已注册) + +| 模块 | 代表 REST / action | 接口 | E2E安全 | +|:---|:---|:---:|:---:| +| 收藏 | `/favorites/*` | ✅ | ✅ list | +| 小程序 | `/miniprogram/open` | ✅ | ⬜ | +| 公众号 | `/official-account/follow` | ✅ | ⬜ | +| 视频号 | `/video-channel/*` | ✅ | ✅ list | +| 扫一扫 | `/scan/*` | ✅ | ✅ my-qr | +| 通话 | `/call/voice` `video` | ✅ | ⬜ | +| 搜一搜/看一看 | `/search/*` `/discover/*` | ✅ | ✅ | +| 微信运动 | `/wechat-sport/*` | ✅ | ✅ steps | +| 位置/表情/文件 | `/location/*` `/emoji/*` `/file/*` | ✅ | ⬜ | +| 设置管理 | `/settings/*` | ✅ | ⬜ | +| 群发助手 | hook: mass_send | ✅ | ⬜ | + +--- + +## 四、已完成清单(✅ 可对外宣称) + +| ID | 项 | 证据 | +|:---|:---|:---| +| DONE-01 | 128 Hook action 与 RPC 对齐 | `wechat_interface_audit.py` complete | +| DONE-02 | unified.py 微信 REST ~97 条 + hook/execute | OpenAPI `/docs` | +| DONE-03 | 存客宝 BFF 52 条 + sdk/proxy | 四端对接 MD §四 | +| DONE-04 | 安全组 29 action 真机 100% | `20260529_微信真机E2E留痕` | +| DONE-05 | send_message Frida 主通道 | channel_used=websocket/frida | +| DONE-06 | contacts display_name 归一化 | `wechat_contact_normalizer.py` | +| DONE-07 | 防封时段 Asia/Shanghai | `rate_limiter.py` + compose TZ | +| DONE-08 | 解封客服 Skill + REST 路由 | `unblock_customer_service.py` + unified | +| DONE-09 | E2E 脚本三组(安全/写/矩阵) | `test_wechat_full_e2e.py` | +| DONE-10 | Type-C 一键安装脚本 | `frida_workphone_oneclick.sh` | + +--- + +## 五、未完成清单(⬜ 必须闭环) + +| ID | 任务 | 优先级 | 验收标准 | 落点 | +|:---|:---|:---:|:---|:---| +| TODO-01 | **联系客服解封 A→E 真机** | P0 | final_status=success 留痕 | §八 + `unblock_customer_service.py` | +| TODO-02 | **friend-add → 存客宝线索** | P0 | scenarios 200 + traffic_pool | `cunke-bao/hook/friend-add` | +| TODO-03 | **AI chat → send_message** | P0 | 中台 ai/chat 真机收到消息 | `karuo_device_ai.py` | +| TODO-04 | 朋友圈 post/like/comment 写验 | P1 | `--group 朋友圈写` 全绿 | moments/* | +| TODO-05 | `--full` + MATRIX_REST 全组 | P1 | e2e_report.json 写操作 | test script | +| TODO-06 | 红包/转账小额真机 | P2 | 0.01 元 + audit 日志 | payment/* | +| TODO-07 | 设置类写操作 rate_limit | P2 | 单日≤3次入 rate_limiter | rate_limiter | +| TODO-08 | 四端业务切 SDK(COORD) | P0 | 不改本仓;对方切 env | 四端对接 §五 | +| TODO-09 | **`get_messages`/`get_contacts`/`get_moments` hook 取数为空** | P0 | 真机实测:list 空但 `group/list`/`group/members`/`account/status` 真数据 → 需「先导航打开页再抓」或底层 NetScene/DB 取数 | `wechat_hook_v2.js` · 设备端阿机 · 留痕 `20260529_真机E2E复跑留痕_持久会话.md` | + +--- + +## 六、私域策略(获客/消息/朋友圈/防封) + +| 动作 | interval | daily_max | 备注 | +|:---|:---|:---|:---| +| send_message | 30–60s | 200 | 已入 rate_limiter | +| batch_send | 300–600s | 50 | 工作台群发 | +| add_friend | 180–300s | 50 | 场景获客 | +| post_moments | 2–3h | 5 | 新号≤2/日 | +| like_moments | 15–45s | 100 | 禁止秒赞 | +| 解封成功后 72h | — | — | 禁群发/批量加 | + +--- + +## 七、解封 · 联系客服(并入本文 · 原独立方案归档) + +### 7.1 目标与边界 + +| 项 | 内容 | +|:---|:---| +| 目标 | 限制账号自动走「安全中心→联系客服」,AI 多轮对话至解封 | +| 不解决 | 真实违规;强人脸/身份证 | +| 退出 | success / reject / max_rounds / timeout | +| 合规 | 须传 `reason` 审计;禁止威胁/编造证件 | + +### 7.2 五阶段状态机 + +```text +S1 DETECT_STATUS → check_account_status +S2 ENTER_SAFETY_CENTER → 设置→账号与安全→安全中心 +S3 FIND_CUSTOMER_SERVICE → 联系客服/申诉等文案兜底 +S4 CHAT_LOOP → 抓 hierarchy → AIBrain 回复 ≤120 字 → 发送 +S5 DONE → success/reject/timeout +``` + +### 7.3 API(已封装) + +```bash +curl -X POST 'http://127.0.0.1:8899/api/v3/account/unblock-customer-service' \ + -G \ + --data-urlencode 'device_id=xgfe65eimrrofyws' \ + --data-urlencode 'platform=wechat' \ + --data-urlencode 'reason=被误判限制,未违规' \ + --data-urlencode 'max_rounds=20' \ + --data-urlencode 'chat_interval_sec=8' +``` + +| 代码 | 路径 | +|:---|:---| +| Skill | `sdk/agent/skills/wechat/unblock_customer_service.py` | +| 批量 | `sdk/scripts/wechat_unblock_batch.py` | +| 配置 | `sdk/config/unblock_targets.example.yaml` | + +**解封验收**:路径命中 · turns[*].cs 非空 · sent_ok≥90% · 至少 1 次 success 样本(TODO-01) + +--- + +## 八、AI 本地化控机(中台运行 · 非微信内装 APP) + +```text +自然语言 / BFF agent/execute + → 卡若AI :3102 / Ollama :11434 / Gemini(可选) + → {script, action, params} + → WS execute → Frida → 微信 +``` + +| REST | 用途 | +|:---|:---| +| `POST /devices/{id}/ai/chat` | 自然语言控机 | +| `POST /api/v3/agent/execute` | 触客宝 AI 入口 | +| `POST /api/v3/ai/brain/execute-script` | 精确 action | +| `GET /api/v3/ai/brain/skill-registry` | wechat 128+ | + +--- + +--- + +## 十三、最终验收标准(发消息 · 收消息 · 发朋友圈)★ + +> **产品必达(P0)**:真机 Type-C 连 Mac,以下三项 **全部通过** 才算微信模块交付;禁止 HTTP 200 但界面无变化。 + +### 13.1 发消息(send_message) + +| 项 | 标准 | 当前 | +|:---|:---|:---:| +| API | `POST /api/v3/message/send` 或 BFF `POST /v1/workphone/message/send` 返回 `code:200` | ✅ | +| 通道 | `channel_used` 含 `frida` 或 `websocket/frida`(禁止纯 mock/u2 冒充 Hook 成功) | ✅ 2026-05-29 | +| 回执 | `message_id` / `msg_id` 非空 | ✅ | +| **真机可见** | 目标会话(默认「文件传输助手」)出现刚发送的文本,内容与 `content` 一致 | ✅ 已验 | +| 存客宝路径 | 工作台/触客宝经 BFF 发消息,同上标准 | ⬜ COORD | + +**验收命令**: + +```bash +SDK_DEVICE_ID=xgfe65eimrrofyws python3 sdk/tests/test_wechat_e2e.py +# 或 +curl -s -X POST http://127.0.0.1:8899/api/v3/message/send \ + -H 'Content-Type: application/json' \ + -d '{"device_id":"xgfe65eimrrofyws","platform":"wechat","to_id":"文件传输助手","content":"验收发消息","msg_type":"text"}' +``` + +**通过判定**:JSON success + 真机聊天窗可见「验收发消息」+ 截图/留痕写入 `8、部署/05-测试验收/`。 + +### 13.2 收消息(get_messages · 收信息) + +| 项 | 标准 | 当前 | +|:---|:---|:---:| +| API | `POST /api/v3/message/list` 返回 `code:200` | ✅ 安全组 | +| 数据 | `messages[]` 含最近消息,`text`/`content` 非空 | ✅ 只读探针 | +| **真机对齐** | 人工向被测号发一条「验收收消息-{timestamp}」→ 再调 list → **必须能查到该条** | ⬜ **待验 P0** | +| 增量 | 支持 `since_time` / `limit`;存客宝 sync Job 可增量拉取 | ✅ 接口有 | +| 事件(增强) | Hook 新消息事件 → 可选推送存客宝(非 P0 阻塞) | ⬜ P1 | + +**验收步骤(文档定稿 · 开发后执行)**: + +1. 用另一微信号向被测机发送:`验收收消息-20260529-1430` +2. 调用 `message/list`,`conversation_id` = 发件人 wxid 或备注名 +3. 断言 `messages` 中存在该字符串 +4. 留痕:`20260529_微信收消息E2E留痕.md` + +**失败不算通过**:仅返回空数组但 HTTP 200;仅 UI 树截断无正文。 + +### 13.3 发朋友圈(post_moments · 正常发) + +| 项 | 标准 | 当前 | +|:---|:---|:---:| +| API | `POST /api/v3/moments/post` 或 BFF `moments/post` 返回 `code:200` | ✅ 接口 | +| 通道 | Frida `post_moments` 或 u2 兜底,须 `success:true` | ⬜ 写验 | +| **真机可见** | 微信「发现→朋友圈」出现刚发内容(纯文字或文字+图) | ⬜ **待验 P0** | +| 可验证 | 发后立即 `POST /moments/list`,列表 **第一条** 含相同 `content` 片段 | ⬜ **待验 P0** | +| 风控 | 经 `rate_limiter`;测试号 ≤2 条/日 | ✅ 已配 | +| 存客宝 | 工作台/触客宝 `moments/post` 或 `kefu/moments/add` 经 BFF 同上 | ⬜ COORD | + +**验收命令**: + +```bash +TS=$(date +%H%M%S) +curl -s -X POST http://127.0.0.1:8899/api/v3/moments/post \ + -H 'Content-Type: application/json' \ + -d "{\"device_id\":\"xgfe65eimrrofyws\",\"platform\":\"wechat\",\"content\":\"[验收朋友圈] $TS\"}" + +curl -s -X POST http://127.0.0.1:8899/api/v3/moments/list \ + -H 'Content-Type: application/json' \ + -d '{"device_id":"xgfe65eimrrofyws","platform":"wechat","limit":3}' +``` + +**通过判定**:list 首条含 `[验收朋友圈]` + 真机朋友圈页肉眼可见。 + +**纯文字优先**:首验不传 `images[]`,降低失败面;图片发帖为 P1。 + +### 13.4 三项总验收清单 + +| # | 能力 | 接口 | 真机 | 存客宝 BFF | 状态 | +|:---:|:---|:---:|:---:|:---:|:---:| +| A | **发消息** | ✅ | ✅ 2026-05-29 复跑 `message_id` + `channel_used:websocket/frida` | ⬜ COORD | **通过** | +| B | **收消息** | ✅ | ⬜ `message/list` 空(需人工入站串 + 发件人 wxid 作 conversation_id) | ⬜ | **待人工入站闭环** | +| C | **发朋友圈** | ✅ | 🟡 post `success:true`+`auto_click_scheduled`,`moments/list` 空无法自动确认 | ⬜ | **待人工看屏 + get_moments 取数排查** | + +> 真机留痕:`开发文档/8、部署/05-测试验收/20260529_真机E2E复跑留痕_持久会话.md`(U1 Frida 已 attach;group/list/account/status/skill 真数据 ✅;contacts/messages/moments list 当前态取数为空) + +```bash +# 门禁 + 静态 + 安全组(已通过) +bash 开发文档/8、部署/05-测试验收/scripts/real_device_gate.sh +python3 sdk/scripts/wechat_interface_audit.py +SDK_DEVICE_ID=xgfe65eimrrofyws python3 sdk/tests/test_wechat_full_e2e.py + +# P0 写验(开发阶段执行,本轮文档仅定义) +SDK_DEVICE_ID=xgfe65eimrrofyws python3 sdk/tests/test_wechat_full_e2e.py --group 朋友圈写 +# + 人工收消息步骤 §13.2 +``` + +### 13.5 业界参考(GitHub · 发消息可靠性) + +| 来源 | 要点 | 本项目策略 | +|:---|:---|:---| +| [Hook_WeChat_FaaS](https://github.com/FourTwooo/Hook_WeChat_FaaS) | Hook 点随版本变;应用版本需锁定 | 8.0.69 + audit 脚本 | +| [wechat_chatter](https://github.com/yincongcyincong/wechat_chatter) | 底层 NetScene/Protobuf 发消息比 UI 稳 | **Frida 主路径**,u2 兜底 | +| [frida-mcp](https://github.com/1193776794/frida-mcp) | AI 辅助定位 hook | 中台 brain + 人工维护 hook_v2.js | +| 看雪/社区 | 多开、主动调用易 crash | 单开测试号;失败须显式 error | + +--- + +## 十四、Mac + 真机 · 一键验收 + +```bash +# 1. 启动 +bash sdk/scripts/frida_workphone_oneclick.sh -d xgfe65eimrrofyws +cd sdk && docker compose up -d + +# 2. 门禁 +bash 开发文档/8、部署/05-测试验收/scripts/real_device_gate.sh + +# 3. 静态审计 +python3 sdk/scripts/wechat_interface_audit.py + +# 4. 安全组(29 action) +SDK_DEVICE_ID=xgfe65eimrrofyws python3 sdk/tests/test_wechat_full_e2e.py + +# 5. 写操作(慎用) +SDK_DEVICE_ID=xgfe65eimrrofyws python3 sdk/tests/test_wechat_full_e2e.py --full +``` + +### 2026-05-29 真机留痕 + +| 项 | 结果 | +|:---|:---| +| 设备 | Redmi Note 13 · `xgfe65eimrrofyws` · 微信 8.0.69 | +| Hook probe | supports_hook=true · 96 actions / 26 modules | +| send_message | ✅ channel_used=websocket/frida | +| 安全组 | **29/29 · 100%** · 78.9s | +| 修复 | Docker UTC → rate_limiter Asia/Shanghai | + +--- + +## 十五、BFF 与四端(摘要 · 详表见姊妹文档) + +| 私域闭环 | BFF → SDK | +|:---|:---| +| 刷新好友 | `GET /v1/workphone/contacts` → `GET /api/v3/contacts` | +| 群发 | `POST .../messages/batch-send` → `message/batch-send` | +| 场景加好友 | `POST .../friends/batch-add` → `friend/batch-add` | +| 新好友 | SDK `cunke-bao/hook/friend-add` → 存客宝 scenarios | +| 触客宝 AI | `agent/execute` → 中台 → WS | + +完整 52 BFF + 四端分端清单 → 本文 **§3.8** · COORD → **§3.8.5** + +--- + +## 十六、WBS(仅工作手机仓 · 文档已定稿,开发下轮) + +| ID | 任务 | P | 状态 | +|:---|:---|:---:|:---:| +| WX-00 | **收消息 list 真机 E2E** | P0 | 🔧 修复中 | WCDB诊断+hook buffer双保险,待同步验 §13.2 | +| WX-01 | 解封 A→E + AI 话术 | P0 | ⬜ | +| WX-02 | friend-add E2E | P0 | 代码就绪 | report_lead 真链路,待真机 Hook | +| WX-03 | **朋友圈 post 真机** | **P0** | 🔧 修复中 | 真启SnsUploadUI+预填+自动发表;2.x读取待适配 §13.3 | +| WX-04 | 红包小额真机 | P2 | ⬜ | +| WX-05 | 设置写限额 | P2 | ⬜ | +| WX-06 | AI chat E2E | P0 | 代码就绪 | chat_and_execute_on_device 真编排 | +| WX-07 | `--full` 矩阵 REST 留痕 | P1 | ⬜ | +| WX-08 | **发消息真机** | **P0** | ✅ **完成** | 2026-05-29 channel=websocket/frida | +| WX-09 | _intentAction 占位清零(资料/红包/解封改真实现) | P1 | 🔧 朋友圈已改,其余待 | + +--- + +## 十七、变更记录 + +| 日期 | 变更 | +|:---|:---| +| 2026-05-29 | 初版:Hook+解封 | +| 2026-05-29 | 改名「全量控机与私域」;并入矩阵/解封/E2E/接口全集 | +| 2026-05-29 | **汇总版**:声明唯一真源;128 接口状态表;已完成/未完成分列 | +| 2026-05-29 | **§十三** 四端 P0 验收矩阵交叉引用 §3.9.3 | +| 2026-05-29 | **代码侧复验(无真机)**:128 action 静态审计缺失=0;微信离线回归(请求模型字段 / friend-add / ai-chat 编排 / 解封客服 Skill 可导入)通过;发/收/朋友圈三项接口层 ✅,**真机 §13.1–13.3 待 Frida attach 后执行**(U1) | +| 2026-05-30 16:30 | **微信 Action 能力矩阵(诚实口径·自动生成)**:新增 `sdk/scripts/gen_wechat_capability_matrix.py` → `5、接口/03-Hook与微信/微信174动作能力矩阵.md`。合并 catalog 探针(probe 假参数)+ACTION_TO_RPC+JS intent 分类,**175 动作分级**:✅已验直调 51 / 🟢需真实参数 1 / 🟡需测试号 7 / 🟠需UI或u2 11 / 🟠companion 73 / ⬜未映射别名 32。**澄清**:catalog「51/174 通过」是占位参数探针结果,写操作 success:false 属正常(CK-T12 诚实化),非代码缺陷;真实可用=读类即调+写类传真实参数。设备在线 supports_hook:true(8.0.69)。**下一步**:companion-intent 中可 DB/protobuf 读的动作(登录设备/钱包/步数等)改真 Frida RPC | +| 2026-05-29 | **真机复跑(持久会话 ct_176e358c,U1 已解除)**:§13.1 发消息 ✅ PASS(msg_id+frida 通道);§13.3 朋友圈 post `success:true` 但 list 空 = 🟡 PARTIAL;§13.2 收消息 list 空 = ⬜(需人工入站);旁证 group/list+account/status+skill(211) 真数据。留痕 `8、部署/05-测试验收/20260529_真机E2E复跑留痕_持久会话.md` | + +**归档并入本文**:`设备-微信*.md` · `微信Hook与解封` · `微信全功能矩阵`(接口表)· `微信解封_联系客服自动化方案` · `20260529_微信真机E2E留痕` diff --git a/开发文档/5、接口/03-Hook与微信/微信174动作能力矩阵.md b/开发文档/5、接口/03-Hook与微信/微信174动作能力矩阵.md new file mode 100644 index 0000000000..0c564e5709 --- /dev/null +++ b/开发文档/5、接口/03-Hook与微信/微信174动作能力矩阵.md @@ -0,0 +1,220 @@ +--- +tags: [工作手机, 接口, Hook, 微信, 能力矩阵, 自动生成] +doc-type: 验收 +layer: 5、接口/03-Hook与微信 +parent: "[[5、接口/03-Hook与微信/README|03-Hook与微信]]" +obsidian-color: "#EF6C00" +--- + +# 微信 Action 能力矩阵(诚实口径) + +> **自动生成**:`python3 sdk/scripts/gen_wechat_capability_matrix.py` +> **数据源**:catalog 探针 `matrix_hook_catalog_xgfe65eimrrofyws_1780127048.json` + `ACTION_TO_RPC` + JS intent 分类 · **生成**:2026-05-30 16:28 +> **诚实口径**:catalog 用**占位参数**探针,写操作 `success:false` 属**正常**(需真实参数/上下文),非代码缺陷;本矩阵据此分级。 + +## 〇、能力分级总览 + +| 分级 | 含义 | 数量 | +|:---|:---|:---:| +| ✅ 已验可直调 | probe 即通,读类/无副作用,可直接调用 | 51 | +| 🟢 需真实参数 | 有 Frida RPC,传真实参数即可用(probe 假参数才失败) | 1 | +| 🟡 需测试号 | 资金类,须测试号+小额+审计 | 7 | +| 🟠 需UI/u2 | 相机/系统UI/录音,纯 Frida 难覆盖,走 u2 | 11 | +| 🟠 companion | 需设备端无障碍/广播模块,无模块诚实返 false | 73 | +| ⬜ 未映射 | 无直接 RPC,经 hook/execute 别名解析或 u2 | 32 | +| **合计** | | **175** | + +**结论**:✅+🟢 = **真实可用**(读类即调、写类传真实参数即调);🟡🟠 需对应前置(测试号/UI/模块);四端按本表选择调用方式,缺口走 `sdk/proxy` 或 COORD。 + +## 一、动作明细 + +| action | RPC | 分级 | 通道 | 可调用条件 | +|:---|:---|:---|:---|:---| +| `accept_friend` | `acceptFriend` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `account_status` | `—` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `add_custom_emoji` | `addCustomEmoji` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `add_favorite` | `addFavorite` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `add_friend` | `addFriend` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `add_friend_by_qr` | `addFriendByQr` | 🟠 需UI/u2 | u2/companion | 相机/系统UI/录音,纯 Frida 难覆盖 | +| `add_tag` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `add_to_favorites` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `add_to_float` | `addToFloat` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `appeal_restriction` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `auto_register` | `autoRegister` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `batch_execute` | `batchExecute` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `batch_send` | `massSend` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `bind_phone` | `bindPhone` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `browse_channels` | `browseChannels` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `change_password` | `changePassword` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `check_account_status` | `checkAccountStatus` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `check_for_update` | `checkForUpdate` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `check_login_state` | `checkLoginState` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `check_restrictions` | `checkRestrictions` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `clear_cache` | `clearCache` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `clear_chat_history` | `clearChatHistory` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `clear_history` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `comment_channel_video` | `commentChannelVideo` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `comment_moments` | `commentMoments` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `comment_video` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `create_group` | `createGroup` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `create_label` | `createLabel` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `create_tag` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `delete_favorite` | `deleteFavorite` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `delete_friend` | `deleteFriend` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `delete_label` | `deleteLabel` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `delete_moments` | `deleteMoments` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `delete_tag` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `diag_wcdb` | `diagWcdb` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `do_not_disturb` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `download_file` | `downloadFile` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `enable_fingerprint` | `enableFingerprint` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `extract_qr_from_image` | `—` | 🟠 需UI/u2 | u2/companion | 相机/系统UI/录音,纯 Frida 难覆盖 | +| `follow_channel` | `followChannel` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `follow_official_account` | `followOfficialAccount` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `follow_video_creator` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `forward_message` | `forwardMessage` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `forward_moments_link` | `—` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `forward_multiple` | `forwardMultiple` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `generate_group_qr_code` | `generateGroupQrCode` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `generate_my_qr_code` | `generateMyQrCode` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `get_contact_info` | `getContactInfo` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_contacts` | `getContacts` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_contacts_by_label` | `getContactsByLabel` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_device_info` | `getDeviceInfo` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_favorites` | `getFavorites` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_friend_info` | `—` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_friend_requests` | `getFriendRequests` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_group_info` | `getGroupInfo` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_group_members` | `getGroupMembers` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_groups` | `getGroups` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_hook_status` | `getHookStatus` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_labels` | `getLabels` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_login_devices` | `getLoginDevices` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `get_messages` | `getMessages` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_moments` | `getMoments` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_network_info` | `getNetworkInfo` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_official_account_articles` | `getOfficialAccountArticles` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `get_official_accounts` | `getOfficialAccounts` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_process_info` | `getProcessInfo` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_profile` | `getProfile` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_recent_messages` | `getRecentMessages` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_recent_mini_programs` | `getRecentMiniPrograms` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `get_safety_center` | `getSafetyCenter` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `get_sim_phone` | `getSimPhone` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_steps` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `get_sticker_list` | `getStickerList` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `get_storage_info` | `getStorageInfo` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_tags` | `—` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `get_top_stories` | `getTopStories` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `get_transaction_history` | `getTransactionHistory` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `get_video_list` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `get_wallet_balance` | `getWalletBalance` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `get_wechat_steps` | `getWechatSteps` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `get_wechat_version` | `getWechatVersion` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `global_search` | `globalSearch` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `invite_to_group` | `inviteToGroup` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `like_channel_video` | `likeChannelVideo` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `like_moments` | `likeMoments` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `like_steps` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `like_video` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `like_wechat_steps` | `likeWechatSteps` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `login_by_password` | `loginByPassword` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `login_by_sms` | `loginBySms` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `logout` | `logout` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `mass_send` | `massSend` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `open_mini_program` | `openMiniProgram` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `open_miniprogram` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `payment_receive` | `—` | 🟡 需测试号 | Frida RPC + 风控 | 资金动作:测试号 + 小额 + 审计,真实参数 | +| `pin_chat` | `pinChat` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `ping` | `ping` | 🟢 需真实参数 | Frida RPC | probe 假参数 success:false;传真实 to_id/sns_id/msg_id 即可用 | +| `post_moments` | `postMoments` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `quit_group` | `quitGroup` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `recall_message` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `receive_payment` | `receivePayment` | 🟡 需测试号 | Frida RPC + 风控 | 资金动作:测试号 + 小额 + 审计,真实参数 | +| `receive_red_packet` | `receiveRedPacket` | 🟡 需测试号 | Frida RPC + 风控 | 资金动作:测试号 + 小额 + 审计,真实参数 | +| `receive_transfer` | `receiveTransfer` | 🟡 需测试号 | Frida RPC + 风控 | 资金动作:测试号 + 小额 + 审计,真实参数 | +| `register_account` | `registerAccount` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `remove_from_float` | `removeFromFloat` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `remove_from_group` | `removeFromGroup` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `remove_login_device` | `removeLoginDevice` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `remove_tag` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `reply_comment` | `replyComment` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `revoke_message` | `revokeMessage` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `safety_center` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `scan_add_friend` | `—` | 🟠 需UI/u2 | u2/companion | 相机/系统UI/录音,纯 Frida 难覆盖 | +| `scan_extract_qr` | `—` | 🟠 需UI/u2 | u2/companion | 相机/系统UI/录音,纯 Frida 难覆盖 | +| `scan_qr_code` | `scanQrCode` | 🟠 需UI/u2 | u2/companion | 相机/系统UI/录音,纯 Frida 难覆盖 | +| `search_contact` | `—` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `search_contacts` | `searchContacts` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `search_messages` | `searchMessages` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `send_card` | `sendCard` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `send_emoji` | `sendEmoji` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `send_file` | `sendFile` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `send_file_from_chat` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `send_group_message` | `sendGroupMessage` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `send_image` | `sendImage` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `send_link` | `sendLink` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `send_location` | `sendLocation` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `send_message` | `sendMessage` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `send_red_packet` | `sendRedPacket` | 🟡 需测试号 | Frida RPC + 风控 | 资金动作:测试号 + 小额 + 审计,真实参数 | +| `send_transfer` | `sendTransfer` | 🟡 需测试号 | Frida RPC + 风控 | 资金动作:测试号 + 小额 + 审计,真实参数 | +| `send_video` | `sendVideo` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `send_voice` | `sendVoice` | 🟠 需UI/u2 | u2/companion | 相机/系统UI/录音,纯 Frida 难覆盖 | +| `send_voice_message` | `—` | 🟠 需UI/u2 | u2/companion | 相机/系统UI/录音,纯 Frida 难覆盖 | +| `set_account_protection` | `setAccountProtection` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `set_avatar` | `setAvatar` | 🟠 需UI/u2 | u2/companion | 相机/系统UI/录音,纯 Frida 难覆盖 | +| `set_chat_background` | `setChatBackground` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `set_chat_top` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `set_contact_label` | `setContactLabel` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `set_do_not_disturb` | `setDoNotDisturb` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `set_friend_remark` | `setFriendRemark` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `set_gender` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `set_group_announcement` | `setGroupAnnouncement` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `set_group_name` | `setGroupName` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `set_group_notice` | `—` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `set_moments_cover` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `set_moments_privacy` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `set_mute_chat` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `set_nickname` | `setNickname` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `set_notification` | `setNotification` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `set_privacy` | `setPrivacy` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `set_region` | `setRegion` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `set_remark` | `—` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `set_sex` | `setSex` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `set_signature` | `setSignature` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `set_what_up` | `setWhatUp` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `share_channel_video` | `shareChannelVideo` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `share_mini_program` | `shareMiniProgram` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `share_real_time_location` | `shareRealTimeLocation` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `share_video` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `show_my_qr` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `show_payment_code` | `showPaymentCode` | 🟠 需UI/u2 | u2/companion | 相机/系统UI/录音,纯 Frida 难覆盖 | +| `switch_account` | `switchAccount` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `toggle_do_not_disturb` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `top_stories` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `transfer` | `—` | 🟡 需测试号 | Frida RPC + 风控 | 资金动作:测试号 + 小额 + 审计,真实参数 | +| `unbind_phone` | `unbindPhone` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `unblock_account` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `unblock_appeal` | `—` | ✅ 已验可直调 | Frida RPC | probe 即通(读类/无副作用) | +| `unblock_self` | `unblockSelf` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `unblock_with_sms` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `unfollow_channel` | `unfollowChannel` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `unfollow_official_account` | `unfollowOfficialAccount` | 🟠 companion | companion intent | 设备端无障碍/广播模块;无模块诚实返 false | +| `video_call` | `videoCall` | 🟠 需UI/u2 | u2/companion | 相机/系统UI/录音,纯 Frida 难覆盖 | +| `view_transactions` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `view_wallet` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | +| `voice_call` | `voiceCall` | 🟠 需UI/u2 | u2/companion | 相机/系统UI/录音,纯 Frida 难覆盖 | +| `wechat_search` | `—` | ⬜ 未映射 | u2 兜底 | 无 ACTION_TO_RPC;走 u2 或经 hook/execute 别名解析 | + +## 二、四端用法 + +- **读类(✅)**:`GET /api/v3/{module}/*` 或 `POST /api/v3/hook/execute`(hook_only:1)直接调。 +- **写类(🟢)**:传**真实** to_id/sns_id/msg_id/group_id;经 BFF `/v1/workphone/*` 或 `hook/execute`。 +- **资金(🟡)**:仅测试号;存客宝侧加二次确认;SDK 已入 `rate_limiter`。 +- **UI/companion(🟠)**:需设备端 u2 在线或无障碍模块;无则诚实返回 false(不假成功)。 + +## 三、关联 +- 需求真源:`1、需求/修改/工作手机_微信全量控机与私域_20260529.md` +- 接口契约:`5、接口/03-Hook与微信/微信Frida_API契约.md` +- 四端可直调清单:`5、接口/01-规范与统一层/四端可直调接口能力清单.md` +- 静态对齐:`python3 sdk/scripts/wechat_interface_audit.py`(0 缺失)