Files
MC_Report/docs/EXTERNAL-API.md
canglan 4dfc30ce89 docs: standalone external API doc for bots/third-party
- docs/EXTERNAL-API.md: auth matrix (ID+Secret / legacy key / JWT),
  Python+Node quickstart, server alias syntax, 9 endpoints with
  request/response examples, status flow, error codes, troubleshooting,
  typical scenarios (QQ bot ticket flow, plugin ban sync)
- README + API.md link to the standalone doc
- verified: 24 checks, endpoints cross-checked doc vs code
2026-08-19 19:40:25 +08:00

8.7 KiB

外部 API 文档(机器人 / 第三方系统)

适用对象:QQ 官方机器人、游戏服务器插件、统计面板等无法做网页登录的外部系统。

  • Base URL:https://<你的域名>/api/external
  • 数据格式:JSON(Content-Type: application/json)
  • 本文档所有接口不需要用户登录,只需要客户端凭据(见下)

一、鉴权(三种方式,任选其一)

方式 A:ID + Secret(推荐,多客户端)

在站点后台 →「外部API」页面创建客户端,获得一对凭据:

Client ID: c_1a2b3c4d5e6f7a8b9c0d1e2f
Secret:    s_9f8e7d6c5b4a39281726354a1b2c3d4e5f60718293a4b5c6d7e8f9a0b1c2d3e

⚠️ Secret 只在创建时显示一次,请立即保存。支持创建多个客户端、单独停用/删除,互不影响。

调用时在请求头携带:

请求头
x-api-client-id 你的 Client ID
x-api-secret 你的 Secret

方式 B:旧版单 Key(兼容)

请求头
x-external-key 部署时配置的 external_api_key

方式 C:用户 JWT(仅限插件)

请求头
Authorization Bearer <JWT>(来自 POST /api/external/auth/login)

二、快速开始(Python / Node 示例)

Python

import requests

BASE = "https://你的域名/api/external"
HEADERS = {
    "x-api-client-id": "c_1a2b3c4d5e6f7a8b9c0d1e2f",
    "x-api-secret": "s_9f8e7d6c...",
    "Content-Type": "application/json",
}

# 提交举报工单
r = requests.post(f"{BASE}/tickets", headers=HEADERS, json={
    "type": "report",
    "title": "恶意破坏",
    "reporter_game_name": "Steve",
    "reporter_game_uid": "df273bda10b94aa18db345574d5a1e1d",
    "target_game_name": "Alex",
    "target_game_uid": "SKIN_UUID_002",
    "reason": "刷屏+破坏他人建筑",
    "description": "多次警告无效",
    "server": "survival",          # 可选: 子服别名
})
print(r.json())  # {"id": 123, "tracking_token": "..."}

Node.js

const BASE = 'https://你的域名/api/external';
const H = {
  'x-api-client-id': 'c_1a2b3c...',
  'x-api-secret': 's_9f8e7d6c...',
  'Content-Type': 'application/json',
};

// 查询工单进度(从提交到结束全程可查)
const res = await fetch(`${BASE}/tickets/track?token=你的tracking_token`, { headers: H });
console.log(await res.json());

三、子服务器定位(server 参数)

子服可在后台「服务器管理」配置外部别名(alias)。所有带 server 的接口支持三种写法:

写法 示例 说明
别名(推荐) survival 服务器改名不影响
分组/子服 网易服务器/生存服 URL 编码或 JSON 直接传
子服名 生存服 同名时取第一个

查询服务器列表(含别名):GET /api/external/servers


四、接口清单

1. 提交工单

POST /api/external/tickets
字段 类型 必填 说明
type string report / suggestion / appeal
title string 标题
reporter_game_name string 提交人游戏名
reporter_game_uid string 提交人 UID / UUID
target_game_name string 条件 被举报人游戏名(report 建议填)
target_game_uid string 条件 被举报人 UID
reason string 条件 举报原因(report/appeal 必填)
description string 条件 详情(suggestion/appeal 必填)
server string 子服(别名/分组/子服名)

限制:同一提交人待处理工单最多 5 个

成功响应 201:

{
  "id": 123,
  "tracking_token": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "server": "生存服"
}

tracking_token 是查询进度的唯一凭证,请妥善保存。

2. 查询工单进度(提交 → 处理 → 结束)

GET /api/external/tickets/track?token=<tracking_token>

成功响应:

