Connecteur Calendly

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
PlateformeCalendly
CatégoriePlanification (Custom)
Complexité d’installationFacile
Intégration officielleNon
Données synchroniséesÉvénements, contacts, réservations, annulations
Méthode d’authentificationOAuth 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 :

  1. Un compte Calendly (plan Professional ou supérieur pour l’accès API)
  2. Un Personal Access Token depuis Calendly Integrations
  3. Un compte Brevo avec accès API
  4. Un compte Tajo avec les permissions connecteur

Authentification

Personal Access Token

Terminal window
# Générez-le sur https://calendly.com/integrations/api_webhooks
export CALENDLY_ACCESS_TOKEN=your_personal_access_token
export TAJO_API_KEY=your_tajo_api_key
export BREVO_API_KEY=your_brevo_api_key

OAuth 2.0

// Flux OAuth 2.0 Authorization Code
const 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 token
const 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_STATUS

Endpoints API

EndpointMéthodeDescription
https://api.calendly.com/users/meGETObtenir l’utilisateur courant
https://api.calendly.com/event_typesGETLister les types d’événements
https://api.calendly.com/scheduled_eventsGETLister les événements planifiés
https://api.calendly.com/scheduled_events/{uuid}GETObtenir un événement planifié
https://api.calendly.com/scheduled_events/{uuid}/inviteesGETLister les invités
https://api.calendly.com/scheduling_linksPOSTCréer un lien de planification
https://api.calendly.com/webhook_subscriptionsPOSTCréer un webhook
https://api.calendly.com/webhook_subscriptionsGETLister les webhooks
https://api.calendly.com/invitee_no_shows/{uuid}GETObtenir 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és
const 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 Brevo
const 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 Calendly
const 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.tajo.io/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
})
}
);

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

RessourceLimiteNotes
Requêtes API6 000/minLimite à l’échelle de l’organisation
Abonnements webhook30 par organisationTous types d’événements confondus
Liens de planificationIllimité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èmeCauseSolution
Webhook non reçuMauvais scopeUtilisez le scope organization pour les webhooks
401 UnauthorizedToken expiréGénérez un nouveau token ou rafraîchissez le token OAuth
Données d’invité manquantesQuestions non configuréesAjoutez des questions personnalisées au type d’événement
Contacts en doublePas de logique de déduplicationUtilisez l’e-mail comme identifiant unique pour les upserts
Limite de débit 429Trop de requêtesImplémentez un backoff et un groupement de requêtes

Mode debug

connectors:
calendly:
debug: true
log_level: verbose
log_webhooks: true

Bonnes pratiques

  1. Utilisez les webhooks, Abonnez-vous à invitee.created et invitee.canceled pour une synchronisation en temps réel
  2. Ajoutez des questions personnalisées, Collectez entreprise, rôle et téléphone pour des profils de contact plus riches
  3. Mappez les types d’événements, Attribuez différentes listes Brevo par type d’événement Calendly
  4. Gérez les no-shows, Suivez les no-shows pour ajuster le scoring des leads et les séquences de relance
  5. Utilisez les liens de planification, Générez des liens uniques pour des expériences de réservation personnalisées
  6. 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

Ressources associées

Subscribe to updates

developer-docs

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

auto-detect
Assistant AI

Bonjour ! Posez-moi vos questions sur la documentation.