Typeform コネクタ

Tajo を介して Typeform を Brevo に接続し、フォーム回答を自動的に同期し、会話型フォームからリードをキャプチャし、アンケート送信やクイズ結果に基づいてマーケティング自動化をトリガーします。

概要

プロパティ
プラットフォームTypeform
カテゴリフォームとアンケート(カスタム)
セットアップの複雑さ簡単
公式統合いいえ
同期データ回答、連絡先、イベント、フォーム
認証方式OAuth 2.0 / Personal Access Token

機能

  • リアルタイム回答同期 - Webhook を介してフォーム送信を自動キャプチャ
  • 連絡先作成 - フォーム回答から Brevo 連絡先を作成または更新
  • リードスコアリング - クイズスコアとフォームデータをリード評価に使用
  • Hidden Fields - Hidden Fields を介して顧客データを渡してパーソナライズされたフォームを実現
  • 条件付きマッピング - 回答ロジックに基づいて異なるフォームフィールドをマッピング
  • マルチフォームサポート - 複数の Typeform を異なる Brevo リストに接続

前提条件

開始する前に、以下を準備してください。

  1. Typeform アカウント(Webhook は Basic プラン以上が必要)
  2. Typeform Account Settings からの Personal Access Token
  3. API アクセス可能な Brevo アカウント
  4. コネクタ権限を持つ Tajo アカウント

認証

Personal Access Token

Terminal window
# 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 認可フロー
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()
});
// 認可コードをアクセストークンと交換
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:
# Typeform のフィールド参照を Brevo 属性にマッピング
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}PUTWebhook を作成/更新
https://api.typeform.com/forms/{form_id}/webhooks/{tag}GETWebhook を取得
https://api.typeform.com/forms/{form_id}/webhooksGETWebhook を一覧取得

コード例

コネクタの初期化

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']
});

フォーム回答の取得

// 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();
// 各回答を 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 の設定

// リアルタイム回答通知用の Webhook を登録
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) => {
// Webhook 署名を検証
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');
});

レート制限

エンドポイントレート制限備考
Create API2 リクエスト/秒フォームの作成と更新
Responses API2 リクエスト/秒回答の取得
Webhooks API2 リクエスト/秒Webhook 管理
すべてのエンドポイント120 リクエスト/分グローバルレート制限

回答のページネーション

Responses API はリクエストあたり最大 1,000 件の回答を返します。大量の回答セットを取得する際は、ページネーションに before または after カーソルパラメータを使用してください。

トラブルシューティング

問題原因解決策
Webhook を受信できないWebhook が無効化されているTypeform ダッシュボードで Webhook を有効化
回答の欠落フィルタが適用されているsince/untilcompleted パラメータを確認
認証エラー 401トークンの期限切れ新しい Personal Access Token を生成
レート制限 429リクエスト過多リクエストスロットリングを実装
回答が空任意のフィールドnull/undefined の回答値を処理

デバッグモード

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

ベストプラクティス

  1. Webhook を使用する - リアルタイム回答キャプチャにはポーリングよりも Webhook を優先
  2. 署名を検証する - セキュリティのため常に Webhook 署名を検証
  3. Hidden Fields を使用する - フォームに既知の顧客データを事前入力
  4. フィールド参照をマッピングする - フィールド ID の代わりに安定した ref 値を使用
  5. 部分的な回答を処理する - 任意のフィールドやスキップされた質問を考慮
  6. リトライロジックを設定する - 冪等な Webhook 処理を実装

セキュリティ

  • OAuth 2.0 - スコープ付きトークンベース認証
  • Webhook 署名 - SHA-256 HMAC 署名検証
  • HTTPS のみ - すべての API エンドポイントに TLS が必要
  • トークンスコープ - 必要最小限の OAuth スコープをリクエスト
  • シークレット管理 - トークンを環境変数またはシークレットマネージャーに保存
  • GDPR コンプライアンス - データ消去リクエストには Delete Responses API を使用

関連リソース

Subscribe to updates

developer-docs

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

auto-detect
AIアシスタント

こんにちは!ドキュメントについて何でもお聞きください。