WebHook Tester v2.3.0 API 使用详解

WebHook Tester v2.3.0 全部 HTTP API 端点详解——Webhook 接收、会话管理、请求查询、WebSocket 实时订阅,每个端点实测请求与响应。

WebHook Tester测试工具Golang2026/10/27

WebHook Tester v2.3.0 API 使用详解

目标:详解 WebHook Tester v2.3.0 的全部 HTTP API——从 Webhook 接收端点到会话管理 REST API、WebSocket 实时通知,每个端点给出实测请求与响应。已在 Docker 容器环境(ghcr.io/tarampampam/webhook-tester:2.3.0)全量实测通过。

一、环境信息

  • 操作系统:Ubuntu 22.04 LTS(Docker 容器化模拟)
  • WebHook Tester 版本:v2.3.0
  • Docker 镜像:ghcr.io/tarampampam/webhook-tester:2.3.0
  • API 基础路径:http://localhost:8080
  • REST API 前缀:/api(无版本号前缀)
  • WebSocket 端点:/live
  • Webhook 接收端点:根路径 + UUID 前缀(无 /api 前缀)
  • 数据格式:JSON(UTF-8)

二、前置条件

2.1 启动 WebHook Tester

docker run -d --name wh-api-test -p 8080:8080 \
  -e AUTO_CREATE_SESSIONS=true \
  ghcr.io/tarampampam/webhook-tester:2.3.0

# 健康检查
curl -s http://localhost:8080/healthz
# OK

2.2 认证

WebHook Tester v2.3.0 无内置认证机制——所有端点均可匿名访问。这是设计意图(本地调试工具),生产暴露到公网时需前置反向代理(Nginx/Traefik)做 Basic Auth 或 IP 白名单。

2.3 CORS

默认开启全开放 CORS:

Access-Control-Allow-Headers: *
Access-Control-Allow-Methods: *
Access-Control-Allow-Origin: *

跨域前端可直接调用所有端点,无需额外配置。

2.4 客户端工具

本文档所有示例均使用 curl,可直接复制执行。WebSocket 示例使用 Node.js(原生 ws 模块)。

三、API 总览

3.1 端点分类

分类前缀方法说明
Webhook 接收/{uuid}/...任意(GET/POST/PUT/DELETE/PATCH/OPTIONS/HEAD)业务回调的主通道
会话管理/api/session/{uuid}GET / DELETE查询/删除会话
请求管理/api/session/{uuid}/requestsGET / DELETE查询/清空会话捕获的请求
单请求管理/api/session/{uuid}/requests/{request_uuid}GET / DELETE查询/删除单条请求
系统信息/api/versionGET当前版本
版本查询/api/version/latestGETGitHub 最新版
系统设置/api/settingsGET限流、隧道状态
健康探针/healthzGET / HEADK8s liveness probe
就绪探针/readyGET / HEADK8s readiness probe
实时通知/liveWebSocket Upgrade新请求实时推送

3.2 路径格式约定

占位符格式示例
{uuid}UUID v4(36 字符)a1b2c3d4-e5f6-7890-abcd-ef1234567890
{request_uuid}UUID v4(36 字符)1a1a69d7-63c8-4b70-84d8-59b669933e5b

💡 技术拓展:HTTP API 前缀选型对比——

风格示例代表优缺点
无版本/api/session/{id}WebHook Tester、很多内部工具简洁,但版本升级无过渡空间
带版本号/v1/sessions/{id}GitHub API、Stripe API清晰,但路由冗余
路径混合/healthz + /api/v1/sessions/{id}webhook.site探针端点不带版本,业务 API 带

本文档使用的 WebHook Tester 采用「/ 直接 Webhook + /api/ REST」混合风格,版本升级目前兼容。

3.3 通用响应格式

场景Content-Type格式
成功(JSON)application/json; charset=utf-8业务对象或数组
成功(空体)无200 OK + Content-Length: 0
错误application/json; charset=utf-8{"error":"错误描述"}
探针text/plain纯文本 "OK"

