Multi-Channel Communication System - Quick Reference
Overview
This is a quick reference guide for the multi-channel communication system. For the complete design document, see multi-channel-communication-system-design.md.
Key Components
1. Core Modules
| Module | Purpose | Location |
|---|---|---|
| CommunicationsModule | Main orchestration, channel adapters, use cases | apps/backend/src/communications/ |
| CommunicationTemplatesModule | Template management and rendering | apps/backend/src/communication-templates/ |
| CommunicationQueueModule | Queue processing, retry logic | apps/backend/src/communication-queue/ |
| CommunicationPreferencesModule | User/customer preferences | apps/backend/src/communication-preferences/ |
2. Database Tables
| Table | Purpose |
|---|---|
communication | Stores all communication records and their delivery status |
communication_template | Message templates with variable placeholders |
communication_queue | Job queue for async message processing |
communication_preference | User/customer communication preferences |
communication_attachment | File attachments (PDFs, images) |
3. Channel Adapters
| Channel | Adapter | Provider | Cost (approx) |
|---|---|---|---|
EmailAdapterService | Sendgrid | $0.0004/email | |
| SMS | SmsAdapterService | Twilio | $0.0075/message |
WhatsAppAdapterService | Twilio | $0.0042/message | |
| Messenger | MessengerAdapterService | Twilio/Facebook | $0.0025/message |
Common Use Cases
1. Send Invoice via Email (Automatic)
Trigger: Sale is created
Flow: OnCreateSaleEvent → CommunicationsService.send() → Email with PDF attachment
// Automatically handled by OnCreateSaleHandler
// No code needed, configured via business settings
2. Send Payment Link via SMS (Manual)
Trigger: User clicks "Send Payment Link" button
Flow: Frontend → POST /api/communications/send → SMS with payment link
// Frontend
await sendCommunication(token, {
channel: 'sms',
type: 'payment_link',
recipientType: 'customer',
recipientId: customerId,
recipientContact: customer.phone,
templateId: 'payment_link_sms',
templateVariables: {
customerName: customer.name,
invoiceNumber: invoice.documentNumber,
amount: invoice.totalAmount,
paymentLink: paymentLink,
},
});
3. Automated Collection Reminders
Trigger: Daily scheduler checks for overdue invoices
Flow: CollectionRemindersScheduler → Checks preferences → Sends via preferred channels
// Automatically runs daily at 9 AM
// Sends to customers with overdue invoices based on their preferences
API Quick Reference
Send Communication
POST /api/communications/send
Authorization: Bearer {token}
Content-Type: application/json
{
"channel": "email|sms|whatsapp|messenger",
"type": "invoice|payment_link|collection_notice|general",
"recipientType": "customer|supplier|user",
"recipientId": "uuid",
"recipientContact": "email@example.com|+1234567890",
"templateId": "uuid", // Optional
"templateVariables": {}, // If using template
"content": "message text", // If not using template
"entityType": "sale|accountsReceivableInvoice", // Optional
"entityId": "uuid" // Optional
}
Get Communication History
GET /api/communications?entityType=sale&entityId={uuid}&page=1&size=20
Authorization: Bearer {token}
Get Communication Stats
GET /api/communications/stats?businessId={uuid}&startDate=2025-10-01&endDate=2025-10-31
Authorization: Bearer {token}
Create Template
POST /api/communication-templates
Authorization: Bearer {token}
{
"name": "Invoice Email",
"code": "invoice_email",
"channel": "email",
"type": "invoice",
"subjectTemplate": "Invoice {{invoiceNumber}} from {{businessName}}",
"bodyTemplate": "Dear {{customerName}},\n\nYour invoice...",
"availableVariables": ["customerName", "invoiceNumber", "amount"]
}
Template Variables Reference
Invoice Templates
| Variable | Type | Description | Example |
|---|---|---|---|
customerName | string | Customer's name | "John Doe" |
invoiceNumber | string | Invoice document number | "INV-1234" |
amount | number | Invoice amount | 1500.00 |
dueDate | date | Payment due date | "2025-10-31" |
businessName | string | Business name | "ACME Corp" |
paymentLink | string | URL for payment | "https://pay.flowpos..." |
Payment Link Templates
| Variable | Type | Description |
|---|---|---|
customerName | string | Customer's name |
invoiceNumber | string | Invoice number |
amount | number | Amount due |
paymentLink | string | Payment URL |
expiresAt | date | Link expiration |
Collection Notice Templates
| Variable | Type | Description |
|---|---|---|
customerName | string | Customer's name |
invoiceNumber | string | Invoice number |
amount | number | Original amount |
balanceDue | number | Remaining balance |
daysOverdue | number | Days past due |
businessName | string | Business name |
paymentLink | string | Payment URL |
Handlebars Helpers
Currency Formatting
Output: $1,500.00
Date Formatting
Output: Oct 19, 2025 | 10/19/25 | October 19, 2025
Conditionals
Environment Variables Checklist
# Email (Sendgrid)
SENDGRID_API_KEY=SG.xxx
SENDGRID_FROM_EMAIL=noreply@yourcompany.com
SENDGRID_FROM_NAME=Your Company
# SMS/WhatsApp (Twilio)
TWILIO_ACCOUNT_SID=ACxxxxx
TWILIO_AUTH_TOKEN=xxxxx
TWILIO_PHONE_NUMBER=+1234567890
TWILIO_WHATSAPP_NUMBER=+1234567890
# Facebook Messenger (Optional)
FACEBOOK_PAGE_ID=xxxxx
FACEBOOK_APP_SECRET=xxxxx
# API URLs
API_URL=https://api.yourcompany.com
PAYMENT_URL=https://pay.yourcompany.com
Webhook Setup
Sendgrid Event Webhook
- Go to Sendgrid Dashboard → Settings → Mail Settings → Event Webhook
- Set HTTP POST URL:
https://api.yourcompany.com/webhooks/sendgrid/events - Select events: Delivered, Opened, Clicked, Bounced, Dropped
- Save
Twilio Status Callbacks
Automatically configured in the adapter code:
- SMS:
${API_URL}/webhooks/twilio/sms-status - WhatsApp:
${API_URL}/webhooks/twilio/whatsapp-status - Messenger:
${API_URL}/webhooks/twilio/messenger-status
Troubleshooting
Message Not Sending
- Check queue status:
SELECT * FROM communication_queue WHERE status = 'failed' - Check communication status:
SELECT * FROM communication WHERE status = 'failed' - Review error messages in
communication.error_message - Check provider credentials in environment variables
- Verify webhook endpoints are accessible
Email Not Delivered
- Check Sendgrid dashboard for bounces/spam reports
- Verify sender email is verified in Sendgrid
- Check customer email is valid
- Review
communication.provider_responsefor details
SMS/WhatsApp Failed
- Verify phone number format (E.164: +1234567890)
- Check Twilio account balance
- For WhatsApp: Verify sender number is approved
- Check Twilio console for detailed error
Template Not Rendering
- Verify all required variables are provided
- Check template syntax (valid Handlebars)
- Review
communication.template_variablesJSON - Test template with preview API:
POST /api/communication-templates/:id/preview
Performance Tips
High Volume Sending
- Batch Processing: Queue processes 10 messages per 30 seconds by default
- Rate Limiting: Built-in rate limiting prevents API throttling
- Priority Queue: Use
priority: 'high'for urgent messages - Scheduled Sending: Spread bulk sends over time using
scheduledAt
Monitoring
Key metrics to monitor:
- Queue size:
SELECT COUNT(*) FROM communication_queue WHERE status = 'pending' - Failure rate:
SELECT COUNT(*) FROM communication WHERE status = 'failed' - Average delivery time:
SELECT AVG(EXTRACT(EPOCH FROM (delivered_at - sent_at))) FROM communication WHERE delivered_at IS NOT NULL
Security Best Practices
- API Keys: Store in environment variables, never commit to git
- Webhooks: Validate webhook signatures from Sendgrid/Twilio
- Customer Data: Only send to verified contacts
- Rate Limiting: Prevents abuse of communication system
- Permissions: Use role-based access control (RBAC) for sending messages
- Audit Trail: All communications logged with timestamps and user
Testing Checklist
Unit Tests
- Email adapter sends correctly
- SMS adapter formats phone numbers
- WhatsApp adapter handles media
- Template renderer processes variables
- Queue service retries failed jobs
Integration Tests
- Send email with attachment
- Send SMS to real number
- WhatsApp message delivery
- Webhook updates status
- Template rendering with real data
E2E Tests
- Create sale → Invoice email sent
- Payment received → Confirmation sent
- Overdue invoice → Collection notice sent
- Low stock → Alert to managers
- Customer preferences honored
Support & Resources
- Full Design Doc: multi-channel-communication-system-design.md
- Sendgrid Docs: https://docs.sendgrid.com/
- Twilio Docs: https://www.twilio.com/docs
- Handlebars Docs: https://handlebarsjs.com/guide/
Implementation Status Tracker
Track your implementation progress:
Phase 1: Foundation ..................... [ ]
Phase 2: Email Enhancement .............. [ ]
Phase 3: SMS & WhatsApp ................. [ ]
Phase 4: Use Cases & Automations ........ [ ]
Phase 5: Frontend Integration ........... [ ]
Phase 6: Queue & Reliability ............ [ ]
Phase 7: Messenger & Testing ............ [ ]
Phase 8: Documentation & Polish ......... [ ]
Quick Start Commands
# Generate database migration
cd packages/backend/database
npm run migration:create -- create-communication-tables
# Run migrations
npm run migration:up
# Seed default templates
npm run seed:run -- communication-templates
# Start backend with dev mode
cd apps/backend
npm run start:dev
# Run tests
npm run test
# Build for production
npm run build
Common Integration Points
In Sales Page
// Add "Send Invoice" button
<Button onClick={() => handleSendInvoice(sale)}>
<Mail className="mr-2" /> Send Invoice
</Button>
In Accounts Receivable Page
// Add "Send Payment Link" button
<Button onClick={() => handleSendPaymentLink(invoice)}>
<Link className="mr-2" /> Send Payment Link
</Button>
In Customer Page
// Add communication history tab
<Tabs>
<TabsList>
<TabsTrigger value="details">Details</TabsTrigger>
<TabsTrigger value="communications">Communications</TabsTrigger>
</TabsList>
<TabsContent value="communications">
<CommunicationHistory entityType="customer" entityId={customer.id} />
</TabsContent>
</Tabs>
Last Updated: October 19, 2025 Version: 1.0 Status: Design Complete - Ready for Implementation