Client.calls.create() doesn't start a call, but no error logged in Twilio or Heroku

897 views Asked by At

I'm hosting a Twilio app on Heroku. I want Twilio to start a separate outbound call and put the user into a conference, if the user selects a certain menu option.

Here is my handler.js:

const VoiceResponse = require('twilio').twiml.VoiceResponse;
const client=require('twilio')(
    process.env.TWILIO_ACCOUNT_SID,
    process.env.TWILIO_AUTH_TOKEN
);
var request = require('request');

exports.menu = function menu(digit,sid) {
  var responseTwiml;
  switch(digit){
    case '1':
        console.log("menu: chose 1");
        responseTwiml=guestCallsHost(sid);
        break;
    default:
        doSomethingElse();
        break;
  }
  return responseTwiml;
};


function guestCallsHost(sid){
    baseUrl='/ivr/callHost';
    console.log("guestCallsHost: baseUrl "+baseUrl);
    conferenceName=sid;
    url='/ivr/callHost?conferenceName='+sid;
    var call=client.calls.create({
        url:url,
        to: process.env.CELL_PHONE_NUMBER,
        from: process.env.TWILIO_PHONE_NUMBER,
        method: 'GET'
    });


    const response = new VoiceResponse();
    const dial = response.dial();
    dial.conference(sid);
    responseStr=response.toString();
    return responseStr;
};


exports.callHost=function callHost(conferenceName){
    const response=new VoiceResponse();
    response.say("testing outbound call to host");
    return response.toString();
};

And here is the router.js that defines the /ivr/ endpoints:

const Router = require('express').Router;
const {
    menu, 
    callHost, 
    } = require('./handler');

const router = new Router();

// GET: /ivr/menu
router.get('/menu', (req, res) => {
  const digit = req.query.Digits;
  const sid=req.query.sid;
  console.log("/ivr/menu: digit "+digit);
  console.log("/ivr/menu: sid "+sid);
  res.send(menu(digit,sid));
});

// GET: /ivr/callHost
router.get('/callHost', (req, res) => {
    console.log("reached callHost endpoint");
  const conferenceName=req.query.conferenceName;
  res.send(callHost(conferenceName));
});

The problem is that the client.calls.create() call is not being made, but no error appears in either the Twilio debugger or the Heroku log. And the /ivr/callHost endpoint is not being visited, despite it being set as the url for client.calls.create(). I know that client has been successfully instantiated as a Twilio object (i think) because when I list all its methods using:

console.log(Object.getOwnPropertyNames(client));

then all the expected Twilio API methods are listed. Or maybe that just means that the object has been created but hasn't been successfully connected to Twilio using the Account SID and Auth Token?

I built this by modifying the app at https://github.com/TwilioDevEd/ivr-phone-tree-node, and I'm able to successfully use client.calls.create() to launch a phone call in another app where I call it in the same index.js file that I'm actually running to start the node app, so maybe in this case the handler.js file isn't actually able to successfully submit the Account SID and Auth Token from where it is in the app structure?

So I'm confused, why can't I make an outbound phone call from inside handler.js? I can transfer inbound calls, so clearly I can modify a live call.

EDIT: I checked whether client is able to make API calls, using:

client
  .calls(sid)
  .fetch()
  .then(call => console.log("call.to "+call.to)).catch(function(error){
    console.log("error: "+error.toString());
  });

The current inbound call's TO number was successfully retrieved, so apparently client has been instantiated and can connect to Twilio's server.

1

There are 1 answers

0
sigil On BEST ANSWER

I solved the problem. It turns out that client.calls.create() requires a full URL with hostname, not just a relative URL, per the documentation for making calls.

I changed:

baseUrl='/ivr/callHost';

to

baseUrl='https://appurl.com/ivr/callHost';

and now the outbound call is successfully generated.