{
  "id": 123,
  "type": "report",
  "title": "恶意破坏",
  "status": "processing",
  "priority": "medium",
  "reporter_game_name": "Steve",
  "target_game_name": "Alex",
  "reason": "刷屏+破坏他人建筑",
  "assigned_to": "管理员",
  "claim_note": "已受理",
  "server_name": "生存服",
  "created_at": "2026-08-19T10:00:00.000Z",
  "updated_at": "2026-08-19T11:30:00.000Z",
  "responses": [
    { "content": "游戏内提交...", "is_staff": 0, "created_at": "..." },
    { "content": "正在核实,请耐心等待", "is_staff": 1, "created_at": "..." }
  ]
}

工单状态流转:

pending(待处理) → processing(处理中) → resolved(已解决)
              ↘ awaiting_info(待补充信息) → processing / rejected(驳回)
              ↘ closed(关闭)   appealed(申诉中) → resolved / rejected

3. 工单列表

GET /api/external/all-tickets?type=&status=&server=&page=&limit=
参数 说明
type report / suggestion / appeal
status pending / processing / awaiting_info / appealing / resolved / rejected / closed
server 子服(别名/分组/子服名)
page / limit 分页,limit ≤ 200,默认 page=1 limit=50

4. 工单详情(含回复与附件)

GET /api/external/all-tickets/:id

5. 拉取封禁列表

GET /api/external/bans?server=&status=&player=&page=&limit=
参数 说明
server 子服过滤(可选)
status active / expired / appealed / lifted(默认不滤)
player 按玩家名或 UID 精确匹配
page / limit 分页,limit ≤ 500

成功响应:

[
  {
    "id": 7,
    "player_name": "Alex",
    "player_uid": "SKIN_UUID_002",
    "source": "netease",
    "reason": "使用外挂",
    "type": "ban",
    "duration": "7d",
    "server_name": "生存服",
    "status": "active",
    "created_at": "2026-08-19T10:00:00.000Z",
    "expires_at": "2026-08-26T10:00:00.000Z"
  }
]

6. 新增封禁

POST /api/external/bans
{
  "player_name": "Alex",
  "player_uid": "SKIN_UUID_002",
  "source": "netease",
  "reason": "使用外挂",
  "type": "ban",
  "duration": "7d",
  "expires_at": "2026-08-26T10:00:00.000Z",
  "server": "survival",
  "status": "active"
}
字段 必填 说明
player_name 玩家名
type ban / mute / warn / other,默认 ban
status active / expired / appealed / lifted,默认 active
expires_at ISO 时间或 null(永久)

响应 201: { "id": 7 }

7. 被举报人统计

GET /api/external/reported-players?server=

响应:

[
  {
    "target_game_name": "Alex",
    "target_game_uid": "SKIN_UUID_002",
    "total": 5,
    "active": 2,
    "resolved": 3,
    "last_report": "2026-08-19T10:00:00.000Z"
  }
]

8. 服务器列表(含别名)

GET /api/external/servers

响应:

[
  { "group_name": "网易服务器", "server_name": "生存服", "alias": "survival" },
  { "group_name": "网易服务器", "server_name": "空岛服", "alias": "skyblock" }
]

9. 工单统计

GET /api/external/stats?server=

响应:

{
  "total": 128,
  "byType": [ { "type": "report", "c": 95 }, { "type": "suggestion", "c": 20 } ],
  "byStatus": [ { "status": "pending", "c": 12 }, { "status": "resolved", "c": 100 } ]
}

五、错误码

HTTP 说明
400 参数错误(缺少必填字段 / 类型不正确 / 待处理工单超上限)
401 鉴权失败(凭据错误或客户端已停用)
404 工单 / 封禁不存在
500 服务器内部错误

错误响应统一为 { "error": "描述信息" }


六、鉴权失败排查

  1. 401 未授权:检查 x-api-client-id / x-api-secret 是否与创建时一致;客户端是否被停用;secret 是否完整无换行空格。
  2. 客户端被停用:后台「外部API」→ 启用。
  3. 需要多个客户端:后台可创建多个,分别用于机器人 / 插件 / 统计面板,互不影响;删除即立即失效。

七、典型场景

QQ 机器人:玩家提交举报

  1. 玩家在 QQ 群发送举报信息 → 机器人调 POST /tickets 提交(reporter 为玩家 QQ 绑定的游戏名/UID)
  2. 机器人把返回的 tracking_token 发给玩家 → 玩家随时发「查进度」→ 机器人调 GET /tickets/track?token=...
  3. 处理结果(状态变化)可通过工单详情轮询,或后台「通知配置」设置 Webhook 推送

服务器插件:同步封禁

  1. 插件启动时调 GET /bans?status=active&server=生存服 拉取本服封禁
  2. 服内封禁新玩家时调 POST /bans 同步到系统
  3. 定期轮询 GET /bans?status=active 保持同步

协议版本 v1 · 服务端接口以部署版本为准