7.5 KiB
与其它 Skill 集成(account-manager)
核心约束
业务 skill 不能自己散落存储账号、密码、API Key、Token。应通过 account-manager CLI(进程隔离)或 CLI + service.rpa_helpers 同进程库(浏览器自动化)组合获取。
两种集成方式
| 方式 | 适用场景 | 调用形态 |
|---|---|---|
| A. CLI subprocess(v1 起) | 任意业务 skill;一次性取账号 JSON / 凭据 / lease | subprocess.run([sys.executable, f"{skill_root}/scripts/main.py", "account", "pick-web", ...]) |
| B. rpa_helpers 同进程 import(v2) | 需要 Playwright 上下文内完成登录与页面操作 | sys.path.insert(0, f"{account_manager_root}/scripts"); from service.rpa_helpers import ensure_logged_in |
常见组合:CLI 负责 pick / lease / get-credential --reveal;rpa_helpers 负责 launch_browser_with_profile + ensure_logged_in。详见 RPA_HELPERS.md。
推荐调用方式
使用 subprocess 调用 scripts/main.py。宿主注入的 JIANGCHANG_DATA_ROOT / JIANGCHANG_USER_ID(或上层包装的 CLAW_*)必须与最终用户会话一致——否则会写到另一套目录。路径调试见 RUNTIME.md。
机器可读命令摘要
| 目的 | 命令 | 成功时 stdout(摘要) |
|---|---|---|
| 枚举平台 | platform list [--domain ...] |
{"success": true, "data": {"platforms": [...]}} |
| 平台详情 | platform get <p> |
{"success": true, "data": {...}} |
| 取单条账号 JSON | account get <id> |
单行 JSON 对象(无固定 success 字段) |
| 批量账号 JSON | account list ... |
单行 JSON 数组 |
| 网页自动化候选 | account pick-web ... |
单行 JSON 对象 |
| 取加密凭据明文 | account get-credential <id> --reveal --lease-token <t> |
单行 JSON,含 plaintext(若可解密) |
| 备份加密凭据 | account export-credentials --plaintext |
JSON 数组(stderr 有警告行) |
| 导入加密凭据 | account import-credentials [--replace-all] |
通常为空(计数在 stderr) |
| 初始化 master key | account init-master-key [--print|--from-env|--rotate] |
单行 JSON |
| 新增网页账号 | account add-web ... |
{"success": true, "data": {...}} |
| 新增凭据 | account add-secret ... |
{"success": true, "data": {...}} |
| 获取 API Key | credential pick ... [--reveal] |
{"success": true, ...} |
| 兼容入口 | get <id> / list-json <p> / pick-web <p> |
同上对应新式命令 |
更完整的命令表见 CLI.md。
解析协议(稳妥做法)
- 读取子进程 stdout;若有多行,集成应以首行为准(export/import 例外:
export整块 stdout 即 JSON;import读 stderr)。 - 优先尝试
json.loads:- 若为 dict 且
success is False→ 读取error.code/error.message。 - 若 dict 且
success is True且存在data→ 业务字段通常在data内(add-web/add-secret/platform)。
- 若为 dict 且
- 若 JSON 首字段不是上述统一格式(例如
pick-web)→ 直接按字段读取。 - 遗留文本失败:首行以
ERROR:开头 → 视为失败(旧别名路径仍可能出现)。
JSON 对象字段
account pick-web(典型)
{
"id": 1,
"platform_key": "maersk",
"account_label": "Maersk simulator booking",
"login_id": "demo@maersk.com",
"profile_dir": "D:/claw-data/10032/account-manager/profiles/logistics/maersk/Maersk_simulator_booking_demo@maersk.com",
"url": "http://localhost:5180/industries/logistics/maersk/login",
"tenant_id": "tenant-demo",
"environment": "simulator",
"role": "booking",
"provider_code": "maersk",
"session_status": "unknown",
"auth_strategy": "qr_code_manual",
"session_persistent": 1,
"device_fingerprint": null,
"lease_token": "…………",
"lease_expires_at": "2026-05-11T12:34:56"
}
lease_* 仅在传入 --lease 时出现;时间与仓库 _unix_to_iso_local 一致。
account get
输出即数据库映射字典(字段与 SCHEMA.md accounts 一致,extra_json 等为结构化 JSON)。
credential pick
{
"success": true,
"id": 1,
"platform_key": "deepseek",
"credential_label": "DeepSeek production key",
"credential_type": "api_key",
"secret_storage": "env",
"secret_ref": "DEEPSEEK_API_KEY",
"secret_mask": "****7890",
"status": "active"
}
仅 --reveal 时附加 secret。请勿向终端用户打印 reveal 结果。
account get-credential
成功示例:
{
"success": true,
"account_id": 42,
"credential_id": 7,
"credential_type": "password",
"secret_storage": "local_encrypted",
"secret_mask": "****abcd",
"plaintext": "……"
}
失败时使用统一 JSON:{"success": false, "error": {"code": "...", "message": "..."}}(亦可能夹杂历史 ERROR: 文本命令——见 ERRORS.md)。
rpa_helpers 同进程使用(摘要)
import sys
AM_ROOT = r"D:\OpenClaw\client-commons\account-manager"
sys.path.insert(0, f"{AM_ROOT}/scripts")
from service.rpa_helpers import (
launch_browser_with_profile,
close_browser,
ensure_logged_in,
)
务必:sys.path 指向 account-manager/scripts,因此 import 形态为 from service.rpa_helpers ...(而不是 from scripts.service.rpa_helpers ...)。
完整 API、登录判定 hook、LoginResult / AuthStrategyError 说明见 RPA_HELPERS.md。
业务流程示例
物流 RPA(CLI)
account pick-web --platform maersk --environment simulator --role booking --lease --holder my-skill- 解析 JSON → 取
id、profile_dir、url、lease_token - 用
profile_dir启动持久化浏览器上下文 - 业务完成后:
lease release <lease_token> - 如遇登录失效:
account mark-session <id> --session-status needs_login
LLM API 调用(CLI)
credential pick --platform deepseek --type api_key --environment production --reveal- 解析 JSON → 取
secret字段 - 仅在内存中使用,不写磁盘、不打日志
加密密码 + 自动登录(CLI + rpa_helpers)
import json
import subprocess
import sys
AM = r"D:\OpenClaw\client-commons\account-manager"
PY = sys.executable
MAIN = f"{AM}/scripts/main.py"
sys.path.insert(0, f"{AM}/scripts")
from service.rpa_helpers import launch_browser_with_profile, close_browser, ensure_logged_in
def am_json(argv: list[str]) -> dict:
r = subprocess.run([PY, MAIN, *argv], capture_output=True, text=True, check=False)
line = (r.stdout or "").splitlines()[0] if r.stdout else ""
return json.loads(line)
# 1) pick 账号 + lease
acc = am_json(
[
"account",
"pick-web",
"--platform",
"icbc_sim",
"--lease",
"--holder",
"my-rpa",
]
)
# 2) 取明文密码(必须 reveal + lease)
cred = am_json(
[
"account",
"get-credential",
str(acc["id"]),
"--reveal",
"--lease-token",
acc["lease_token"],
]
)
# 3) 浏览器 + 登录
ctx, page = launch_browser_with_profile(acc["profile_dir"])
try:
result = ensure_logged_in(page, acc, credentials={"plaintext": cred["plaintext"]})
if not result.ok:
print(result.message, file=sys.stderr)
sys.exit(1)
# …业务逻辑…
finally:
close_browser(ctx)
subprocess.run([PY, MAIN, "lease", "release", acc["lease_token"]], check=False)
退出码
请以 stdout JSON / ERROR: 前缀 为准;不要仅依赖退出码。