Aller au contenu

Cal.com → Odoo CRM

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énement Cal.comAction OdooNotification
BOOKING_CREATEDCréer opportunitéMessage + fichier iCal
BOOKING_CANCELLEDMarquer comme perdueMessage d’annulation
BOOKING_RESCHEDULEDMettre à jour datesMessage + nouveau iCal
MEETING_ENDEDAugmenter probabilitéMessage fin de réunion

ProblèmeSans syncAvec sync
Double saisieCréer manuellement l’opportunité après RDVAutomatique
Oubli de suiviPas de rappel après la réunionStage CRM mis à jour
Calendrier disperséRDV Cal.com ≠ calendrier proFichier iCal envoyé
Annulations non tracéesPerdre l’info de l’annulationLead marqué comme perdu

BOOKING_CREATED · probability 10%

MEETING_ENDED · probability 30%

Qualification manuelle · probability 50%+

Won

Lost


Cal.com webhook

Switch · triggerEvent

BOOKING_CREATED → Create opportunity

BOOKING_CANCELLED → Mark Lost

BOOKING_RESCHEDULED → Update dates

MEETING_ENDED → Update stage

Notify + iCal

Notify

BOOKING_CREATED

Create Opportunity Odoo · probability 10

Load All Admins · Data Table

Format Booking Notification

Loop · pour chaque admin

Generate iCal File

Send Calendar File · Telegram

📅 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/123

Cal.com Trigger :

Events:
- BOOKING_CREATED
- BOOKING_CANCELLED
- BOOKING_RESCHEDULED
- MEETING_ENDED

Switch Node (Route by Event) :

Type: Switch
Mode: Rules
Value: {{ $json.triggerEvent }}
Rules:
- Output 0: BOOKING_CREATED
- Output 1: BOOKING_CANCELLED
- Output 2: BOOKING_RESCHEDULED
- Output 3: MEETING_ENDED

Find Opportunity (Odoo) :

Resource: Custom
Custom Resource: crm.lead
Operation: Get Many
Limit: 1
Filter:
- Field: email_from
Operator: =
Value: {{ $json.attendees[0].email }}
const booking = $json;
const attendee = booking.attendees[0];
const formatICalDate = (date) => {
return new Date(date).toISOString()
.replace(/[-:]/g, '').split('.')[0] + 'Z';
};
const icsContent = `BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//N8N//Booking//FR
BEGIN:VEVENT
UID:${booking.uid}@cal.com
DTSTART:${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:CONFIRMED
END:VEVENT
END:VCALENDAR`;
return [{
json: { fileName: `rdv-${attendee.name}.ics` },
binary: {
calendar: {
data: Buffer.from(icsContent).toString('base64'),
mimeType: 'text/calendar'
}
}
}];
# Configuration correcte
Fields:
active: {{ false }} # Mode expression !
probability: {{ 0 }} # Mode expression !

LimiteImpactMitigation
Matching par emailDoublons si emails différentsRecherche élargie future
Pas de sync inverseOdoo → Cal.com non implémentéActions Telegram
Un seul attendeeMulti-participants non gérésPrévu si besoin

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
ProblèmeVérification
Pas de déclenchementCal.com: webhook configuré ? N8N: workflow actif ?
Opportunité non trouvéeEmail attendee = email_from dans Odoo ?
Update échoueVérifier permissions credentials Odoo
iCal non généréNode Generate iCal connecté ? Binary data présent ?