Cal.com → Odoo CRM
1. Quoi ? — Définition et contexte
Section intitulée « 1. Quoi ? — Définition et contexte »Le workflow Cal.com → Odoo CRM synchronise automatiquement les événements Cal.com avec Odoo CRM. Il gère le cycle de vie complet des rendez-vous : création, annulation, reprogrammation et fin de réunion.
Événements gérés
Section intitulée « Événements gérés »| Événement Cal.com | Action Odoo | Notification |
|---|---|---|
BOOKING_CREATED | Créer opportunité | Message + fichier iCal |
BOOKING_CANCELLED | Marquer comme perdue | Message d’annulation |
BOOKING_RESCHEDULED | Mettre à jour dates | Message + nouveau iCal |
MEETING_ENDED | Augmenter probabilité | Message fin de réunion |
2. Pourquoi ? — Enjeux et motivations
Section intitulée « 2. Pourquoi ? — Enjeux et motivations »Problèmes résolus
Section intitulée « Problèmes résolus »| Problème | Sans sync | Avec sync |
|---|---|---|
| Double saisie | Créer manuellement l’opportunité après RDV | Automatique |
| Oubli de suivi | Pas de rappel après la réunion | Stage CRM mis à jour |
| Calendrier dispersé | RDV Cal.com ≠ calendrier pro | Fichier iCal envoyé |
| Annulations non tracées | Perdre l’info de l’annulation | Lead marqué comme perdu |
Cycle de vie du lead
Section intitulée « Cycle de vie du lead »BOOKING_CREATED → Opportunité probability: 10% │ ▼MEETING_ENDED → probability: 30% │ ▼Qualification manuelle → probability: 50%+ │ ▼Won / Lost3. Comment ? — Mise en œuvre technique
Section intitulée « 3. Comment ? — Mise en œuvre technique »Architecture
Section intitulée « Architecture »Cal.com (all events) | v Switch (triggerEvent) | +---> BOOKING_CREATED ----> Create opportunity ----> Notify + iCal | +---> BOOKING_CANCELLED --> Find opportunity ----> Mark Lost ----> Notify | +---> BOOKING_RESCHEDULED -> Find opportunity ----> Update dates ----> Notify + iCal | +---> MEETING_ENDED ------> Find opportunity ----> Update stage ----> NotifyFlow : Création de rendez-vous
Section intitulée « Flow : Création de rendez-vous »BOOKING_CREATED │ ▼ Create Opportunity (Odoo) - name: "RDV {attendee.name}" - email_from: attendee.email - probability: 10 │ ▼ Load All Admins (Data Table) │ ▼ Format Booking Notification │ ▼ Loop: Pour chaque admin │ ▼ Generate iCal File │ ▼ Send Calendar File (Telegram)Exemple de notification
Section intitulée « Exemple de notification »📅 Nouveau RDV Cal.com
👤 Client : Jean Dupont📧 Email : jean.dupont@example.com
🗓️ Date : jeudi 20 janvier 2026⏰ Horaire : 14:00 - 15:00📋 Type : Appel découverte
🔗 Opportunité : https://odoo.guigpap.com/odoo/crm/123Configuration N8N
Section intitulée « Configuration N8N »Cal.com Trigger :
Events: - BOOKING_CREATED - BOOKING_CANCELLED - BOOKING_RESCHEDULED - MEETING_ENDEDSwitch Node (Route by Event) :
Type: SwitchMode: RulesValue: {{ $json.triggerEvent }}
Rules: - Output 0: BOOKING_CREATED - Output 1: BOOKING_CANCELLED - Output 2: BOOKING_RESCHEDULED - Output 3: MEETING_ENDEDFind Opportunity (Odoo) :
Resource: CustomCustom Resource: crm.leadOperation: Get ManyLimit: 1Filter: - Field: email_from Operator: = Value: {{ $json.attendees[0].email }}Génération iCal
Section intitulée « Génération iCal »const booking = $json;const attendee = booking.attendees[0];
const formatICalDate = (date) => { return new Date(date).toISOString() .replace(/[-:]/g, '').split('.')[0] + 'Z';};
const icsContent = `BEGIN:VCALENDARVERSION:2.0PRODID:-//N8N//Booking//FRBEGIN:VEVENTUID:${booking.uid}@cal.comDTSTART:${formatICalDate(booking.startTime)}DTEND:${formatICalDate(booking.endTime)}SUMMARY:RDV Cal.com - ${attendee.name}DESCRIPTION:Rendez-vous avec ${attendee.name}LOCATION:${booking.location || 'À définir'}STATUS:CONFIRMEDEND:VEVENTEND:VCALENDAR`;
return [{ json: { fileName: `rdv-${attendee.name}.ics` }, binary: { calendar: { data: Buffer.from(icsContent).toString('base64'), mimeType: 'text/calendar' } }}];Note sur les types Odoo
Section intitulée « Note sur les types Odoo »# Configuration correcteFields: active: {{ false }} # Mode expression ! probability: {{ 0 }} # Mode expression !4. Et si ? — Perspectives et limites
Section intitulée « 4. Et si ? — Perspectives et limites »Limites actuelles
Section intitulée « Limites actuelles »| Limite | Impact | Mitigation |
|---|---|---|
| Matching par email | Doublons si emails différents | Recherche élargie future |
| Pas de sync inverse | Odoo → Cal.com non implémenté | Actions Telegram |
| Un seul attendee | Multi-participants non gérés | Prévu si besoin |
Scénarios d’évolution
Section intitulée « Scénarios d’évolution »Si besoin de sync inverse :
- Webhook Odoo → N8N quand opportunité modifiée
- Mettre à jour le booking Cal.com
- Attention aux boucles infinies
Si multi-types de RDV :
- Créer différents types d’opportunité selon le type Cal.com
- Assigner automatiquement selon le type
- Probabilité initiale différenciée
Si volume de RDV augmente :
- Digest quotidien au lieu de notif individuelle
- Filtrage par type de RDV
- Assignation round-robin
Troubleshooting
Section intitulée « Troubleshooting »| Problème | Vérification |
|---|---|
| Pas de déclenchement | Cal.com: webhook configuré ? N8N: workflow actif ? |
| Opportunité non trouvée | Email attendee = email_from dans Odoo ? |
| Update échoue | Vérifier permissions credentials Odoo |
| iCal non généré | Node Generate iCal connecté ? Binary data présent ? |
Pages liées
Section intitulée « Pages liées »Workflows
Section intitulée « Workflows »- Notification Hub — Routage centralisé
- Website Lead Notification — Leads formulaire web
Infrastructure
Section intitulée « Infrastructure »- Odoo 18 sur Docker — ERP et CRM