Connecteur Calendly
Statut du connecteur: Prévu Pas encore construit. Tajo n'exécute pas ce connecteur aujourd'hui.
Illustration · données d’exemple
Exemple de synchronisation
Source
Calendly
Statut du connecteur: Prévu
Destination
Votre autre outil
Statut du connecteur: Outil personnalisé
Correspondance des champs
| Champ source | Champ de destination | Valeur d’exemple |
|---|---|---|
record.id | source_id | record_1042 |
record.updated_at | updated_at | 2026-10-18T08:00:00Z |
record.value | value | sample_value |
- Préparer
- Vérifier un enregistrement
- Approuver cette version
Les statuts concernent chaque connecteur et ne garantissent pas que cette synchronisation soit prête. Champs illustratifs. Vérifiez le schéma réel et les autorisations avant toute synchronisation.
Connectez Calendly à Brevo via Tajo pour synchroniser automatiquement les invités de réunion en tant que contacts, déclencher des séquences e-mail selon les événements de réservation et fluidifier vos workflows commerciaux et d’onboarding.
Vue d’ensemble
| Propriété | Valeur |
|---|---|
| Plateforme | Calendly |
| Catégorie | Planification (Custom) |
| Complexité d’installation | Facile |
| Intégration officielle | Non |
| Données synchronisées | Événements, contacts, réservations, annulations |
| Méthode d’authentification | OAuth 2.0 / Personal Access Token |
Fonctionnalités
- Synchronisation des invités, Créez automatiquement des contacts Brevo à partir des invités de réunion
- Déclencheurs de réservation, Lancez des automatisations Brevo lors de la réservation de réunions
- Gestion des annulations, Déclenchez des flux de réengagement en cas d’annulation
- Détection des no-shows, Mettez à jour le statut du contact quand un invité manque une réunion
- Mappage des types d’événements, Mappez différents types d’événements Calendly vers des listes Brevo
- Scheduling API, Intégrez la planification directement dans votre application sans redirections
Prérequis
Avant de commencer, assurez-vous de disposer de :
- Un compte Calendly (plan Professional ou supérieur pour l’accès API)
- Un Personal Access Token depuis Calendly Integrations
- Un compte Brevo avec accès API
- Un compte Tajo avec les permissions connecteur
Authentification
Personal Access Token
# Générez-le sur https://calendly.com/integrations/api_webhooksexport CALENDLY_ACCESS_TOKEN=your_personal_access_tokenexport TAJO_API_KEY=your_tajo_api_keyexport BREVO_API_KEY=your_brevo_api_keyOAuth 2.0
// Flux OAuth 2.0 Authorization Codeconst authUrl = 'https://auth.calendly.com/oauth/authorize?' + new URLSearchParams({ client_id: process.env.CALENDLY_CLIENT_ID, redirect_uri: 'https://your-app.com/callback', response_type: 'code' });
// Échanger le code contre un tokenconst tokenResponse = await fetch('https://auth.calendly.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.CALENDLY_CLIENT_ID, client_secret: process.env.CALENDLY_CLIENT_SECRET, redirect_uri: 'https://your-app.com/callback' })});Configuration
Configuration de base
connectors: calendly: enabled: true access_token: "${CALENDLY_ACCESS_TOKEN}"
sync: contacts: true events: true cancellations: true
event_mapping: discovery_call: list_id: 10 event_type_uri: "https://api.calendly.com/event_types/abc123" demo: list_id: 11 event_type_uri: "https://api.calendly.com/event_types/xyz789"
webhook: signing_key: "${CALENDLY_WEBHOOK_SIGNING_KEY}"Mappage des champs
field_mapping: email: email name: FIRSTNAME questions_and_answers: company: COMPANY role: JOB_TITLE phone: SMS event_type_name: CALENDLY_EVENT_TYPE scheduled_at: MEETING_DATE status: BOOKING_STATUSEndpoints API
| Endpoint | Méthode | Description |
|---|---|---|
https://api.calendly.com/users/me | GET | Obtenir l’utilisateur courant |
https://api.calendly.com/event_types | GET | Lister les types d’événements |
https://api.calendly.com/scheduled_events | GET | Lister les événements planifiés |
https://api.calendly.com/scheduled_events/{uuid} | GET | Obtenir un événement planifié |
https://api.calendly.com/scheduled_events/{uuid}/invitees | GET | Lister les invités |
https://api.calendly.com/scheduling_links | POST | Créer un lien de planification |
https://api.calendly.com/webhook_subscriptions | POST | Créer un webhook |
https://api.calendly.com/webhook_subscriptions | GET | Lister les webhooks |
https://api.calendly.com/invitee_no_shows/{uuid} | GET | Obtenir le statut no-show |
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('calendly', { accessToken: process.env.CALENDLY_ACCESS_TOKEN});Lister les événements planifiés
// Récupérer les événements planifiésconst response = await fetch( 'https://api.calendly.com/scheduled_events?' + new URLSearchParams({ user: 'https://api.calendly.com/users/YOUR_USER_ID', min_start_time: '2024-01-01T00:00:00Z', max_start_time: '2024-12-31T23:59:59Z', status: 'active', count: 100 }), { headers: { 'Authorization': `Bearer ${process.env.CALENDLY_ACCESS_TOKEN}`, 'Content-Type': 'application/json' } });
const events = await response.json();Synchroniser les invités vers Brevo
// Obtenir les invités d'un événement planifié et les synchroniser vers Brevoconst inviteesResponse = await fetch( `https://api.calendly.com/scheduled_events/${eventUuid}/invitees`, { headers: { 'Authorization': `Bearer ${process.env.CALENDLY_ACCESS_TOKEN}` } });
const { collection } = await inviteesResponse.json();
for (const invitee of collection) { await tajo.contacts.sync({ email: invitee.email, attributes: { FIRSTNAME: invitee.name, CALENDLY_EVENT_TYPE: invitee.event, MEETING_DATE: invitee.created_at, BOOKING_STATUS: invitee.status }, listIds: [10] });}Configurer les abonnements webhook
// S'abonner aux événements Calendlyconst webhook = await fetch( 'https://api.calendly.com/webhook_subscriptions', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.CALENDLY_ACCESS_TOKEN}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ url: 'https://api.example.com/webhooks/calendly', events: [ 'invitee.created', 'invitee.canceled', 'invitee_no_show.created' ], organization: 'https://api.calendly.com/organizations/YOUR_ORG_ID', scope: 'organization', signing_key: process.env.CALENDLY_WEBHOOK_SIGNING_KEY }) });Caution
L’adresse example.com ci-dessus est un exemple provisoire en attendant que l’endpoint Tajo soit disponible.
Gérer les événements webhook
app.post('/webhooks/calendly', async (req, res) => { // Vérifier la signature du webhook const signature = req.headers['calendly-webhook-signature']; const isValid = verifyCalendlySignature( req.rawBody, signature, process.env.CALENDLY_WEBHOOK_SIGNING_KEY );
if (!isValid) return res.status(401).send('Unauthorized');
const { event, payload } = req.body;
switch (event) { case 'invitee.created': await tajo.contacts.sync({ email: payload.email, attributes: { BOOKING_STATUS: 'booked' }, listIds: [10] }); break; case 'invitee.canceled': await tajo.contacts.update(payload.email, { attributes: { BOOKING_STATUS: 'cancelled' } }); break; case 'invitee_no_show.created': await tajo.contacts.update(payload.email, { attributes: { BOOKING_STATUS: 'no_show' } }); break; }
res.status(200).send('OK');});Limites de débit
| Ressource | Limite | Notes |
|---|---|---|
| Requêtes API | 6 000/min | Limite à l’échelle de l’organisation |
| Abonnements webhook | 30 par organisation | Tous types d’événements confondus |
| Liens de planification | Illimité | Pas de limite par minute |
Pagination
Les réponses de l’API Calendly utilisent une pagination basée sur un curseur. Utilisez next_page_token de l’objet pagination pour récupérer les résultats suivants. La taille de page par défaut est 20 éléments, avec un maximum de 100.
Dépannage
| Problème | Cause | Solution |
|---|---|---|
| Webhook non reçu | Mauvais scope | Utilisez le scope organization pour les webhooks |
| 401 Unauthorized | Token expiré | Générez un nouveau token ou rafraîchissez le token OAuth |
| Données d’invité manquantes | Questions non configurées | Ajoutez des questions personnalisées au type d’événement |
| Contacts en double | Pas de logique de déduplication | Utilisez l’e-mail comme identifiant unique pour les upserts |
| Limite de débit 429 | Trop de requêtes | Implémentez un backoff et un groupement de requêtes |
Mode debug
connectors: calendly: debug: true log_level: verbose log_webhooks: trueBonnes pratiques
- Utilisez les webhooks, Abonnez-vous à
invitee.createdetinvitee.canceledpour une synchronisation en temps réel - Ajoutez des questions personnalisées, Collectez entreprise, rôle et téléphone pour des profils de contact plus riches
- Mappez les types d’événements, Attribuez différentes listes Brevo par type d’événement Calendly
- Gérez les no-shows, Suivez les no-shows pour ajuster le scoring des leads et les séquences de relance
- Utilisez les liens de planification, Générez des liens uniques pour des expériences de réservation personnalisées
- Définissez un scope organisation, Utilisez des webhooks au niveau org pour capter les événements de tous les membres
Sécurité
- OAuth 2.0, Authentification basée sur des tokens à portée limitée
- Signatures des webhooks, Validation HMAC des webhooks entrants
- HTTPS uniquement, Tous les endpoints API nécessitent un chiffrement TLS
- Expiration des tokens, Les tokens OAuth expirent et nécessitent des flux de rafraîchissement
- Scopes minimaux, Demandez uniquement les scopes OAuth nécessaires
- Stockage sécurisé, Stockez les tokens dans des variables d’environnement ou des gestionnaires de secrets