Please excuse our look. We're just getting started here.

Want to learn more about Twilio Forums? Check out our FAQ page here.

Newbie Twiml question

Hi there
I'm trying to create my first function.

entry function:
exports.handler = function(context, event, callback) {
const twiml = new Twilio.twiml.VoiceResponse();

twiml.gather({
    input: 'dtmf speech',
    timeout: 5,
    hints: 'numbers',
    action: '/action'
}).say('Please enter a number');

callback(null, twiml);

};

action function

exports.handler = function(context, event, callback) {
const twiml = new Twilio.twiml.VoiceResponse();

const command = event.SpeechResult;

twiml.say('You said '+ command);

}

When I call and after I enter the number and '#', it generates an error and hangs up.
What I'm trying to do is to use the input from the first function in the second one, but it seems like I'm missing something crucial.

Thanks for your input

Tagged:

Best Answer

Answers

  • shelbyz
    shelbyz ✭✭✭

    The action function above looks to be missing a callback(...) execution, but it could be that you did not fully copy the function body over. Since your gather is also allowing dtmf you may want to account for that in your function as well.

    exports.handler = function(context, event, callback) {
        const twiml = new Twilio.twiml.VoiceResponse();
        let response;
        if (event.SpeechResult) {
            response = event.SpeechResult;
        } else if (event.Digits) {
            response = event.Digits;
        } else {
            // an error occurred
            response = 'Possibly no response or an error';
        }
    
        twiml.say(`You said ${response}`);
        callback(null, twiml);
    }
    

    If that still seems to have issues, I would look at the error log generated when you hit encounter the issue to see if it has any additional details.

  • This is the full action code

    exports.handler = function(context, event, callback) {
    const twiml = new Twilio.twiml.VoiceResponse();

    twiml.say('hello');
    
    const command = event.SpeechResult;
    console.log("after SpeechResult");
    twiml.say('You said'+ command);
    
    const got = require ('got');
    got('/employee/?Filters=Number:'+ command + '&Fields=FirstName,LastName&exactmatch=true',{headers: {
          Authorization: 'Bearer ABC123'}} 
        )
        .then(response => {
            const employee = JSON.parse(response.body);
    
            let fullname = employee.records[0].firstName + " " + employee.records[0].lastName;
    
            twiml.say("Hi, " + fullname);
            callback(null, twiml);
    
        })
        .catch((error) => {
            twiml.say(command +'is not a valid  number, please try again');
            return callback(command + ' is not a valid number, please try again');
            }
        );
    callback(null, twiml);
    

    }

  • shelbyz
    shelbyz ✭✭✭

    Alright so there are 3 places where callback(...) is executed. The .then(...) and .catch(...) should be fine, but you will want to remove the last. The callback(...) method signals to Twilio serverless runtime that you are done executing and the resources should be cleaned up. If another callback(...) is executed that would be unexpected behavior.

    In your .catch(...) you may want to change the code to:

    .catch((error) => {
            twiml.say(command +'is not a valid  number, please try again');
            callback(null, twiml);
        }
    );
    

    A callback with first parameter set will cause an error response and would cause the call to top. Returning the twiml object you have been building would give the caller an error message. Returning the callback does not have much meaning as we have no additional promise chain listeners, so that can be dropped as well.

  • I added the last callback(null, twiml); to test, but without it, it still generates the error. If I try via web, it works. the issue happens only when calling in

  • This is the error from the log
    Message
    An attempt to retrieve content from https://webhooks.twilio.com/v1/Accounts/ returned the HTTP status code 400
    HTTP retrieval failure

    Possible Causes

    Web server returned a 4xx or 5xx HTTP response to Twilio
    Misconfigured Web Server
    Network disruptions between Twilio and your web server
    No Content-Type header attached to response
    Content-Type doesn't match actual content, e.g. an MP3 file that is being served with Content-Type: audio/x-wav, instead of Content-Type: audio/mpeg
    

    Possible Solutions

    Double check that your TwiML URL does not return a 4xx or 5xx error
    Make certain that the URL does not perform a 302 redirect to an invalid URL
    Confirm the URL requested is not protected by HTTP Auth
    Make sure your web server allows HTTP POST requests to static resources (if the URL refers to .xml or .html files)
    Verify your web server is up and responsive
    Check to see that the URL host is not a private or local IP address
    Verify the ping times and packet loss between your web server and www.twilio.com
    

    I checked the URL and it returns the expected result on its own.

  • shelbyz
    shelbyz ✭✭✭

    Hmm, do you know if the /action endpoint is called? If not, can you share the TwiML/XML generated by the first function?

  • I changed the code a bit and it seems like the function is being called, the problem seems to be in the way the result is coming in. If I give the user the option to use 'dtmf speech', how can I capture either of them? if I use speech, it comes into the SpeechResult, if I use dtmf, SpeechResult will be null

  • Thank you, this is all I needed