SocialToAI免费开始控制台

Webhooks

Webhook 在事情发生时主动通知你自己的系统,不用反复来查。在控制台添加一个 https 地址并选好事件;每当其中一件事发生,SocialToAI 就向它推送一条签名的 JSON 消息。消息里只有数字、编号和链接,没有任何人写的文字。投递至少一次,失败会在大约一天内重试;Webhook 不收费。

添加端点

  • 在控制台打开设置 → Webhook,添加一个端点:你自己的 https 地址,以及它要接收的事件。端点只在控制台管理,没有用 Key 调用的路由。
  • 地址必须是 https,并且指向公网。保存前我们会先给它推送一条签名的检查消息(type 是 endpoint.check),它必须回 2xx。
  • 然后显示签名密钥,只显示这一次。它以 whsec_ 开头,请当场复制到你的接收端配置里。之后控制台只显示它的最后四位。
  • 每个账户最多 10 个端点。端点属于账户,不属于某把 Key:撤销 Key 不影响它。

事件

每条消息都是一个 JSON 对象:id(事件编号)、type、created_at,然后是这个事件自己的字段。summary 里按名字放着这次运行的数字。

type什么时候发字段
tool_run.finished现成工具的一次运行以 ok 或 empty 结束。tool, handle, status, summary, cost_credits, quoted_credits, result_url
tool_run.failed现成工具的一次运行以 partial 或 failed 结束。tool, handle, status, summary, cost_credits, quoted_credits, result_url
batch.finished一个批量任务结束,不论什么状态。tool, batch_id, summary, cost_credits, download_url
schedule_run.finished定期运行的一次运行完成。summary.new_items 是上一次没有的条数,new_links 是其中前几条的链接。tool, schedule_id, handle, summary, cost_credits, new_links, report_url
schedule.alert定期运行的主要数字变化超过 alert_percent,或从 0 变成非 0。tool, schedule_id, handle, summary, cost_credits, report_url
balance.low余额跌破提醒线,和余额提醒邮件同时发出。balance_credits, threshold_credits, billing_url
daily_cap.reached当天(UTC)账户每日上限第一次拒绝调用。daily_limit_credits, resets_at, settings_url
一条消息
{  "id": "evt_0123456789abcdef01234567",  "type": "schedule_run.finished",  "created_at": "2026-10-25T09:00:12.000Z",  "tool": "search",  "schedule_id": "00000000-0000-4000-8000-000000000021",  "handle": "res_00000000000040008000000000000003",  "summary": {    "new_items": 12  },  "cost_credits": 2,  "report_url": "https://socialtoai.com/console/tools/"}

示例:编号和数字是占位。

校验签名

每条消息带两个请求头。SocialToAI-Signature 是 t=<秒>,v1=<十六进制>:t 是签名时的 Unix 时间,v1 是用你的签名密钥对 <t>.<正文> 做的 HMAC-SHA256(十六进制),正文是原始请求体。SocialToAI-Webhook-Id 是这次投递的编号,重试时不变。

  • 用收到的原始正文计算 HMAC,不要先解析 JSON;比较时用常数时间比较。
  • t 和你的时钟相差超过 5 分钟的消息直接拒绝,防止重放。
  • 同一条消息可能到达不止一次。已经处理过的 id 直接跳过;在控制台手动重发的消息 id 不变,投递编号是新的。
import { createHmac, timingSafeEqual } from "node:crypto";// rawBody: the request body exactly as it arrived, before any JSON parsing.export function verify(rawBody, header, secret) {  const parts = Object.fromEntries(header.split(",").map((part) => part.split("=")));  const seconds = Number(parts.t);  if (!Number.isInteger(seconds) || Math.abs(Date.now() / 1000 - seconds) > 300) return false;  const expected = createHmac("sha256", secret).update(`${seconds}.${rawBody}`).digest();  const given = Buffer.from(parts.v1 ?? "", "hex");  return given.length === expected.length && timingSafeEqual(given, expected);}
import hashlib, hmac, time# raw_body: the request body as bytes, exactly as it arrived.def verify(raw_body: bytes, header: str, secret: str) -> bool:    parts = dict(part.split("=", 1) for part in header.split(","))    seconds = int(parts.get("t", "0"))    if abs(time.time() - seconds) > 300:        return False    signed = f"{seconds}.".encode() + raw_body    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()    return hmac.compare_digest(expected, parts.get("v1", ""))

投递与重试

  • 在 8 秒内回 2xx。不跟随重定向;每次推送前都会重新检查地址。
  • 其他状态码、没有应答,或 2 分钟内没有结果,都算一次失败的尝试。之后依次在 1 分钟、5 分钟、30 分钟、2 小时、6 小时、24 小时后重试,连首次共 7 次。
  • 连续 10 次尝试失败,只暂停这一个端点,并给你发一封邮件;其他照常,定期运行也照常跑。在控制台里可以恢复。
  • 控制台保留最近 30 天的投递记录,可以发送测试事件,也可以重发任意一条。

最近更新: