Recording calls using twilio rest api - node.js

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.

Related

Get Twilio phone number Friendly Name when forwarding SMS message using Twilio Functions

I would like to pass along the Twilio phone number's Friendly Name when I forward the SMS message to another phone number. (The Friendly Name is a property assigned to a Twilio number when it is purchased.)
This is not the same as "Send Branded SMS Messages Using Twilio Alphanumeric Sender ID" described here and here.
I am operating in the USA where the above is not supported, and I am OK including the "Friendly Name" in the body of the forwarded message (or the subject line of the email). Also, The "Friendly Name" is not associated with the original sender of the message as in the above examples, but instead is associated with my Twilio numbers. Hope that's all clear.
I am using this example code:
Forwarding SMS messages to another phone number – Twilio Support
Three parameters are passed into the function:
exports.handler = function(context, event, callback) {
context includes environment variables I configure. callback isn't relevant to this question. And for the event parameter, we have these properties:
AccountSid
ApiVersion
Body
From
FromCity
FromCountry
FromState
FromZip
MessageSid
NumMedia
NumSegments
SmsMessageSid
SmsSid
SmsStatus
To
ToCity
ToCountry
ToState
ToZip
Using Twilio Functions, I want to obtain Friendly Name, which is not a property of event. Is it possible to obtain the Friendly Name through one of the other properties? If so, how?
UPDATE: from this Twilio doc I see a clue that I can possibly get Friendly Name from AccountSid.something.outgoing_caller_id.friendlyName
I can't quite understand how to do that in a Twilio function. I tried using:
context.getTwilioClient();
The docs say that "will return an initialized REST client that you can use to make calls to the Twilio REST API." However, it returns an empty httpClient object along with strings for username, password and accountSID. I was expecting a populated object from which I could obtain the phone number's Friendly Name.
As an aside, I would like to ask what objects get passed into the event parameter. In what circumstances would the event parameter contain different properties from those I listed above?
You are well on the right path! Excellent research. In fact, context.getTwilioClient() is part of it. Once you have the Twilio REST API client initialized, you can use another Twilio API to determine what the FriendlyName is from the event.To. I found that here, Filter IncomingPhoneNumbers with exact match.
Below is one way, there certainly may may be others.
const got = require('got');
// async function to deal with async REST API call
exports.handler = async function(context, event, callback) {
const client = context.getTwilioClient();
// await an async response
await client.incomingPhoneNumbers
.list({phoneNumber: event.To, limit: 1})
.then(incomingPhoneNumbers => event.friendlyName = incomingPhoneNumbers[0].friendlyName)
.catch(err => console.log(err));
const requestBody = {
personalizations: [{ to: [{ email: context.TO_EMAIL_ADDRESS }] }],
from: { email: context.FROM_EMAIL_ADDRESS },
subject: `New SMS message from: ${event.From}`,
content: [
{
type: 'text/plain',
value: `${event.Body} - ${event.friendlyName}`
}
]
};
got
.post('https://api.sendgrid.com/v3/mail/send', {
headers: {
Authorization: `Bearer ${context.SENDGRID_API_KEY}`,
"Content-Type": 'application/json'
},
body: JSON.stringify(requestBody)
})
.then(response => {
console.log(response);
let twiml = new Twilio.twiml.MessagingResponse();
twiml.message({to: '+1555xxxxxxx'}, `You Message: ${event.Body} - ${event.friendlyName}`);
callback(null, twiml);
})
.catch(err => {
console.log(err);
callback(err);
});
};
Specific to the key's associated with the event object, this is a handy one to use.
Object.keys(event).forEach( thisKey => console.log(`${thisKey}: ${event[thisKey]}`));

How to get Conference Sid at the time of dialing twilio call

I've been working with twilio, using Node.js, and dialing call between two web end points. One is client and other is agent. I'm using following code to dial call.
function dialCall(calledNumber, url) {
client.calls.create({
to: `client:${calledNumber}`,
from: twilioNumber,
url: url
})
.then(call => call.sid));
}
I'm using following twiml to establish a call.
const generateTwiml = (conferenceName) => {
let twimlResponse = new VoiceResponse();
twimlResponse.say(`Welcome to unity dialer.`, {
voice: 'alice',
});
const dial = twimlResponse.dial({
timeLimit: '600',
});
dial.conference({
startConferenceOnEnter: true,
endConferenceOnExit: true
}, "Test Room");
return twimlResponse.toString();
};
I've been successfully calling both agents and clients and getting callSid of both calls. However, my question is that at this point of time I also want to get conference Sid as well as I'm dialing the call as conference. What is the method to get that. As per documentation there is a method to fetch conference using conference name and status. However, if I use this some time the same is not returned due to race condition and I have to implement set time out function for same arbitrary delay. I've been getting the result but is there any other solution available for that.
Twilio developer evangelist here.
At the time you return the TwiML to create the conference there is not yet a conference resource so there's no way to get the conference SID at that stage.
As you describe, you can use the conference resource to list conferences and filter by the name you give it. However, you can't list the conferences at the time you return the TwiML because that conference hasn't been created by then.
Rather than setting a timeout, which could be flaky, I recommend you use the statusCallback attribute of the <Conference> TwiML to set a URL to callback to when the conference starts. In the parameters to that callback you will get the ConferenceSid.

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.

Twilio: Hangup a call in an existing conference, ERROR 20404

Following situation:
Someone called my Twilio Number
Twilio requested my url
Caller gets into a conference (don't starts until a second person join)
TwiML makes call to a Mobile
The Moblie dont accept the call
=> no second Person enters the conference so it wont stop and the caller is stuck there.
My solution is to end the whole call if this happens, I already know where to place the endCall function so this is not my problem. The function looks like this (You'll find it in the twilio API too):
client.calls(accountSid).update({
status: "completed"
}, function(err, call) {
if(err){
console.log(err);
}
});
My programm logic is fine, I see that this function is called at the right place but I receive this Error:
{ status: 404,
message: 'The requested resource /2010-04-01/Accounts/AC/Calls/AC.json was not found',
code: 20404,
moreInfo: 'https://www.twilio.com/docs/errors/20404' }
I already red whats at the moreInfo url but I disqualify
the solutions there. Maybe you have an idea whats the problem with this.
Twilio developer evangelist here.
You are almost all the way there. Your problem is that you are using your accountSid when trying to update the call's status.
You need to get hold of the callSid of the original call. You will find the callSid in the parameters that you receive in the incoming webhook when the person calls your Twilio number.
app.post('/calls', function(req, res, next) {
var callSid = req.body.CallSid;
// store callSid somewhere for use later
// return TwiML to set up conference and dial your mobile number
});
You'll need to save that callSid and then use it at this point later when you want to hangup the call.
client.calls(callSid).update({
status: "completed"
}, function(err, call) {
if(err){
console.log(err);
}
});
Let me know if this helps at all.

Resources