Webhook
Webhook 会在平台发生操作后,把 GAMEMONITORING 事件发送到你的系统。它是普通的 POST 请求,请求体为 JSON,网站、面板或游戏服务可以据此自动响应。
如果你要配置投票奖励,请先按照本指南连接 Webhook,然后使用单独流程:投票奖励。
连接
此设置会把 GAMEMONITORING 项目连接到你的处理器,并提供用于验证传入请求的签名 token。
- 打开 我的项目,创建项目或选择已有项目,然后进入 Webhook 设置。
- 创建公开 HTTPS endpoint,接受
Content-Type: application/json的POST请求,并且不要重定向请求。 - 在 Webhook 设置中填写完整处理器 URL,例如
https://panel.example.com/gamemonitoring-webhook,并保存。 - 从同一块设置中复制签名 token,并把它写入处理器脚本。
- 在处理器中验证
signature,处理需要的event_type,并且只在事件处理完成后返回成功的2xx响应。
本地测试时,可以在自己的电脑上运行处理器,并通过公开 HTTPS URL 暴露它。可以使用 ngrok 或其他隧道服务,然后在 Webhook 设置中填写生成的公开 URL。
设置完成后,从界面发送测试 Webhook 并检查投递状态。对于示例 URL,服务器必须在 /gamemonitoring-webhook 路径接受 POST。
如果测试失败,请先查看处理器响应:401 表示签名错误,403 或 HTML 验证页面通常表示 WAF 或 bot protection,超时表示该 URL 无法从互联网访问或响应太慢。
处理器要求
- URL 必须可以从互联网访问。本地地址、私有网络以及带登录名或密码的 URL 不适用。
- 生产环境建议使用 HTTPS。HTTP 也支持,但传输过程中的数据保护较弱。
- 处理器必须接受
POST方法和 JSON 请求体,且不发生重定向。 - 只有在系统处理完事件后才返回
2xx。通常204 No Content就足够。 - 如果事件无法安全处理,请返回错误码。
3xx、4xx、5xx、超时和连接错误都会被视为投递失败。 - 如果使用 firewall、bot protection 或 allowlist,请把 GAMEMONITORING IP 地址 加入例外。
- 不要在响应体中返回 token、stack trace、SQL 错误或其他内部细节。处理器响应会显示在界面中,因此错误文本必须安全且易懂。
事件数据
每个 Webhook 都会带有 JSON 请求体和基础字段:
event_type— 需要处理的事件。event_id— 唯一事件 ID。请与event_type一起用于幂等处理和防重复投递。is_test— 表示来自界面的测试投递。signature— 事件请求体的签名。
示例解读:event_type 表示需要处理哪个事件;event_id 用于在修改状态前保证幂等;is_test: true 表示技术投递检查;signature 不是业务数据,只用于验证请求真实性。
处理逻辑取决于 event_type。对于 server.vote 和 project.vote,请使用单独流程:投票奖励。
如果 is_test 为 true,请验证签名并返回 2xx,但不要修改余额、发放物品或启动生产操作。
处理器响应示例
每个传入事件都应以一个明确结果结束:
204 No Content— 签名正确,事件已处理或已安全跳过。测试投递和已经处理过的事件也返回相同响应。400 Bad Request— 缺少必填字段。这表示处理器错误或请求体不符合预期,不应执行业务逻辑。401 Unauthorized— 签名无效。不要发起 API 请求,不要修改数据库,也不要发放奖励。500 Internal Server Error— 数据库、队列或内部系统暂时不可用。投递会保持失败状态,修复原因后可以重试。
例如,处理器收到事件、验证签名、保存 event_type + event_id 并处理事件后,可以返回 204。如果数据库不可用,事件无法保存,最好返回 500,避免投递过早被标记为成功。
签名验证
签名位于 signature 字段。请在任何业务逻辑、API 请求或数据库修改之前验证它。
验证时,取事件请求体中除 signature 以外的所有字段,按 key 字母顺序排序,并组成用 & 连接的 key=value 字符串。布尔值写作 true 或 false。
对于上面的示例,签名字符串只由 event_id、event_type 和 is_test 组成。然后使用 Webhook 设置中的签名 token 计算 HMAC-SHA256,并与请求中的 signature 比较。
示例中的预计算签名使用演示 token paste-webhook-token-here。在你的处理器中,请使用 Webhook 设置中的 token。
在处理器中:
- 用排序后的 key 构建签名字符串;
- 使用签名 token 计算
HMAC-SHA256; - 用恒定时间比较函数将结果与
signature比较:PHP 使用hash_equals,Node.js 使用timingSafeEqual,Python 使用compare_digest; - 如果签名无效,返回
401。
第 1 步:基础处理器
先实现一个能接受任意 Webhook 的处理器:读取 JSON,验证 signature,处理测试投递,检查基础字段,并返回 204。在这一步,处理器只确认投递可以被正确接收。请在这个基础路径可用后再添加具体事件的逻辑。
第 2 步:添加去重
Webhook 使用 at-least-once 投递模型:同一个事件可能到达多次。在处理器修改系统状态之前,请按 event_type + event_id 让该操作具备幂等性。
首先创建一张表,用唯一键保存 event_type 和 event_id 这一对值。如果记录已经存在,说明事件已经处理过。
然后扩展基础处理器:在签名和基础字段验证通过后,保存 event_type + event_id,并在同一个事务中执行状态变更。
不要把昵称、用户 ID 或服务器 ID 作为去重 key:同一个用户可能触发不同事件,也可能稍后重复一次允许的操作。key 必须是 event_type + event_id。
示例:处理器已经修改了你的系统状态,但在 GAMEMONITORING 收到 204 之前连接中断。稍后投递被重试,同一个事件再次到达。处理器必须找到已经保存的 event_type + event_id,跳过重复状态变更,并返回 204。
如果处理器暂时无法处理事件,请返回错误响应。原因修复后,如果该事件支持重试,可以从界面重新发送投递。
测试和重新发送
测试投递(is_test: true)会检查处理器 URL、签名和 HTTP 响应。处理器必须走同一条处理路径:读取 JSON,验证 signature,识别 is_test,并返回成功的 2xx 响应。
测试事件不得修改余额、库存、角色、订阅或其他生产数据。测试只需要技术日志和 204 响应。
如果投递失败,界面会显示状态、HTTP 状态码和处理器响应。修复原因后,如果该事件支持重试,可以重新发送失败的投递。