Konektor Calendly
Status konektor: Direncanakan Belum dibangun. Tajo belum menjalankan konektor ini.
Ilustrasi · data contoh
Contoh sinkronisasi
Sumber
Calendly
Status konektor: Direncanakan
Tujuan
Alat Anda yang lain
Status konektor: Alat khusus
Pemetaan field
| Field sumber | Field tujuan | Nilai contoh |
|---|---|---|
record.id | source_id | record_1042 |
record.updated_at | updated_at | 2026-10-18T08:00:00Z |
record.value | value | sample_value |
- Susun draf
- Tinjau satu data
- Setujui versi ini
Status berlaku untuk masing-masing konektor dan tidak menjamin sinkronisasi ini siap. Field ini hanya ilustrasi. Periksa skema dan izin sebenarnya sebelum sinkronisasi berjalan.
Hubungkan Calendly ke Brevo melalui Tajo untuk otomatis menyinkronkan invitee rapat sebagai contacts, memicu rangkaian email berdasarkan event booking, dan merampingkan alur kerja sales serta onboarding Anda.
Ikhtisar
| Properti | Nilai |
|---|---|
| Platform | Calendly |
| Kategori | Scheduling (Kustom) |
| Kompleksitas penyiapan | Mudah |
| Integrasi resmi | Tidak |
| Data yang disinkronkan | Events, Contacts, Bookings, Cancellations |
| Metode autentikasi | OAuth 2.0 / Personal Access Token |
Fitur
- Sync invitee - Buat contacts Brevo secara otomatis dari invitee rapat
- Pemicu booking - Jalankan otomatisasi Brevo ketika rapat dipesan
- Penanganan pembatalan - Picu alur re-engagement saat terjadi pembatalan
- Deteksi no-show - Perbarui status contact ketika invitee tidak hadir di rapat
- Pemetaan tipe event - Petakan berbagai tipe event Calendly ke list Brevo
- Scheduling API - Bangun penjadwalan langsung di dalam aplikasi Anda tanpa redirect
Prasyarat
Sebelum memulai, pastikan Anda memiliki:
- Akun Calendly (paket Professional atau di atasnya untuk akses API)
- Personal Access Token dari Calendly Integrations
- Akun Brevo dengan akses API
- Akun Tajo dengan permission konektor
Autentikasi
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' })});Konfigurasi
Penyiapan dasar
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}"Pemetaan field
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_STATUSEndpoint API
| Endpoint | Method | Deskripsi |
|---|---|---|
https://api.calendly.com/users/me | GET | Mengambil pengguna saat ini |
https://api.calendly.com/event_types | GET | Menampilkan tipe event |
https://api.calendly.com/scheduled_events | GET | Menampilkan event terjadwal |
https://api.calendly.com/scheduled_events/{uuid} | GET | Mengambil satu event terjadwal |
https://api.calendly.com/scheduled_events/{uuid}/invitees | GET | Menampilkan invitee |
https://api.calendly.com/scheduling_links | POST | Membuat scheduling link |
https://api.calendly.com/webhook_subscriptions | POST | Membuat webhook |
https://api.calendly.com/webhook_subscriptions | GET | Menampilkan webhook |
https://api.calendly.com/invitee_no_shows/{uuid} | GET | Mengambil status no-show |
Contoh kode
Inisialisasi konektor
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});Menampilkan event terjadwal
// 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();Menyinkronkan invitee ke Brevo
// 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] });}Menyiapkan langganan webhook
// 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
Alamat example.com di atas adalah placeholder sampai endpoint Tajo tersedia.
Menangani event webhook
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');});Batas rate
| Sumber daya | Batas | Catatan |
|---|---|---|
| Request API | 6.000/menit | Batas berlaku untuk seluruh organisasi |
| Langganan webhook | 30 per organisasi | Mencakup semua tipe event |
| Scheduling link | Tanpa batas | Tidak ada batas per menit |
Paginasi
Respons Calendly API menggunakan paginasi berbasis cursor. Gunakan next_page_token dari objek pagination untuk mengambil hasil berikutnya. Ukuran halaman default adalah 20 item, dengan maksimal 100.
Pemecahan masalah
| Masalah | Penyebab | Solusi |
|---|---|---|
| Webhook tidak diterima | Scope salah | Gunakan scope organization untuk webhook |
| 401 Unauthorized | Token kedaluwarsa | Buat token baru atau jalankan refresh token OAuth |
| Data invitee tidak lengkap | Pertanyaan belum dikonfigurasi | Tambahkan pertanyaan kustom ke tipe event |
| Contact ganda | Tidak ada logika deduplikasi | Gunakan email sebagai identifier unik untuk upsert |
| Rate limit 429 | Terlalu banyak request | Terapkan backoff dan kelompokkan request |
Mode debug
connectors: calendly: debug: true log_level: verbose log_webhooks: truePraktik terbaik
- Gunakan webhook - Berlangganan
invitee.createddaninvitee.canceleduntuk sync real-time - Tambahkan pertanyaan kustom - Kumpulkan data perusahaan, jabatan, dan telepon agar profil contact lebih kaya
- Petakan tipe event - Tetapkan list Brevo yang berbeda untuk setiap tipe event Calendly
- Tangani no-show - Lacak no-show untuk menyesuaikan lead scoring dan rangkaian tindak lanjut
- Gunakan scheduling link - Buat scheduling link unik untuk pengalaman booking yang dipersonalisasi
- Setel scope organisasi - Gunakan webhook tingkat organisasi untuk menangkap event dari seluruh anggota tim
Keamanan
- OAuth 2.0 - Autentikasi berbasis token dengan scope terbatas
- Signature webhook - Validasi signature HMAC untuk webhook masuk
- HTTPS saja - Semua endpoint API memerlukan enkripsi TLS
- Masa berlaku token - Token OAuth kedaluwarsa dan memerlukan alur refresh
- Scope minimal - Minta hanya scope OAuth yang diperlukan
- Penyimpanan aman - Simpan token di environment variable atau secret manager