node.jstwiliotwilio-apitwilio-click-to-call

Twilio Request URL Endpoint Returns json, but Twilio Says it Is Wrong Content-Type?


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:

enter image description here

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());

Solution

  • 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.