3
votes

I believe I might not quite understand the process flow for Twilio calls. I have two scenarios - one where I make a call from my browser to a phone (outgoing), and the second where I make a call from my phone to the browser(client) (incoming).

For both of these calls, I log the post data sent by twilio in a log file when that request reaches my Twilio Voice URL.

And in both cases, the "direction" post variable says "inbound". I would expect one to say "inbound" and the other "outbound", or "outbound-dial" (according to the docs).

Yet they both say "inbound". So I'm probably misunderstanding how this value gets set by Twilio. Can someone please explain what I've gotten wrong?

I was hoping to use this "direction" variable to determine in my app whether a call was going out from the client to a phone, or coming in from a phone to the client. i.e. when a request reaches my twilio voice url, my code can determine whether it's an incoming call to the browser, or an outgoing call to a phone or another client.

More details about the two scenarios.

(1) I have a simple Twilio client that exists on a web page. When I enter a phone number and click connect, it calls the Twilio.Device.connect javascript function which passes the connection to my Twilio Voice Url at Twilio.

I would expect the "direction" data to say "outbound" or "outbound-dial" in this case, but it says "inbound".

(2) I make a call from my phone to the browser client, using the twilio registered phone number to look up the client info.

I would expect the "direction" data to say "inbound", which it does.

Any help would be appreciated. Thanks!

2
This is not really a programming question, so it would be best to direct this to Twilio support with some example SIDs and they will be able to explain.philnash
Did you ever find the solution to this? I'm setting up this exact scenario and I'm seeing the same thing you did.agritton

2 Answers

0
votes

For anybody who finds this, I have found a github issue that says this is by design.

when making a call from a Twilio client (e.g. the iOS mobile client in your case), you are actually making an "inbound" call request to your TwiML application. To separate the two use cases (Twilio number inbound vs. call initiated by mobile client) my suggestion is to have different endpoints in your application server

It also suggest that we create two separate endpoints to handle in/out scenarios. While I think this is VERY bad design, nothing we can do about it except workarounds...

As if this isn't enough, the outbound call's status is 'completed' in each of the following scenarios: OUTBOUND ANSWERED - OUTBOUND OUR USER CANCELLED THE CALL - OUTBOUND CALL RECEIVER REJECTED THE CALL.

And here is an example response of the status callback of an outbound call (same on each above scenarios):

ApiVersion: '2010-04-01',
Called: '',
CallStatus: 'completed',
Duration: '1',
From: 'client:Anonymous',
CallDuration: '4',
Direction: 'inbound',
Timestamp: 'Mon, 22 Mar 2021 18:03:11 +0000',
AccountSid: 'XXXXXXXX',
CallbackSource: 'call-progress-events',
ApplicationSid: 'XXXXXXXXX',
Caller: 'client:Anonymous',
SequenceNumber: '0',
To: '',
CallSid: 'XXXXXXXXXXXX'

However, there is an option in dial called action where you can specify what to do when the call ends.

let dial = resp.dial({ 
  callerId: from,
  action: 'YOUR_API_URL' // replace with your endpoint URL. default call method is POST.
})

There we can see DialCallStatus which can be completed/busy/failed etc.

Also note that Twilio will throw an error so don't forget to handle the response to Twilio there, otherwise it will say "application err occurred" at the end of the call. I simply did hangup at the beginning of action (call end) endpoints and seems like it did the trick.

One final side note is, the action endpoint for outbounds don't have much data in the response like the inbound calls, so you can retreive the information using the DialCallSid parameter, and fetch the call resource

// Download the helper library from https://www.twilio.com/docs/node/install
// Your Account Sid and Auth Token from twilio.com/console
// and set the environment variables. See http://twil.io/secure
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = require('twilio')(accountSid, authToken);

client.calls('CAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')
      .fetch()
      .then(call => console.log(call.to));
0
votes

As an completion to @Luna's answer, I want to add few notes that may help anyone developing a twiML based application.

Normally, when you are making a call using your twiML client (JS, IOS, Android), the voice hook receives parameters which can help you identify if the call is in-bound or out-band. As an example, a parameter called To:"" with empty value means that the in-bound request to your twiML app was not dialing any of the numbers in your application, so its safe to say that your application was actually trying to make an out-bound call.

Also, From and Caller parameters may start with client: which again means the same thing as above.