跳到主要内容

Webhook 自动化

Basic 套餐及以上

Webhook 需要付费套餐。Basic:1 个 Webhook,Pro:3 个,Ultra:10 个。

Webhook 让你把 TellDone 连接到任意外部服务。当你创建语音笔记时,TellDone 处理后会自动把提取出的数据 - 笔记、任务、事件和报告 - 发送到你指定的 URL。每个任务和事件作为独立的投递发送,所以你的自动化工具可以分别处理它们。

选择发送什么

每个自动化都有自己的载荷开关。任选一个或任意组合:

  • 笔记 - 完整的处理后笔记(标题、转录文本、摘要、标签、语言)
  • 音频 - 在 Ultra 套餐上,随笔记载荷附上一个 24 小时有效的音频文件下载链接
  • 任务 - 每个提取的任务一个投递
  • 事件 - 每个提取的日历事件一个投递
  • 报告 - 每份生成的每日、每周、每月或每年报告一个投递

你可以随时在自动化的设置中更改开关 - 更改仅对新事件生效。

设置 Webhook

Zapier、Make 和 n8n 自动化设置

  1. 进入**「设置 > 集成 > Webhook 自动化」**
  2. 点按新建自动化

新建自动化 Webhook 设置

  1. 输入名称(例如「我的 Zapier Webhook」)
  2. 粘贴你自动化服务的 Webhook URL
  3. 选择要发送的数据:笔记、任务、事件、报告(或任意组合)
  4. 可选地添加认证头 - 作为 Authorization 头发送的令牌,用于安全端点
  5. 点按保存
  6. 复制签名密钥 - 只在创建时或轮换时完整显示。如果你想验证 Webhook 真实性会用到它
  7. 点按**「测试」**向你的端点发送一个示例载荷,不会创建真实事件
提示

Webhook URL 必须使用 HTTPS。HTTP 地址和私有网络 IP 不会被接受。

发送的内容

每个投递是一个 JSON 对象,包含三个字段:event(事件类型)、timestampdata(实际内容)。下面是每种事件类型的样子。

