本文是插件 HTTP 通信格式的唯一规范。除特别说明外,JSON 字符串使用 UTF-8。
配置:
local.http.enabled
local.http.host
local.http.port
local.http.auth_token
local.http.max_body_bytes
接口:
| 方法 | 路径 | 作用 |
|---|---|---|
GET |
/health |
服务状态 |
POST |
/v1/messages |
本地服务向 QQ 发送消息 |
auth_token 非空时,两个接口都必须携带:
Authorization: Bearer <token>监听 127.0.0.1 或 ::1 时可在本机调试中留空。监听局域网地址时插件要求
配置 Token,否则拒绝启动。
群聊:
{
"target": {
"id": "123456",
"conversation_type": "qq_group"
},
"content": {
"text": "hello from local"
}
}私聊:
{
"target": {
"id": "654321",
"conversation_type": "qq_private"
},
"content": {
"text": "hello from local"
}
}target.type 可以省略,默认且唯一的新类型为 qq_session。
| 字段 | 必需 | 类型 | 默认值 | 作用 |
|---|---|---|---|---|
message_id |
否 | string | 插件生成 UUID | 调用方消息 ID |
source |
否 | object | HTTP 来源 | 本地调用方信息,供兜底路由匹配 |
target |
条件必需 | object | 本地占位目标 | 直接发送时指定 QQ 会话;省略时使用兜底路由 |
sender |
否 | object | 空对象 | 本地逻辑发送者信息 |
content |
是 | object | 无 | 消息内容 |
extra |
否 | object | {} |
调用方扩展数据 |
未知顶层字段当前会被忽略。调用方不应依赖这一行为扩展协议。
| 字段 | 必需 | 可填值 | 作用 |
|---|---|---|---|
type |
否 | qq_session |
可省略 |
id |
推荐 | string | 群号、QQ 号或平台 OpenID |
conversation_type |
ID 模式推荐 | qq_group、qq_private |
会话类型 |
source_type |
否 | 同上 | conversation_type 的兼容名称 |
platform |
否 | string | 同一 ID 在多个适配器存在时用于消歧 |
alias |
兜底 | string | WebUI 映射或 /interconnect bind 创建的别名 |
extra |
否 | object | 兼容扩展 |
id 与 alias 至少填写一个。两者同时存在时,插件先按
id + conversation_type + platform 查找,再使用 alias。
旧值 type=qq_session_alias 会在 HTTP 入口转换为 qq_session,仅用于兼容。
| 字段 | 必需 | 默认值 | 作用 |
|---|---|---|---|
type |
否 | http_endpoint |
本地来源类型 |
id |
否 | "" |
来源实例 ID |
alias |
否 | "" |
来源别名 |
extra.endpoint_id |
否 | "" |
省略 target 时供兜底路由匹配 |
只有省略 target 时,source.extra.endpoint_id 才通常需要填写。
| 字段 | 类型 | 作用 |
|---|---|---|
id |
string | 本地发送者 ID |
name |
string | 显示名称 |
platform |
string | 调用方平台 |
group_id |
string | 调用方分组,可选 |
extra |
object | 扩展数据 |
sender 只进入内部标准包,不会改变 QQ 消息的实际发送账号。
当前 QQ sender 实际发送:
textimages
text 与 images 至少有一个非空。其他标准内容字段可被解析,但当前不会
发送到 QQ,调用方不应将其作为已实现能力。
| 字段 | 类型 | 默认值 | 作用 |
|---|---|---|---|
text |
string | "" |
文本 |
images |
array | [] |
图片列表 |
mentions |
array[string] | [] |
标准包兼容字段 |
extra |
object | {} |
内容扩展 |
图片对象常用字段:
| 字段 | 必需 | 可填值 | 作用 |
|---|---|---|---|
source_type |
是 | url、file |
图片来源 |
url |
URL 模式 | HTTP(S) URL | 网络图片 |
file_path |
file 模式 | data 目录内允许的路径 | 本地图片 |
media_id |
否 | string | 调用方媒体 ID |
mime_type |
否 | string | MIME 类型 |
sha256 |
否 | string | 校验摘要 |
size_bytes |
否 | integer | 字节数 |
extra |
否 | object | 扩展数据 |
完整请求:
{
"message_id": "las-20260816-001",
"source": {
"type": "http_endpoint",
"id": "las",
"extra": {
"endpoint_id": "notifications"
}
},
"target": {
"id": "123456",
"conversation_type": "qq_group",
"platform": "aiocqhttp"
},
"sender": {
"id": "local-service",
"name": "LAS"
},
"content": {
"text": "构建完成",
"images": [
{
"source_type": "url",
"url": "https://example.com/result.png",
"mime_type": "image/png"
}
]
},
"extra": {
"job_id": "build-42"
}
}插件使用固定顺序,避免直达请求被路由意外覆盖:
- 请求包含非空
target:直接发送到该 QQ 会话。 - 请求省略
target:匹配local_to_qq路由。 - 路由没有命中:返回投递失败。
兜底路由示意:
模板 HTTP 到 QQ 会话
source.type http_endpoint
source.endpoint_id notifications
target.source_type qq_group
target.id 123456
请求:
{
"source": {
"type": "http_endpoint",
"extra": {
"endpoint_id": "notifications"
}
},
"content": {
"text": "route fallback"
}
}成功:
{
"ok": true,
"message_id": "las-20260816-001",
"results": [
{
"target": {
"type": "qq_session",
"id": "123456",
"alias": "",
"extra": {
"source_type": "qq_group"
}
},
"ok": true,
"message": "sent"
}
]
}目标存在但投递失败时返回 HTTP 502:
{
"ok": false,
"message_id": "las-20260816-001",
"results": [
{
"target": {
"type": "qq_session",
"id": "123456",
"alias": "",
"extra": {
"source_type": "qq_group"
}
},
"ok": false,
"message": "QQ session '123456' has not been recorded."
}
]
}请求级错误:
{
"ok": false,
"error": {
"code": "invalid_request",
"message": "target.id or target.alias is required for QQ session targets."
}
}| HTTP 状态 | code | 含义 |
|---|---|---|
| 400 | invalid_json |
JSON 无法解析 |
| 400 | invalid_request |
字段或内容非法 |
| 401 | unauthorized |
Bearer Token 错误 |
| 413 | request_too_large |
超过请求体上限 |
| 500 | internal_error |
未预期的服务端错误 |
| 502 | 无请求级 code | 请求有效,但 QQ 投递失败 |
插件不能仅凭群号或 QQ 号重新构造所有 AstrBot 适配器的发送地址,因此维护
sessions.bindings:
{
"alias": "qq_group_123456",
"source_type": "qq_group",
"conversation_id": "123456",
"platform": "aiocqhttp",
"unified_msg_origin": "...",
"updated_at": "2026-08-16T12:00:00+00:00"
}通常无需人工创建。QQ 消息命中 QQ->HTTP 路由时自动记录。WebUI 已存在的会话 项会在该会话下一次发言时自动补全或刷新地址。
若返回“未记录”或“没有发送地址”:
- 检查
sessions.auto_record。 - 检查映射中的
source_type、conversation_id和可选platform。 - 让目标会话发送一条消息;新会话需命中一条 QQ->HTTP 路由。
- 重试请求。
- 最后在目标会话执行
/interconnect bind <alias>,并发送{"target":{"alias":"<alias>"},...}。
手动别名只是发送地址兜底,不控制 QQ 入站转发权限。
只有启用的“QQ 到 HTTP Webhook”路由会触发 POST。来源可限制:
source.type:qq_group、qq_private或*source.conversation_idsource.sender_idsource.session_alias,仅兜底
内容可限制:
match.text_prefixmatch.regexmatch.require_image
所有非空条件使用 AND 逻辑。QQ 会话不需要预先绑定。
{
"schema_version": "1.0",
"event_type": "message",
"message_id": "qq-message-id",
"direction": "qq_to_local",
"route_id": "qq_group_to_las",
"message_type": "mixed",
"source": {
"type": "qq_group",
"id": "123456",
"alias": "qq_group_123456",
"extra": {
"group_id": "123456",
"user_id": "654321",
"platform": "aiocqhttp"
}
},
"target": {
"type": "http_webhook",
"id": "las",
"alias": "",
"extra": {}
},
"sender": {
"id": "654321",
"name": "Alice",
"platform": "aiocqhttp",
"group_id": "123456",
"extra": {}
},
"content": {
"text": "hello from QQ",
"images": [],
"videos": [],
"files": [],
"attachments": [],
"links": [],
"forwards": [],
"mentions": [],
"extra": {}
},
"raw_refs": {
"astrbot_message_id": "qq-message-id",
"unified_msg_origin": "...",
"raw_message_id": "qq-message-id",
"extra": {}
},
"timestamp": "2026-08-16T12:00:00+00:00",
"extra": {}
}字段:
| 字段 | 作用 |
|---|---|
schema_version |
protocol.schema_version |
event_type |
当前固定为 message |
message_id |
标准化消息 ID |
direction |
固定为 qq_to_local |
route_id |
实际命中的路由 |
message_type |
text、image、mixed 等 |
source |
QQ 会话;id 是统一会话 ID |
target |
Webhook 逻辑目标 |
sender |
QQ 发送者 |
content |
文本、媒体、链接、转发和 mentions |
raw_refs |
AstrBot 原始引用,可配置关闭 |
timestamp |
ISO 8601 时间 |
extra |
扩展对象,可配置关闭 |
Webhook 的 URL、Token、Headers、超时和重试配置不会进入标准包体。
protocol.include_raw_refs=false 删除整个 raw_refs。
protocol.include_extra=false 递归删除所有名为 extra 的扩展对象。
完整示例文件:
templates/qq_to_http_webhook.standard.json。
设置:
protocol.webhook_payload_mode = template
protocol.webhook_payload_template_files = [选择的 JSON 文件]
WebUI 文件目录:
AstrBot/data/plugin_data/astrbot_plugin_interconnect/files/protocol/webhook_payload_template_files/
只使用选择列表中的第一个文件。模板必须是小于等于 1 MiB 的 UTF-8 JSON 对象,不能位于插件 data 目录之外。
模板示例:
{
"id": "${message_id}",
"text": "${content.text}",
"conversation": "${source.id}",
"sender": "${sender}",
"images": "${content.images}"
}可使用标准包体的任意点路径,例如:
${schema_version}${message_id}${route_id}${source.id}${sender.id}${content.text}${content.images}${raw_refs.unified_msg_origin}${envelope}
字符串值完全等于一个占位符时保留原 JSON 类型;占位符嵌入普通字符串时转换 为文本。未知占位符、非法 JSON、非对象根节点或文件错误会使该次投递失败并 记录到 diagnostics。
配置界面不提供内联 JSON 编辑器,也不支持每条路由覆盖模板。旧内联字段只为 已有配置兼容而保留。
$body = @{
target = @{
id = "123456"
conversation_type = "qq_group"
}
content = @{
text = "hello from LAS"
}
} | ConvertTo-Json -Depth 8
Invoke-RestMethod `
-Method Post `
-Uri "http://127.0.0.1:8765/v1/messages" `
-ContentType "application/json" `
-Body $body配置了 Token 时添加:
-Headers @{ Authorization = "Bearer <token>" }- 调用方应根据
schema_version解析 QQ->HTTP 包体。 - 新代码使用
target.type=qq_session;旧qq_session_alias仅兼容。 - HTTP 和未来 WS 必须使用同一目标字段、消息模型与恢复顺序。
- 协议新增字段应保持向后兼容;破坏性修改必须提升版本并同步本文件与测试。