---
title: "Typeform 커넥터"
description: "Tajo를 통해 Typeform의 폼 응답, 설문 조사, 대화형 데이터 수집을 Brevo와 동기화하는 완전한 통합 가이드입니다."
url: https://tajo.io/kr/docs/connectors/custom/typeform/
markdown: https://tajo.io/kr/docs/connectors/custom/typeform.md
lang: ko-KR
robots: noindex
---

Tajo 사전 이용 신청

이름과 회사 이메일 주소를 입력하세요. Tajo 이용 신청을 확인할 수 있는 링크를 이메일로 보내드립니다.

# Typeform 커넥터

커넥터 상태: 예정 아직 구축되지 않았습니다. Tajo는 현재 이 커넥터를 실행하지 않습니다.

| 원본 필드 | 대상 필드 | 예시 값 |
| --- | --- | --- |
| `record.id` | `source_id` | `record_1042` |
| `record.updated_at` | `updated_at` | `2026-10-18T08:00:00Z` |
| `record.value` | `value` | `sample_value` |

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

## 개요

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

## 기능

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

## 사전 요구 사항

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

1. Typeform 계정 (웹훅용 Basic 요금제 이상)
2. [Typeform 계정 설정](https://admin.typeform.com/account#/section/tokens)의 개인 액세스 토큰
3. API 접근이 가능한 Brevo 계정
4. 커넥터 권한이 있는 Tajo 계정

## 인증

### 개인 액세스 토큰

```bash
# 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

```javascript
// 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'
  })
});
```

## 구성

### 기본 설정

```yaml
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}"
```

### 필드 매핑

```yaml
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/forms` | GET | 모든 폼 목록 |
| `https://api.typeform.com/forms/{form_id}` | GET | 폼 가져오기 |
| `https://api.typeform.com/forms` | POST | 폼 생성 |
| `https://api.typeform.com/forms/{form_id}` | PUT | 폼 업데이트 |
| `https://api.typeform.com/forms/{form_id}/responses` | GET | 응답 가져오기 |
| `https://api.typeform.com/forms/{form_id}/responses` | DELETE | 응답 삭제 |
| `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}/webhooks` | GET | 웹훅 목록 |

## 코드 예제

### 커넥터 초기화

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

### 폼 응답 가져오기

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

### 웹훅 설정

```javascript
// 실시간 응답 알림을 위한 웹훅 등록
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.example.com/webhooks/typeform',
      enabled: true,
      secret: process.env.TYPEFORM_WEBHOOK_SECRET
    })
  }
);
```

Caution

위의 `example.com` 주소는 Tajo 엔드포인트가 제공될 때까지 사용하는 자리표시자입니다.

### 웹훅 이벤트 처리

```javascript
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 API | 2 요청/초 | 폼 생성 및 업데이트 |
| Responses API | 2 요청/초 | 응답 가져오기 |
| Webhooks API | 2 요청/초 | 웹훅 관리 |
| 모든 엔드포인트 | 120 요청/분 | 전역 속도 제한 |

응답 페이지네이션

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

## 문제 해결

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

### 디버그 모드

```yaml
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 사용

## 관련 리소스

- [Calendly 커넥터](https://tajo.io/kr/docs/connectors/custom/calendly)
- [Zapier 커넥터](https://tajo.io/kr/docs/connectors/custom/zapier)
- [고객 동기화 스킬](https://tajo.io/kr/docs/skills/data-sync/customer-sync)
- [Typeform 개발자 문서](https://www.typeform.com/developers/)