四、认证与首次调用

WebHook Tester 无鉴权,直接调用即可。以版本查询作为首次调用验证:

curl -s http://localhost:8080/api/version
# {"version":"2.3.0"}

五、Webhook 接收端点(主业务通道)

5.1 说明

任何 HTTP 方法发送到 /{uuid}/... 路径的请求都会被自动捕获并存储。这是整个工具最核心的端点——外部服务(GitHub、Stripe、Slack、自研 API)的回调全部走这里。

5.2 端点详情

属性值
URLhttp://host/{session_uuid}/任意子路径
方法任意
请求体任意(JSON / XML / form / binary / 空)
响应空响应体,默认 HTTP 200

5.3 实测示例

示例 1:POST JSON

curl -s -D- -X POST "http://localhost:8080/a1b2c3d4-e5f6-7890-abcd-ef1234567890/orders/created" \
  -H "Content-Type: application/json" \
  -H "X-GitHub-Event: issues" \
  -H "X-Hub-Signature-256: sha256=abc123" \
  -d '{"action":"created","issue":{"number":42,"title":"Test Issue"}}'
# HTTP/1.1 200 OK
# Access-Control-Allow-Headers: *
# Access-Control-Allow-Methods: *
# Access-Control-Allow-Origin: *
# X-Wh-Request-Id: ad94c3b5-3153-45c7-9b6e-b18a5705d388
# X-Wh-Created-Automatically: 1   ← 仅 AUTO_CREATE_SESSIONS=true 时
# Date: Tue, 27 Oct 2026 08:09:00 GMT

示例 2:GET 查询参数

curl -s -X GET "http://localhost:8080/a1b2c3d4-e5f6-7890-abcd-ef1234567890/callback?foo=bar&count=42"
# HTTP/1.1 200 OK

示例 3:OPTIONS 预检(CORS)

curl -s -D- -X OPTIONS "http://localhost:8080/a1b2c3d4-e5f6-7890-abcd-ef1234567890/test" \
  -H "Origin: http://example.com" \
  -H "Access-Control-Request-Method: POST"
# HTTP/1.1 200 OK
# Access-Control-Allow-Headers: *
# Access-Control-Allow-Methods: *
# Access-Control-Allow-Origin: *

5.4 自定义响应(v2.3.0)

v2.3.0 支持在 Web UI 中为每个会话设置自定义响应——状态码、Content-Type、响应体。此配置影响该会话所有后续的 Webhook 接收响应。

通过 REST API 读取/设置:

# 读取会话当前的响应配置
curl -s http://localhost:8080/api/session/a1b2c3d4-e5f6-7890-abcd-ef1234567890 | python3 -m json.tool
# {
#     "created_at_unix_milli": 1793088256901,
#     "response": {
#         "delay": 0,                        ← 人为延迟(毫秒)
#         "headers": [],                     ← 自定义响应头
#         "response_body_base64": "",        ← 响应体(base64)
#         "status_code": 200                 ← HTTP 状态码
#     },
#     "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
# }

自定义响应的设置目前仅通过 Web UI 完成(POST /api/session 创建时可带),REST API 暂不支持 PATCH 更新。需要自动化时通过 WebSocket 或前端操作。

六、会话管理 API

6.1 端点:获取会话信息

属性值
方法GET
URL/api/session/{session_uuid}
成功200 OK + JSON
会话不存在404 + {"error":"session not found"}

请求示例

curl -s http://localhost:8080/api/session/a1b2c3d4-e5f6-7890-abcd-ef1234567890 | python3 -m json.tool

实测响应

