跳转到内容

自定义 Webhook:推送到任意接收端

自定义 Webhook 集成把你创建的每条分享以结构化、带 HMAC 签名的 JSON 推送到任意公网 https 地址 —— 自动化平台(n8n、Zapier、Make、IFTTT)、你自己的后端 / 工单系统,或机器人中转。

只需一个 URL:无需注册应用、无需申请凭证。服务端自动生成 HMAC 签名密钥,你的接收端可据此验证请求确实来自 BugCapturer。

第 1 步:在接收端创建 Webhook 地址

Section titled “第 1 步:在接收端创建 Webhook 地址”

在目标系统里创建一个 Webhook 接收节点,复制它的 https 地址:

  • n8n:添加 Webhook 节点 → 使用 Production URL(方法:POST)
  • Zapier:用 Catch Hook 触发器建 Zap,复制 hook 地址
  • Make:添加 Custom webhook 模块,复制其地址
  • 自有系统:暴露任意接受 POST JSON 的公网 https 接口
  1. 登录 app.bugcapturer.com 打开「集成」页
  2. 左侧平台列表选择「自定义 Webhook」→ 点击「添加集成」
  3. 填写名称Webhook URL(https、公网)
  4. 点击「验证并保存」—— 服务端校验 URL(仅公网 https)并向你的接收端发送一条签名的测试事件event=test
  5. 测试通过后会一次性展示 HMAC 密钥——请立即复制保存到你的接收端配置。之后卡片只显示末 4 位;可随时通过卡片菜单「重置密钥」轮换

每条分享会触发一次 POST 请求,Content-Type: application/json(UTF-8),payload 为 schema v1:

{
"event": "share.created",
"source": "BugCapturer",
"schema_version": 1,
"sent_at": "2026-09-14T21:30:00+08:00",
"share": {
"token": "a1b2c3d4",
"report_url": "https://app.bugcapturer.com/share/a1b2c3d4",
"screenshot_url": "https://api.bugcapturer.com/api/shares/a1b2c3d4/file",
"submitted_at": "2026-09-14T21:29:58+08:00",
"expires_at": "2026-12-13T21:29:58+08:00"
},
"report": {
"description": "提交订单按钮点击后无响应",
"feedback_type": "",
"page_url": "https://example.com/checkout",
"page_title": "结算页 - Example Shop",
"browser": "Chrome 128",
"os": "Windows 11",
"screen": "1920x1080",
"console_errors_count": 2,
"network_errors_count": 0
}
}
字段说明
eventshare.created(分享创建)/ test(保存校验与「测试」按钮)
schema_version固定 1;仅破坏性变更时递增,消费端按此兼容
share.token分享唯一 token
share.report_url报告完整页面(浏览器打开,链接不过期)
share.screenshot_url截图代理地址(302 至带签名的存储 URL)
share.expires_at分享到期时间,到期后文件自动删除
report.description问题描述,超 2000 字符截断
report.page_url采集报告时的页面 URL(已脱敏)
report.feedback_type预留字段——schema v1 中恒为空(插件表单已不再采集报告类型)
report.*_errors_count仅条数——隐私红线,不包含控制台 / 网络错误正文;完整内容点 report_url 查看
全部时间字段ISO 8601,带 +08:00 时区

每个请求都携带请求头:

X-BugCapturer-Signature: t=<unix 时间戳>,v1=<十六进制摘要>

其中 v1 = HMAC-SHA256(secret, "{t}.{原始请求体}")。验签时用 "{t}." + 原始 body 重新计算 HMAC 并以恒定时间比较,同时拒绝与本地时钟偏差超过 5 分钟的时间戳(防重放)。

Python:

import hmac, hashlib, time
def verify(secret: str, header: str, raw_body: bytes, tolerance: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
if abs(time.time() - int(parts["t"])) > tolerance:
return False # 超出时钟容差,疑似重放
expected = hmac.new(secret.encode(),
f'{parts["t"]}.'.encode() + raw_body,
hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts["v1"])
# Flask 示例
@app.route("/webhooks/bugcapturer", methods=["POST"])
def hook():
if not verify(SECRET, request.headers["X-BugCapturer-Signature"], request.get_data()):
return "bad signature", 401
payload = request.get_json()
... # 按自有逻辑处理
return "", 204

Node.js:

const crypto = require("crypto");
function verify(secret, header, rawBody, tolerance = 300_000) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() - Number(parts.t) * 1000) > tolerance) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`, "utf8")
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
// Express 示例(需要原始 body)
app.post("/webhooks/bugcapturer",
express.raw({ type: "application/json" }),
(req, res) => {
if (!verify(SECRET, req.get("X-BugCapturer-Signature"), req.body)) {
return res.status(401).send("bad signature");
}
const payload = JSON.parse(req.body);
... // 按自有逻辑处理
res.status(204).end();
});
  • 创建(及轮换)后仅展示一次;之后卡片只显示 ······<末 4 位>
  • 菜单「重置密钥」会让旧密钥立即失效——请先更新接收端,再点「测试」确认
  • 密钥不会出现在投递日志、错误信息或邮件中

保存时提示「URL 不合法」? 仅接受公网 https 地址(不支持 http://、localhost / 内网 IP、携带用户凭证的 URL)。这是为了防止 SSRF 攻击,保护我们的网络。

测试请求返回 401/403? 你的接收端有自己的鉴权。要么放行携带 X-BugCapturer-Signature 头的请求,要么把接收端认可的鉴权 token 放进 URL 路径(n8n / Zapier 的 hook 地址本身已内嵌 token)。

一条报告能推给多个集成吗? 可以——配置多个集成后,分享前在插件里用「同步目标」选择器指定目标,只有选中的那个集成会收到这条报告。