Connecteur Typeform
Connectez Typeform à Brevo via Tajo pour synchroniser automatiquement les réponses de formulaires, capturer des leads depuis des formulaires conversationnels, et déclencher des automatisations marketing basées sur les soumissions d’enquêtes et les résultats de quiz.
Vue d’ensemble
| Propriété | Valeur |
|---|---|
| Plateforme | Typeform |
| Catégorie | Formulaires et Enquêtes (Personnalisé) |
| Complexité de configuration | Facile |
| Intégration officielle | Non |
| Données synchronisées | Réponses, Contacts, Événements, Formulaires |
| Méthode d’authentification | OAuth 2.0 / Jeton d’accès personnel |
Fonctionnalités
- Synchronisation des réponses en temps réel - Capture automatique des soumissions de formulaires via webhooks
- Création de contacts - Créer ou mettre à jour des contacts Brevo depuis les réponses de formulaires
- Scoring de leads - Utiliser les scores de quiz et les données de formulaires pour la qualification de leads
- Champs masqués - Transmettre les données clients via des champs masqués pour des formulaires personnalisés
- Mappage conditionnel - Mapper différents champs de formulaires selon la logique de réponse
- Support multi-formulaires - Connecter plusieurs typeforms à différentes listes Brevo
Prérequis
Avant de commencer, assurez-vous d’avoir :
- Un compte Typeform (plan Basic ou supérieur pour les webhooks)
- Un jeton d’accès personnel depuis les paramètres du compte Typeform
- Un compte Brevo avec accès API
- Un compte Tajo avec permissions de connecteur
Authentification
Jeton d’accès personnel
# Générez un jeton sur https://admin.typeform.com/account#/section/tokensexport TYPEFORM_ACCESS_TOKEN=tfp_your_personal_access_tokenexport TAJO_API_KEY=your_tajo_api_keyexport BREVO_API_KEY=your_brevo_api_keyOAuth 2.0
// Flux d'autorisation OAuth 2.0const 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() });
// Échange du code d'autorisation contre un jeton d'accèsconst 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' })});Configuration
Configuration de base
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}"Mappage de champs
field_mapping: # Mapper les références de champs Typeform aux attributs Brevo email: email name: FIRSTNAME company: COMPANY phone: SMS score: LEAD_SCORE quiz_result: QUIZ_SCORE nps_rating: NPS_SCORE feedback: LAST_FEEDBACKEndpoints API
| Endpoint | Méthode | Description |
|---|---|---|
https://api.typeform.com/forms | GET | Lister tous les formulaires |
https://api.typeform.com/forms/{form_id} | GET | Récupérer un formulaire |
https://api.typeform.com/forms | POST | Créer un formulaire |
https://api.typeform.com/forms/{form_id} | PUT | Mettre à jour un formulaire |
https://api.typeform.com/forms/{form_id}/responses | GET | Récupérer les réponses |
https://api.typeform.com/forms/{form_id}/responses | DELETE | Supprimer les réponses |
https://api.typeform.com/forms/{form_id}/webhooks/{tag} | PUT | Créer/mettre à jour un webhook |
https://api.typeform.com/forms/{form_id}/webhooks/{tag} | GET | Obtenir un webhook |
https://api.typeform.com/forms/{form_id}/webhooks | GET | Lister les webhooks |
Exemples de code
Initialiser le connecteur
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']});Récupérer les réponses de formulaires
// Récupérer les réponses via l'API Responsesconst 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();
// Synchroniser chaque réponse vers Brevofor (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] }); }}Configurer les webhooks
// Enregistrer un webhook pour des notifications de réponses en temps réelawait 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 }) });Gérer les événements webhook
app.post('/webhooks/typeform', async (req, res) => { // Vérifier la signature du 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');});Limites de taux
| Endpoint | Limite de taux | Notes |
|---|---|---|
| API Create | 2 requêtes/sec | Création et mise à jour de formulaires |
| API Responses | 2 requêtes/sec | Récupération de réponses |
| API Webhooks | 2 requêtes/sec | Gestion des webhooks |
| Tous les endpoints | 120 requêtes/min | Limite de taux globale |
Pagination des réponses
L’API Responses retourne un maximum de 1 000 réponses par requête. Utilisez les paramètres de curseur before ou after pour la pagination lors de la récupération de grands ensembles de réponses.
Dépannage
| Problème | Cause | Solution |
|---|---|---|
| Webhook non reçu | Webhook désactivé | Activez le webhook dans le tableau de bord Typeform |
| Réponses manquantes | Filtre appliqué | Vérifiez les paramètres since/until et completed |
| Erreur d’auth 401 | Jeton expiré | Générez un nouveau jeton d’accès personnel |
| Limite de taux 429 | Trop de requêtes | Implémentez une limitation de requêtes |
| Réponses vides | Champs optionnels | Gérez les valeurs de réponses null/undefined |
Mode debug
connectors: typeform: debug: true log_level: verbose log_webhooks: true log_responses: trueBonnes pratiques
- Utilisez les webhooks - Privilégiez les webhooks au polling pour capturer les réponses en temps réel
- Validez les signatures - Vérifiez toujours les signatures des webhooks pour la sécurité
- Utilisez les champs masqués - Pré-remplissez les données clients connues dans les formulaires
- Mappez les références de champs - Utilisez les valeurs
refstables des champs plutôt que les IDs - Gérez les réponses partielles - Tenez compte des questions optionnelles et ignorées
- Configurez une logique de retry - Implémentez un traitement webhook idempotent
Sécurité
- OAuth 2.0 - Authentification basée sur jetons avec périmètres
- Signatures webhook - Validation de signature HMAC SHA-256
- HTTPS uniquement - Tous les endpoints API nécessitent TLS
- Périmètres de jetons - Demandez les périmètres OAuth minimaux requis
- Gestion des secrets - Stockez les jetons dans des variables d’environnement ou gestionnaires de secrets
- Conformité RGPD - Utilisez l’API Delete Responses pour les demandes d’effacement de données