1

I am attempting to modify the following code to perform a whisper and require the agent who answers to press 1. If they do not answer or do not press 1, the call will then go to voicemail. I need this to be in a function simply because I can't call a Twiml Bin from Studio. Any help would be greatly appreciated. The source of the script below is https://github.com/philnash/useful-twilio-functions/tree/master/hunt.

exports.handler = function(context, event, callback) {
  const numbers = context.PHONE_NUMBERS.split(',').map(number => number.trim());
  const response = new Twilio.twiml.VoiceResponse();
  if (event.DialCallStatus === 'complete') {
    // Call was answered and completed
    response.hangup();
  } else if (event.finished === 'true') {
    if (context.FINAL_URL) {
      response.redirect(context.FINAL_URL);
    } else {
      response.hangup();
    }
  } else {
    const numberToDial = event.nextNumber ? event.nextNumber : numbers[0];
    const currentNumberIndex = numbers.indexOf(numberToDial);
    let url;
    if (currentNumberIndex + 1 === numbers.length) {
      // No more numbers to call after this.
      url = '/hunt?finished=true';
    } else {
      const nextNumber = numbers[currentNumberIndex + 1];
      url = '/hunt?nextNumber=' + encodeURIComponent(nextNumber);
    }
    const dial = response.dial({ action: url });
    dial.number(numberToDial);
  }
  callback(null, response);
};

1 Answers1

1

Twilio developer evangelist (and owner of that repo) here.

To perform a whisper you need to add a url attribute to the <Number> that points to a URL that returns TwiML with the message you want to whisper.

In the code above, this means you need to update the line:

dial.number(numberToDial);

to:

dial.number({ url: 'https://example.com/whisper' }, numberToDial);

Then, at that URL you need to return your message nested in a <Gather> so you can get the result from the answerer. The <Gather> will need an action attribute set to a URL where you will get the result. You could do this with just a TwiML Bin and the result should look a bit like this:

<Response>
  <Gather action="ACTION_URL" numDigits="1">
   <Say>You are receiving a call, please dial 1 to accept or anything else to reject</Say>
  </Gather>
</Response>

Finally, your ACTION_URL needs to point at a function again, so that you can deal with the result. Something like this should work:

function handler(context, event, callback) {
  const response = new Twilio.twiml.VoiceResponse();
  if (event.Digits === '1') {
    response.say('Connecting you now');
  } else {
    response.hangup();
  }
  callback(null, response);
}

This will do the whispering, but since this is part of the hunt from that function, you'll need to provide your FINAL_URL that would take the caller to voicemail after the hunt is over.

Let me know if that helps at all.

philnash
  • 70,667
  • 10
  • 60
  • 88
  • Thank you! This works perfectly. The only thing we had to change was the "/hunt?" in the original code to use the full URL of the function. That's because we are calling the function from Studio and it would try and process against https://webhooks.twilio.com/hunt instead of the actual function. Thank you again! – Moez Tharani Jul 28 '18 at 14:55
  • Not sure if you can help further on this, but it isn't actually working properly when called from Studio. It dials the numbers fine, but the whisper functionality is lost. If I had to guess, Twilio doesn't support calling from a Twiml bin from a function that's been called from Studio. Using a function for whisper instead of Twiml bin might work. Any suggestions? – Moez Tharani Jul 28 '18 at 16:28
  • I'm not sure what the issue there is. Are you using an absolute URL for the `` url? – philnash Jul 30 '18 at 01:34
  • Yes. The only other thing I can think of is that for the voicemail URL, I'm using a Twimlet (https://www.twilio.com/labs/twimlets). Again, it works perfectly fine if I have the phone number use it directly, it just doesn't work when called via Studio. – Moez Tharani Jul 30 '18 at 14:31
  • I recommend you actually send this one in to [Twilio support](https://www.twilio.com/help/contact) as it may be an issues with the interaction of voice calls and Studio that can be fixed. It definitely sounds like it should work, especially if a call going through the flow works when Studio is not involved. – philnash Jul 30 '18 at 22:49
  • I've opened a ticket with Twilio @philnash, but I also have some more information for you and some thoughts on what's wrong. This actually does work the same if it's called directly or via Studio. If the agent answers and then disconnects without pressing 1, the call goes to voicemail as expected. If, however, the agent rejects the call or doesn't answer it, the caller is connected anyway and is then sent to the agents cellphone voicemail. Maybe something to do with DiaCallStatus? – Moez Tharani Aug 01 '18 at 15:22
  • That's a good point. Can you test what `DialCallStatus` comes back if the agent rejects the call from the whisper and let me know? – philnash Aug 05 '18 at 05:35
  • The DialCallStatus is completed in either scenario. If I look at the logs for both calls, the exact same post is made to the function and the response is the same in both cases (Redirect with the final URL). But the next step of actually going to the voicemail is only completed if the agent answers first, then hangs up. – Moez Tharani Aug 05 '18 at 21:16
  • Another weird thing that happens here. When I choose 1 to answer the call, I get an error instead of "Connecting". The error in the logs is below. Also, if I (agent) disconnects the call first, the person on the other end is connected to my Twilio voicemail. This happens even after having a long conversation. – Moez Tharani Aug 07 '18 at 21:05
  • Ok, I was able to fix the issue of the error by modifying the whisper function to use exports.handler = function instead of function handler. But the issue of the call going to the cellphone voicemail if rejected still remains. Additionally, the caller being connected to Twilio voicemail after the call is ended by the agent is also still happening. Twilio has not provided any support on this. – Moez Tharani Aug 07 '18 at 21:22
  • Hi @MoezTharani, this conversation has taken a long time and is difficult to follow what you have now and what is going wrong. You also mention an error. You should probably start a new question and fill in the details that you are using now, including any errors, what you expect to happen and what is happening right now. Feel free to let me know when you do that. – philnash Aug 10 '18 at 06:29
  • Done. https://stackoverflow.com/questions/51845132/twilio-studio-function-voicemail-issue – Moez Tharani Aug 14 '18 at 15:39