笔记(note.created

包含 AI 生成的标题、完整转录文本、摘要、笔记类型、标签、优先级、语言和创建日期。

{
"event": "note.created",
"timestamp": "2026-02-27T14:38:00Z",
"data": {
"note_id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Meeting notes - Project Alpha",
"transcript": "Full transcript text...",
"summary": "Brief AI-generated summary...",
"type": "meeting",
"tags": ["work", "project-alpha"],
"priority": "high",
"language": "en",
"created_at": "2026-02-27T10:00:00Z"
}
}

Ultra 套餐上,笔记投递还可以包含指向音频录音的链接(audio_urlaudio_formatduration_seconds)。链接 24 小时后过期。在创建自动化时通过「Note + Audio」选项启用。

任务(task.created

每个任务一个投递。一条带 3 个任务的笔记会发送 3 个独立的 Webhook。

{
"event": "task.created",
"timestamp": "2026-02-27T14:38:01Z",
"data": {
"note_id": "550e8400-...",
"note_title": "Meeting notes - Project Alpha",
"task_id": "660f9511-...",
"title": "Send proposal to client",
"description": "Include pricing for Q2",
"priority": "high",
"due_date": "2026-03-01",
"reminder_at": "2026-02-28T09:00:00Z",
"tags": ["work"],
"status": "todo",
"created_at": "2026-02-27T10:00:00Z"
}
}

事件(calendar_event.created

每个日历事件一个投递。

{
"event": "calendar_event.created",
"timestamp": "2026-02-27T14:38:02Z",
"data": {
"note_id": "550e8400-...",
"note_title": "Meeting notes",
"event_id": "770a0622-...",
"title": "Team standup",
"description": "Weekly sync",
"start": "2026-03-03T10:00:00+03:00",
"end": "2026-03-03T10:30:00+03:00",
"location": "Zoom",
"is_all_day": false,
"attendees": ["alice@example.com"],
"tags": ["work"],
"created_at": "2026-02-27T10:00:00Z"
}
}

报告(report.created

当生成每日、每周、每月或每年报告时发送。

{
"event": "report.created",
"timestamp": "2026-02-28T00:05:00Z",
"data": {
"report_id": "880b1733-...",
"report_type": "daily",
"period_start": "2026-02-27",
"period_end": "2026-02-27",
"content_md": "# Daily Report\n\n...",
"content_json": {
"productivity_score": 72,
"day_type": "productive",
"tasks_created": 5,
"tasks_completed": 3
},
"created_at": "2026-02-28T00:05:00Z"
}
}

安全

每个投递都使用你自动化的签名密钥经 HMAC-SHA256 签名。每个投递都会包含以下头:

  • X-LP-Signature - HMAC-SHA256 签名(sha256=...
  • X-LP-Timestamp - 用于签名的 Unix 时间戳
  • X-LP-Event - 事件类型(note.createdtask.createdcalendar_event.createdreport.created
  • X-LP-Delivery-Id - 唯一投递 ID(用于去重)
  • User-Agent - 始终是 TellDone-Webhooks/1.0

签名头会随每个投递发送,与其他设置无关。

如果你在自动化设置中设置了认证头,它会作为 Authorization 头随每个投递发送。如果认证头字段为空,则不发送 Authorization 头。这个值可以是任意字符串 - TellDone 原样转发,不添加任何前缀。

每个自动化都有自己的签名密钥,所以轮换一个不会影响你其他的 Webhook。签名密钥只在创建自动化时或点按**「轮换密钥」时完整显示一次 - 之后只能看到末尾几位字符。要换新的,请在自动化设置中点按「轮换密钥」** - 这会生成新的 HMAC 密钥,URL 和认证头不变。旧密钥立即失效。

只接受 HTTPS URL。HTTP、IP 地址和私有网络地址会被拒绝。

验证 Webhook 签名

验证 HMAC

每个投递包含一个签名头,形如 X-LP-Signature: sha256=<hex>。下面的示例展示如何在 Python 中验证。

每个 Webhook 都经过签名,让你能确认它确实来自 TellDone。签名计算如下:

HMAC-SHA256(signing_secret, timestamp + "." + raw_body)

结果以十六进制编码,并在签名头中加 sha256= 前缀。

使用原始请求体

TellDone 序列化 JSON 时分隔符后带空格(例如 {"event": "note.created"})。如果你解析后再重新序列化主体,签名将不匹配。请始终对请求主体的原始字节进行验证。

Python

import hmac
import hashlib

def verify_signature(raw_body: bytes, signature: str, timestamp: str, secret: str) -> bool:
payload = f"{timestamp}.".encode() + raw_body
expected = "sha256=" + hmac.new(
secret.encode(), payload, hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)

# Flask example
@app.route("/webhook/telldone", methods=["POST"])
def telldone_webhook():
raw_body = request.get_data() # raw bytes, NOT request.json
signature = request.headers.get("X-LP-Signature", "")
timestamp = request.headers.get("X-LP-Timestamp", "")

if not verify_signature(raw_body, signature, timestamp, SIGNING_SECRET):
abort(403)

data = request.json
# process webhook...

Node.js

const crypto = require("crypto");

function verifySignature(rawBody, signature, timestamp, secret) {
const payload = `${timestamp}.${rawBody}`;
const expected =
"sha256=" +
crypto.createHmac("sha256", secret).update(payload).digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}

// Express example (use express.raw to get the raw body)
app.post("/webhook/telldone", express.raw({ type: "application/json" }), (req, res) => {
const rawBody = req.body.toString();
const signature = req.headers["x-lp-signature"] || "";
const timestamp = req.headers["x-lp-timestamp"] || "";

if (!verifySignature(rawBody, signature, timestamp, SIGNING_SECRET)) {
return res.status(403).send("Invalid signature");
}

const data = JSON.parse(rawBody);
// process webhook...
});

重放保护(可选)

为了防止重放攻击,请检查时间戳是否较新:

import time

def verify_timestamp(timestamp: str, tolerance_seconds: int = 300) -> bool:
try:
return abs(time.time() - int(timestamp)) < tolerance_seconds
except (ValueError, TypeError):
return False

常见错误

错误修正
使用解析 + 重新序列化的主体使用原始请求体
JS 中使用 JSON.stringify()(紧凑、无空格)使用原始主体或匹配 Python 的间距
忘记时间戳前缀载荷格式为 timestamp + "." + body
直接比较字符串使用 hmac.compare_digesttimingSafeEqual

重试策略

如果你的端点失败,TellDone 会以指数退避(先几分钟,然后更长间隔)重试每个投递:

尝试延迟
第 1 次重试30 秒
第 2 次重试2 分钟
第 3 次重试15 分钟
第 4 次重试1 小时
第 5 次重试4 小时

5 次失败尝试后,投递会标记为失效。你仍然可以在投递日志中手动重试。

TellDone 如何处理不同的响应:

  • 2xx - 投递成功
  • 4xx(除 429 外) - 立即标记失效,不重试(你的端点明确拒绝了数据)
  • 429(Too Many Requests) - 重试,遵守 Retry-After
  • 5xx 或超时 - 按上面的计划重试

投递反复失败时

你不必盯着投递日志才能知道哪里坏了。TellDone 会替你监控连续失败,并分两阶段触达你。

3 次失败后:收件箱警告

连续 3 次投递失败后,TellDone 会在你的收件箱中创建一条**「Webhook 失败」类别的消息。消息会指出受影响的自动化,并直接链接到「设置 > 集成 > 自动化 > [失败的自动化] > 投递日志」**,让你检查响应并决定下一步。

提示

收件箱警告意味着你能从应用图标徽章发现自动化坏了,而不是几周后从下游工具的数据缺失里才发现。

20 次失败后:自动禁用

自动禁用

如果同一个自动化连续 20 次投递失败(在收件箱警告之后开始计数),TellDone 会自动关闭该自动化,停止 ping 已坏的端点,并保护你的每月投递配额。在目的地修复问题后,再到**「设置 > 集成 > 自动化」**重新启用该自动化。

下次投递成功时,连续失败计数器会归零。

管理 Webhook

  • 暂停/恢复 - 不删除任何自动化也能禁用,随时重新启用
  • 投递日志 - 查看所有投递,包括状态、HTTP 代码和响应时间。按已投递或错误筛选。点按任意失败的投递,选择**「重试」**重新发送,无需等待下一次计划重试
  • 测试 - 点按**「测试」**向你的端点发送一个示例载荷(主体中带 "test": true),不会创建真实事件。测试发送不计入你的每月配额
  • 轮换密钥 - 生成新的 HMAC 签名密钥,URL 或认证头不变
  • 编辑 - 更新 URL、认证头或载荷开关(笔记 / 音频 / 任务 / 事件 / 报告)。更改立即生效
  • 删除 - 永久移除自动化及其所有投递日志

投递限制

Webhook 投递有两个限制:每月配额(硬性限制,按套餐不同)和每小时防爆量限制(柔性限制,所有付费套餐相同)。

套餐Webhooks每月投递数每小时爆量
Free00-
Basic1300100
Pro33,000100
Ultra1015,000100

Ultra 套餐还支持笔记载荷中的音频链接(24 小时过期)。

这两个限制的行为:

  • 超过每月限额:投递被标记为失败,不会重试。新的投递将在下个月 1 日计数器重置时恢复。
  • 超过每小时限额:投递会延后并在约 5 分钟后重试,所以短时间的爆量不会丢失数据。这是一种柔性的防爆量保护,不是永久拒绝。

测试发送和从投递日志手动重新投递都不计入这两个限制。

过滤测试事件

当你点按**「测试」**时,载荷顶层包含 "test": true。在你的自动化工具中,可以检查这个字段,存在时跳过处理。

平台指南

各自动化工具的逐步设置说明:

  • Zapier - 通过 Zaps 把 TellDone 连接到上千个应用
  • Make - 构建可视化的自动化场景(前身为 Integromat)
  • n8n - 在自托管或云端工作流中使用 TellDone Webhook
  • 自定义端点 - 任何接受 HTTPS POST 请求的服务都能配合 TellDone Webhook

常见用例

  • 通过 Zapier 把任务发送到 Google Sheet
  • 通过 Make 把笔记变成 Slack 消息
  • 通过 n8n 把事件记录到自定义 CRM
  • 把所有笔记备份到云存储
  • 把报告转发到团队仪表盘

另见

  • 收件箱与支持 - 如果 Webhook 反复失败,你会在收件箱看到消息
  • Zapier - 逐步 Zapier 设置
  • Make - 逐步 Make 设置
  • n8n - 逐步 n8n 设置
  • Todoist - 专门的双向任务同步(无需 Webhook)
  • Notion - 专门的 Notion 集成
  • 邮件转发 - 通过邮件接收笔记数据