I’m working on getting Twilio app-to-phone voice calls working.
Here’s my current flow.
- Client clicks the “Make Call” button on my website.
- My site sets up the Twilio device and calls
const call = await twilioDevice.connect({ params });
- On my server, the endpoint specified in Twilio App-> Voice Configuration ->Request URL is hit. This endpoint is called “/make-calls” (This all seems to work as expected up to this point).
- My “make-calls” endpoint calls
twilioClient.calls.create()
and returns this xml to Twilio:
<Response>
<Connect/>
</Response>
- There are no errors shown by Twilio, but in console.log on the client I see:
console.js:288 [TwilioVoice][Call] Received an error from the gateway:
ConnectionError: ConnectionError (31005): Error sent from gateway in
HANGUP
at Call._onHangup (call.js:291:23)
at PStream.emit (events.js:161:5)
at PStream._handleTransportMessage (pstream.js:148:10)
at WSTransport.emit (events.js:161:5)
at WSTransport._onSocketMessage (wstransport.js:156:18)
The client immediately hangs up the call. The callee’s phone rings, but no one is on the other end to talk to.
My server console.logs show that ‘/twiml’ endpoint is never hit, and neither is my ‘handle-amd-result’ endpoint.
What am I leaving out?
Here's the code from my "make-calls" endpoint:
console.log('-----')
console.log('/make-call. req?.body:', req?.body);
let nurseId = req?.body?.nurseId;
const navData = await getNavigatorData(nurseId);
const toNumber = navData?.phone_1;
let nurseName = navData?.name_first;
const twilioPhoneNumber = Meteor.settings.private.twilio.phoneNumber;
console.log('toNumber:', toNumber);
let xml = '';
const twilioClient = twilio(accountSid, authToken);
try {
const call = await twilioClient.calls.create({
url: `${baseUrl}twiml`,
to: toNumber,
from: twilioPhoneNumber,
// twiml: twimlString,
machineDetection: 'Enable',
AsyncAmdStatusCallback: `${baseUrl}handle-amd-result`,
statusCallbackEvent: ['initiated', 'ringing', 'answered', 'completed'],
statusCallbackMethod: 'POST',
machineDetectionTimeout: 30
})
let responseObject = {
Response: {
Connect: true,
Play: true
}
}
xml = xmlJs.js2xml(responseObject, xmlJsOptions);
xml = "<Response>n" +
" <Connect/>n" +
"</Response>"
console.log('xml: ', xml)
res.set('Content-Type', 'text/xml');
res.status(200).send(xml);
} catch (err) {
let responseObject = {
Response: {
Success: false,
Message: 'Failed to initiate call',
Error: err.message
}
}
xml = "<?xml version="1.0" encoding="UTF-8"?>" + xmlJs.js2xml(responseObject, xmlJsOptions);
res.set('Content-Type', 'text/xml');
res.status(500).send(xml);
}