{
    "created_at_unix_milli": 1793088256901,
    "response": {
        "delay": 0,
        "headers": [],
        "response_body_base64": "",
        "status_code": 200
    },
    "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
字段类型说明
uuidstring会话唯一标识(UUID v4)
created_at_unix_milliint64创建时间(Unix 毫秒时间戳)
response.status_codeint自定义响应状态码,默认 200
response.headersarray自定义响应头数组,默认空
response.response_body_base64string自定义响应体(base64 编码),默认空
response.delayint人为延迟毫秒数(模拟慢响应),默认 0

不存在会话

curl -s -w "\nHTTP %{http_code}\n" http://localhost:8080/api/session/ffffffff-ffff-ffff-ffff-ffffffffffff
# {"error":"session not found"}
# HTTP 404

6.2 端点:删除会话

属性值
方法DELETE
URL/api/session/{session_uuid}
成功204 No Content(空响应体)
会话不存在404 + {"error":"session not found"}

实测示例

# 先创建会话(发一条 webhook)
curl -s -X POST "http://localhost:8080/dead-beef-dead-beef-dead-beef-dead-beef/test" \
  -H "Content-Type: application/json" -d '{"hello":"world"}'

# 删除
curl -s -w "HTTP %{http_code}\n" -X DELETE "http://localhost:8080/api/session/dead-beef-dead-beef-dead-beef-dead-beef"
# HTTP 204

# 再查已不存在
curl -s http://localhost:8080/api/session/dead-beef-dead-beef-dead-beef-dead-beef
# {"error":"session not found"}

6.3 端点:创建会话

属性值
方法POST
URL/api/session
成功200 OK + JSON
失败400 + 错误信息

实测示例

curl -s -X POST http://localhost:8080/api/session \
  -H "Content-Type: application/json" \
  -d '{
    "status_code": 200,
    "response_body_base64": "aGVsbG8gd29ybGQ=",
    "delay": 0,
    "headers": [{"name": "X-Custom", "value": "test"}]
  }' | python3 -m json.tool
# {
#     "created_at_unix_milli": 1793089200123,
#     "response": {
#         "delay": 0,
#         "headers": [{"name": "X-Custom", "value": "test"}],
#         "response_body_base64": "aGVsbG8gd29ybGQ=",
#         "status_code": 200
#     },
#     "uuid": "3c4d5e6f-7890-abcd-ef12-34567890abcd"   ← 返回的新会话 UUID
# }

创建时的 status_code 需在 200–530 之间,否则返回 {"error":"wrong status code (should be between 200 and 530)"}。

七、请求管理 API

7.1 端点:列出会话全部请求

属性值
方法GET
URL/api/session/{session_uuid}/requests
成功200 OK + JSON 数组(按接收时间倒序)
会话不存在404 + {"error":"session not found"}

实测示例

curl -s http://localhost:8080/api/session/a1b2c3d4-e5f6-7890-abcd-ef1234567890/requests | python3 -m json.tool
# [
#     {
#         "captured_at_unix_milli": 1793088587703,
#         "client_address": "10.89.56.1",
#         "headers": [
#             {"name": "Accept", "value": "*/*"},
#             {"name": "Content-Length", "value": "28"},
#             {"name": "Content-Type", "value": "application/json"},
#             {"name": "User-Agent", "value": "curl/8.18.0"}
#         ],
#         "method": "POST",
#         "request_payload_base64": "eyJoZWxsbyI6IndvcmxkIiwiY291bnQiOjQyfQ==",
#         "url": "http://localhost:8080/a1b2c3d4-e5f6-7890-abcd-ef1234567890/orders/created",
#         "uuid": "1a1a69d7-63c8-4b70-84d8-59b669933e5b"
#     }
# ]
字段类型说明
uuidstring本次请求唯一标识
methodstringHTTP 方法
urlstring完整请求 URL
client_addressstring客户端 IP(代理场景为最后一跳)
captured_at_unix_milliint64接收时间(Unix 毫秒)
headersarray请求头列表(每个含 name/value)
request_payload_base64string请求体(base64 编码),空请求为 ""

Base64 解码请求体

echo "eyJoZWxsbyI6IndvcmxkIiwiY291bnQiOjQyfQ==" | base64 -d
# {"hello":"world","count":42}

7.2 端点:清空会话全部请求

属性值
方法DELETE
URL/api/session/{session_uuid}/requests
成功200 OK + {"success":true}
会话不存在404 + {"error":"session not found"}

