Calendly Connector
Connector-Status: Geplant Noch nicht gebaut. Tajo betreibt diesen Connector heute nicht.
Illustration · Beispieldaten
Sync-Beispiel
Quelle
Calendly
Connector-Status: Geplant
Ziel
Ihr anderes Tool
Connector-Status: Eigenes Tool
Feldzuordnung
| Quellfeld | Zielfeld | Beispielwert |
|---|---|---|
record.id | source_id | record_1042 |
record.updated_at | updated_at | 2026-10-18T08:00:00Z |
record.value | value | sample_value |
- Entwerfen
- Einen Datensatz prüfen
- Diese Version freigeben
Der Status gilt für einzelne Connectoren und garantiert nicht, dass dieser Sync bereit ist. Felder zur Veranschaulichung. Prüfen Sie vor dem Sync das tatsächliche Schema und die Berechtigungen.
Verbinde Calendly über Tajo mit Brevo, um Meeting-Eingeladene automatisch als Kontakte zu synchronisieren, E-Mail-Sequenzen auf Basis von Buchungsereignissen auszulösen und deine Vertriebs- und Onboarding-Workflows zu optimieren.
Überblick
| Eigenschaft | Wert |
|---|---|
| Plattform | Calendly |
| Kategorie | Scheduling (Custom) |
| Einrichtungsaufwand | Einfach |
| Offizielle Integration | Nein |
| Synchronisierte Daten | Events, Kontakte, Buchungen, Stornierungen |
| Auth-Methode | OAuth 2.0 / Personal Access Token |
Funktionen
- Synchronisierung Eingeladener - Erstelle Brevo-Kontakte automatisch aus Meeting-Eingeladenen
- Buchungs-Trigger - Löse Brevo-Automatisierungen bei gebuchten Meetings aus
- Umgang mit Stornierungen - Starte Re-Engagement-Flows bei Stornierungen
- No-Show-Erkennung - Aktualisiere den Kontaktstatus, wenn Eingeladene Meetings verpassen
- Event-Typ-Zuordnung - Ordne verschiedene Calendly-Event-Typen Brevo-Listen zu
- Scheduling API - Baue Terminbuchung ohne Redirects direkt in deine App ein
Voraussetzungen
Bevor du beginnst, stelle sicher, dass du Folgendes hast:
- Ein Calendly-Konto (Professional-Plan oder höher für API-Zugriff)
- Ein Personal Access Token aus Calendly Integrations
- Ein Brevo-Konto mit API-Zugriff
- Ein Tajo-Konto mit Connector-Berechtigungen
Authentifizierung
Personal Access Token
# Generate at 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
// OAuth 2.0 Authorization Code Flowconst 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' });
// Exchange code for 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' })});Konfiguration
Grundeinrichtung
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}"Feldzuordnung
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_STATUSAPI-Endpunkte
| Endpunkt | Methode | Beschreibung |
|---|---|---|
https://api.calendly.com/users/me | GET | Aktuelle:n Nutzer:in abrufen |
https://api.calendly.com/event_types | GET | Event-Typen auflisten |
https://api.calendly.com/scheduled_events | GET | Geplante Events auflisten |
https://api.calendly.com/scheduled_events/{uuid} | GET | Ein geplantes Event abrufen |
https://api.calendly.com/scheduled_events/{uuid}/invitees | GET | Eingeladene auflisten |
https://api.calendly.com/scheduling_links | POST | Scheduling-Link erstellen |
https://api.calendly.com/webhook_subscriptions | POST | Webhook erstellen |
https://api.calendly.com/webhook_subscriptions | GET | Webhooks auflisten |
https://api.calendly.com/invitee_no_shows/{uuid} | GET | No-Show-Status abrufen |
Code-Beispiele
Connector initialisieren
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});Geplante Events auflisten
// Retrieve scheduled eventsconst 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();Eingeladene mit Brevo synchronisieren
// Get invitees for a scheduled event and sync to 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] });}Webhook-Abonnements einrichten
// Subscribe to Calendly eventsconst 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
Die Adresse example.com oben ist ein Platzhalter, bis der Tajo-Endpunkt verfügbar ist.
Webhook-Events verarbeiten
app.post('/webhooks/calendly', async (req, res) => { // Verify webhook signature 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');});Ratenbegrenzungen
| Ressource | Limit | Hinweise |
|---|---|---|
| API-Anfragen | 6.000/Min. | Organisationsweites Limit |
| Webhook-Abonnements | 30 pro Organisation | Über alle Event-Typen hinweg |
| Scheduling-Links | Unbegrenzt | Kein Limit pro Minute |
Paginierung
Antworten der Calendly-API verwenden cursorbasierte Paginierung. Nutze das next_page_token aus dem pagination-Objekt, um weitere Ergebnisse abzurufen. Die Standard-Seitengröße beträgt 20 Einträge, maximal 100.
Fehlerbehebung
| Problem | Ursache | Lösung |
|---|---|---|
| Webhook wird nicht empfangen | Falscher Scope | Verwende den organization-Scope für Webhooks |
| 401 Unauthorized | Token abgelaufen | Neues Token generieren oder OAuth-Token erneuern |
| Fehlende Einladungsdaten | Fragen nicht konfiguriert | Benutzerdefinierte Fragen zum Event-Typ hinzufügen |
| Doppelte Kontakte | Keine Dedup-Logik | E-Mail als eindeutige Kennung für Upserts verwenden |
| Rate Limit 429 | Zu viele Anfragen | Backoff und Request-Batching umsetzen |
Debug-Modus
connectors: calendly: debug: true log_level: verbose log_webhooks: trueBest Practices
- Webhooks nutzen - Abonniere
invitee.createdundinvitee.canceledfür eine Echtzeit-Synchronisierung - Benutzerdefinierte Fragen hinzufügen - Erfasse Unternehmen, Rolle und Telefon für reichere Kontaktprofile
- Event-Typen zuordnen - Weise unterschiedliche Brevo-Listen pro Calendly-Event-Typ zu
- No-Shows verarbeiten - Verfolge No-Shows, um Lead-Scoring und Follow-up-Sequenzen anzupassen
- Scheduling-Links nutzen - Erstelle eindeutige Scheduling-Links für personalisierte Buchungserlebnisse
- Organisationsscope setzen - Nutze organisationsweite Webhooks, um Events aller Team-Mitglieder zu erfassen
Sicherheit
- OAuth 2.0 - Scope-basierte, tokengestützte Authentifizierung
- Webhook-Signaturen - HMAC-Signaturvalidierung für eingehende Webhooks
- Nur HTTPS - Alle API-Endpunkte erfordern TLS-Verschlüsselung
- Token-Ablauf - OAuth-Tokens laufen ab und erfordern Refresh-Flows
- Minimale Scopes - Fordere nur die erforderlichen OAuth-Scopes an
- Sichere Speicherung - Tokens in Umgebungsvariablen oder Secret Managern ablegen