plivo-smartroute-addon
v1.1.0
Published
Smart Plivo call routing with sticky agents, IVR, and intelligent call management
Maintainers
Readme
Plivo Call Router
Smart Plivo call routing with sticky agents, IVR support, out-of-office handling, and intelligent call management.
Features
- Sticky Agent Routing: Automatically routes calls to the last agent who called the customer
- Employee-Based Routing: Routes calls to assigned employees based on customer relationships
- IVR Support: Full support for Interactive Voice Response systems
- Out-of-Office Handling: Configurable out-of-office messages and behavior
- Call Recording: Automatic call recording with callback support
- Status Determination: Intelligent call status determination based on business logic
- Sequential & Simultaneous Dialing: Support for both routing modes
- Extensible: Adapter-based architecture for easy integration with any database/ORM
Installation
npm install plivo-call-routerQuick Start
Basic Usage
const plivoRouter = require('plivo-call-router');
// Define your database adapters
const adapters = {
findVoiceCall: async ({ sid }) => {
// Your database query to find a call by SID
return await VoiceCall.findOne({ where: { sid } });
},
createVoiceCall: async (callData) => {
// Your database query to create a call record
return await VoiceCall.create(callData);
},
updateVoiceCall: async (sid, updates) => {
// Your database query to update a call record
return await VoiceCall.update(updates, { where: { sid } });
},
getMerchantByDID: async (did) => {
// Your database query to get merchant by DID
return await VoiceCallDidMap.getVoiceCallDidMap(did);
},
findAvailableAgents: async ({ plivoNumber, status, limit, orderBy }) => {
// Your database query to find available agents
return await VoiceCallAgent.findAll({
where: { plivo_phone_number: plivoNumber, status },
order: orderBy,
limit
});
},
// ... other adapters
};
// Configure webhook handlers
const config = {
webhookBaseUrl: 'https://your-domain.com',
recordingCallbackUrl: 'https://your-domain.com/api/v1/webhook/plivo/recording-callback',
dialCallbackUrl: 'https://your-domain.com/api/v1/webhook/plivo/dial-callback',
onCallCompleted: async ({ call, direction }) => {
// Your automation logic
console.log(`Call ${call.sid} completed (${direction})`);
},
onMissedCall: async ({ call }) => {
// Your missed call handling
console.log(`Call ${call.sid} was missed`);
},
onOutOfOffice: async ({ call }) => {
// Your out-of-office handling
console.log(`Call ${call.sid} received during OOO hours`);
}
};
// Handle incoming call webhook
app.post('/webhook/plivo/incoming', async (req, res) => {
const response = await plivoRouter.webhooks.handleIncomingCall(
req.body,
adapters,
config
);
res.status(response.statusCode).send(response.body);
});
// Handle hangup webhook
app.post('/webhook/plivo/hangup', async (req, res) => {
const response = await plivoRouter.webhooks.handleHangup(
req.body,
adapters,
config
);
res.status(response.statusCode).send(response.body);
});API Reference
Webhook Handlers
webhooks.handleHangup(event, adapters, config)
Handles Plivo hangup webhook events for both inbound and outbound calls.
webhooks.handleIncomingCall(event, adapters, config)
Handles incoming call webhooks with automatic agent routing.
webhooks.handleIVRIncomingCall(event, adapters, config)
Handles IVR-enabled incoming calls.
webhooks.handleIVRAction(event, adapters, config)
Handles IVR digit input actions.
webhooks.handleRecordingCallback(event, adapters)
Handles call recording completion callbacks.
webhooks.handleDialCallback(event, adapters)
Handles dial action callbacks (A-leg and B-leg management).
Routing Utilities
routing.routeAgents(options)
Intelligently routes agents based on priority:
- Sticky agent (last agent who called customer)
- Employee agent (assigned employee)
- Available agents (from agent pool)
routing.findStickyAgent(options)
Finds the sticky agent for a customer.
routing.findEmployeeAgent(options)
Finds the employee agent for a customer.
routing.findAvailableAgents(options)
Finds available agents from the agent pool.
XML Builders
xml.createResponse()
Creates a new Plivo Response object.
xml.addRecording(response, callbackUrl, options)
Adds recording configuration to response.
xml.addSimultaneousDial(response, numbers, options)
Adds simultaneous dial configuration.
xml.addSequentialDial(response, numbers, options)
Adds sequential dial configuration.
xml.addIVRInput(response, actionUrl, message, options)
Adds IVR GetInput configuration.
xml.createOutOfOfficeResponse(message, options)
Creates an out-of-office response.
Status Determination
status.determineCallStatus(options)
Determines final call status based on business logic.
status.determineUserStatus(options)
Determines user/agent status.
status.determineCustomerStatus(options)
Determines customer status.
Utilities
utils.normalizeNumber(number)
Normalizes phone numbers to E.164 format.
utils.parseWebhookEvent(event)
Parses webhook event body and query parameters.
utils.getParam(body, params, key)
Gets parameter from body or query params.
Adapter Interface
Your adapters should implement the following methods:
findVoiceCall({ sid })- Find call by SIDcreateVoiceCall(callData)- Create call recordupdateVoiceCall(sid, updates)- Update call recordupdateVoiceCallRecording(sid, recordingData)- Update recording infogetMerchantByDID(did)- Get merchant by DIDgetMerchantByPlivoNumber(plivoNumber)- Get merchant by Plivo numbergetIVRConfig(plivoNumber)- Get IVR configurationgetOutOfOfficeConfig(plivoNumber)- Get out-of-office configurationfindLastOutboundCall({ merchantId, customerNumber, hoursBack })- Find last outbound callfindCustomer({ merchantId, phoneNumber })- Find customerfindUserByEmployeeId(employeeId)- Find user by employee IDfindAvailableAgents({ plivoNumber, status, limit, orderBy })- Find available agentsfindAnsweredBlegs(callUuid)- Find answered B-legsprocessCustomers(customers)- Process/create customers
Configuration Options
webhookBaseUrl- Base URL for webhook callbacksrecordingCallbackUrl- URL for recording callbacksdialCallbackUrl- URL for dial callbacksonCallCompleted- Callback for completed callsonMissedCall- Callback for missed callsonOutOfOffice- Callback for out-of-office callssendIncomingCallEvent- Function to send incoming call socket events
Examples
Sticky Agent Routing
const agents = await plivoRouter.routing.routeAgents({
findLastOutboundCall: adapters.findLastOutboundCall,
findCustomer: adapters.findCustomer,
findUserByEmployeeId: adapters.findUserByEmployeeId,
findAvailableAgents: adapters.findAvailableAgents,
merchantId: 'merchant-123',
customerNumber: '+1234567890',
plivoNumber: '+1987654321',
limit: 8
});Custom Status Determination
const statusResult = plivoRouter.status.determineCallStatus({
user_status: 'answered',
customer_status: 'completed',
plivo_status: 'completed',
hangup_cause_name: 'NORMAL_CLEARING',
is_out_of_office: false,
is_missed_call: false,
user_on_call_duration: 120,
total_call_duration: 120
});Building XML Responses
const response = plivoRouter.xml.createResponse();
plivoRouter.xml.addRecording(response, 'https://example.com/recording-callback');
plivoRouter.xml.addSimultaneousDial(response, ['+1234567890', '+0987654321'], {
timeout: '20',
callerId: '+1987654321',
callbackUrl: 'https://example.com/dial-callback'
});
const xml = response.toXML();License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Author
Satwik Loka
