Référence des types d'événements
Cette référence complète couvre tous les types d’événements webhook disponibles dans Brevo, avec des exemples spécifiques pour l’intégration de la plateforme de fidélité Tajo.
Événements email
delivered
Déclenché lorsqu’un email est livré avec succès dans la boîte de réception du destinataire.
Exemple de charge utile :
{ "event": "delivered", "id": 123456, "date": "2024-01-25 14:30:00", "ts": 1640995200, "template_id": 101, "tags": ["loyalty", "points-earned"], "sending_ip": "185.107.232.1", "event_id": "evt_abc123"}Cas d’usage Tajo :
- Mettre à jour le taux de livraison dans les profils clients
- Déclencher des actions de suivi pour les campagnes de fidélité
- Suivre les performances de livraison email par niveau
async function handleEmailDelivered(event) { const customer = await loyaltyService.getCustomer(event.email);
// Update delivery stats await loyaltyService.updateEngagement(event.email, { emailsDelivered: customer.emailsDelivered + 1, lastEmailDelivered: new Date(event.date), deliveryRate: calculateDeliveryRate(customer) });
// Track loyalty campaign delivery if (event.tags.includes('loyalty')) { await loyaltyService.trackCampaignMetric('loyalty_email_delivered', { email: event.email, template_id: event.template_id, tier: customer.loyaltyTier }); }}opened
Déclenché lorsqu’un destinataire ouvre un email (suit le chargement du pixel).
Exemple de charge utile :
{ "event": "opened", "date": "2024-01-25 15:45:00", "ts": 1641000300, "template_id": 101, "tags": ["loyalty", "tier-upgrade"], "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)", "geo": { "country": "US", "region": "CA", "city": "San Francisco" }}Cas d’usage Tajo :
- Augmenter les scores d’engagement client
- Suivre l’efficacité des campagnes de fidélité
- Déclencher des récompenses basées sur le comportement
- Personnaliser les communications futures
async function handleEmailOpened(event) { const customer = await loyaltyService.getCustomer(event.email);
// Significant engagement - boost score await loyaltyService.updateEngagement(event.email, { emailsOpened: customer.emailsOpened + 1, lastEmailOpened: new Date(event.date), engagementScore: customer.engagementScore + 5, preferredDevice: getDeviceType(event['user-agent']) });
// Reward engagement for loyalty members if (event.tags.includes('loyalty') && customer.loyaltyTier) { await loyaltyService.awardEngagementBonus(event.email, { type: 'email_engagement', points: getEngagementPoints(customer.loyaltyTier), reason: 'Email opened' }); }
// Track timing patterns for optimization await loyaltyService.recordEngagementTime(event.email, { campaign: event.template_id, openTime: new Date(event.date), timezone: getTimezone(event.geo) });}clicked
Déclenché lorsqu’un destinataire clique sur un lien dans un email.
Exemple de charge utile :
{ "event": "clicked", "date": "2024-01-25 16:20:00", "ts": 1641002400, "template_id": 101, "tags": ["loyalty", "rewards-reminder"], "link": "https://yourdomain.com/rewards?utm_source=brevo&utm_campaign=loyalty", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}Cas d’usage Tajo :
- Suivre les performances du tunnel de conversion
- Attribuer des bonus de clic
- Identifier le contenu à forte valeur
- Optimiser le flux email vers site web
async function handleEmailClicked(event) { const customer = await loyaltyService.getCustomer(event.email); const clickedUrl = new URL(event.link);
// High-value engagement await loyaltyService.updateEngagement(event.email, { emailsClicked: customer.emailsClicked + 1, lastEmailClicked: new Date(event.date), engagementScore: customer.engagementScore + 15, clickThroughRate: calculateCTR(customer) });
// Track specific link types if (clickedUrl.pathname.includes('/rewards')) { await loyaltyService.trackEvent(event.email, 'Rewards Page Clicked', { source: 'email', campaign: event.template_id, utm_campaign: clickedUrl.searchParams.get('utm_campaign') });
// Award exploration bonus await loyaltyService.awardEngagementBonus(event.email, { type: 'rewards_exploration', points: 10, reason: 'Clicked rewards link' }); }
// Track product interest if (clickedUrl.pathname.includes('/products')) { const productId = extractProductId(clickedUrl); await loyaltyService.trackProductInterest(event.email, productId, { source: 'email_click', timestamp: new Date(event.date) }); }}bounced / hard_bounced
Déclenché lorsqu’un email rebondit (échec temporaire) ou fait l’objet d’un rebond permanent (hard bounce).
Exemple de charge utile :
{ "event": "hard_bounced", "date": "2024-01-25 14:35:00", "ts": 1640995500, "template_id": 101, "tags": ["loyalty"], "reason": "550 5.1.1 User unknown", "bounce_type": "hard"}Cas d’usage Tajo :
- Mettre à jour le statut de validité de l’email
- Basculer vers des canaux de communication alternatifs
- Nettoyer la base de données clients
- Empêcher les envois ultérieurs vers des adresses invalides
async function handleEmailBounced(event) { const isHardBounce = event.event === 'hard_bounced' || event.bounce_type === 'hard';
if (isHardBounce) { // Permanent failure - mark email as invalid await loyaltyService.updateCustomerStatus(event.email, { emailStatus: 'invalid', emailBounced: true, bounceReason: event.reason, lastBounce: new Date(event.date), communicationPreference: 'sms' // Switch to SMS if available });
// Remove from email marketing lists await loyaltyService.removeFromEmailMarketing(event.email);
// Suggest phone verification const customer = await loyaltyService.getCustomer(event.email); if (customer?.phone) { await loyaltyService.suggestPhoneVerification(customer.phone); }
} else { // Soft bounce - temporary issue await loyaltyService.updateEngagement(event.email, { softBounceCount: customer.softBounceCount + 1, lastSoftBounce: new Date(event.date) });
// Retry logic for soft bounces if (customer.softBounceCount < 5) { await loyaltyService.scheduleEmailRetry(event.email, event.template_id); } }}spam
Déclenché lorsqu’un destinataire signale un email comme spam.
Exemple de charge utile :
{ "event": "spam", "date": "2024-01-25 17:10:00", "ts": 1641005400, "template_id": 101, "tags": ["loyalty", "promotional"]}Cas d’usage Tajo :
- Arrêter immédiatement les communications email
- Réviser et améliorer le contenu des emails
- Analyser les modèles de spam par segment
- Mettre en place des processus d’opt-in plus stricts
async function handleEmailSpam(event) { // Immediately disable email marketing await loyaltyService.updateCustomerPreferences(event.email, { emailMarketing: false, marketingEnabled: false, spamReported: true, spamReportDate: new Date(event.date) });
// Alert marketing team for review await loyaltyService.alertMarketing('spam_complaint', { email: event.email, template: event.template_id, campaign_tags: event.tags, severity: 'high' });
// Analyze spam patterns await loyaltyService.analyzeSpamPattern({ template_id: event.template_id, tags: event.tags, customer_segment: await loyaltyService.getCustomerSegment(event.email) });
// Consider account review if multiple spam reports const customer = await loyaltyService.getCustomer(event.email); if (customer.spamReports > 2) { await loyaltyService.flagForReview(event.email, 'multiple_spam_reports'); }}Événements SMS
sms_delivered
Déclenché lorsqu’un SMS est livré avec succès sur le téléphone du destinataire.
Exemple de charge utile :
{ "event": "sms_delivered", "phone": "+1234567890", "date": "2024-01-25 14:45:00", "ts": 1640996700, "message-id": "sms_abc123", "tags": ["loyalty", "points-alert"], "sender": "TAJO", "content": "🎉 Great news! You earned 150 points from your recent purchase. Total: 1,250 points."}Cas d’usage Tajo :
- Confirmer la livraison SMS réussie
- Suivre les taux d’engagement SMS
- Valider l’exactitude des numéros de téléphone
- Surveiller les performances de livraison des opérateurs
async function handleSMSDelivered(event) { const customer = await loyaltyService.getCustomerByPhone(event.phone);
await loyaltyService.updateEngagement(customer.email, { smsDelivered: customer.smsDelivered + 1, lastSMSDelivered: new Date(event.date), smsDeliveryRate: calculateSMSDeliveryRate(customer), phoneStatus: 'valid' });
// Track loyalty SMS performance if (event.tags.includes('loyalty')) { await loyaltyService.trackCampaignMetric('loyalty_sms_delivered', { phone: event.phone, content_type: getSMSContentType(event.content), customer_tier: customer.loyaltyTier }); }}sms_failed
Déclenché lorsque la livraison du SMS échoue.
Exemple de charge utile :
{ "event": "sms_failed", "phone": "+1234567890", "date": "2024-01-25 14:32:00", "ts": 1640996320, "message-id": "sms_def456", "tags": ["loyalty", "urgent"], "sender": "TAJO", "reason": "Invalid phone number format", "error_code": "30006"}Cas d’usage Tajo :
- Mettre à jour la validité du numéro de téléphone
- Basculer vers les notifications email
- Nettoyer la base de données des numéros de téléphone
- Alerter le service client pour une vérification manuelle
async function handleSMSFailed(event) { const customer = await loyaltyService.getCustomerByPhone(event.phone);
await loyaltyService.updateCustomerStatus(customer.email, { phoneStatus: 'invalid', smsEnabled: false, smsFailureReason: event.reason, lastSMSFailure: new Date(event.date), communicationPreference: 'email' });
// For urgent loyalty notifications, fall back to email if (event.tags.includes('urgent') || event.tags.includes('loyalty')) { await loyaltyService.sendEmailFallback(customer.email, { originalSMS: event.content, reason: 'SMS delivery failed' }); }
// Flag for phone number verification await loyaltyService.flagForPhoneVerification(customer.email);}sms_reply
Déclenché lorsqu’un destinataire répond à un SMS.
Exemple de charge utile :
{ "event": "sms_reply", "phone": "+1234567890", "date": "2024-01-25 15:20:00", "ts": 1641000000, "message-id": "sms_reply_123", "text": "BALANCE", "original_message_id": "sms_abc123"}Cas d’usage Tajo :
- Traiter les commandes du programme de fidélité
- Gérer les demandes du service client
- Mettre à jour les préférences de communication
- Déclencher des réponses automatisées
async function handleSMSReply(event) { const customer = await loyaltyService.getCustomerByPhone(event.phone); const replyText = event.text.toUpperCase().trim();
// High engagement - customer actively participating await loyaltyService.updateEngagement(customer.email, { smsReplies: customer.smsReplies + 1, lastSMSReply: new Date(event.date), engagementScore: customer.engagementScore + 10 });
// Process loyalty commands switch (replyText) { case 'BALANCE': await loyaltyService.sendPointsBalance(event.phone); break;
case 'REWARDS': await loyaltyService.sendAvailableRewards(event.phone, customer.loyaltyTier); break;
case 'TIER': await loyaltyService.sendTierInfo(event.phone, customer); break;
case 'HELP': await loyaltyService.sendSMSHelp(event.phone); break;
case 'STOP': case 'UNSUBSCRIBE': await loyaltyService.unsubscribeFromSMS(event.phone); break;
default: // Forward to customer service await loyaltyService.forwardToSupport(customer.email, { channel: 'sms', message: event.text, timestamp: new Date(event.date) }); }}Événements contact
contact_created
Déclenché lorsqu’un nouveau contact est ajouté à Brevo.
Exemple de charge utile :
{ "event": "contact_created", "date": "2024-01-25 13:15:00", "ts": 1640992500, "attributes": { "FIRSTNAME": "John", "LASTNAME": "Doe", "LOYALTY_ID": "LYL-2024-001", "LOYALTY_TIER": "Bronze", "LOYALTY_POINTS": 0 }, "lists": [1, 5]}Cas d’usage Tajo :
- Déclencher les campagnes de bienvenue
- Configurer l’inscription au programme de fidélité
- Initialiser le parcours client
- Attribuer des bonus d’inscription
async function handleContactCreated(event) { const isLoyaltyMember = event.attributes?.LOYALTY_ID;
if (isLoyaltyMember) { // New loyalty member - trigger welcome flow await loyaltyService.triggerWelcomeFlow(event.email, { loyaltyId: event.attributes.LOYALTY_ID, tier: event.attributes.LOYALTY_TIER || 'Bronze', signupBonus: 500 });
// Award signup bonus await loyaltyService.awardPoints(event.email, { amount: 500, reason: 'Welcome bonus', type: 'signup_bonus' });
// Schedule onboarding emails await loyaltyService.scheduleOnboardingSequence(event.email, { tier: event.attributes.LOYALTY_TIER, preferences: event.attributes }); }
// Track signup source await loyaltyService.trackSignupSource(event.email, { lists: event.lists, attributes: event.attributes, timestamp: new Date(event.date) });}contact_updated
Déclenché lorsque les informations d’un contact sont mises à jour.
Exemple de charge utile :
{ "event": "contact_updated", "date": "2024-01-25 16:45:00", "ts": 1641003900, "updated_attributes": { "LOYALTY_POINTS": 1250, "LOYALTY_TIER": "Silver", "TOTAL_SPENT": 899.99 }, "previous_attributes": { "LOYALTY_POINTS": 750, "LOYALTY_TIER": "Bronze", "TOTAL_SPENT": 549.99 }}Cas d’usage Tajo :
- Détecter les montées en niveau
- Suivre les variations du solde de points
- Surveiller la complétude du profil
- Déclencher des campagnes spécifiques au niveau
async function handleContactUpdated(event) { const updated = event.updated_attributes; const previous = event.previous_attributes;
// Check for tier upgrade if (updated.LOYALTY_TIER && updated.LOYALTY_TIER !== previous.LOYALTY_TIER) { await loyaltyService.handleTierUpgrade(event.email, { previousTier: previous.LOYALTY_TIER, newTier: updated.LOYALTY_TIER, pointsBalance: updated.LOYALTY_POINTS });
// Send congratulations await loyaltyService.sendTierUpgradeEmail(event.email, { newTier: updated.LOYALTY_TIER, benefits: loyaltyService.getTierBenefits(updated.LOYALTY_TIER) }); }
// Track significant point increases const pointIncrease = updated.LOYALTY_POINTS - previous.LOYALTY_POINTS; if (pointIncrease > 0) { await loyaltyService.trackPointsEarned(event.email, { amount: pointIncrease, newTotal: updated.LOYALTY_POINTS, source: 'profile_update' }); }
// Monitor spending milestones if (updated.TOTAL_SPENT > previous.TOTAL_SPENT) { await loyaltyService.checkSpendingMilestones(event.email, { currentSpend: updated.TOTAL_SPENT, previousSpend: previous.TOTAL_SPENT }); }}Bonnes pratiques de traitement des événements
1. Gestion de l’idempotence
class WebhookProcessor { constructor() { this.processedEvents = new Set(); }
async processEvent(event) { const eventKey = `${event.event}_${event.email}_${event.ts}`;
if (this.processedEvents.has(eventKey)) { console.log('Duplicate event ignored:', eventKey); return; }
this.processedEvents.add(eventKey);
try { await this.handleEvent(event); } catch (error) { this.processedEvents.delete(eventKey); // Allow retry throw error; } }}2. Séquençage des événements
async function processEventInSequence(event) { const customer = await loyaltyService.getCustomer(event.email); const lastProcessedTime = customer.lastWebhookProcessed || 0;
// Ensure events are processed in chronological order if (event.ts < lastProcessedTime) { console.warn('Out-of-order event received, queuing for later processing'); await loyaltyService.queueEventForLaterProcessing(event); return; }
await handleWebhookEvent(event);
// Update last processed timestamp await loyaltyService.updateCustomer(event.email, { lastWebhookProcessed: event.ts });}3. Traitement par lots
class BatchEventProcessor { constructor() { this.eventBatch = []; this.batchSize = 100; this.flushInterval = 5000; // 5 seconds
setInterval(() => this.flushBatch(), this.flushInterval); }
addEvent(event) { this.eventBatch.push(event);
if (this.eventBatch.length >= this.batchSize) { this.flushBatch(); } }
async flushBatch() { if (this.eventBatch.length === 0) return;
const batch = this.eventBatch.splice(0);
try { await loyaltyService.processBatchEvents(batch); } catch (error) { console.error('Batch processing failed:', error); // Re-queue failed events this.eventBatch.unshift(...batch); } }}Prochaines étapes
- Guide de sécurité des webhooks - Bonnes pratiques de sécurité
- Tester les webhooks - Tests et débogage
- Analytics webhook - Surveillance des performances
- Intégration de la plateforme - Guide d’intégration complet