Typeform 커넥터

Tajo를 통해 Typeform을 Brevo에 연결하여 폼 응답을 자동으로 동기화하고, 대화형 폼에서 리드를 캡처하며, 설문 제출 및 퀴즈 결과를 기반으로 마케팅 자동화를 트리거하십시오.

개요

속성
플랫폼Typeform
카테고리폼 및 설문 조사 (Custom)
설정 복잡도쉬움
공식 통합아니오
동기화 데이터응답, 연락처, 이벤트, 폼
인증 방법OAuth 2.0 / 개인 액세스 토큰

기능

  • 실시간 응답 동기화 - 웹훅을 통해 폼 제출을 자동으로 캡처
  • 연락처 생성 - 폼 응답에서 Brevo 연락처 생성 또는 업데이트
  • 리드 점수 산출 - 퀴즈 점수 및 폼 데이터를 리드 자격 부여에 활용
  • Hidden Fields - 맞춤형 폼을 위해 Hidden Fields를 통해 고객 데이터 전달
  • 조건부 매핑 - 응답 로직에 따라 다양한 폼 필드 매핑
  • 다중 폼 지원 - 여러 typeform을 다른 Brevo 목록에 연결

사전 요구 사항

시작하기 전에 다음이 준비되어 있는지 확인하십시오.

  1. Typeform 계정 (웹훅용 Basic 요금제 이상)
  2. Typeform 계정 설정의 개인 액세스 토큰
  3. API 접근이 가능한 Brevo 계정
  4. 커넥터 권한이 있는 Tajo 계정

인증

개인 액세스 토큰

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}PUT웹훅 생성/업데이트
https://api.typeform.com/forms/{form_id}/webhooks/{tag}GET웹훅 가져오기
https://api.typeform.com/forms/{form_id}/webhooksGET웹훅 목록

코드 예제

커넥터 초기화

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

웹훅 설정

// 실시간 응답 알림을 위한 웹훅 등록
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
})
}
);

웹훅 이벤트 처리

app.post('/webhooks/typeform', async (req, res) => {
// 웹훅 서명 확인
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 요청/초웹훅 관리
모든 엔드포인트120 요청/분전역 속도 제한

응답 페이지네이션

Responses API는 요청당 최대 1,000개의 응답을 반환합니다. 대량의 응답 세트를 가져올 때는 페이지네이션을 위해 before 또는 after 커서 매개변수를 사용하십시오.

문제 해결

문제원인해결 방법
웹훅이 수신되지 않음웹훅이 비활성화됨Typeform 대시보드에서 웹훅 활성화
응답 누락필터 적용됨since/untilcompleted 매개변수 확인
인증 오류 401토큰 만료됨새 개인 액세스 토큰 생성
속도 제한 429너무 많은 요청요청 스로틀링 구현
답변이 비어 있음선택적 필드null/undefined 답변 값 처리

디버그 모드

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

모범 사례

  1. 웹훅 사용 - 실시간 응답 캡처를 위해 폴링보다 웹훅 선호
  2. 서명 검증 - 보안을 위해 항상 웹훅 서명 확인
  3. Hidden Fields 사용 - 폼에 알려진 고객 데이터 미리 채우기
  4. 필드 참조 매핑 - 필드 ID 대신 안정적인 필드 ref 값 사용
  5. 부분 응답 처리 - 선택적 및 건너뛴 질문 고려
  6. 재시도 로직 설정 - 멱등성 웹훅 처리 구현

보안

  • OAuth 2.0 - 범위 지정된 토큰 기반 인증
  • 웹훅 서명 - 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 어시스턴트

안녕하세요! 문서에 대해 무엇이든 물어보세요.