Dial in another participant inTwilio - twilio

After joining a conference call I am trying to dial in another participant to the conference call. I have 2 functions /ConnectConfrenceCall and /conference (see below the functions)
When getting the callback from /Confrencecall it enters /confrence. I get the below logs as if it is suppose to call but I never get a call. I dont see any outgoing cal in my logs.Anyway to debug this?
//ConnectConfrenceCall
exports.handler = function (context, event, callback) {
console.log("in confrencecalll");
let conferenceName = "My Conference";
let twiml = new Twilio.twiml.VoiceResponse();
twiml.say("Please wait while we dial you into the call.");
twiml.dial().conference(
{
statusCallback: `https://${context.DOMAIN_NAME}/conference`,
statusCallbackEvent: "join",
},
conferenceName
);
callback(null, twiml);
};
/confrence
exports.handler = function(context, event, callback) {
console.log("in confrence");
let toPhoneNumber = "+xxxxxx";
let fromNumber = "+xxxxx";
const twilioClient = context.getTwilioClient();
if (
(event.StatusCallbackEvent == "participant-join") &
(event.SequenceNumber == "1")
) {
console.log("in confrence IN!"+event.ConferenceSid);
twilioClient.conferences(event.ConferenceSid)
.participants
.create({
label: 'customer',
earlyMedia: true,
beep: 'onEnter',
record: true,
from: fromNumber,
to: toPhoneNumber
})
.then(participant => console.log(participant.callSid));
}else{
console.log("in confrence else");
return callback(null, twilioClient);
}
console.log("in confrence end");
return callback(null, 'success');
};
Logs
Execution started...
2022-12-18 14:07:13 UTC
In confrencecalll
2022-12-18 14:07:13 UTC
Execution ended in 94.03ms using 102MB
2022-12-18 14:07:17 UTC
Execution started...
2022-12-18 14:07:17 UTC
In confrence
2022-12-18 14:07:17 UTC
In confrence IN!CFc5xxxxxxxx
2022-12-18 14:07:17 UTC
In confrence end
2022-12-18 14:07:17 UTC
Execution ended in 144.57ms using 105MB```

Related

Forwarding an incoming call after task reservation timeout

I am using Twilio Flex to support a call center. I have a TaskRouter workflow set up where Task Reservation Timeout is set to 120 seconds. In its filter, I've created two routing steps. The first one finds matching workers in the main queue and has a timeout of 120 seconds. After 120 seconds, it should move to Call Forward Queue. In the call forward queue, no workers exist (target worker expression: 1==2). I'm catching all these events with a "trEventListener" function. Once a task is moved into the Call Forward queue, I call the "callForward" function which uses twiml.dial() to connect the call to an external number. I also change this task's status to "canceled" with a custom reason so I can track it in flex insights. I am using the guide in this link to form my logic: https://support.twilio.com/hc/en-us/articles/360021082934-Implementing-Voicemail-with-Twilio-Flex-TaskRouter-and-WFO.
Call forwarding is working fine but according to Flex insights, there are some calls that get handled after 120 seconds (between 120 - 300 seconds). Ideally, these should be forwarded as well. There is also no error logged for me to track down why this is happening to only a handful of calls.
Furthermore, in some cases, when I try to change the task status to cancel with my custom reason, it spits out the following error: Cannot cancel task because it is not pending or reserved. In other cases, it works fine. It's again hard to figure out why it's selectively working and not consistent in its behavior.
Here is the function code.
trEventListener.js:
exports.handler = function(context, event, callback) {
const client = context.getTwilioClient();
let task = '';
let workspace = '';
console.log(`__[trEventStream]__: Event recieved of type: ${event.EventType}`);
// setup an empty success response
let response = new Twilio.Response();
response.setStatusCode(204);
// switch on the event type
switch(event.EventType) {
case 'task-queue.entered':
// ignore events that are not entering the 'Call Forward' TaskQueue
if (event.TaskQueueName !== 'Call Forward') {
console.log(`__[trEventStream]__: Entered ${event.TaskQueueName} queue - no forwarding required!`);
return callback(null, response);
}
console.log(`__[trEventStream]__: entered ${event.TaskQueueName} queue - forwarding call!`);
task = event.TaskSid;
workspace = event.WorkspaceSid;
const ta = JSON.parse(event.TaskAttributes);
const callSid = ta.call_sid;
let url = `https://${context.DOMAIN_NAME}/forwardCall`;
// redirect call to forwardCall function
client.calls(callSid).update({
method: 'POST',
url: encodeURI(url),
}).then(() => {
console.log(`__[trEventStream]__: [SUCCESS] ~> Task with id ${task} forwarded to external DID`);
// change task status to canceled so it doesn't appear in flex or show up as a pending task
client.taskrouter.workspaces(workspace)
.tasks(task)
.update({
assignmentStatus: 'canceled',
reason: 'Call forwarded'
})
.then(task => {
console.log(`__[trEventStream]__: [SUCCESS] ~> Task canceled`);
return callback(null, response);
}).catch(err => {
console.log(`__[trEventStream]__: [ERROR] ~> Task not marked complete: `, err);
// doesn't warrant reponse 500 since call still forwarded :)
return callback(null, response);
});
}).catch(err => {
console.log(`__[trEventStream]__: [ERROR] ~> Task failed to forward to external DID: `, err);
response.setStatusCode(500);
return callback(err, response);
});
break;
default:
return callback(null, response);
}
};
callForward.js:
exports.handler = function(context, event, callback) {
console.log(`forwarding call`);
// set-up the variables that this Function will use to forward a phone call using TwiML
// REQUIRED - you must set this
let phoneNumber = event.PhoneNumber || context.NUMBER;
// OPTIONAL
let callerId = event.CallerId || null;
// OPTIONAL
let timeout = event.Timeout || null;
// OPTIONAL
let allowedCallers = event.allowedCallers || [];
let allowedThrough = true;
if (allowedCallers.length > 0) {
if (allowedCallers.indexOf(event.From) === -1) {
allowedThrough = false;
}
}
// generate the TwiML to tell Twilio how to forward this call
let twiml = new Twilio.twiml.VoiceResponse();
let dialParams = {};
if (callerId) {
dialParams.callerId = callerId;
}
if (timeout) {
dialParams.timeout = timeout;
}
if (allowedThrough) {
twiml.dial(dialParams, phoneNumber); // making call :)
}
else {
twiml.say('Sorry, you are calling from a restricted number. Good bye.');
}
// return the TwiML
callback(null, twiml);
};
Any kind of help and/or guidance will be appreciated.
Twilio developer evangelist here.
When you redirect a call from a task, its task is cancelled with the reason "redirected" so you don't need to cancel it yourself.
Your code was failing to update the task occasionally because of a race condition between your code and the task getting cancelled by Twilio.

