Messaging Service Events
Events from the Messaging service for contact management, consent, and message tracking.
Overview
The Messaging service handles contact management, consent (GDPR/POPIA), and message delivery. Events from Messaging drive consent synchronization and campaign interaction tracking. Contact + consent events are published to the BullMQ crm-events queue with the job name as the event type (no messaging. prefix) and the job data.payload as the event payload. Message and engagement events below document the domain contract even if they are not yet forwarded to CRM.
Contact Events
contact.created
Fired when a new contact is created.
{
eventId: "evt_123",
tenantId: "tenant_123",
contactId: "contact_uuid_456",
email: "john@example.com",
phoneNumber: "+27821234567",
firstName: "John",
lastName: "Smith",
emailOptIn: true,
smsOptIn: false
}
CRM Actions:
- Resolve identity
- Link
messagingContactId - Sync consent flags
Priority: Normal
contact.updated
Fired when contact details change.
{
eventId: "evt_124",
tenantId: "tenant_123",
contactId: "contact_uuid_456",
email: "john@example.com",
phoneNumber: "+27821234567",
firstName: "Jonathan",
lastName: "Smith-Jones",
emailOptIn: true,
smsOptIn: false
}
CRM Actions:
- Update profile fields if not already set
- Create activity if significant change
Priority: Normal
Consent Events
contactPreference.updated
Fired when consent/opt-in status changes.
{
eventId: "evt_125",
tenantId: "tenant_123",
contactId: "contact_uuid_456",
smsOptIn: true
}
CRM Actions:
- Update consent flags on profile (
smsOptIn,emailOptIn, etc.) - Create/update
MarketingConsentrecord - Create
CONSENT_OPTED_INorCONSENT_OPTED_OUTactivity - Update segment membership based on consent
Priority: High
Opt-In Fields:
emailOptIn- Email marketingsmsOptIn- SMS marketingpushOptIn- Push notificationswhatsappOptIn- WhatsApp messages
Only the relevant opt-in field is included per preference update.
contact.deleted
Fired when a contact is deleted.
{
eventId: "evt_126",
tenantId: "tenant_123",
contactId: "contact_uuid_456"
}
CRM Actions:
- Currently ignored by the CRM consumer (reserved for future cleanup/audit handling)
Message Events
message.sent
Fired when a message is sent.
{
type: "message.sent",
identity: { messagingContactId: "contact_uuid_456" },
payload: {
messageId: "msg_789",
contactId: "contact_uuid_456",
channel: "EMAIL",
templateId: "template_123",
templateName: "December Newsletter",
campaignId: "campaign_dec_2025",
sentAt: "2025-12-14T08:00:00Z"
}
}
CRM Actions:
- Create
MESSAGE_SENTactivity - Create/update
CampaignInteraction(type: SENT) - Update
lastMessageAt
Priority: Normal
message.delivered
Fired when delivery is confirmed.
{
type: "message.delivered",
identity: { messagingContactId: "contact_uuid_456" },
payload: {
messageId: "msg_789",
deliveredAt: "2025-12-14T08:00:05Z"
}
}
CRM Actions:
- Create
MESSAGE_DELIVEREDactivity - Update
CampaignInteraction(type: DELIVERED)
Priority: Low
message.failed
Fired when delivery fails.
{
type: "message.failed",
identity: { messagingContactId: "contact_uuid_456" },
payload: {
messageId: "msg_789",
reason: "invalid_email",
failedAt: "2025-12-14T08:00:05Z"
}
}
CRM Actions:
- Create
MESSAGE_FAILEDactivity - Consider marking email/phone as unverified
Priority: High
message.bounced
Fired when email bounces.
{
type: "message.bounced",
identity: { messagingContactId: "contact_uuid_456" },
payload: {
messageId: "msg_789",
bounceType: "hard", // hard or soft
reason: "mailbox_not_found",
bouncedAt: "2025-12-14T08:00:10Z"
}
}
CRM Actions:
- Create
MESSAGE_BOUNCEDactivity - If hard bounce, set
emailVerified= false - Auto opt-out from email if multiple hard bounces
- Update
CampaignInteraction(type: BOUNCED)
Priority: High
Bounce Types:
hard- Permanent failure (invalid email)soft- Temporary failure (mailbox full)
Engagement Events
email.opened
Fired when email is opened (tracking pixel).
{
type: "email.opened",
identity: { messagingContactId: "contact_uuid_456" },
payload: {
messageId: "msg_789",
campaignId: "campaign_dec_2025",
openedAt: "2025-12-14T09:15:00Z",
deviceType: "mobile",
userAgent: "..."
}
}
CRM Actions:
- Create
EMAIL_OPENEDactivity - Create
CampaignInteraction(type: OPENED) - Update
lastActivityAt,lastEmailOpenAt - Trigger engagement score refresh
Priority: Low
email.clicked
Fired when a link in email is clicked.
{
type: "email.clicked",
identity: { messagingContactId: "contact_uuid_456" },
payload: {
messageId: "msg_789",
campaignId: "campaign_dec_2025",
linkId: "link_123",
linkUrl: "https://example.com/offer",
clickedAt: "2025-12-14T09:16:30Z"
}
}
CRM Actions:
- Create
EMAIL_CLICKEDactivity - Create
CampaignInteraction(type: CLICKED) - Create
AttributionEventif applicable - High-value engagement signal
Priority: Low
sms.replied
Fired when customer replies to SMS.
{
type: "sms.replied",
identity: { messagingContactId: "contact_uuid_456" },
payload: {
originalMessageId: "msg_789",
replyText: "Yes, I'm interested",
repliedAt: "2025-12-14T10:00:00Z"
}
}
CRM Actions:
- Create
SMS_REPLIEDactivity - High-value engagement indicator
- Update engagement score
Priority: Normal
Event Priority Summary
| Event | Priority | Reason |
|---|---|---|
contact.created | Normal | Profile linking |
contact.updated | Normal | Profile sync |
contactPreference.updated | High | Legal compliance |
message.sent | Normal | Campaign tracking |
message.delivered | Low | Delivery confirmation |
message.failed | High | Delivery issues |
message.bounced | High | Email hygiene |
email.opened | Low | Engagement tracking |
email.clicked | Low | Engagement tracking |
sms.replied | Normal | High-value engagement |