Search code examples
javascripttwilioivrtwilio-studiotwilio-functions

Twilio Studio - Having trouble making requests to the API


I'm facing an issue in the development of my IVR using Twilio Studio. Currently, I need to make some requests using an API. By default, to make the requests, it's necessary to pass through the authentication endpoint so that a token can be generated, allowing me to use it in other endpoints. My question is, how do I use the generated token in a new function so that the request is made correctly?

So far, I've tried to invoke the widget that requests the token in the new function that will validate other matters, but it returns an error stating that the content cannot be accessed.

Flow: flow diagram

  • Widget Run Function - Authorization_API1 - > The responsible function for generating the token.

  • Widget Split based on - tokenCriado1 - > The responsible function for validating if the return is "success".

  • Widget Run Function - validaDebito - > It performs a new API call based on the generated token.

My function

const axios = require('axios');

exports.handler = function(context, event, callback) {
        
    // Get the CPF/CNPJ from the event
    const cpfCnpj = event.CPF_CNPJ;

    // Check if the CPF/CNPJ was provided
    if (!cpfCnpj) {
        return callback("CPF/CNPJ not provided.");
    }

    // Get the token generated by the Authorization_API1 widget
    const token = event.widgets.Authorization_API1.parsed.token;

    // Check if the token was provided
    if (!token) {
        return callback("Authorization token not provided.");
    }

    // Base URL of the endpoint
    const baseUrl = 'https://app.omnilink.com.br/apigateway/getcliente';

    // Complete URL with the 'CPF_CNPJ' parameter
    const endpointUrl = `${baseUrl}?CPF_CNPJ=${cpfCnpj}`;

    // Make an HTTP request to get the client's data
    axios.get(endpointUrl, {
        headers: {
            Authorization: `Bearer ${token}` // Add the token to the authorization header
        }
    })
    .then(response => {
        // Check if the response was successful
        if (response.status === 200) {
            // Check if ComunicacaoChip and ComunicacaoSatelital are true
            const cliente = response.data.Cliente;
            if (cliente.ComunicacaoChip && cliente.ComunicacaoSatelital) {
                // Client has no debts
                callback(null, { success: true, inadimplente: false });
            } else {
                // Client is in debt
                callback(null, { success: true, inadimplente: true });
            }
        } else {
            // Response was not successful
            callback(`Error in request: ${response.statusText}`);
        }
    })
    .catch(error => {
        // Error making the HTTP request
        callback(`Error obtaining client data: ${error}`);
    });
};

Debugging Information

Request URL: https://validadebito-4911.twil.io/validaDebito
Request Method: POST
Response Status Code: 500
Response Content Type: application/json

Flow Data

 "widgets": {
    "MenuPrincipalSelecao": {},
    "Authorization_API1": {
      "status_code": 200,
      "content_type": "application/json",
      "parsed": {
        "success": true,
        "token": "TOKEN"
      },
      "body": "{\"success\":true,\"token\":\"TOKEN\"}"
    },
    "validaDebito": {
      "status_code": 500,
      "Called": "+551150399828",
      "ToState": "SP",
      "body": "{\"message\":\"Cannot read properties of undefined (reading 'Authorization_API1')\",\"name\":\"TypeError\",\"stack\":\"TypeError: Cannot read properties of undefined (reading 'Authorization_API1')\\n    at exports.handler (/var/task/handlers/ZN7acdff34f5d5c6173bca9f9d8d4133a4.js:14:33)\\n    at exports.handler (/var/task/node_modules/runtime-handler/index.js:339:10)\\n    at exports.handler (/var/task/runtime-handler.js:17:17)\\n    at Runtime.handleOnceNonStreaming (file:///var/runtime/index.mjs:1173:29)\"}",

Solution

  • It looks like you were expecting the widgets object to be automatically passed down to the function being run. The Twilio documentation [1] provides a complete example, but you need to add function parameters in the "run function" widget to pass down data to the function.

    The following configuration allows you to pass the parsed token from the Authorization_API1 widget response to the function, this value will be set against the "token" key on the event object.

    Key: token
    Value: {{widgets.Authorization_API1.parsed.token}} 
    

    If you update line 14 of your Twilio function to be

    const token = event.token
    

    Then you should be able to use the token to call your API.

    I hope this helps

    [1] https://www.twilio.com/docs/studio/widget-library/run-function#example-random-number-generator