plugin/adapters/ 下的单文件独立进程:autClaw 负责启动进程、下发配置和分发消息;你的适配器 worker 负责协议适配——解析账号、把平台事件转成标准事件、把标准发送动作转成平台协议包。
本页是语言无关的契约总览:接入形态、能力声明、manifest 头注、标准事件和出站动作。看完后进入对应语言篇章动手实现。
选择开发语言
Go 适配器(推荐)
编译为原生二进制常驻运行,内存占用低;官方 SDK 封装了连接、握手、断线重连和并发控制。
Node.js 适配器
直连 control 协议,无需编译;适合需要复用平台官方 npm SDK 或快速原型的场景。
先记住三条边界
- worker 负责协议适配:账号解析、入站标准化、出站构造、回执解码、登录和平台 workflow。
- autClaw 负责运行编排:启动进程、下发配置、维护 control 连接、分发消息和记录回执。
- 协议专属逻辑 只放在适配器 worker 内,不要依赖 autClaw 核心层为单个渠道做特殊处理。
接入形态与能力
worker 在上线时声明自己支持的能力,autClaw 按能力决定把哪些工作交给它。三种标准形态:- 四核心能力缺一项,共享路由形态就不可用。
- 声明
open_ingress后,该im_type的 receive 路由整体切到原样转发,resolve_account/normalize_inbound不再被调用。适合微信公众号这类回调必须验签或加解密的平台。
manifest 头注
适配器放在plugin/adapters/,文件顶部用注释头注声明元信息。推荐文件名 adapter_{im_type}_{transport} 加语言扩展名,例如 adapter_demo_http.go、adapter_demo_ws.js;autClaw 会根据文件名辅助推断路由,但关键字段仍应显式声明。
Go 与 Node.js 的头注注释格式略有差异(Go 还需要构建约束行),见各语言篇章。未识别的字段不会报错,也不参与任何功能。
title、author、version、public、price 等通用字段见 插件 manifest 声明头。
生命周期与消息信封
适配器进程通过 control websocket 与 autClaw 通讯,地址从环境变量AUTCLAW_ADAPTER_CONNECT_URL 读取。生命周期固定为三步:
1
收到 adapter_init
autClaw 在连接建立后下发配置:
account_configs(每个账号带 instance_id,后续所有事件必须回填)、global_config_values、common 等。先缓存配置、重建账号索引,再进入下一步。2
回发 adapter_worker_ready
payload 必须携带
"contract": "v3" 和能力声明,否则 autClaw 直接关闭连接。能力按每次连接声明,autClaw 只认当前连接上报的能力。3
处理业务调用
响应 autClaw 发起的动作,或主动发起上报。断线后自动重连,重连会重新收到
adapter_init。{"aut_echo": "call_1", "ok": true, "aut_params": {}};失败响应 {"aut_echo": "call_1", "ok": false, "aut_error": "原因"}。
- 响应必须原样返回
aut_echo,不要带aut_action。 aut_params必须是对象,没有数据时返回{}。- worker 内部异常必须捕获并转成失败响应,不能让连接崩溃。
- worker 主动调用 autClaw 时自己生成
aut_echo、维护 pending 映射并设置超时;断线时所有 pending 立即失败。
adapter_worker_ready.aut_params):
标准事件
所有入站路径(normalize_inbound 返回值、主动上报批次、raw ingress 结果)统一使用同一种事件结构:
消息内容只写在
message.chain.items 里,段类型:text、image、voice、video、file、at、reply。文本段必须有 text;媒体段必须有 source(URL 或平台 file key);at 段必须有 target_id;reply 段必须有 reply_to_id。任一事件缺必填字段,整批事件都会被拒绝。
出站动作
autClaw 把插件的发送请求转成标准动作,交给 worker 的build_outbound 翻译成平台 payload:
目标规则:群消息用
session_type: "group" + chat_id;私聊消息用 session_type: "private" + user_id。
build_outbound 的返回决定发送方式:
transport: "ws":由 autClaw 持有的发送连接发出;需要回执时把request_id写入平台echo/nonce字段,回执到达后 autClaw 调decode_receipt解码(返回matched、request_id、ok、data.message_id;不是回执的 payload 返回{"matched": false})。executor: "worker":autClaw 回调adapter_execute_outbound,worker 自己调平台 API 发送。响应有两层ok:外层表示调用是否执行,aut_params.ok表示平台发送是否成功。
媒体契约
插件发送媒体时,worker 从payload.media(单媒体动作)或 payload.items(混合消息)读取:
- 默认模式:不要声明
media头注。autClaw 会把本地文件转换成短时效临时 URL(约 60 秒)再传给 worker,worker 把source当 URL 处理并尽快取用,支持http://、https://、data:、base64://和平台 file key。 - 本地路径模式:声明
//[media: {"requires_file_path":true}]后,autClaw 会物化文件并传file_path。只有 worker 与 autClaw 在同一文件系统、且平台 SDK 必须读本地文件时才使用。 - 文件发送保留
name和mime_type;不要把本地路径直接发给远端平台。
扫码登录
扫码登录分两层声明:- manifest 头注
//[supports_qr_login: true]:让设置页展示扫码入口,即使 worker 未上线。 adapter_worker_ready里的supports_qr_login: true:声明当前在线 worker 能执行扫码动作。autClaw 只检查这一层,且要求四核心能力同时在位。
adapter_login_qr_start 生成二维码:
adapter_login_qr_wait 等待结果(请求带 session_key 和 timeout_ms)。未完成时返回 {"connected": false, "status": "wait"};成功时返回账号配置:
account_config 持久化到适配器设置(与已有账号合并别名和配置,无默认账号时设为默认)。status 建议使用 wait、scanned、confirmed、expired、error。不支持扫码的适配器两层都不要声明。
worker 主动动作
adapter_emit_inbound_events 的响应是逐事件结果:
ok: true 不等于全部入队。平台游标只能推进到第一个 rejected 之前,缺口必须重发、不得跳过;调用本身失败(超时、断线)表示整批未确认,必须整批重试。配合 dedupe_key,重试不会造成重复投递。queued、waiter_consumed、filtered、duplicate 都算已接受。
raw ingress(高级)
平台回调必须由 worker 验签或加解密时(例如微信公众号),声明open_ingress 能力。autClaw 把 HTTP 请求原样转发给 worker 的 adapter_open_ingress:
verified: false时 autClaw 返回 403,不产生任何副作用。response_mode为immediate(立即应答)或passive(被动回复:在平台被动窗口内等插件回复并编码进响应)。- 每个账号可在设置页拿到专属回调地址
/api/{im_type}/receive/{ingress_id}。 - 请求与响应 body 上限 1 MiB;被动回复必须在平台时限内完成。
发布前检查
- 收到
adapter_init后再处理平台业务消息;ready 声明了contract: "v3"。 - 所有带
aut_echo的调用都能返回成功或失败;主动调用设置了超时并在断线时清理。 - 事件带齐
im_type、instance_id;主动上报按outcomes推进游标。 - 媒体优先使用
source;只有声明requires_file_path才读取file_path。 - 日志、
meta、raw不包含 token、密码、私钥、验证码或完整签名。 - 实测私聊、群聊、媒体、撤回、掉线重连;支持扫码的再实测扫码流程。
下一步
Go 适配器开发
用官方 SDK 实现完整适配器,含最小骨架和测试方法。
Node.js 适配器开发
直连 control 协议实现完整适配器,含可运行的完整示例。