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.
Related
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);
};
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");
});
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);
},
});
I'm trying to move the inbound caller to a conference room:
//this is the endpoint for the voice webhook
app.post('/voice',(req,res)=>{
sid=req.body.CallSid;
conferenceName="test conference room";
params={'conferenceName':conferenceName};
url='https://appname.herokuapp.com/addToConference?conferenceName=test';
console.log('now updating inbound call sid '+sid);
client.calls(sid).update({
url:url,
method:'GET'
});
});
//this is the endpoint for adding a caller to a conference
app.get('/addToConference',(req,res)=>{
var conferenceName=req.query.conferenceName;
const response=new VoiceResponse();
response.say("Now connecting you to conference "+conferenceName);
dial=response.dial();
dial.conference(conferenceName);
responseTwiml=response.toString();
console.log("responseTwiml: "+responseTwiml);
res.send(responseTwiml);
});
Console logging shows that the .update() call is reached:
now updating inbound call sid 9j92f892309
But then the Twilio debugger shows an 11205 error, where the url is https://appname.herokuapp.com/voice/. The console log does not show Now connecting you to conference test, so I'm guessing the /addToConference endpoint isn't being reached. Heroku error log shows a Request timeout error.
How can I reach the endpoint and drop the inbound caller into a conference call? If it matters, I want the app to then call someone else, interact with them, and then transfer that call recipient to the conference where the inbound caller is waiting.
Twilio developer evangelist here.
There's a couple of issues here. To start with, the 11205 error is because of a timeout from the call to your /voice endpoint. The issue here is that you never return anything from the function with the res. You could fix that one by calling res.send('') at the end of that function.
However...
There is no need to do the redirect that you're doing at all. You can use the initial webhook response to both drop the caller into the conference and dial the other party. You would do this with the following code:
app.post('/voice',(req,res)=>{
conferenceName="test conference room";
url='https://appname.herokuapp.com/addToConference?conferenceName=' + conferenceName;
client.calls.create({
from: YOUR_TWILIO_NUMBER,
to: THE_OTHER_PERSON,
url: url
});
const response=new VoiceResponse();
response.say("Now connecting you to conference "+conferenceName);
dial=response.dial();
dial.conference(conferenceName);
responseTwiml=response.toString();
res.set('Content-Type': 'text/xml');
res.send(responseTwiml);
});
For this you will still need the /addToConference endpoint which just adds the other caller to the conference, which would look like this:
app.get('/addToConference',(req,res)=>{
var conferenceName=req.query.conferenceName;
const response=new VoiceResponse();
response.say("Now connecting you to conference "+conferenceName);
dial=response.dial();
dial.conference(conferenceName);
responseTwiml=response.toString();
console.log("responseTwiml: "+responseTwiml);
res.send(responseTwiml);
});
You could also redirect the caller in the way you wanted to do in the first place, but instead of modifying the call with the REST API you would use the TwiML <Redirect> verb. That would look like this:
app.post('/voice',(req,res)=>{
conferenceName="test conference room";
url='https://appname.herokuapp.com/addToConference?conferenceName=' + conferenceName;
client.calls.create({
from: YOUR_TWILIO_NUMBER,
to: THE_OTHER_PERSON,
url: url
});
const response=new VoiceResponse();
response.redirect(url);
responseTwiml=response.toString();
res.set('Content-Type': 'text/xml');
res.send(responseTwiml);
});
Let me know if that helps at all.
I am using twilio's rest API's to make and record calls.
client.calls.create({
url:" <my callback url>",
to: " <called number> ",
from: <calling number>,
recordingStatusCallback: <my recording url>,
Record: "true",
sendDigits: "1234"
}, function(err, call) {
if(err){
console.log(err);
}
else{
console.log("Call connected");
}
});
Now, I am unable to understand one thing. Since I have already set the recording property, When twilio makes a call at my callback url, What twiML am I supposed to send if I want to record the entirety of the call ??
Twilio developer evangelist here.
Because you have set the record parameter in the request to make the call you don't need to return return any more TwiML to record the whole call.
You just need to return TwiML to do whatever else that you are then recording, like forward to another number with <Dial> or <Play> the user a message.