Modify Twilio statusCallback during live call - node.js

I am trying to update a statusCallback during a live call. When I set the statusCallback statically in the console the callback triggers and everything functions as expected.
When I try to update the callback during a live call, the callback seems to be ignored. Am I supposed to be able to change the statusCallback during a live call? Am I missing something obvious?
Code snippet:
var callsid = A_VALID_SID_OBTAINED_PROGRAMATICALLY;
var statuscallback = A_VALID_URL_WHICH_WORKS_WHEN_DEFINED_STATICALLY_IN_CONTROLPANEL;
var client = require('twilio')(MYACCOUNT,MYSID);
client.calls(callsid).update({
statusCallback: statuscallback
})
.then(call => {
callback(null,"SUCCESS");
});

Related

How do I automatically cancel Twilio outbound call as soon as the call status changes to ringing

hello there I am using Twilio to place outbound call I have local node app that initiates a call. I also have Twilio status callback function which monitors the status of call. I want to cancel/end the call when the call status changes to "ringing" I have tried to end a call with hangup and reject TwiML. I was expecting a call to be cancelled automatically but my phone keeps ringing.
node code for placing a call
router.post('/call', async (requ, resp) => {
const accountSid = myaccoundsid;
const authToken = myauthtoken;
const client = require('twilio')(accountSid, authToken);
client.calls
.create({
to: 'to_number',
from: 'from_number',
url: 'http://demo.twilio.com/docs/voice.xml',
statusCallback: 'url_to_my_status_call_back_function',
statusCallbackMethod: 'POST',
statusCallbackEvent: ['initiated', 'ringing', 'answered', 'completed'],
})
.then((call) => {
console.log(call.status);
});
});
The call status returned in my terminal is queued.
My status callback function
const VoiceResponse = require('twilio').twiml.VoiceResponse;
const response = new VoiceResponse();
exports.handler = function(context, event, callback) {
if(event.CallStatus ==='ringing'){
console.log("Call status changed: "+ event.CallStatus);
response.hangup();
console.log(response.toString());
}
callback(null, response);
};
Twilio console
any help will be appreciated thank you
Twilio developer evangelist here.
First, you should likely check with the Twilio terms, specifically the terms related to voice calls to ensure that you do not fall foul of this rule:
Customer will not have, in a given month, (a) a high volume of unanswered outbound voice call attempts from a single originating phone number or (b) a low average outbound voice call duration. Telecommunications providers may independently block Customer’s use of their networks if Customer engages in any of the foregoing behavior.
If you have a legitimate reason to hang up a call as soon as it starts ringing, then read on.
Status callback webhooks are asynchronous, they happen outside of the call itself, so returning TwiML to them does not affect the call. Instead, to use a status callback to affect a call, you need to use the REST API to modify the call and complete it.
An example of this might be:
exports.handler = async function(context, event, callback) {
if(event.CallStatus ==='ringing'){
const client = context.getTwilioClient();
await client.calls(event.CallSid).update({ status: 'canceled' });
}
callback(null, response);
};

Using Twilio API resources within Twilio Functions