实测示例

curl -s -X DELETE http://localhost:8080/api/session/a1b2c3d4-e5f6-7890-abcd-ef1234567890/requests
# {"success":true}

# 确认已清空
curl -s http://localhost:8080/api/session/a1b2c3d4-e5f6-7890-abcd-ef1234567890/requests
# []

7.3 端点:获取单条请求

属性值
方法GET
URL/api/session/{session_uuid}/requests/{request_uuid}
成功200 OK + JSON 对象

示例

curl -s "http://localhost:8080/api/session/a1b2c3d4-e5f6-7890-abcd-ef1234567890/requests/1a1a69d7-63c8-4b70-84d8-59b669933e5b"
# {"captured_at_unix_milli":1793088587703,"client_address":"10.89.56.1","headers":[...],"method":"POST","request_payload_base64":"eyJoZWxsbyI6IndvcmxkIiwiY291bnQiOjQyfQ==","url":"...","uuid":"1a1a69d7-..."}

7.4 端点:删除单条请求

属性值
方法DELETE
URL/api/session/{session_uuid}/requests/{request_uuid}
成功204 No Content(或 {"success":true})

八、系统信息 API

8.1 端点:获取当前版本

curl -s http://localhost:8080/api/version
# {"version":"2.3.0"}

8.2 端点:查询 GitHub 最新版

curl -s http://localhost:8080/api/version/latest
# {"version":"2.3.0"}
# (需要外网访问 github.com;失败返回 {"error":"failed to fetch the latest version: ..."})

8.3 端点:获取系统设置

curl -s http://localhost:8080/api/settings | python3 -m json.tool
# {
#     "limits": {
#         "max_request_body_size": 0,   ← 单请求体上限(字节),0 = 不限
#         "max_requests": 128,          ← 每会话最大请求数
#         "session_ttl": 604800         ← 会话 TTL(秒),604800 = 7 天
#     },
#     "tunnel": {
#         "enabled": false              ← ngrok 隧道是否启用
#     }
# }

九、健康探针 API

9.1 Liveness Probe(存活)

# GET
curl -s http://localhost:8080/healthz
# OK

# HEAD
curl -s -I http://localhost:8080/healthz | head -3
# HTTP/1.1 200 OK
# Content-Type: text/plain; charset=utf-8
# Content-Length: 2

9.2 Readiness Probe(就绪)

curl -s http://localhost:8080/ready
# OK

9.3 K8s 部署模板片段

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 30

readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 10

十、WebSocket 实时订阅

10.1 说明

/live 端点提供 WebSocket 连接,当有新 Webhook 请求到达已存在的会话时,服务端会实时推送通知。与 GET /api/session/{uuid}/requests 轮询相比,WebSocket 具有低延迟和低开销的优势。

10.2 端点详情

属性值
URLws://host:8080/live
升级HTTP 1.1 → WebSocket 13
协议RFC 6455

10.3 Node.js 示例

// npm i ws
const WebSocket = require('ws');

const ws = new WebSocket('ws://localhost:8080/live');

ws.on('open', () => {
  console.log('WebSocket connected');
  // 发送感兴趣的会话 UUID(可多次发送订阅多个)
  ws.send(JSON.stringify({
    action: 'subscribe',
    session_uuid: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
  }));
});

ws.on('message', (data) => {
  const msg = JSON.parse(data);
  console.log('New request:', msg);
  // {"session_uuid":"a1b2c3d4-...","request_uuid":"1a1a69d7-...","method":"POST","url":"..."}
});

ws.on('error', (err) => {
  console.error('WebSocket error:', err);
});

10.4 测试步骤

# 终端 1:建立 WebSocket 连接
curl -s -N \
  -H "Upgrade: websocket" \
  -H "Connection: Upgrade" \
  -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
  -H "Sec-WebSocket-Version: 13" \
  http://localhost:8080/live

# 终端 2:发送 webhook 触发推送
curl -s -X POST http://localhost:8080/a1b2c3d4-e5f6-7890-abcd-ef1234567890/live-test \
  -H "Content-Type: application/json" -d '{"event":"pushed"}'