twilio recordingStatusCallback is not sending parameters to url

I want to send a number with recordingStatusCallback url. But, when I receive the log of the parameters in web-hook url, I don't see the parameter I passed in the URL. I was parsing the parameters as url-endcoded format.
Below code, I am sending chunkStartNumber=18 in url,but there is no trace of chunkStartNumber in log below
var recLenDivided=18;
let twiml = new Twilio.twiml.VoiceResponse();
twiml.record({
action:`https://xyz`,
method: 'GET',
finishOnKey: '5',
recordingStatusCallback:`http://xyz/hookFolder?chunkStartNumber=${recLenDivided}`
});
return callback(null, twiml);
}
The parser code
const express = require ('express')
const bodyParser = require ('body-parser')
const app = express()
const PORT = 3000
app.use(express.static("public"))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended:true}))
app.post("/hookFolder",(req, res) => {
console.log(req.body)
res.status(200).end()
})
The log
{ RecordingSource: 'RecordVerb',RecordingSid: 'RE', RecordingUrl: 'https://api.twilio.com/2010-04-01/', RecordingStatus: 'completed', RecordingChannels: '1', ErrorCode: '0', CallSid: 'CA', RecordingStartTime: 'Tue, 22 Dec 2020 18:09:44 +0000', AccountSid: 'AC', RecordingDuration: '9' }
Try req.query.
Also, no need to use Bodyparser. Built in with later versions of Express.
4.16.0 - Release date: 2017-09-28
https://expressjs.com/en/changelog/4x.html
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

Twilio Cloud Based Functions and Libraries

#philnash had a solution [here][1] that I tried and had a problem - I'm using Twilio's Cloud Functions and getting no intellisense on client.messages - any idea how to reference the correct library
client.messages.create({
In the screenshot, you spelled client wrong, cleint.
exports.handler = function(context, event, callback) {
const twilioClient = context.getTwilioClient();
twilioClient.messages
.create({
body: 'Hello World',
to: '+14075551212',
from: '+18025551212 ',
}).then(message => {
console.log('Created call using callback');
console.log(message.sid);
callback();
})
.catch(error => {
console.log(error);
callback("error");
});
};
You should update the Twilio client library version as well, 3.29.2 is pretty old.

Call forwarding + SMS + Whisper?

I'm trying to implement a Twilio function to (1) forward calls to my personal phone, (2) send a "heads up" SMS just before, and (3) say a whisper prior to connecting. I've been able to set up Twilio to do any 2 of the previous 3 things but never the 3 at the same time!
exports.handler = function(context, event, callback) {
// Get an initialized Twilio API client
const client = context.getTwilioClient();
twilioClient.messages.create({
to: 'PERSONAL_PHONE',
from: 'TWILIO_PHONE',
body: 'Incoming!!!'
}).then(function() {
const twiml = new Twilio.twiml.VoiceResponse();
twiml.dial.number({ url: WHISPER_URL }, 'PERSONAL_PHONE');
callback(null, twiml);
});
};
When implementing this, it sends the SMS but the call never connects (and the calling party hears an error message).
Would really appreciate a lesson here :)
Thank you!
Btw, I found a solution:
exports.handler = function(context, event, callback) {
// Get an initialized Twilio API client
const client = context.getTwilioClient();
twilioClient.messages.create({
to: 'NUMBER',
from: 'TWILIO_PHONE',
body: 'Incoming!!!'
}).then(function() {
const twiml = new Twilio.twiml.VoiceResponse();
const dialobj = twiml.dial();
dialobj.number({url:'WHISPER_URL'},'NUMBER');
callback(null, twiml);
});
};

How to record a conference call within a Twilio runtime function?

This Twilio runtime function creates a conference, but I am unable to figure out how to activate recording.
exports.handler = function(context, event, callback) {
let twiml = new Twilio.twiml.VoiceResponse();
twiml.say("You have joined my conference bridge");
let conferenceName = "My Conference Bridge";
twiml.dial().conference(conferenceName);
callback(null, twiml);
};
screenshot of the runtime function
How about this.
exports.handler = function(context, event, callback) {
let twiml = new Twilio.twiml.VoiceResponse();
twiml.say("You will now be entered into your confernece");
twiml.dial().conference({record: 'record-from-start'}, 'myconference');
callback(null, twiml);
};

Resources