Complete API reference for the Twilio Synthetic Call Data Generator.
- Core Modules
- Personas
- Pairing
- Orchestration
- Segment Integration
- Serverless Functions
- Configuration
- Data Models
File: src/main.js
Orchestrates the complete synthetic call generation pipeline.
Usage:
node src/main.jsProcess Flow:
- Load customer and agent personas
- Select intelligent customer-agent pairing
- Create Segment profiles for all customers
- Create Twilio conference
- Add customer and agent participants
- Simulate call completion with analytics
- Update Segment profiles with ML scores
File: src/personas/customer-loader.js
Loads and validates customer persona data from JSON files.
Loads customer personas from a JSON file.
Parameters:
filePath(string, optional): Path to customers JSON file. Defaults tocustomers.json
Returns: Array of customer objects
Throws: Error if file doesn't exist or contains invalid JSON
Example:
const { loadCustomers } = require('./src/personas/customer-loader');
const customers = loadCustomers();
console.log(`Loaded ${customers.length} customers`);Validates a customer object against required schema.
Parameters:
customer(object): Customer object to validate
Returns: true if valid
Throws: Error if validation fails
Required Fields:
CustomerName(string)PhoneNumber(string, E.164 format)ContactInformation(string, valid email)TechnicalProficiency(string: "Low", "Medium", "High")PastInteractions(array)PreferredContactMethod(string)CurrentIssue(string)
Example:
const { validateCustomer } = require('./src/personas/customer-loader');
const customer = {
CustomerName: "John Doe",
PhoneNumber: "+15551234567",
ContactInformation: "john@example.com",
TechnicalProficiency: "Medium",
// ... other fields
};
validateCustomer(customer); // throws if invalidFinds a customer by exact name match.
Parameters:
name(string): Customer name to search
Returns: Customer object or null
Example:
const customer = getCustomerByName("Emily Watson");
if (customer) {
console.log(`Found: ${customer.PhoneNumber}`);
}Finds a customer by phone number.
Parameters:
phoneNumber(string): Phone number to search
Returns: Customer object or null
Example:
const customer = getCustomerByPhone("+15551234567");Returns a random customer from loaded personas.
Returns: Random customer object
Example:
const customer = getRandomCustomer();
console.log(`Selected: ${customer.CustomerName}`);File: src/personas/agent-loader.js
Loads and validates agent persona data from JSON files.
Loads agent personas from a JSON file.
Parameters:
filePath(string, optional): Path to agents JSON file. Defaults toagents.json
Returns: Array of agent objects
Example:
const { loadAgents } = require('./src/personas/agent-loader');
const agents = loadAgents();
console.log(`Loaded ${agents.length} agents`);Validates an agent object against required schema.
Parameters:
agent(object): Agent object to validate
Returns: true if valid
Throws: Error if validation fails
Required Fields:
AgentName(string)PhoneNumber(string, E.164 format)Competence(string: "Low", "Medium", "High")Communication(string: "Poor", "Average", "Excellent")Experience(string)Specialization(string)
File: src/pairing/pair-selector.js
Intelligently pairs customers with agents based on compatibility factors.
Selects optimal customer-agent pairing.
Parameters:
customers(array): Array of customer objectsagents(array): Array of agent objects
Returns: Object with customer and agent properties
Pairing Strategy:
- Frustrated customers → High competence agents
- Low technical proficiency → Excellent communication agents
- Complex issues → Experienced agents
- Random selection from filtered pool
Example:
const { selectPair } = require('./src/pairing/pair-selector');
const customers = loadCustomers();
const agents = loadAgents();
const { customer, agent } = selectPair(customers, agents);
console.log(`Paired: ${customer.CustomerName} with ${agent.AgentName}`);Generates a deterministic conference ID.
Parameters:
customer(object): Customer objectagent(object): Agent object
Returns: String in format CF{32-char-hex}
Example:
const conferenceId = generateConferenceId(customer, agent);
// Output: "CF7bdf13de62d3197bf501f3b3c595f9eb"File: src/orchestration/conference-orchestrator.js
Creates and manages Twilio conferences using TwiML Application for AI-powered conversations.
Creates a Twilio conference with customer and agent participants using OpenAI integration.
Parameters:
twilioClient(object): Initialized Twilio clienttwimlAppSid(string): TwiML Application SID for voice handlingagentPhoneNumber(string): Phone number for agent participant (E.164)customerPhoneNumber(string): Phone number for customer participant (E.164)options(object, optional): Configuration optionsstrategy(string): Pairing strategy ('random', 'frustrated', etc.)
Returns: Promise resolving to object:
{
conferenceSid: "CFxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
conferenceId: "CF1234567890abcdef1234567890abcd",
customer: {
participantSid: "CAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
callSid: "CAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
customerName: "Lucy Macintosh",
phoneNumber: "+15551234567"
},
agent: {
participantSid: "CAyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
callSid: "CAyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
agentName: "Sarah",
phoneNumber: "+15559998888"
},
timerScheduled: true,
timerDuration: 300,
timestamp: "2025-01-15T10:00:00.000Z"
}Example:
const twilio = require('twilio');
const { createConference } = require('./src/orchestration/conference-orchestrator');
const client = twilio(accountSid, authToken);
const result = await createConference(
client,
'APxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', // TwiML App SID
'+15559998888', // Agent phone
'+15551234567', // Customer phone
{ strategy: 'random' }
);
console.log(`Conference created: ${result.conferenceSid}`);File: src/orchestration/add-participant.js
Adds participants to Twilio conferences using TwiML Application with OpenAI integration.
Adds a customer to an existing conference using TwiML Application.
Parameters:
twilioClient(object): Initialized Twilio clientconferenceSid(string): Conference SIDcustomer(object): Customer persona object withCustomerNametwimlAppSid(string): TwiML Application SIDcustomerPhoneNumber(string): Phone number to call customer from (E.164)
Returns: Promise resolving to participant object
{
participantSid: "CAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
callSid: "CAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
conferenceSid: "CFxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
participantType: "customer",
customerName: "Lucy Macintosh"
}Features:
- Uses TwiML Application for voice handling
- Automatic retry on network errors (max 3 attempts)
- Exponential backoff (1s, 2s, 4s)
- No retry on 4xx client errors
- Input validation with E.164 phone format
- URL-encoded parameters
Example:
const participant = await addCustomerToConference(
client,
'CFxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
{ CustomerName: 'Lucy Macintosh' },
'APxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'+15551234567'
);
console.log(`Customer added: ${participant.callSid}`);TwiML Application URL Format:
app:APxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx?role=customer&persona=Lucy%20Macintosh&conferenceId=CFxxx
Adds an AI-powered agent to a conference using TwiML Application.
Parameters:
twilioClient(object): Initialized Twilio clientconferenceSid(string): Conference SIDagent(object): Agent persona object withAgentNametwimlAppSid(string): TwiML Application SIDagentPhoneNumber(string): Phone number to call agent from (E.164)
Returns: Promise resolving to participant object
{
participantSid: "CAyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
callSid: "CAyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
conferenceSid: "CFxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
participantType: "agent",
agentName: "Sarah"
}TwiML Application Features:
- OpenAI gpt-4o-mini integration via serverless functions
- Dynamic persona loading from JSON files
- System prompt construction with agent characteristics
- Conversation history management
- Speech-to-text with enhanced models
- Neural voice synthesis
Example:
const participant = await addAgentToConference(
client,
'CFxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
{ AgentName: 'Sarah' },
'APxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'+15559998888'
);
console.log(`Agent added with OpenAI: ${participant.callSid}`);TwiML Application URL Format:
app:APxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx?role=agent&persona=Sarah&conferenceId=CFxxx
File: src/segment/profile-creator.js
Creates Segment CDP profiles from customer personas.
Factory method to initialize ProfileCreator with Segment credentials.
Parameters:
writeKey(string): Segment write key
Returns: ProfileCreator instance
Example:
const ProfileCreator = require('./src/segment/profile-creator');
const creator = ProfileCreator.initialize(process.env.SEGMENT_WRITE_KEY);Creates a Segment profile for a single customer.
Parameters:
customer(object): Customer persona object
Returns: Promise resolving on success
Segment Event:
- Type:
identify - User ID:
cust_{md5(phoneNumber)} - Traits: All customer fields in snake_case
Example:
await creator.createProfile(customerData);Creates Segment profiles for multiple customers.
Parameters:
customers(array): Array of customer objects
Returns: Promise resolving to object:
{
success: true,
profilesCreated: 10,
errors: []
}Example:
const result = await creator.createBatchProfiles(customers);
console.log(`Created ${result.profilesCreated} profiles`);File: src/segment/profile-updater.js
Updates Segment profiles with call analytics and ML scores.
Factory method to initialize ProfileUpdater.
Parameters:
writeKey(string): Segment write key
Returns: ProfileUpdater instance
Example:
const ProfileUpdater = require('./src/segment/profile-updater');
const updater = ProfileUpdater.initialize(process.env.SEGMENT_WRITE_KEY);Updates a profile with call outcome analytics.
Parameters:
userId(string): Segment user ID (cust_*)analytics(object): Call analytics data
Analytics Object:
{
sentiment: 'positive' | 'neutral' | 'negative',
resolution: 'resolved' | 'unresolved' | 'escalated',
escalation: boolean,
wordCount: number
}Returns: Promise resolving on success
Segment Events:
-
Identify: Updates profile traits
churn_risk_score(0-100)propensity_to_buy(0-100)satisfaction_score(0-100)total_calls(incremented)last_call_sentimentlast_call_resolution
-
Track:
call_completedevent- All analytics fields
- Calculated ML scores
- Timestamp
ML Score Calculations:
Churn Risk Score:
- Base:
baselineRiskfrom persona (30-70) - Sentiment impact: -15 (positive), +20 (negative)
- Resolution impact: -10 (resolved), +15 (unresolved)
- Escalation penalty: +25
- Call duration: -5 (long calls reduce risk)
- Capped at 0-100
Propensity to Buy:
- Base:
baselinePropensityfrom persona (20-60) - Sentiment impact: +20 (positive), -15 (negative)
- Resolution impact: +15 (resolved), -10 (unresolved)
- Escalation penalty: -20
- Capped at 0-100
Satisfaction Score:
- Positive + resolved: 85-95
- Neutral or mixed: 50-70
- Negative + unresolved: 20-40
- Random variance: ±10
Example:
const analytics = {
sentiment: 'positive',
resolution: 'resolved',
escalation: false,
wordCount: 250
};
await updater.updateFromCallAnalytics('cust_abc123', analytics);Updates profile from Twilio transcription webhook.
Parameters:
webhookData(object): Webhook POST body from Twilio
Required Fields:
TranscriptionText(string)CallSid(string)From(string, customer phone)
Returns: Promise resolving on success
Example:
// In webhook handler
app.post('/transcription-webhook', async (req, res) => {
await updater.updateFromTranscriptionWebhook(req.body);
res.send('OK');
});File: functions/conference-status-webhook.js
Handles Twilio conference lifecycle events.
Endpoint: POST /conference-status-webhook
Twilio Events:
conference-startconference-endparticipant-joinparticipant-leave
POST Parameters:
StatusCallbackEvent(string): Event typeConferenceSid(string): Conference SIDFriendlyName(string): Conference friendly nameParticipantLabel(string): "customer" or "agent"CallSid(string): Participant call SID
Response: TwiML <Response></Response>
Side Effects:
- Logs all conference events
- Tracks participant join/leave times
- Monitors conference status
Example Configuration:
const conference = await client.conferences.create({
statusCallback: 'https://your-service.twil.io/conference-status-webhook',
statusCallbackEvent: ['start', 'end', 'join', 'leave']
});File: functions/conference-timer.js
Manages conference duration and automatic ending.
Endpoint: GET /conference-timer
Query Parameters:
conferenceSid(string): Conference SIDduration(number, optional): Minutes before ending. Default: 5
Response: JSON
{
message: "Conference will end in X minutes",
conferenceSid: "CFxxxx",
scheduledEnd: "2025-01-15T10:30:00.000Z"
}Features:
- Schedules conference ending
- Configurable duration
- Graceful participant removal
Example:
GET /conference-timer?conferenceSid=CFxxxx&duration=10File: functions/voice-handler.js
Entry point for TwiML Application voice calls. Redirects to transcribe function to start AI conversation loop.
Endpoint: POST /voice-handler
Query Parameters:
role(string): Participant role ("agent" or "customer")persona(string): Persona name (e.g., "Sarah", "Lucy Macintosh")conferenceId(string): Conference SID
Response: TwiML with <Redirect> to transcribe endpoint
Features:
- Extracts role and persona from URL parameters
- Initializes conversation flow
- Logs incoming calls
- No conversation history on first call
Example TwiML Response:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Redirect method="POST">/transcribe?role=agent&persona=Sarah&conferenceId=CFxxx&conversationHistory=</Redirect>
</Response>File: functions/transcribe.js
Listens for speech input using Twilio's <Gather> verb and redirects to respond function.
Endpoint: POST /transcribe
Query Parameters:
role(string): Participant role ("agent" or "customer")persona(string): Persona nameconferenceId(string): Conference SIDconversationHistory(string, optional): JSON-encoded conversation messages
Response: TwiML with <Gather> for speech input
Speech Recognition Settings:
- Model:
experimental_conversations- Optimized for natural dialogue - Enhanced:
true- Higher accuracy - Timeout:
auto- Smart silence detection - Profanity Filter:
false- Captures authentic conversation - Action: Redirects to
/respondwith speech result
Agent Introduction:
- Agents deliver scripted introduction on first message only
- Voice: Polly.Joanna-Neural
- Introduction loaded from
agents.json
Example TwiML Response:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather input="speech"
action="/respond?role=agent&persona=Sarah&conferenceId=CFxxx&conversationHistory=%5B%5D"
method="POST"
speechTimeout="auto"
speechModel="experimental_conversations"
enhanced="true"
profanityFilter="false">
<Say voice="Polly.Joanna-Neural">Hello, this is Sarah. How can I help you today?</Say>
</Gather>
<Redirect method="POST">/transcribe?role=agent&persona=Sarah&conferenceId=CFxxx&conversationHistory=%5B%5D</Redirect>
</Response>File: functions/respond.js
Processes speech input via OpenAI gpt-4o-mini and generates AI response.
Endpoint: POST /respond
Query Parameters:
role(string): Participant rolepersona(string): Persona nameconferenceId(string): Conference SIDconversationHistory(string): JSON-encoded conversationSpeechResult(string): Transcribed speech from Gather
OpenAI Integration:
- Model: gpt-5-nano
- Temperature: 0.7 (natural variation)
- Max Tokens: 150 (concise responses)
- System Prompt: Dynamically loaded from persona JSON files
Conversation Flow:
- Load persona data (agent or customer)
- Parse conversation history
- Add system prompt (first message only)
- Append user speech to conversation
- Call OpenAI API
- Add assistant response to history
- Speak response using
<Say> - Redirect back to
/transcribefor next turn
Error Handling:
- Falls back to generic apology message
- Preserves conversation history on error
- Continues conversation loop
Example TwiML Response:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say voice="Polly.Joanna-Neural">I'd be happy to help you with that account issue. Let me look into it for you.</Say>
<Redirect method="POST">/transcribe?role=agent&persona=Sarah&conferenceId=CFxxx&conversationHistory=%5B...%5D</Redirect>
</Response>Conversation History Format:
[
{
"role": "system",
"content": "You are Sarah, a highly competent customer service agent..."
},
{
"role": "user",
"content": "I need help with my account"
},
{
"role": "assistant",
"content": "I'd be happy to help you with that account issue."
}
]File: functions/utils/persona-loader.js
Utility function for loading agent and customer personas from JSON assets.
Function: loadPersona(role, personaName)
Parameters:
role(string): "agent" or "customer"personaName(string): Name of persona to load
Returns: Persona object:
{
name: "Sarah",
role: "agent",
systemPrompt: "You are Sarah, a highly competent...",
introduction: "Hello, this is Sarah. How can I help you today?",
rawData: { /* original JSON data */ }
}Features:
- Loads from
agents.jsonorcustomers.jsonassets - Handles wrapped data (AgentPrompts/CustomerPrompts)
- Constructs OpenAI system prompts
- Returns null for non-existent personas
Example:
const { loadPersona } = require(Runtime.getFunctions()['utils/persona-loader'].path);
const agent = loadPersona('agent', 'Sarah');
const customer = loadPersona('customer', 'Lucy Macintosh');File: functions/transcription-webhook.js
Processes call transcriptions and updates Segment profiles.
Endpoint: POST /transcription-webhook
POST Parameters:
TranscriptionText(string): Full call transcriptionCallSid(string): Call SIDFrom(string): Customer phone numberTranscriptionStatus(string): "completed" or "failed"
Response: TwiML <Response></Response>
Processing:
- Validates transcription data
- Analyzes sentiment from text
- Determines resolution status
- Checks for escalation keywords
- Counts words as call duration proxy
- Updates Segment profile with analytics
Sentiment Analysis:
- Positive keywords: "thank", "great", "helpful", "resolved", "perfect"
- Negative keywords: "frustrated", "angry", "upset", "terrible", "disappointed"
- Default: "neutral"
Resolution Detection:
- Resolved: "resolved", "fixed", "solved", "working"
- Escalated: "escalate", "supervisor", "manager", "complaint"
- Default: "unresolved"
Example:
// Configure recording with transcription
await client.calls(callSid).update({
record: true,
transcribe: true,
transcribeCallback: 'https://your-service.twil.io/transcription-webhook'
});File: functions/error-handler.js
Receives real-time error and warning notifications from Twilio Debugger.
Endpoint: POST /error-handler
POST Parameters (from Twilio Debugger):
Sid(string): Unique error event identifierAccountSid(string): Twilio Account SIDLevel(string): "ERROR" or "WARNING"Timestamp(string): ISO 8601 timestampPayload(string/JSON): Error details including:error_code(string): Twilio error codemessage(string): Error descriptionmore_info(string): Documentation URLresource_sid(string): Affected resource SIDrequest_url(string): Failed request URLresponse_status_code(number): HTTP status code
Response: JSON
{
success: true,
errorSid: "NOxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
severity: "CRITICAL",
remediation: {
severity: "CRITICAL",
actions: [
"ALERT: Webhook endpoint may be down",
"Check serverless function deployment status"
],
automated: true
},
timestamp: "2025-10-09T00:15:23.456Z"
}Error Severity Classification:
CRITICAL (requires immediate action):
- 11200: HTTP retrieval failure (webhook down)
- 20003: Authentication failed
- 20404: Resource not found
- 53205: Conference error
HIGH (needs attention):
- 11100: Invalid TwiML
- 12100: Document parse failure
- 21211: Invalid phone number
- 21217: Phone number not reachable
MEDIUM (non-blocking):
- 13224: Call leg already ended
- 13227: Call in wrong state
LOW (informational):
- All warnings
Automated Remediation Actions:
| Error Code | Action |
|---|---|
| 11200 | Alert webhook down, suggest redeployment |
| 11100 | Log invalid TwiML for review |
| 21211 | Flag invalid phone number |
| 53205 | Log conference failure, retry recommended |
| 60001 | Skip Voice Intelligence transcription |
Security:
- Validates
X-Twilio-Signatureheader - Rejects requests with invalid signatures
- Returns 403 for unauthorized requests
Structured Error Logging:
{
"errorType": "TwilioDebuggerError",
"sid": "NOxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"level": "ERROR",
"errorCode": "11200",
"message": "HTTP retrieval failure",
"resourceSid": "CAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"requestUrl": "https://example.com/webhook",
"responseStatusCode": "404",
"timestamp": "2025-10-09T00:15:23.456Z"
}Configuration:
- Deploy error-handler function
- Configure in Twilio Console:
- Go to: https://console.twilio.com/us1/monitor/debugger
- Click Settings (gear icon)
- Enter webhook URL:
https://your-domain.twil.io/error-handler - Save
Helper Script:
npm run configure-debuggerOptional External Alerting:
The function includes commented-out integrations for:
- Slack notifications
- SendGrid email alerts
- PagerDuty incidents
- GitHub issue creation
Uncomment and configure environment variables to enable.
Example:
// In .env or Twilio Function environment
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/WEBHOOK/URL
// Function will automatically send Slack notifications for CRITICAL errorsFile: src/config/index.js
Centralized configuration management.
Exports:
module.exports = {
twilio: {
accountSid: process.env.TWILIO_ACCOUNT_SID,
authToken: process.env.TWILIO_AUTH_TOKEN
},
segment: {
writeKey: process.env.SEGMENT_WRITE_KEY
},
agent: {
phoneNumber: process.env.AGENT_PHONE_NUMBER
}
};Usage:
const config = require('./src/config');
const client = twilio(config.twilio.accountSid, config.twilio.authToken);
const creator = ProfileCreator.initialize(config.segment.writeKey);Environment Variables:
| Variable | Required | Description |
|---|---|---|
TWILIO_ACCOUNT_SID |
Yes | Twilio Account SID |
TWILIO_AUTH_TOKEN |
Yes | Twilio Auth Token |
SEGMENT_WRITE_KEY |
Yes | Segment Write Key |
AGENT_PHONE_NUMBER |
No | Default agent phone for testing |
{
"CustomerName": "string", // Full name
"PhoneNumber": "string", // E.164 format (+15551234567)
"ContactInformation": "string", // Email address
"TechnicalProficiency": "string", // "Low" | "Medium" | "High"
"PastInteractions": ["string"], // Array of past interaction descriptions
"PreferredContactMethod": "string", // "Phone" | "Email" | "Chat"
"CurrentIssue": "string", // Description of current issue
"InitialSentiment": "string", // "Frustrated" | "Neutral" | "Happy"
"baselineRisk": number, // 0-100, initial churn risk
"baselinePropensity": number // 0-100, initial propensity to buy
}{
"AgentName": "string", // First name only
"PhoneNumber": "string", // E.164 format
"Competence": "string", // "Low" | "Medium" | "High"
"Communication": "string", // "Poor" | "Average" | "Excellent"
"Experience": "string", // Years of experience
"Specialization": "string" // Area of expertise
}{
"sentiment": "string", // "positive" | "neutral" | "negative"
"resolution": "string", // "resolved" | "unresolved" | "escalated"
"escalation": boolean, // true if escalated
"wordCount": number // Proxy for call duration
}{
"userId": "string", // "cust_{md5(phone)}"
"traits": {
"customer_name": "string",
"phone_number": "string",
"contact_information": "string",
"technical_proficiency": "string",
"preferred_contact_method": "string",
"current_issue": "string",
"initial_sentiment": "string",
"churn_risk_score": number, // 0-100
"propensity_to_buy": number, // 0-100
"satisfaction_score": number, // 0-100
"total_calls": number,
"last_call_sentiment": "string",
"last_call_resolution": "string"
},
"timestamp": "ISO8601"
}{
"userId": "string",
"event": "call_completed",
"properties": {
"sentiment": "string",
"resolution": "string",
"escalation": boolean,
"word_count": number,
"churn_risk_score": number,
"propensity_to_buy": number,
"satisfaction_score": number,
"call_sid": "string",
"conference_sid": "string"
},
"timestamp": "ISO8601"
}Validation Errors:
throw new Error('CustomerName is required');
throw new Error('Invalid phone number format');Twilio API Errors:
{
status: 400,
message: 'Invalid To phone number',
code: 21211
}Segment API Errors:
{
message: 'Invalid write key',
status: 401
}Add-participant functions implement exponential backoff:
const delays = [1000, 2000, 4000]; // ms
for (const delay of delays) {
try {
return await operation();
} catch (err) {
if (!isRetryable(err)) throw err;
await sleep(delay);
}
}npm testnpm run test:coveragenpm run test:e2enpm run smoke-testconst twilio = require('twilio');
const config = require('./src/config');
const { loadCustomers } = require('./src/personas/customer-loader');
const { loadAgents } = require('./src/personas/agent-loader');
const { selectPair } = require('./src/pairing/pair-selector');
const ProfileCreator = require('./src/segment/profile-creator');
const ProfileUpdater = require('./src/segment/profile-updater');
const { createConference } = require('./src/orchestration/conference-orchestrator');
async function main() {
// 1. Initialize clients
const twilioClient = twilio(config.twilio.accountSid, config.twilio.authToken);
const profileCreator = ProfileCreator.initialize(config.segment.writeKey);
const profileUpdater = ProfileUpdater.initialize(config.segment.writeKey);
// 2. Load personas
const customers = loadCustomers();
const agents = loadAgents();
// 3. Select pairing
const { customer, agent } = selectPair(customers, agents);
console.log(`Pairing: ${customer.CustomerName} → ${agent.AgentName}`);
// 4. Create Segment profiles
await profileCreator.createBatchProfiles(customers);
// 5. Create conference
const result = await createConference(
twilioClient,
agent.PhoneNumber,
customer,
agent
);
console.log(`Conference: ${result.conference.sid}`);
// 6. Simulate call completion (in production, triggered by webhook)
const analytics = {
sentiment: 'positive',
resolution: 'resolved',
escalation: false,
wordCount: 250
};
const userId = `cust_${crypto.createHash('md5')
.update(customer.PhoneNumber)
.digest('hex')}`;
await profileUpdater.updateFromCallAnalytics(userId, analytics);
console.log('Pipeline complete!');
}
main().catch(console.error);- Conference creation: 100/second
- Participant addition: 100/second
- API calls: 10,000/hour (adjustable)
- Events: 500 events/second
- Batch size: 100 events/batch
- Max payload: 32KB
- Twilio Docs: https://www.twilio.com/docs
- Segment Docs: https://segment.com/docs
- GitHub Issues: Create an issue
API Version: 1.0.0 Last Updated: 2025-01-15