My javascript web app is using Twilio Voice API.
I have this code running on my server. It is in an endpoint named "/make-call" It is in the endpoint on my server that is specified in my TwiML app->Voice Configuration->Request URL.
The code runs and the Twilio rings the phone of the callee. But on the client, a voice says "We're sorry, an application error has occurred." Looking at the Error logs on Twilio, I see:
Twilio is unable to process the Content-Type of the provided URL. Please see Twilio's documentation on accepted content types for more information on valid Content-Types. You must return a Content-Type for all requests. Requests without a Content-Type will appear in the Debugger as a 502 Bad Gateway error.
But it appears that json is being returned. Here's a screenshot from the Twilio console:
What am I missing?
Here's the code from my /make-call endpoint:
console.log('/make-call. req?.body:', req?.body);
let nurseId = req?.body?.nurseId;
const navData = await getData(nurseId);
const toNumber = navData?.phone_1;
let nurseName = navData?.name_first;
const twilioPhoneNumber = Meteor.settings.private.twilio.phoneNumber;
console.log('toNumber:', toNumber);
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
})
res.setHeader('Content-Type', 'application/json');
res.status(200).json({
success: true,
message: 'Call initiated successfully',
callSid: call.sid
});
} catch (err) {
res.setHeader('Content-Type', 'application/json');
res.status(500).json({
success: false,
message: 'Failed to initiate call',
error: err.message
});
}
...and just in case it is relevant, here's the code from my /twiml endpoint:
console.log('-----')
console.log('/twiml webhook. req?.body: ', req?.body)
//trying this out - start
const {VoiceResponse} = twilioClient.twiml;
const response = new VoiceResponse();
// Generate TwiML response
response.say('Hello, this is a response from your TwiML endpoint!');
response.play('http://demo.twilio.com/docs/classic.mp3');
console.log('response.toString(): ', response.toString())
res.set('Content-Type', 'text/xml');
res.send(response.toString());
Solved!
It appears that only xml is permitted as the content type. I updated my code to:
let responseObject = {
response: {
success: true,
message: 'Call initiated successfully',
callSid: call.sid
}
}
xml = xmlJs.js2xml(responseObject, xmlJsOptions);
res.set('Content-Type', 'text/xml');
res.status(200).send(xml);
...and am no longer getting this error. Thanks, Twilio tech support, for this info.