在开发期间测试 webhooks 需要您的端点可从公共互联网访问。本指南涵盖几种方法,从快速检查工具到完整的本地开发设置。
方案 1:webhook.site(快速检查)
webhook.site 提供一个临时公共 URL,用于捕获和显示传入的 HTTP 请求。这是无需编写任何代码即可查看 NueForm 发送内容的最快方式。
- 访问 webhook.site。
- 复制唯一的 URL(例如
https://webhook.site/abc123-def456-...)。 - 将其设置为表单的 webhook URL:
curl -X PUT https://app.nueform.com/api/v1/webhooks/form/YOUR_FORM_ID \
-H "Authorization: Bearer nf_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "url": "https://webhook.site/abc123-def456-..." }'
- 向您的表单提交一个回复。
- 刷新 webhook.site 查看捕获的请求,包括头信息、正文和
X-NueForm-Signature。
webhook.site 适合用于检查,但不支持运行自定义验证逻辑。用它来了解负载格式,然后转到本地服务器进行完整测试。
方案 2:ngrok(本地开发)
ngrok 创建从公共 URL 到本地机器的安全隧道。这使您可以在开发服务器上接收真实的 webhook 传递。
设置
- 安装 ngrok:
# macOS (Homebrew)
brew install ngrok
# 或从 https://ngrok.com/download 下载
- 启动本地 webhook 服务器(例如在端口 3001):
node server.js
# 或
python app.py
- 启动 ngrok 隧道:
ngrok http 3001
- 从 ngrok 输出中复制 HTTPS 转发 URL:
Forwarding https://a1b2c3d4.ngrok-free.app -> http://localhost:3001
- 将 ngrok URL 设置为您的 webhook 端点:
curl -X PUT https://app.nueform.com/api/v1/webhooks/form/YOUR_FORM_ID \
-H "Authorization: Bearer nf_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "url": "https://a1b2c3d4.ngrok-free.app/webhooks/nueform" }'
- 向您的表单提交回复。Webhook 将到达您的本地服务器。
检查流量
ngrok 在 http://localhost:4040 提供本地 Web 界面,您可以在其中检查通过隧道的所有请求、重放请求以及查看头信息和响应码。
免费的 ngrok URL 每次重启 ngrok 时都会变化。记得在获得新隧道 URL 时更新 NueForm 中的 webhook URL。考虑升级到付费 ngrok 计划以获得稳定的子域名。
方案 3:curl(模拟负载)
您可以使用 curl 向本地服务器发送测试 webhook 负载,而无需通过 NueForm。这对于单独测试验证和处理逻辑很有用。
生成签名的测试负载
首先,创建测试负载并用 webhook 密钥签名:
# 您的 webhook 密钥(来自 NueForm API 或仪表板)
SECRET="a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
# 测试负载
PAYLOAD='{
"event": "form.submitted",
"formId": "507f1f77bcf86cd799439011",
"formTitle": "Test Form",
"responseId": "507f1f77bcf86cd799439022",
"answers": [
{ "questionId": "507f1f77bcf86cd799439033", "value": "Test answer" },
{ "questionId": "507f1f77bcf86cd799439044", "value": 5 }
],
"submittedAt": "2025-03-15T14:32:07.123Z"
}'
# 计算 HMAC-SHA256 签名
SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $2}')
echo "Signature: $SIGNATURE"
发送签名请求
curl -X POST http://localhost:3001/webhooks/nueform \
-H "Content-Type: application/json" \
-H "X-NueForm-Signature: $SIGNATURE" \
-d "$PAYLOAD"
单行命令
将所有内容合并为一条命令:
SECRET="your_secret_here"
PAYLOAD='{"event":"form.submitted","formId":"507f1f77bcf86cd799439011","formTitle":"Test Form","responseId":"507f1f77bcf86cd799439022","answers":[{"questionId":"q1","value":"hello"}],"submittedAt":"2025-03-15T14:32:07.123Z"}'
SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $2}')
curl -X POST http://localhost:3001/webhooks/nueform \
-H "Content-Type: application/json" \
-H "X-NueForm-Signature: $SIGNATURE" \
-d "$PAYLOAD"
测试签名拒绝
要验证您的端点是否正确拒绝无效签名,发送一个带有错误签名的请求:
curl -X POST http://localhost:3001/webhooks/nueform \
-H "Content-Type: application/json" \
-H "X-NueForm-Signature: 0000000000000000000000000000000000000000000000000000000000000000" \
-d '{"event":"form.submitted","formId":"test","formTitle":"Test","responseId":"test","answers":[],"submittedAt":"2025-03-15T14:32:07.123Z"}'
您的端点应返回 401 Unauthorized。
方案 4:Node.js 测试脚本
创建独立的 Node.js 脚本,快速签名并发送测试负载:
import crypto from 'crypto';
const SECRET = process.env.NUEFORM_WEBHOOK_SECRET || 'your_secret_here';
const ENDPOINT = process.env.WEBHOOK_URL || 'http://localhost:3001/webhooks/nueform';
const payload = JSON.stringify({
event: 'form.submitted',
formId: '507f1f77bcf86cd799439011',
formTitle: 'Customer Feedback Survey',
responseId: crypto.randomUUID().replace(/-/g, '').slice(0, 24),
answers: [
{ questionId: 'q_name', value: 'Jane Doe' },
{ questionId: 'q_email', value: 'jane@example.com' },
{ questionId: 'q_rating', value: 4 },
{ questionId: 'q_feedback', value: 'Great product!' },
{ questionId: 'q_features', value: ['Feature A', 'Feature C'] },
],
submittedAt: new Date().toISOString(),
});
const signature = crypto
.createHmac('sha256', SECRET)
.update(payload)
.digest('hex');
const response = await fetch(ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-NueForm-Signature': signature,
},
body: payload,
});
console.log(`Status: ${response.status}`);
console.log(`Body: ${await response.text()}`);
运行命令:
NUEFORM_WEBHOOK_SECRET=your_secret node test-webhook.mjs
方案 5:触发真实提交
最全面的测试方式是向表单提交实际回复:
- 配置您的 webhook URL(单表单或全局)指向测试端点。
- 在浏览器中打开已发布的表单。
- 填写并提交表单。
- 在端点上观察 webhook 传递。
这会端到端测试整个管道,包括答案验证、测验评分以及 NueForm 生成的实际负载。
调试失败的传递
如果您的 webhook 端点没有收到请求,请按以下检查清单排查:
1. 验证 URL 已配置
# 检查单表单 webhook
curl https://app.nueform.com/api/v1/webhooks/form/YOUR_FORM_ID \
-H "Authorization: Bearer nf_your_api_key"
# 检查全局 webhooks
curl https://app.nueform.com/api/v1/webhooks/global \
-H "Authorization: Bearer nf_your_api_key"
2. 验证 URL 可达
# 测试您的端点是否接受 POST 请求
curl -X POST https://your-endpoint.com/webhooks/nueform \
-H "Content-Type: application/json" \
-d '{"test": true}'
3. 检查 webhook 密钥
只有在您的账户设置了 webhook 密钥时,webhooks 才会被分发。验证:
curl https://app.nueform.com/api/v1/webhooks/secret \
-H "Authorization: Bearer nf_your_api_key"
如果响应显示密钥,则没问题。如果没有,此请求会自动生成一个。
4. 检查您的计划
Webhooks 需要 Pro 计划或更高级别。在 NueForm 仪表板的账户设置中验证您的计划状态。
5. 检查超时
NueForm 有 5 秒超时。如果您的端点响应时间超过此限制,请求将被中止。确保您立即返回 200 OK 并在后台处理数据。
6. 检查防火墙和网络规则
确保您的服务器允许来自外部来源的 POST 请求。如果您在防火墙或 VPN 后面,可能需要将 NueForm 的 IP 范围添加到白名单或使用 ngrok。
常见测试错误
| 错误 | 解决方案 |
|---|---|
在签名验证之前使用 express.json() 中间件 | 在 webhook 路由上使用 express.raw({ type: 'application/json' }) |
| 使用已撤销或过期的 API 密钥进行测试 | 生成新的 API 密钥 |
| 忘记启用全局 webhooks | 在每个全局 webhook 条目上设置 "enabled": true |
| webhook URL 使用 HTTP 而非 HTTPS | NueForm 发送到您提供的任何 URL,但在生产中请使用 HTTPS |
| 未检查是否有 webhook 密钥 | 在期望传递之前确保您的账户有 webhook 密钥 |