← 帮助中心

使用 Webhook 接收实时事件

在 ColdSend 中创建 Webhook 端点、订阅邮件与潜客事件、校验签名,并监控投递情况

自动化与 Webhook5 分钟阅读更新于 2026年8月9日

Webhook 让 ColdSend 能在你的工作区发生任何变化时实时通知你自己的应用——邮件发出、潜客回复、链接被点击、潜客退订,等等。你不需要轮询 API:事件发生的那一刻,ColdSend 就会向你的端点发送一个 HTTP POST 请求。

本指南带你来创建 Webhook、选择要接收的事件、验证请求确实来自 ColdSend,以及排查投递失败的问题。

适用场景

如果你符合以下情况,就该用 Webhook:

  • 想在事情发生的那一刻,把潜客/回复数据同步进 CRM 或内部工具
  • 需要触发自动化(例如潜客回复时通知 Slack、潜客退订时更新表格)
  • 想实时追踪互动(打开、点击、退信),而不用轮询
  • 正在 ColdSend 的营销引擎之上构建自定义集成

前置条件

  • 一个能访问 Settings → Webhooks 的 ColdSend 账户
  • 一个可公网访问、能接收 POST 请求的 HTTPS 端点(不接受纯 http:// 地址)
  • 你的端点必须在 10 秒内返回 2xx 状态码,投递才算成功

💡 提示: 还没准备好端点?在搭建集成期间,可以用 webhook.site 或 RequestBin 这类服务来查看 ColdSend 发来的请求。


第 1 步:打开 Webhooks 设置

  1. 登录你的 ColdSend 账户。
  2. 在左侧边栏进入 Settings。
  3. 选择 Webhooks 标签页。

你会看到现有 Webhook 的列表(如果有的话),以及每个 Webhook 的状态和最近一次投递结果。

Webhooks 设置页面


第 2 步:创建 Webhook

  1. 点击 Create Webhook 按钮。

  2. 在对话框中填写:

    字段 说明
    Name 这个 Webhook 的易读名称(例如 “CRM Sync”)
    Endpoint URL ColdSend 向你 POST 事件的 HTTPS 地址
    Event Types 这个 Webhook 要接收哪些事件
  3. 选择一个或多个事件类型,或者用 Select All Events 订阅全部。

创建 Webhook 对话框

  1. 点击 Create Webhook。

可用的事件类型

事件 触发时机
Reply Received 潜客回复了邮件
Email Bounced 邮件退信
Lead Unsubscribed 潜客退订
Email Sent 邮件成功发出
Email Delivered 投递已确认
Email Opened 邮件被打开
Link Clicked 邮件中的链接被点击
Lead Status Changed 潜客状态发生变化

第 3 步:保存签名密钥

Webhook 创建完成后,ColdSend 会仅显示一次你的签名密钥:

签名密钥对话框

⚠️ 重要

签名密钥只会显示一次,之后无法再次获取。请立即复制并安全保存(例如放进环境变量或密钥管理服务)。你需要用它来验证收到的请求确实来自 ColdSend(见第 5 步)。

如果你弄丢了密钥,删除这个 Webhook 再新建一个,就能拿到新的密钥。


第 4 步:发送测试事件

在接入集成之前,先验证你的端点能正常工作:

  1. 在列表中找到你的 Webhook,点击 Test 操作。
  2. ColdSend 会向你的端点发送一个 ping 事件。
  3. 结果会显示你的端点返回的 HTTP 状态码。

测试 Webhook

测试事件长这样:

{
  "event_type": "ping",
  "event_id": "a1b2c3d4-...",
  "occurred_at": "2026-08-09T10:00:00+00:00",
  "team_id": "your-team-id",
  "campaign_id": null,
  "data": { "message": "Webhook test from ColdSend" }
}

你的端点应返回任意 2xx 状态(例如 200 OK)。其他任何状态都会被记为失败。


第 5 步:校验请求签名

每个 Webhook 请求都带有 HMAC-SHA256 签名,你可以据此确认请求来自 ColdSend,且没有被篡改。

请求头

请求头 说明
X-ColdSend-Signature sha256= 加上原始请求体的 HMAC-SHA256 十六进制摘要
X-ColdSend-Event 事件类型(例如 reply_received)
X-ColdSend-Delivery-Id 本次投递的唯一 ID
X-ColdSend-Attempt 这是第几次投递尝试(1 = 首次尝试)
User-Agent 固定为 ColdSend-Webhooks/1

校验步骤

  1. 以字节形式读取原始请求体(不要解析后再重新序列化 JSON——格式差异会导致签名校验失败)。
  2. 使用第 3 步的密钥计算 HMAC-SHA256(body, signing_secret)。
  3. 用恒定时间比较把结果与 X-ColdSend-Signature 请求头对比。

Node.js 示例:

import crypto from "crypto";

function verifyColdSendSignature(req, secret) {
  const signature = req.headers["x-coldsend-signature"];
  const expected =
    "sha256=" +
    crypto.createHmac("sha256", secret).update(req.rawBody).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

Python(FastAPI)示例:

import hashlib
import hmac

def verify_coldsend_signature(body: bytes, secret: str, signature: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode("utf-8"), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

⚠️ 签名不匹配的请求一律拒绝——它不是来自 ColdSend。


第 6 步:处理收到的事件

所有真实事件共用同一个信封结构:

{
  "event_type": "reply_received",
  "event_id": "7f3a9c1e-...",
  "occurred_at": "2026-08-09T10:15:32+00:00",
  "team_id": "your-team-id",
  "campaign_id": "campaign-id-or-null",
  "data": { ... }
}

data 对象随事件类型不同而不同:

事件类型 data 字段
email_sent lead_email、from_email、subject、sequence_step、message_id
email_delivered lead_email、delivered_at
email_opened lead_email、sequence_step、opened_at
link_clicked lead_email、link_index、url、clicked_at
email_bounced lead_email、bounce_type、status_message、sequence_step
reply_received lead_email、subject、reply_text、is_auto_reply、inbox_email
lead_unsubscribed lead_email、method
lead_status_changed lead_email、from_status、to_status

reply_received 载荷示例:

{
  "event_type": "reply_received",
  "event_id": "7f3a9c1e-...",
  "occurred_at": "2026-08-09T10:15:32+00:00",
  "team_id": "your-team-id",
  "campaign_id": "e9d8c7b6-...",
  "data": {
    "lead_email": "prospect@example.com",
    "subject": "Re: Quick question",
    "reply_text": "Sure, let's talk Thursday.",
    "is_auto_reply": false,
    "inbox_email": "alex@yourdomain.com"
  }
}

端点的最佳实践

  • 快速响应:立即返回 200,再异步处理事件(例如推入队列)。耗时超过 10 秒的请求会被视为失败。
  • 保证幂等:ColdSend 保证至少一次投递,所以同一事件偶尔可能到达两次。用 event_id 去重。
  • 只在成功时返回 2xx:任何 2xx 都算投递成功;其他一律视为失败。

第 7 步:监控投递

每个 Webhook 都保留一份投递日志,可以在 Webhooks 设置页面查看:

  1. 点击某个 Webhook,打开它的投递历史。
  2. 每条记录显示事件类型、状态、HTTP 响应码以及错误信息。

投递日志

投递状态

状态 含义
Succeeded 你的端点返回了 2xx 响应
Failed 投递失败——要么是 4xx 响应(永久失败,不重试),要么是可重试的失败仍在进行中
Dead 所有重试尝试都已用尽

失败的投递可以在你修好端点后,从投递日志中手动重新投递。


重试与自动暂停

ColdSend 会用指数退避自动重试失败的投递:

尝试次数 时间
第 1 次 事件发生时立即
第 2 次 约 1 分钟后
第 3 次 约 5 分钟后
第 4 次 约 30 分钟后

重试行为取决于失败类型:

  • 超时、网络错误和 5xx 响应 → 会重试(最多共 4 次尝试)
  • 4xx 响应 → 视为永久失败,不重试(先修复客户端的问题,再重新投递)

如果某个 Webhook 出现连续 5 次投递死亡,ColdSend 会自动暂停它,避免持续冲击一个已经坏掉的端点。你随时可以在 Webhooks 设置页面重新启用被暂停的 Webhook。


管理 Webhook

在 Webhooks 设置页面,你可以:

  • 编辑 —— 修改名称、端点 URL 或订阅的事件类型
  • 暂停 / 恢复 —— 启用或停用某个 Webhook,而不用删除它
  • 删除 —— 永久移除某个 Webhook(其签名密钥同时失效)

Webhook 操作

注意: 被暂停或删除的 Webhook 不会收到任何事件。暂停期间发生的事件,在恢复后不会补发。


故障排查

我的端点始终收不到事件

  • 确认该 Webhook 在 Webhooks 设置页面中处于启用状态(未被暂停)
  • 确认该 Webhook 订阅了你期望的事件类型
  • 确保你的端点可从公网访问——ColdSend 无法访问 localhost、私有 IP 或仅限 VPN 的主机
  • 检查投递日志里的错误详情

投递结果显示“Request timed out”

你的端点响应时间超过了 10 秒。请立即返回 200,再异步处理载荷。

签名校验一直失败

  • 使用原始请求体的字节——重新序列化已解析的 JSON 会改变空白与键顺序,导致签名不匹配
  • 确认密钥复制完整(没有多余的空格或换行)
  • 记住签名请求头带有 sha256= 前缀

投递因 4xx 响应失败

4xx 错误(例如 401、404、422)是永久性的,不会重试。先修好端点那边的问题(认证、路由、载荷校验),再从投递日志里使用重新投递。

我的 Webhook 被自动暂停了

在连续 5 次投递死亡之后,ColdSend 会自动暂停该 Webhook。查看投递日志找到根本错误,修好端点后再重新启用它。


常见问题

我可以创建多少个 Webhook? 可以创建多个 Webhook,每个都有自己的端点和事件类型选择——比如一个给 CRM,一个给 Slack 通知。

我会收到所有营销活动的事件吗? 会——一个 Webhook 接收整个工作区(所有营销活动)的事件,只按你选择的事件类型过滤。

如果我的端点挂了会怎样? ColdSend 会用指数退避重试(约 1 分钟、约 5 分钟、约 30 分钟)。如果全部重试失败,这次投递会被标记为 dead。连续 5 次投递死亡后,Webhook 会被自动暂停。

我可以为现有的 Webhook 获取新的签名密钥吗? 不行——密钥只在创建时显示一次,无法再次查看或重新生成。要轮换密钥,请删除该 Webhook 并新建一个。

Webhook 投递是否保证恰好一次? 不保证——投递是至少一次。极少数情况下,同一事件可能被投递两次。请在你这边用 event_id 字段去重。

ColdSend 会补发我创建 Webhook 之前发生的事件吗? 不会。你只会收到 Webhook 创建并启用之后发生的事件。

相关 指南