关于 deepgram-webhooks
此技能面向将 Deepgram 转录结果接入应用的开发者,介绍如何处理异步回调。内容涵盖回调身份验证、载荷字段、重试行为和本地测试。
主要功能
- 01处理异步转录回调
- 02使用回调 URL 的 Basic Auth 验证
- 03在存在时检查 dg-token
- 04读取转录结果载荷
- 05使用 Hookdeck CLI 本地测试
适用场景
- 01接收已完成的转录结果
- 02保护 Deepgram 回调端点
- 03在本地开发时检查 webhook 载荷
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ hookdeck/ webhook-skills --skill deepgram-webhooks安装后在 Claude Code 中输入/deepgram-webhooks确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/express/.env.examplepackage.jsonREADME.mdvitest.config.jsexamples/express/src/index.jsexamples/express/test/webhook.test.jsexamples/fastapi/.env.examplemain.pyREADME.mdrequirements.txttest_webhook.pyexamples/nextjs/.env.examplepackage.jsonREADME.mdvitest.config.tsexamples/nextjs/app/webhooks/deepgram/route.tsexamples/nextjs/test/webhook.test.tsreferences/overview.mdsetup.mdverification.md详细介绍
Deepgram Webhooks
何时使用此技能
- 为转录结果设置 Deepgram 回调处理程序
- 处理来自 Deepgram 的异步转录结果
- 为 Deepgram 回调实现 Webhook 身份验证
- 处理转录完成事件
核心代码
Deepgram Webhooks(回调)用于异步接收转录结果。在转录请求中提供回调 URL 后,Deepgram 会立即返回一个 request_id,并在处理完成时将转录结果发送到你的回调 URL。
基本 Webhook 处理程序
// Express.js example
const crypto = require('crypto');
function safeEqual(a, b) {
const ab = Buffer.from(a || '', 'utf8');
const bb = Buffer.from(b || '', 'utf8');
return ab.length === bb.length && crypto.timingSafeEqual(ab, bb);
}
app.post('/webhooks/deepgram', express.raw({ type: 'application/json' }), (req, res) => {
// 1. Primary check: Basic Auth credentials you embedded in the callback URL
// (https://user:[email protected]/webhooks/deepgram)
const auth = req.headers['authorization'] || '';
const decoded = auth.startsWith('Basic ')
? Buffer.from(auth.slice(6), 'base64').toString('utf8')
: '';
const sep = decoded.indexOf(':');
if (
sep === -1 ||
!safeEqual(decoded.slice(0, sep), process.env.DEEPGRAM_CALLBACK_USERNAME) ||
!safeEqual(decoded.slice(sep + 1), process.env.DEEPGRAM_CALLBACK_PASSWORD)
) {
return res.status(401).send('Unauthorized');
}
// 2. Supplementary check: dg-token is NOT sent on every callback,
// so only compare it when it is present
const dgToken = req.headers['dg-token'];
if (dgToken && process.env.DEEPGRAM_API_KEY_ID && !safeEqual(dgToken, process.env.DEEPGRAM_API_KEY_ID)) {
return res.status(403).send('Invalid dg-token');
}
// The callback body is the normal /v1/listen response: { metadata, results }
const payload = JSON.parse(req.body.toString());
const requestId = payload.metadata?.request_id;
const transcript = payload.results?.channels?.[0]?.alternatives?.[0]?.transcript;
console.log('Received transcription:', requestId, transcript);
// Return success to prevent retries
res.status(200).send('OK');
});
身份验证方式
Deepgram 文档介绍了两种回调身份验证方式:
- Basic Auth(主要方式):将凭据嵌入回调 URL;Deepgram 会通过
Authorization: Basic标头发送这些凭据 - dg-token 标头(辅助方式):存在时,其中包含提交请求所用密钥的 API Key Identifier。Deepgram 文档指出,该标头“并不能保证在每个回调请求中都存在”,因此绝不要单独依赖它
// Basic Auth in callback URL (percent-encode special characters in the credentials)
// https://username:[email protected]/webhooks/deepgram
// dg-token: check only when present
const dgToken = req.headers['dg-token'];
if (dgToken && dgToken !== process.env.DEEPGRAM_API_KEY_ID) {
return res.status(403).send('Invalid dg-token');
}
使用回调发起请求
curl \
--request POST \
--header 'Authorization: Token YOUR_DEEPGRAM_API_KEY' \
--header 'Content-Type: audio/wav' \
--data-binary @audio.wav \
--url 'https://api.deepgram.com/v1/listen?callback=https://username:[email protected]/webhooks/deepgram'
常见事件类型
Deepgram 回调不包含事件类型字段。请求正文与同步 /v1/listen 请求返回的 JSON 相同,包含一个 metadata 对象和一个 results 对象。results 的结构会根据请求中启用的功能而变化:
| 字段 | 描述 | 是否始终存在 |
|---|---|---|
metadata.request_id | 转录请求的唯一标识符(与提交请求时返回的 request_id 相同) | 是 |
metadata.created | 转录创建时间戳 | 是 |
metadata.duration | 音频时长,单位为秒 | 是 |
metadata.channels | 音频通道数 | 是 |
metadata.extra | 通过 extra=KEY:VALUE 传入的键值对 | 仅当传入 extra 时存在 |
results.channels[].alternatives | 转录备选结果 | 是 |
results.channels[].alternatives[].transcript | 转录文本 | 是 |
results.channels[].alternatives[].confidence | 置信度分数(0-1) | 是 |
环境变量
# Your Deepgram API Key (for making requests)
DEEPGRAM_API_KEY=your_api_key_here
# Basic Auth credentials you embed in the callback URL (primary check)
DEEPGRAM_CALLBACK_USERNAME=your_callback_username
DEEPGRAM_CALLBACK_PASSWORD=your_callback_password
# Optional: API Key Identifier, used to check the dg-token header when present
# Note: This is NOT your API Key secret - it's a unique identifier shown
# in the Deepgram console that identifies which API key was used for a request
DEEPGRAM_API_KEY_ID=your_api_key_id_here
# Your webhook endpoint URL
WEBHOOK_URL=https://your-domain.com/webhooks/deepgram
本地开发
要在本地测试 Webhook,请安装 Hookdeck CLI:
# Create a local tunnel (no account required)
npx hookdeck-cli listen 3000 deepgram --path /webhooks/deepgram
# Use the provided URL as your callback URL when making Deepgram requests
这将提供:
- 用于测试的本地隧道 URL
- 用于查看 Webhook 负载的 Web UI
- 请求历史记录和调试工具
重要说明
重试行为
- Deepgram 会对失败的回调(状态码非 200-299)最多重试 10 次
- 每次重试间隔 30 秒
- 对于已成功处理的 Webhook,始终返回 200-299 状态码
端口限制
- 回调仅允许使用 80、443、8080 和 8443 端口
- 确保你的 Webhook 端点使用其中一个端口
不验证签名
- Deepgram 不会为回调签名(无 HMAC、无时间戳)
- 使用嵌入回调 URL 的 Basic Auth 凭据进行身份验证;由于
dg-token标头并非每次回调都会发送,因此只能将其用作辅助检查 - Webhook 端点始终使用 HTTPS
资源
- overview.md - Deepgram Webhooks 的定义和转录事件
- setup.md - 在 Deepgram API 请求中配置回调
- verification.md - 身份验证方式和安全注意事项
- examples/ - Express、Next.js 和 FastAPI 的完整实现
推荐:webhook-handler-patterns
对于生产环境中的处理程序,请同时安装此模式技能。关键参考资料(仅安装此技能时也可使用以下链接):
相关技能
- stripe-webhooks - Stripe 支付 Webhook
- shopify-webhooks - Shopify 商店 Webhook
- github-webhooks - GitHub 仓库 Webhook
- webhook-handler-patterns - 幂等性、错误处理、重试逻辑
- hookdeck-event-gateway - 可替代队列的 Webhook 基础设施,为 Webhook 处理程序提供可靠投递、自动重试、重放、速率限制和可观测性
评论
支持 Markdown