javascriptnode.jsexpresstwilioplivo

getting empty body in record action - twilio


My use case:

My case is that i'm making a bot for listening podcast in which user will make call to twilio number and bot will ask what type of podcast would you like to listen then record for 10 seconds

when recording finish, it say user to please wait while we are finding podcast

I want that recording in my webhook so i will figure out caller mood and find appropriate podcast mp3 file from my database and play to caller

Issue I'm Facing:

I'm getting empty body in all of my webhooks

My code:

var express = require("express");
var bodyParser = require("body-parser");
var VoiceResponse = require('twilio').twiml.VoiceResponse;

var app = express();
var port = (process.env.PORT || 4000);

app.use(bodyParser.json())

// helper to append a new "Say" verb with alice voice
function say(text, twimlRef) {
    twimlRef.say({ voice: 'alice' }, text);
}
// respond with the current TwiML content
function respond(responseRef, twimlRef) {
    responseRef.type('text/xml');
    responseRef.send(twimlRef.toString());
}

app.post("/voice", function (request, response, next) {
    console.log("request: ", request.body); //body is comming as empty object

    var phone = request.body.From;
    var input = request.body.RecordingUrl;
    var twiml = new VoiceResponse();
    console.log("phone, input: ", phone, input);

    say('What type of podcast would you like to listen. Press any key to finish.', twiml);
    twiml.record({
        method: 'POST',
        action: '/voice/transcribe',
        transcribeCallback: '/voice/transcribe',
        maxLength: 10
    });

    respond(response, twiml);
});

app.post("/voice/transcribe", function (request, response, next) {
    console.log("request: ", request.body); //body is comming as empty object

    var phone = request.body.From;
    var input = request.body.RecordingUrl;
    var twiml = new VoiceResponse();

    var transcript = request.body.TranscriptionText;    
    console.log("transcribe text: ", transcript);

    //here i will do some magic(Ai) to detect user mood and find an 
    //appropriate mp3 file from my database and send to twilio

    var mp3Url = 'https://api.twilio.com/cowbell.mp3'

    say('start playing.', twiml);
    twiml.play(mp3Url);

    respond(response, twiml);
});

app.listen(port, function () {
    console.log('app is running on port', port);
});

API Test with postman:

enter image description here

enter image description here

added url as webhook on twilio:

enter image description here

Heroku Logs:

enter image description here


Solution

  • Twilio developer evangelist here.

    You are using body-parser which is good. However, you are using the JSON parser. Twilio makes requests in the format of application/www-x-form-urlencoded so you should change:

    app.use(bodyParser.json())
    

    to

    app.use(bodyParser.urlencoded({ extended: false }))
    

    Then you should see the parsed body as part of the request.body object.

    As an extra note, the transcribeCallback is sent asynchronously to the call. So returning TwiML in response to that request won't affect the call at all. You will need to modify the call in flight, by redirecting it to some new TwiML when you get the result of transcription. An example of updating a call with Node.js is below:

    const accountSid = 'your_account_sid';
    const authToken = 'your_auth_token';
    const client = require('twilio')(accountSid, authToken);
    
    client.calls('CAe1644a7eed5088b159577c5802d8be38')
      .update({
        url: 'http://demo.twilio.com/docs/voice.xml',
        method: 'POST',
      })
      .then((call) => console.log(call.to));