Typeform 连接器

通过 Tajo 将 Typeform 连接到 Brevo,自动同步表单回复,从对话式表单中捕获线索,并根据调查提交和测验结果触发营销自动化。

概览

属性
平台Typeform
类别表单与调查(自定义)
设置复杂度简单
官方集成
同步数据回复、联系人、事件、表单
认证方式OAuth 2.0 / 个人访问令牌

功能

  • 实时回复同步 - 通过 Webhook 自动捕获表单提交
  • 联系人创建 - 从表单回复创建或更新 Brevo 联系人
  • 线索评分 - 使用测验评分和表单数据进行线索资格筛选
  • 隐藏字段 - 通过隐藏字段传递已知客户数据,实现个性化表单
  • 条件映射 - 基于回复逻辑映射不同的表单字段
  • 多表单支持 - 将多个 Typeform 连接到不同的 Brevo 列表

前提条件

开始之前,请确保您已具备:

  1. Typeform 账户(基础版或以上,Webhook 功能需要)
  2. 来自 Typeform 账户设置 的个人访问令牌
  3. 具有 API 访问权限的 Brevo 账户
  4. 具有连接器权限的 Tajo 账户

认证

个人访问令牌

Terminal window
# Generate a token at https://admin.typeform.com/account#/section/tokens
export TYPEFORM_ACCESS_TOKEN=tfp_your_personal_access_token
export TAJO_API_KEY=your_tajo_api_key
export BREVO_API_KEY=your_brevo_api_key

OAuth 2.0

// OAuth 2.0 Authorization Flow
const authUrl = 'https://api.typeform.com/oauth/authorize?' +
new URLSearchParams({
client_id: process.env.TYPEFORM_CLIENT_ID,
redirect_uri: 'https://your-app.com/callback',
scope: 'forms:read responses:read webhooks:write accounts:read',
state: generateState()
});
// Exchange authorization code for access token
const tokenResponse = await fetch('https://api.typeform.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code: authorizationCode,
client_id: process.env.TYPEFORM_CLIENT_ID,
client_secret: process.env.TYPEFORM_CLIENT_SECRET,
redirect_uri: 'https://your-app.com/callback'
})
});

配置

基础设置

connectors:
typeform:
enabled: true
access_token: "${TYPEFORM_ACCESS_TOKEN}"
forms:
- form_id: "abc123"
list_id: 5
mapping:
email_field: "email"
name_field: "full_name"
- form_id: "xyz789"
list_id: 6
mapping:
email_field: "work_email"
sync:
responses: true
contacts: true
events: true
webhook:
enabled: true
secret: "${TYPEFORM_WEBHOOK_SECRET}"

字段映射

field_mapping:
# Map Typeform field references to Brevo attributes
email: email
name: FIRSTNAME
company: COMPANY
phone: SMS
score: LEAD_SCORE
quiz_result: QUIZ_SCORE
nps_rating: NPS_SCORE
feedback: LAST_FEEDBACK

API 端点

端点方法描述
https://api.typeform.com/formsGET列出所有表单
https://api.typeform.com/forms/{form_id}GET检索表单
https://api.typeform.com/formsPOST创建表单
https://api.typeform.com/forms/{form_id}PUT更新表单
https://api.typeform.com/forms/{form_id}/responsesGET检索回复
https://api.typeform.com/forms/{form_id}/responsesDELETE删除回复
https://api.typeform.com/forms/{form_id}/webhooks/{tag}PUT创建/更新 Webhook
https://api.typeform.com/forms/{form_id}/webhooks/{tag}GET获取 Webhook
https://api.typeform.com/forms/{form_id}/webhooksGET列出 Webhook

代码示例

初始化连接器

import { TajoClient } from '@tajo/sdk';
const tajo = new TajoClient({
apiKey: process.env.TAJO_API_KEY,
brevoApiKey: process.env.BREVO_API_KEY
});
await tajo.connectors.connect('typeform', {
accessToken: process.env.TYPEFORM_ACCESS_TOKEN,
forms: ['abc123', 'xyz789']
});

检索表单回复

// Fetch responses using the Responses API
const response = await fetch(
'https://api.typeform.com/forms/abc123/responses?' +
new URLSearchParams({
page_size: 25,
since: '2024-01-01T00:00:00Z',
completed: 'true'
}),
{
headers: {
'Authorization': `Bearer ${process.env.TYPEFORM_ACCESS_TOKEN}`
}
}
);
const data = await response.json();
// Sync each response to Brevo
for (const item of data.items) {
const answers = item.answers;
const email = answers.find(a => a.field.ref === 'email')?.email;
if (email) {
await tajo.contacts.sync({
email,
attributes: {
FIRSTNAME: answers.find(a => a.field.ref === 'name')?.text,
LEAD_SCORE: item.calculated?.score || 0
},
listIds: [5]
});
}
}

设置 Webhook

// Register a webhook for real-time response notifications
await fetch(
'https://api.typeform.com/forms/abc123/webhooks/tajo-sync',
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.TYPEFORM_ACCESS_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://api.tajo.io/webhooks/typeform',
enabled: true,
secret: process.env.TYPEFORM_WEBHOOK_SECRET
})
}
);

处理 Webhook 事件

app.post('/webhooks/typeform', async (req, res) => {
// Verify webhook signature
const signature = req.headers['typeform-signature'];
const isValid = verifyTypeformSignature(
req.rawBody, signature, process.env.TYPEFORM_WEBHOOK_SECRET
);
if (!isValid) return res.status(401).send('Unauthorized');
const { form_response } = req.body;
await tajo.connectors.handleWebhook('typeform', {
topic: 'form_response',
payload: form_response
});
res.status(200).send('OK');
});

速率限制

端点速率限制说明
创建 API2 请求/秒表单创建和更新
回复 API2 请求/秒回复检索
Webhook API2 请求/秒Webhook 管理
所有端点120 请求/分钟全局速率限制

回复分页

回复 API 每次请求最多返回 1,000 条回复。检索大量回复集时,使用 beforeafter 游标参数进行分页。

故障排除

问题原因解决方案
未收到 WebhookWebhook 已禁用在 Typeform 控制台中启用 Webhook
回复缺失应用了过滤条件检查 since/untilcompleted 参数
认证错误 401令牌已过期生成新的个人访问令牌
速率限制 429请求过多实施请求限流
答案为空可选字段处理 null/undefined 答案值

调试模式

connectors:
typeform:
debug: true
log_level: verbose
log_webhooks: true
log_responses: true

最佳实践

  1. 使用 Webhook - 优先使用 Webhook 而非轮询,实现实时回复捕获
  2. 验证签名 - 始终验证 Webhook 签名以确保安全
  3. 使用隐藏字段 - 在表单中预填充已知的客户数据
  4. 映射字段引用 - 使用稳定的字段 ref 值而非字段 ID
  5. 处理部分回复 - 考虑可选和跳过的问题
  6. 设置重试逻辑 - 实施幂等的 Webhook 处理

安全

  • OAuth 2.0 - 范围化的基于令牌的认证
  • Webhook 签名 - SHA-256 HMAC 签名验证
  • 仅 HTTPS - 所有 API 端点需要 TLS
  • 令牌范围 - 请求最低所需的 OAuth 范围
  • 密钥管理 - 在环境变量或密钥管理器中存储令牌
  • GDPR 合规 - 使用删除回复 API 处理数据删除请求

相关资源

Subscribe to updates

developer-docs

Drop your email or phone number — we'll send you what matters next.

auto-detect
AI 助手

你好!关于文档有任何问题都可以问我。