Tham chiếu các loại sự kiện
Tài liệu tham chiếu toàn diện này bao quát tất cả các loại sự kiện webhook có sẵn trong Brevo, kèm những ví dụ cụ thể cho việc tích hợp với nền tảng khách hàng thân thiết Tajo.
Sự kiện email
delivered
Được kích hoạt khi một email được gửi thành công tới hộp thư của người nhận.
Ví dụ payload:
{ "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"}Trường hợp sử dụng khi tích hợp Tajo:
- Cập nhật tỷ lệ gửi thành công trong hồ sơ khách hàng
- Kích hoạt các hành động tiếp theo cho chiến dịch khách hàng thân thiết
- Theo dõi hiệu quả gửi email theo từng hạng
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
Được kích hoạt khi người nhận mở một email (theo dõi qua việc tải pixel).
Ví dụ payload:
{ "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" }}Trường hợp sử dụng khi tích hợp Tajo:
- Tăng điểm tương tác của khách hàng
- Theo dõi hiệu quả của chiến dịch khách hàng thân thiết
- Kích hoạt phần thưởng dựa trên hành vi
- Cá nhân hóa các liên lạc sau này
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
Được kích hoạt khi người nhận nhấp vào một liên kết trong email.
Ví dụ payload:
{ "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"}Trường hợp sử dụng khi tích hợp Tajo:
- Theo dõi hiệu quả của phễu chuyển đổi
- Cộng điểm thưởng cho lượt nhấp
- Xác định nội dung có giá trị cao
- Tối ưu hóa luồng từ email tới website
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
Được kích hoạt khi một email bị trả lại (lỗi tạm thời) hoặc bị trả lại vĩnh viễn (lỗi vĩnh viễn).
Ví dụ payload:
{ "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"}Trường hợp sử dụng khi tích hợp Tajo:
- Cập nhật trạng thái hợp lệ của email
- Chuyển sang các kênh liên lạc thay thế
- Làm sạch cơ sở dữ liệu khách hàng
- Ngăn việc tiếp tục gửi tới các địa chỉ không hợp lệ
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
Được kích hoạt khi người nhận đánh dấu một email là spam.
Ví dụ payload:
{ "event": "spam", "date": "2024-01-25 17:10:00", "ts": 1641005400, "template_id": 101, "tags": ["loyalty", "promotional"]}Trường hợp sử dụng khi tích hợp Tajo:
- Dừng ngay lập tức việc liên lạc qua email
- Xem lại và cải thiện nội dung email
- Phân tích các mẫu spam theo từng phân khúc
- Áp dụng quy trình opt-in chặt chẽ hơn
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'); }}Sự kiện SMS
sms_delivered
Được kích hoạt khi một tin nhắn SMS được gửi thành công tới điện thoại của người nhận.
Ví dụ payload:
{ "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."}Trường hợp sử dụng khi tích hợp Tajo:
- Xác nhận SMS đã gửi thành công
- Theo dõi tỷ lệ tương tác qua SMS
- Kiểm chứng độ chính xác của số điện thoại
- Giám sát hiệu quả gửi tin của nhà mạng
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
Được kích hoạt khi việc gửi SMS thất bại.
Ví dụ payload:
{ "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"}Trường hợp sử dụng khi tích hợp Tajo:
- Cập nhật tính hợp lệ của số điện thoại
- Chuyển sang thông báo qua email
- Làm sạch cơ sở dữ liệu số điện thoại
- Cảnh báo bộ phận chăm sóc khách hàng để xác minh thủ công
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
Được kích hoạt khi người nhận trả lời một tin nhắn SMS.
Ví dụ payload:
{ "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"}Trường hợp sử dụng khi tích hợp Tajo:
- Xử lý các lệnh của chương trình khách hàng thân thiết
- Xử lý yêu cầu chăm sóc khách hàng
- Cập nhật tùy chọn liên lạc
- Kích hoạt phản hồi tự động
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) }); }}Sự kiện liên hệ
contact_created
Được kích hoạt khi một liên hệ mới được thêm vào Brevo.
Ví dụ payload:
{ "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]}Trường hợp sử dụng khi tích hợp Tajo:
- Kích hoạt các chiến dịch chào mừng
- Thiết lập việc ghi danh vào chương trình khách hàng thân thiết
- Khởi tạo hành trình khách hàng
- Cộng điểm thưởng đăng ký
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
Được kích hoạt khi thông tin liên hệ được cập nhật.
Ví dụ payload:
{ "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 }}Trường hợp sử dụng khi tích hợp Tajo:
- Phát hiện việc thăng hạng
- Theo dõi thay đổi số dư điểm
- Giám sát mức độ đầy đủ của hồ sơ
- Kích hoạt các chiến dịch riêng theo hạng
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 }); }}Thực hành tốt nhất khi xử lý sự kiện
1. Xử lý tính bất biến khi lặp lại
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ắp xếp thứ tự sự kiện
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. Xử lý theo lô
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); } }}Bước tiếp theo
- Hướng dẫn bảo mật webhook - Các thực hành bảo mật tốt nhất
- Kiểm thử webhook - Kiểm thử và gỡ lỗi
- Phân tích webhook - Giám sát hiệu năng
- Tích hợp nền tảng - Hướng dẫn tích hợp đầy đủ