DATA CONTRIBUTION API · V1
把新文章投递给号外
面向已获授权的数据贡献方。一次请求可投递 1–100 篇文章,通过签名和字段校验后会立即进入公开索引与 RSS。
接口地址
POSThttps://haowai.thesignalwise.com/api/v1/webhooks/articles
请求体必须是 UTF-8 JSON,最大 256 KiB。完整机器可读定义见 OpenAPI 文档。
Key ID 和 Secret 由服务管理员线下提供。公开文档永远不会展示真实凭据。
请求签名
每次请求发送四个认证头:
Content-Type: application/json
X-Webhook-Key-Id: YOUR_KEY_ID
X-Webhook-Timestamp: UNIX_SECONDS
X-Webhook-Nonce: A_NEW_UUID
X-Webhook-Signature: v1=LOWERCASE_HEX_HMAC
签名原文是以下 UTF-8 字节,换行符固定为
:
v1
{timestamp}
{nonce}
{raw request body}
使用共享 Secret 计算 HMAC-SHA256,并编码为小写十六进制。时间戳默认只能与服务器时间相差五分钟。
Node.js 示例
import { createHmac, randomUUID } from "node:crypto";
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = randomUUID();
const body = JSON.stringify(event);
const signed = `v1\n${timestamp}\n${nonce}\n${body}`;
const signature = createHmac("sha256", process.env.WEBHOOK_SECRET)
.update(signed, "utf8")
.digest("hex");
await fetch("https://haowai.thesignalwise.com/api/v1/webhooks/articles", {
method: "POST",
headers: {
"content-type": "application/json",
"x-webhook-key-id": process.env.WEBHOOK_KEY_ID,
"x-webhook-timestamp": timestamp,
"x-webhook-nonce": nonce,
"x-webhook-signature": `v1=${signature}`
},
body
});
文章数据
{
"schema_version": "1.0",
"event_id": "018f5d53-f856-7d26-9b6d-a87d5e2c10f3",
"source": "wechat-monitor",
"sent_at": "2026-09-28T07:03:20+08:00",
"articles": [{
"external_id": "optional-stable-id",
"title": "文章标题",
"url": "https://mp.weixin.qq.com/s/example",
"description": "文章描述",
"author": { "id": "author-id", "name": "作者" },
"account": { "id": "account-id", "name": "公众号名称" },
"published_at": "2026-09-28T07:00:00+08:00",
"discovered_at": "2026-09-28T07:03:12+08:00",
"extra": { "monitor_rule": "news" }
}]
}
title、url、account.id、account.name 和 discovered_at 是文章必填字段。作者、真实发布时间、描述、封面、语言和 extra 均可按实际发现能力补充。
所有时间使用带时区的 RFC 3339 格式。扩展数据必须放在 extra 对象中;未知的顶层字段会被拒绝,避免拼写错误静默丢失。
响应与去重
{
"event_id": "018f5d53-f856-7d26-9b6d-a87d5e2c10f3",
"status": "accepted",
"counts": { "received": 1, "created": 1, "updated": 0, "duplicate": 0 },
"request_id": "01..."
}
同一逻辑事件重试时保持 event_id 不变。每一次 HTTP 尝试都生成新的 nonce、时间戳和签名。号外会同时根据外部文章 ID 和规范化 URL 去重。
可靠重试
- 只自动重试
429、500、502、503和504。 - 使用带随机抖动的指数退避,并遵循
Retry-After。 - 监控程序本地保留 outbox,直到收到成功响应。
- 认证或校验错误应先修正配置/数据,不要盲目重试。