I've nearly finished my phone system with twilio and the final part is a voicemail playback. If the call fails or is declined, the calling party can leave a message and it saves to the twilio recordings. All server side code is done in Twilio Functions.
Now I want the end party to be able to check their voicemail by dialing an extension and playing back the saved messages. Everything up to the playing back of messages is done because I can't get the recording uri from a list of recordings.
Note NodeJS is not my strong suite.
I have tried playing back all recordings with:
exports.handler = function(context, event, callback) {
const twilioClient = context.getTwilioClient();
let response = new Twilio.twiml.VoiceResponse();
twilioClient.recordings.each(recording => response.play(recording.uri));
callback(null, response);
}
But I don't the expected result (i.e. I get a 200 OK and the <Response/> xml). I have Enable ACCOUNT_SID and AUTH_TOKEN enabled in the functions configuration.
I feel like it has something to do with the callback and the request to the api being asynchronous but I couldn't find much information on the recordings docs (https://www.twilio.com/docs/api/voice/recording).
Found the documentation I was after in the automated docs (https://www.twilio.com/docs/libraries/reference/twilio-node/3.11.2/Twilio.Api.V2010.AccountContext.RecordingList.html).
client.recordings.each({
callback: function (recording) {
response.say('New Message');
const recordingSid = recording.sid;
},
done: function () {
callback(null, response);
},
});

How can I get the caller from an incoming phone call webhook request?

I'm going to develop a webhook for incoming calls in Twilio:
app.post('/voice', (req, res) => {
const twiml = new VoiceResponse();
const caller = ...;
twiml.say('hello, your number is ' + caller);
res.type('text/xml');
res.send(twiml.toString());
});
How can I get the caller phone number from the request (req)? I don't need the name, but just the number.
I can't find in docs what is sent in the POST body when a webhook is invoked.
The caller phone number you're looking for is in req object.
It's req.body.From.
In your example const caller = ...;
becomes const caller = req.body.From;.
Docs:
Request parameters
https://www.twilio.com/docs/api/twiml/twilio_request#synchronous-request-parameters
Respond to incoming phone calls in Node.js
https://www.twilio.com/docs/guides/how-to-respond-to-incoming-phone-calls-in-node-js#write-nodejs-code-to-handle-the-incoming-phone-call
Call Monitoring with Node.js
https://www.twilio.com/blog/2015/09/monitoring-call-progress-events-with-node-js-and-express.html

Access transcriptionText from twilio

I want to access the transcription text that has been generated by transcribe in my Twilio account under transcriptions as I want to compare user recorded response as text
twiml.say('Hi there! Please speak your response after the beep,-Get ready!')
.record({
transcribe:true,
timeout:5,
maxLength:30,
transcribeCallback:'/recording',
action:'/recording'
});
app.post('/recording', (request,response) => {
if(transcriptionText=='yes'){
twiml.say('thank you for positive response');
}
response.type('text/xml');
response.send(twiml.toString());
});
Twilio developer evangelist here.
When using transcription with <Record>, once the recording is complete the call will continue on to make a request to the action attribute synchronously. Whatever you return from the action attribute URL will control the call.
The actual transcription, however, takes a bit more time and when you get a webhook to the transcribeCallback URL it is done asynchronously, outside the context of the call. So, returning TwiML will not affect the call at all.
You will get the transcription text by inspecting the body of the request. There are plenty of parameters sent to the transcribeCallback, but the one you are looking for is the TranscriptionText. In your Node.js app, which looks like Express to me, you can get hold of it by calling request.body.TranscriptionText.
If you do want to affect the call when you receive the transcribe callback you will need to use the REST API to modify the call and redirect it to some new TwiML.
Let me know if that helps at all.
[edit]
From the comments I can see you are trying to drive a part of the call from a spoken response. The transcribeCallback URL isn't called immediately as the transcription needs to be done, so you need an action URL that you can send your caller to while you wait.
So, adjust your recording route to have different endpoints for action and transcribeCallback:
app.post("/voice", (request, response) => {
var twiml = new twilio.TwimlResponse();
twiml.say('Hi there! Please speak your response after the beep,-Get ready!')
.record({
transcribe:true,
timeout:5,
maxLength:30,
transcribeCallback:'/transcribe',
action:'/recording'
});
response.type('text/xml');
response.send(twiml.toString());
})
Then your recording endpoint will need to keep the user waiting while Twilio transcribes the text.
app.post('/recording', (request,response) => {
var twiml = new twilio.TwimlResponse();
// A message for the user
twiml.say('Please wait while we transcribe your answer.');
twiml.pause();
// Then redirect around again while we wait
twiml.redirect('/recording');
response.type('text/xml');
response.send(twiml.toString());
});
Finally, when you get the transcribe callback you can figure out the course from the transcribed text somehow and then redirect the live call into a new endpoint that carries on the call with the new information.
app.post('/transcribe', (request, response) => {
var text = request.body.TranscriptionText;
var callSid = require.body.CallSid;
// Do something with the text
var courseId = getCourseFromText(text);
var accountSid = '{{ account_sid }}'; // Your Account SID from www.twilio.com/console
var authToken = '{{ auth_token }}'; // Your Auth Token from www.twilio.com/console
var client = new twilio.RestClient(accountSid, authToken);
// Redirect the call
client.calls(callSid).update({
url: '/course?courseId=' + courseId,
method: 'POST'
}, (err, res) => {
response.sendStatus(200);
})
});

twilio node disconnect event

I need a callback url or callback function to be triggered when the phone call disconnects after creating a call with
client.calls.create({
url: "my url" + order._id + '/0',
to: store.notification_phone,
from: myNumber
}, function (err, call) {
});
I'm not sure if I need to create the callback in the nodejs app that does the above call or in the nodejs express server that generates the twiml.
I found a .disconnect( handler(connection) ) under Twilio.Connection, but this doesn't appear to be available in my nodejs.
Twilio developer evangelist here.
To get a callback via a webhook when the call ends you need to pass a statusCallback URL to your call function as well.
client.calls.create({
url: "my url" + order._id + '/0',
to: store.notification_phone,
from: myNumber,
statusCallback: "/calls/callback"
}, function (err, call) {
});
You will then need to implement an endpoint in your express application that receives the callback with all the parameters about the call.
Twilio.Connection and the .disconnect(handler(connection)) that you found are part of the Twilio Client JavaScript library that lets you make calls in the browser, so are not part of the server side API helper.

Resources