Connettore Calendly

Collega Calendly a Brevo tramite Tajo per sincronizzare automaticamente gli invitati ai meeting come contatti, attivare sequenze email in base agli eventi di prenotazione e snellire i flussi di sales e onboarding.

Panoramica

ProprietàValore
PiattaformaCalendly
CategoriaScheduling (Custom)
Complessità di setupFacile
Integrazione ufficialeNo
Dati sincronizzatiEventi, Contatti, Prenotazioni, Cancellazioni
Metodo di autenticazioneOAuth 2.0 / Personal Access Token

Funzionalità

  • Sync invitati - Crea automaticamente contatti Brevo dagli invitati ai meeting
  • Trigger di prenotazione - Attiva automazioni Brevo quando viene prenotato un meeting
  • Gestione cancellazioni - Attiva flussi di re-engagement in caso di cancellazione
  • Rilevamento no-show - Aggiorna lo stato del contatto quando l’invitato non si presenta
  • Mapping dei tipi di evento - Mappa i vari tipi di evento Calendly su liste Brevo diverse
  • Scheduling API - Costruisci lo scheduling direttamente nella tua app senza redirect

Prerequisiti

Prima di iniziare, assicurati di avere:

  1. Un account Calendly (piano Professional o superiore per l’accesso API)
  2. Un Personal Access Token da Calendly Integrations
  3. Un account Brevo con accesso API
  4. Un account Tajo con permessi sui connettori

Autenticazione

Personal Access Token

Terminal window
# Genera su 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

// Flusso 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'
});
// Scambia il code per 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'
})
});

Configurazione

Setup di 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}"

Mapping dei campi

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

Endpoint API

EndpointMetodoDescrizione
https://api.calendly.com/users/meGETOttieni l’utente corrente
https://api.calendly.com/event_typesGETElenca i tipi di evento
https://api.calendly.com/scheduled_eventsGETElenca gli eventi programmati
https://api.calendly.com/scheduled_events/{uuid}GETOttieni un evento programmato
https://api.calendly.com/scheduled_events/{uuid}/inviteesGETElenca gli invitati
https://api.calendly.com/scheduling_linksPOSTCrea uno scheduling link
https://api.calendly.com/webhook_subscriptionsPOSTCrea un webhook
https://api.calendly.com/webhook_subscriptionsGETElenca i webhook
https://api.calendly.com/invitee_no_shows/{uuid}GETOttieni lo stato di no-show

Esempi di codice

Inizializzare il connettore

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

Elencare gli eventi programmati

// Recupera gli eventi programmati
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();

Sincronizzare gli invitati su Brevo

// Recupera gli invitati di un evento programmato e sincronizzali su 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]
});
}

Configurare le sottoscrizioni webhook

// Sottoscrivi gli eventi 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
})
}
);

Gestire gli eventi webhook

app.post('/webhooks/calendly', async (req, res) => {
// Verifica la firma del 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');
});

Limiti di rate

RisorsaLimiteNote
Richieste API6.000/minLimite a livello di organizzazione
Sottoscrizioni webhook30 per organizzazioneSu tutti i tipi di evento
Scheduling linkIllimitatiNessun limite al minuto

Paginazione

Le risposte dell’API Calendly usano paginazione basata su cursor. Usa next_page_token dall’oggetto pagination per recuperare i risultati successivi. La dimensione pagina di default è 20 elementi, con un massimo di 100.

Risoluzione dei problemi

ProblemaCausaSoluzione
Webhook non ricevutoScope erratoUsa lo scope organization per i webhook
401 UnauthorizedToken scadutoGenera un nuovo token o fai il refresh OAuth
Dati invitato mancantiDomande non configurateAggiungi domande personalizzate al tipo di evento
Contatti duplicatiNessuna logica di dedupUsa l’email come identificatore univoco per gli upsert
Rate limit 429Troppe richiesteImplementa backoff e batching delle richieste

Modalità debug

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

Best practice

  1. Usa i webhook - Sottoscrivi invitee.created e invitee.canceled per il sync in real-time
  2. Aggiungi domande personalizzate - Raccogli dati su azienda, ruolo e telefono per profili contatto più ricchi
  3. Mappa i tipi di evento - Assegna liste Brevo diverse per ciascun tipo di evento Calendly
  4. Gestisci i no-show - Traccia i no-show per regolare lead scoring e sequenze di follow-up
  5. Usa gli scheduling link - Genera scheduling link univoci per esperienze di prenotazione personalizzate
  6. Imposta lo scope organizzativo - Usa webhook a livello di org per catturare eventi di tutti i membri del team

Sicurezza

  • OAuth 2.0 - Autenticazione basata su token con scope
  • Firme webhook - Validazione firma HMAC per i webhook in ingresso
  • Solo HTTPS - Tutti gli endpoint API richiedono cifratura TLS
  • Scadenza token - I token OAuth scadono e richiedono flussi di refresh
  • Scope minimi - Richiedi solo gli scope OAuth necessari
  • Archiviazione sicura - Memorizza i token in variabili d’ambiente o secret manager

Risorse correlate

Subscribe to updates

developer-docs

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

auto-detect
Assistente AI

Ciao! Chiedimi qualsiasi cosa sulla documentazione.