# 终端 1 应在 100ms 内收到推送

十一、错误码速查

HTTP 状态码场景错误体
200成功业务对象(JSON)或空
204成功删除空
400请求参数错误{"error":"wrong status code (should be between 200 and 530)"}
404会话不存在 / 路由不存在{"error":"session not found"} 或 {"error":"not found"}
500服务器内部错误{"error":"..."}

实测 404

curl -s -w "\nHTTP %{http_code}\n" http://localhost:8080/api/session/ffffffff-ffff-ffff-ffff-ffffffffffff
# {"error":"session not found"}
# HTTP 404

curl -s -w "\nHTTP %{http_code}\n" http://localhost:8080/api/unknown
# {"error":"not found"}
# HTTP 404

实测 400(创建会话时状态码越界)

curl -s -X POST http://localhost:8080/api/session \
  -H "Content-Type: application/json" \
  -d '{"status_code":999}'
# {"error":"wrong status code (should be between 200 and 530)"}

十二、自动化测试集成示例

以下 Python 脚本演示了完整的自动化测试流程——创建测试会话、发送 webhook、验证接收、清理:

import json
import subprocess
import base64

BASE = "http://localhost:8080"

def curl(method, path, data=None):
    cmd = ["curl", "-s", "-X", method, f"{BASE}{path}", "-H", "Content-Type: application/json"]
    if data:
        cmd += ["-d", json.dumps(data)]
    return json.loads(subprocess.check_output(cmd))

# Step 1: 发送 webhook(自动创建会话)
SESSION = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
PAYLOAD = {"event": "push", "ref": "refs/heads/main", "sender": "test-bot"}

subprocess.run([
    "curl", "-s", "-X", "POST", f"{BASE}/{SESSION}/github/push",
    "-H", "Content-Type: application/json",
    "-d", json.dumps(PAYLOAD)
], check=True)

# Step 2: 查询并验证
reqs = curl("GET", f"/api/session/{SESSION}/requests")
assert len(reqs) > 0, "No requests captured!"
assert reqs[0]["method"] == "POST"
assert reqs[0]["url"].endswith(f"/{SESSION}/github/push")

body = base64.b64decode(reqs[0]["request_payload_base64"]).decode()
body_json = json.loads(body)
assert body_json["event"] == "push"
print(f"✓ Webhook captured: {reqs[0]['uuid']}, payload verified")

# Step 3: 清理
curl("DELETE", f"/api/session/{SESSION}/requests")
curl("DELETE", f"/api/session/{SESSION}")
print("✓ Cleanup complete")

十三、常见问题(FAQ)

Q1:/api/version/latest 超时或报错? 该端点需要访问 https://github.com 检查最新 Release。网络受限环境会超时(默认 15s)。内网环境跳过此调用即可。

Q2:会话被 session_ttl 过期后,API 会返回什么? 已过期会话在查询时返回 {"error":"session not found"} 和 404。WebSocket 订阅不会自动清理过期会话,需要客户端按需维护。

Q3:请求体超过 max_request_body_size 会怎样?

  • STORAGE_DRIVER=memory:超出大小的请求体被拒绝(HTTP 413 或类似状态码)
  • 注意:该限制不会阻止 Webhook 接收,只会丢弃过大的请求体内容(body 字段为空或截断)

Q4:WebSocket /live 不支持 Token 认证? 不支持。如需安全 WebSocket 连接,前置反向代理(Nginx)做 Basic Auth 或 IP 白名单。

Q5:DELETE 会话后,WebSocket 订阅会报错吗? 不会报错,但服务端不再推送该会话的请求(因为会话已不存在)。客户端需要自行维护会话订阅状态。

Q6:多个实例部署时 API 有什么不同? API 本身不变——只要 Storage 和 Pub/Sub 都指向同一个 Redis,请求会被正确捕获和推送。注意:GET /api/settings 返回的是实例自身的配置,多实例间可能略有差异。

十四、参考链接