0

So I'm playing with Twilio Studio, and building a sample IVR. I have it doing a web request to an API that looks up the customer based on their phone number. That works, I can get/say their name to them.

I'm having trouble with the next step, I want to do another http request and pass the 'customer_id' that I get in webrequest1 to webrequest2, but it almost looks like all the web requests fire right when the call starts instead of in order/serialized.

It looks sorta like this;

  • call comes in, make http request to lookup customer (i get their customer_id and name)
  • split on content, if customer name is present, (it is, it goes down this decision path)
  • do another http request to "get_open_invoice_count", this request needs the customer_id though and not their phone number.

From looking at the logs it's always got a blank value there, even though in the "Say" step just above I can say their customer_id and name.

I can almost imagine someone is going to say I should go use a function, but for some reason I can't get a simple function to do a (got) get request.

I've tried to copy/paste this into a function and I kind of think this example is incomplete: https://support.twilio.com/hc/en-us/articles/115007737928-Getting-Started-with-Twilio-Functions-Beta-

var got = require('got');
got('https://swapi.co/api/people/?search=r2', {json: true})
  .then(function(response) {
   console.log(response)
   twiml.message(response.body.results[0].url)
   callback(null, twiml);
  })
  .catch(function(error) {
    callback(error)
  })

If this is the right way to do it, I'd love to see one of these ^ examples that returns json that can be used in the rest of the flow. Am I missing something about the execution model? I'm hoping it executes step by step as people flow through the studio, but I'm wondering if it executes the whole thing at boot?

Maybe another way to ask this question is; If I wanted to have the IVR be like - If I know who you are, i send you down this path, if I know who you are I want to lookup some account details and say them to you and give you difference choices than if you are a stranger. ---- how do you do this?

Troy Anderson
  • 616
  • 1
  • 6
  • 10

1 Answers1

0

You're right -- that code excerpt from the docs is just a portion that demonstrates how you might use the got package.

That same usage in context of the complete Twilio Serverless Function could look something like this:

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

  var got = require('got');

  got('https://example.com/api/people/?search=r2', { json: true })
    .then(function(response) {
      console.log(response);
      twiml.message(response.body.results[0].url);

      callback(null, twiml);
    })
    .catch(function(error) {
      callback(error);
    });
};

However, another part of the issue here is that the advice in this documentation is perfectly reasonable for Functions when building an app on the Twilio Runtime, but there are a couple of unsaid caveats when invoking these functions from a Studio Flow context. Here's some relevant docs about that: https://support.twilio.com/hc/en-us/articles/360019580493-Using-Twilio-Functions-to-Enhance-Studio-Voice-Calls-with-Custom-TwiML

This function would be acceptable if you were calling it directly from an inbound number, but when you use the Function widget within a Studio flow to return TwiML, Studio releases control of the call.

If you want to call external logic that returns TwiML from a flow, and want to return to that flow later, you need to use the TwiML Redirect widget (see "Returning control to Studio" for details).

However, you don't have to return TwiML to Studio when calling external logic! It sounds like you want to make an external call to get some information, and then have your Flow direct the call down one path or another, based on that information. When using a Runtime Function, just have the function return an object instead of twiml, and then you can access that object's properties within your flow as liquid variables, like {{widgets.MY_WIDGET_NAME.parsed.PROPERTY_NAME}}. See the docs for the Run Function widget for more info. You would then use a "Split Based On..." widget following the function in your flow to direct the call down the desired branch.

The one other thing to mention here is the Make HTTP Request widget. If your Runtime Function is just wrapping a call to another web service, you might be able to get away with just using the widget to call that service directly. This works best when the service is under your control, since then you can ensure that the returned data is in a format that is usable to the widget.

NReilingh
  • 1,730
  • 17
  • 32