Twilio Integration
🎯 Overview
The Twilio integration enables DashClicks to provide SMS messaging, voice calling, and phone number management capabilities through Twilio's communications platform. It supports bulk SMS sending, call handling, phone number provisioning, regulatory compliance, and A2P (Application-to-Person) messaging registration.
Provider: Twilio (https://www.twilio.com)
API Version: Twilio REST API
Integration Type: REST API with SDK (twilio-node) + WebSocket for real-time events
📁 Directory Structure
Documentation Structure:
twilio/
├── 📄 index.md - Twilio integration overview and setup
├── 📄 sms.md - SMS messaging (bulk sending, status tracking)
├── 📄 calls.md - Voice calls (making, managing, retrieving)
├── 📄 numbers.md - Phone number management (purchase, configuration)
├── 📄 subaccounts.md - Subaccount management for multi-tenancy
├── 📄 account.md - Account information and balance
├── 📄 regulatory-compliance.md - Regulatory bundles and compliance
├── 📄 a2p.md - A2P brand and campaign registration
├── 📄 addresses.md - Address validation and management
└── 📄 pricing.md - Pricing information for SMS/voice
Source Code Location:
- Base Path:
external/Integrations/Twilio/ - Providers:
Providers/(9 provider files with business logic) - Controllers:
Controllers/ - Routes:
Routes/ - Models:
Models/(Twilio-specific models) - Utilities:
Utils/ - Validations:
Validations/
🗄️ MongoDB Collections
📚 Detailed Schema: See Database Collections Documentation
twilio-number
- Purpose: Store purchased Twilio phone numbers and configuration
- Model:
external/Integrations/Twilio/Models/twilio-number.js - Primary Use: Track phone numbers, SMS URLs, and associations
- Key Fields:
phoneNumber- E.164 formatted phone numbersid- Twilio phone number SIDsmsUrl- Webhook URL for incoming SMSaccountSid- Twilio account/subaccount SIDfriendlyName- Display name
Twilio-Specific Collections
twilio-calls- Call records and metadatatwilio-messages- SMS message historytwilio-subaccounts- Subaccount managementtwilio-regulatory-bundles- Compliance bundle trackingtwilio-a2p-campaigns- A2P campaign registrations
🔐 Authentication & Configuration
Authentication Method: HTTP Basic Auth (Account SID + Auth Token)
Required Environment Variables:
| Variable | Description | Required |
|---|---|---|
TWILIO_ACCOUNT_SID | Master Twilio account SID | ✅ |
TWILIO_AUTH_TOKEN | Master Twilio auth token | ✅ |
TWILIO_SMS_URL | Webhook URL for incoming SMS | ❌ |
TWILIO_VOICE_URL | Webhook URL for incoming calls | ❌ |
Authentication Pattern:
const Twilio = require('twilio');
// Using account-specific credentials (multi-tenant)
const client = Twilio(accountSID, authToken);
// Master account (development)
const client = Twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
Multi-Tenant Pattern:
All Twilio Provider functions accept accountSID and authToken as parameters, enabling multi-tenant architecture where each DashClicks client can have their own Twilio subaccount.
🏗️ Architecture Overview
Key Responsibilities:
- SMS Messaging: Bulk SMS sending, delivery tracking, status callbacks
- Voice Calls: Outbound calls, call management, call logs
- Phone Numbers: Purchase, configure, release phone numbers
- Subaccounts: Create and manage Twilio subaccounts for clients
- Regulatory Compliance: Manage regulatory bundles for compliance
- A2P Messaging: Brand and campaign registration for 10DLC
- Address Management: Validate and store addresses for compliance
- Pricing: Retrieve SMS and voice pricing by country
API Communication Pattern:
- REST API via Twilio SDK (twilio-node)
- WebSocket for real-time events (socket.js provider)
- Webhook callbacks for async events (SMS delivery, call status)
- Account SID + Auth Token authentication
Multi-Tenant Architecture:
graph TB
A[DashClicks Client 1] -->|Subaccount 1| B[Twilio Subaccount 1]
C[DashClicks Client 2] -->|Subaccount 2| D[Twilio Subaccount 2]
E[DashClicks Client 3] -->|Subaccount 3| F[Twilio Subaccount 3]
B --> G[Twilio Master Account]
D --> G
F --> G
G -->|Messages/Calls| H[Carriers/Recipients]
Rate Limiting:
- Twilio enforces API rate limits (varies by account tier)
- SMS sending: Typically 1-10 messages per second
- No explicit rate limiting in code - relies on Twilio's limits
- Recommendation: Implement queuing for bulk SMS
🔗 Features & Capabilities
Core Features
- 📱 SMS Messaging - Send SMS, bulk messaging, delivery tracking
- 📞 Voice Calls - Make calls, retrieve call logs, manage calls
- 📲 Phone Numbers - Buy numbers, configure, search available
- 👥 Subaccounts - Create and manage Twilio subaccounts
- 💼 Account - Retrieve account info and balance
- 📋 Regulatory Compliance - Manage regulatory bundles
- 🏢 A2P Registration - Brand and campaign registration for 10DLC
- 🏠 Addresses - Address validation and management
- 💰 Pricing - Get SMS and voice pricing
🔄 Integration Data Flow
SMS Sending Flow
sequenceDiagram
participant DC as DashClicks API
participant SMSProvider as SMS Provider
participant TwilioClient as Twilio SDK
participant TwilioAPI as Twilio API
participant Recipient
DC->>SMSProvider: sendSms(accountSID, authToken, recipients, from, message)
SMSProvider->>SMSProvider: Create Twilio client
loop For each recipient
SMSProvider->>TwilioClient: messages.create()
TwilioClient->>TwilioAPI: POST /Messages
TwilioAPI->>Recipient: Deliver SMS
TwilioAPI-->>TwilioClient: Message SID + status
TwilioClient-->>SMSProvider: SMS sent
end
SMSProvider->>SMSProvider: Collect results
SMSProvider-->>DC: Return valid/invalid numbers
TwilioAPI->>DC: Status callback (async)
Note over DC: delivered/failed/undelivered
style SMSProvider fill:#e3f2fd
style TwilioAPI fill:#fff4e6
Phone Number Purchase Flow
sequenceDiagram
participant DC as DashClicks API
participant NumberProvider as Number Provider
participant TwilioAPI as Twilio API
participant DB as MongoDB
DC->>NumberProvider: purchaseNumber(accountSID, phoneNumber)
NumberProvider->>TwilioAPI: POST /IncomingPhoneNumbers
Note over NumberProvider,TwilioAPI: Body: phoneNumber, smsUrl, voiceUrl
TwilioAPI-->>NumberProvider: Number purchased (SID)
NumberProvider->>DB: Save to twilio-number
Note over DB: phoneNumber, sid, smsUrl, accountSid
NumberProvider-->>DC: Return number details
style NumberProvider fill:#e3f2fd
style TwilioAPI fill:#fff4e6
🔗 Submodules
- SMS Provider - Complete SMS messaging capabilities
- Calls Provider - Voice call management
- Number API Provider - Phone number operations
- Subaccount API Provider - Subaccount management
- Account Provider - Account information
- Regulatory Compliance Provider - Compliance bundles
- A2P Provider - A2P brand and campaign registration
- Address API Provider - Address management
- Pricing Provider - Pricing information
🚨 Error Handling
Common Error Scenarios:
-
Invalid Phone Number Format
- Error: "The 'To' number is not a valid phone number"
- Cause: Phone number not in E.164 format
- Solution: Validate and format as
+[country code][number]
-
Insufficient Balance
- Error: "Insufficient balance"
- Cause: Twilio account out of credits
- Solution: Add funds to Twilio account
-
Invalid Credentials
- Status: 401 Unauthorized
- Cause: Invalid Account SID or Auth Token
- Solution: Verify credentials
-
Rate Limit Exceeded
- Status: 429 Too Many Requests
- Cause: Exceeded API rate limits
- Solution: Implement backoff and retry logic
-
Unverified Phone Number
- Error: "The number is unverified"
- Cause: Trial account trying to send to unverified number
- Solution: Verify number or upgrade account
📊 Monitoring & Logging
- SMS Status Callbacks: Webhook for delivery status
- Call Status Callbacks: Webhook for call progress
- Error Logging: Errors returned in Provider responses
- No Centralized Logging: Each Provider handles errors independently
🔗 Related Documentation
- Twilio API Documentation: https://www.twilio.com/docs/api
- Twilio SMS API: https://www.twilio.com/docs/sms
- Twilio Voice API: https://www.twilio.com/docs/voice
- Twilio Phone Numbers: https://www.twilio.com/docs/phone-numbers
- A2P 10DLC: https://www.twilio.com/docs/sms/a2p-10dlc
- Twilio Node SDK: https://www.twilio.com/docs/libraries/node
⚠️ Important Integration Notes
- Multi-Tenant: All providers accept accountSID/authToken for subaccount isolation
- E.164 Format: Phone numbers must be in E.164 format
+[country][number] - Async Callbacks: SMS/call status updates arrive via webhooks
- Rate Limits: Twilio enforces rate limits per account tier
- Trial Accounts: Limited to verified phone numbers
- A2P Registration: Required for high-volume SMS to US numbers
- Regulatory Compliance: Some countries require regulatory bundles
- Webhook Security: Validate Twilio signature on incoming webhooks
- Error Handling: Providers return Promise.resolve/reject patterns
- SDK Usage: Uses official twilio-node SDK for API calls
🔧 Quick Start Examples
Send SMS
const smsProvider = require('./Providers/sms-api');
// Send SMS to multiple recipients
const result = await smsProvider.sendSms(
accountSID,
authToken,
['+12125551234', '+12125555678'],
'+12125550100', // From number
'Hello from DashClicks!',
'https://app.dashclicks.com/webhooks/sms-status', // Status callback
);
console.log('Valid numbers:', result.validNumberArr);
console.log('Invalid numbers:', result.invalidNumberArr);
console.log('Sent messages:', result.sentSmsDetails);
Purchase Phone Number
const numberProvider = require('./Providers/number-api');
// Purchase a specific number
const number = await numberProvider.purchaseNumber(
accountSID,
authToken,
'+12125551234',
'https://app.dashclicks.com/webhooks/sms',
'https://app.dashclicks.com/webhooks/voice',
);
console.log('Purchased:', number.phoneNumber);
console.log('SID:', number.sid);
Create Subaccount
const subaccountProvider = require('./Providers/subaccount-api');
// Create subaccount for client
const subaccount = await subaccountProvider.createSubAccount(
masterAccountSID,
masterAuthToken,
'Client Name',
);
console.log('Subaccount SID:', subaccount.sid);
console.log('Auth Token:', subaccount.authToken);
💡 Provider Pattern
All Twilio providers follow a consistent pattern:
// Provider function signature
exports.functionName = async (accountSID, authToken, ...params) => {
try {
// 1. Create Twilio client
const client = Twilio(accountSID, authToken);
// 2. Call Twilio API
const result = await client.resource.method(params);
// 3. Return success
return Promise.resolve(result);
} catch (error) {
// 4. Return error
return Promise.reject(error);
}
};
Benefits:
- Consistent: All providers use same pattern
- Multi-Tenant: Each call uses specific account credentials
- Error Handling: Standardized Promise-based error handling
- Testable: Easy to mock Twilio SDK
🎯 Use Cases
SMS Marketing Campaigns
// Send bulk SMS campaign
const recipients = await Customer.find({ optedIn: true }).select('phone');
const phoneNumbers = recipients.map(c => c.phone);
const result = await smsProvider.sendSms(
accountSID,
authToken,
phoneNumbers,
twilioNumber,
'Special offer: 50% off this week!',
);
Call Tracking
// Track incoming calls
const calls = await callProvider.getCalls(accountSID, authToken, {
startTime: '2024-01-01',
endTime: '2024-01-31',
});
const callVolume = calls.length;
const totalDuration = calls.reduce((sum, call) => sum + parseInt(call.duration), 0);
Phone Number Provisioning
// Find and purchase local number
const available = await numberProvider.searchAvailableNumbers(accountSID, authToken, 'US', {
areaCode: '212',
limit: 10,
});
const number = await numberProvider.purchaseNumber(
accountSID,
authToken,
available[0].phoneNumber,
smsUrl,
voiceUrl,
);