
语言 🇨🇳 简体中文
概述
实现
幕后原理
使用 FastComments,可以在每当评论被添加、更新或从我们的系统中删除时调用一个 API 端点。
我们通过基于 HTTP/HTTPS 的异步 webhooks 来实现这一功能。
支持的事件与资源 
FastComments 仅支持 Comment 资源的 webhooks。
我们支持针对评论的创建、删除和更新的 webhooks。
在我们的系统中,这些都被视为独立的事件,因此在 webhook 事件的语义 和结构上有所不同。
本地开发设置 
对于本地开发,可以使用像 ngrok 这样的工具。
为了简化保持系统安全的流程,本地开发遵循与设置和保护其他环境相同的流程。
第 1 步:将 "localhost" 添加到您帐户中的域名。
在 此处 将 "localhost" 添加为域名。
第 2 步:选择一个 API 密钥
我们将为您的域添加 webhook 配置,因此需要一个 API 密钥。您可以在 这里 完成该操作。
在 "Associate with domain" 下 - 选择您的 "localhost" 域。
注意:或者,您可以为所有测试活动和预发布(staging)环境使用一个 API Secret。只需为 "All Domains" 添加一个 API Secret,并给它一个类似 "test" 的名称。
确保您已为生产域定义了 API Secret。所有其他域的事件将使用通配符(测试)密钥。
第 3 步:添加您的 Webhook
在运行 ngrok 或类似工具时,在 此处 为 "localhost" 设置值。
当点击 Send Test Payload 时,我们会发送两个测试事件以检查您是否验证了 API 密钥。
一旦验证通过,点击 Save。
第 4 步:添加评论
现在您可以添加、编辑或删除评论,并应该会看到我们使用您的测试 API 密钥通过事件调用您的本地开发机器。事件可能最多有 30 秒的延迟 才能到达您的机器。
设置 
对 localhost 的操作与在生产环境中相同。确保您已设置生产域名和 API Secrets。
首先,导航到 Webhooks 管理。这是通过 管理数据 -> Webhooks 访问的。
配置页面如下所示:
在此页面中,您可以为每种评论事件指定端点。
对于每种事件类型,请务必点击 Send Test Payload 以确保您的集成已正确设置。有关详细信息,请参阅下一节“测试”。
测试 
在 Webhooks 管理页面中,每个事件类型(Create、Update、Delete)都有 Send Test Payload 按钮。Create 和 Update 事件会发送一个虚拟的 WebhookComment 对象,而测试 Delete 时会发送仅包含 ID 的虚拟请求体。
验证有效载荷
测试您的 webhook 集成时,请确认传入请求包含以下头部:
token- 您的 API SecretX-FastComments-Timestamp- Unix 时间戳(秒)X-FastComments-Signature- HMAC-SHA256 签名
使用 HMAC 签名验证以确保有效载荷的真实性。
测试工具
开发过程中可以使用诸如 webhook.site 或 ngrok 之类的工具来检查传入的 webhook 有效载荷。
事件类型
- Create Event: 当创建新评论时触发。默认方法:PUT
- Update Event: 当编辑评论时触发。默认方法:PUT
- Delete Event: 当删除评论时触发。默认方法:DELETE
每个事件在请求体中包含完整的评论数据(有关有效载荷格式,请参见 数据结构)。
数据结构 
通过 webhook 发送的唯一结构是下面用 TypeScript 描述的 WebhookComment 对象。
WebhookComment 对象结构
“create” 事件结构
“create” 事件的请求正文是一个 WebhookComment 对象。
“update” 事件结构
“update” 事件的请求正文是一个 WebhookComment 对象。
“delete” 事件结构
“delete” 事件的请求正文是一个 WebhookComment 对象。
变更(自 2023 年 11 月 14 日)
此前,“delete” 事件的请求正文仅包含评论 id。现在它包含删除时的完整评论。
Run 
当用户在评论中被提及时,信息会存储在名为 mentions 的列表中。该列表中的每个对象具有以下结构。
Run 
HTTP 方法
您可以在管理面板中为每种 webhook 事件类型配置 HTTP 方法:
- Create 事件:POST 或 PUT(默认:PUT)
- Update 事件:POST 或 PUT(默认:PUT)
- Delete 事件:DELETE、POST 或 PUT(默认:DELETE)
由于所有请求都包含 ID,Create 和 Update 操作默认是幂等的(PUT)。重复相同的 Create 或 Update 请求不应在你端创建重复对象。
请求头
每个 webhook 请求都包含以下头:
| Header | Description |
|---|---|
Content-Type |
application/json |
token |
你的 API Secret |
X-FastComments-Timestamp |
请求签名时的 Unix 时间戳(秒) |
X-FastComments-Signature |
HMAC-SHA256 签名(sha256=<hex>) |
请参阅 安全与 API 令牌 以获取有关验证 HMAC 签名的信息。
安全性与 API 令牌 
FastComments 的 webhook 请求包含多种身份验证机制以确保安全。
发送的请求头
| 请求头 | 描述 |
|---|---|
token |
您的 API Secret(用于向后兼容) |
X-FastComments-Timestamp |
请求签名时的 Unix 时间戳(秒) |
X-FastComments-Signature |
负载的 HMAC-SHA256 签名 |
HMAC 签名验证(推荐)
我们强烈建议验证 HMAC 签名,以确保 webhook payload 是真实且未被篡改。
Signature Format: sha256=<hex-encoded-signature>
签名的计算方法:
- 连接:
timestamp + "." + JSON_payload_body - 使用您的 API Secret 作为密钥计算 HMAC-SHA256
- 对结果进行十六进制编码
示例验证(Node.js)
const crypto = require('crypto');
function verifyWebhookSignature(req, apiSecret) {
const timestamp = req.headers['x-fastcomments-timestamp'];
const signature = req.headers['x-fastcomments-signature'];
if (!timestamp || !signature) {
return false;
}
// 验证时间戳是否近期(在 5 分钟内)
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - parseInt(timestamp, 10)) > 300) {
return false; // 防止重放攻击
}
// 验证签名
const payload = JSON.stringify(req.body);
const expectedSignature = crypto
.createHmac('sha256', apiSecret)
.update(`${timestamp}.${payload}`)
.digest('hex');
return signature === `sha256=${expectedSignature}`;
}
示例验证(Python)
import hmac
import hashlib
import time
import json
def verify_webhook_signature(headers, body, api_secret):
timestamp = headers.get('X-FastComments-Timestamp')
signature = headers.get('X-FastComments-Signature')
if not timestamp or not signature:
return False
# 验证时间戳是否近期
now = int(time.time())
if abs(now - int(timestamp)) > 300:
return False
# 验证签名
payload = json.dumps(body, separators=(',', ':'))
message = f"{timestamp}.{payload}"
expected = hmac.new(
api_secret.encode(),
message.encode(),
hashlib.sha256
).hexdigest()
return signature == f"sha256={expected}"
示例验证(PHP)
function verifyWebhookSignature($headers, $body, $apiSecret) {
$timestamp = $headers['X-FastComments-Timestamp'] ?? null;
$signature = $headers['X-FastComments-Signature'] ?? null;
if (!$timestamp || !$signature) {
return false;
}
// 验证时间戳是否近期(在 5 分钟内)
$now = time();
if (abs($now - intval($timestamp)) > 300) {
return false;
}
// 验证签名
$payload = json_encode($body, JSON_UNESCAPED_SLASHES);
$message = $timestamp . '.' . $payload;
$expectedSignature = 'sha256=' . hash_hmac('sha256', $message, $apiSecret);
return hash_equals($expectedSignature, $signature);
}
旧版身份验证
包含您 API Secret 的 token 请求头仍会出于向后兼容而发送。然而,我们建议迁移到 HMAC 验证以提高安全性,因为它可以防止重放攻击。
工作原理与重试处理 
系统中对 Comment 对象的所有更改都会触发一个事件,该事件最终会进入队列。
初始 webhook 事件通常会在事件源发生后的六秒内发送。
如果您的 API 宕机,您可以在 Webhooks 管理页面监控此队列。
如果对您的 API 的请求失败,我们会按照一个计划将其重新排入队列。
该计划为 1 Minute * the retry count。如果调用失败一次,它将在一分钟后重试。如果失败两次,则会等待两分钟,依此类推。这样做是为了避免在因为负载相关原因导致您的 API 宕机时对其造成过载。
可以在日志页面取消 Webhooks。
结论
本 Webhooks 文档到此结束。
我们希望您觉得 FastComments Webhook 集成易于理解且便于快速设置。
如果您认为已发现我们文档中的任何空白或不足,请在下方告知我们。