0

I am trying to set up a hunt group with Twilio Twiml

Do I have to set up a different twimlbin for each number in the hunt group?

Or is there a way to join all this together into a single Twimlbin?

Twimlbin 1:
<Response>
    <Dial 
         action="http://www.ourapp.com/webhook;FailUrl=/Twimlbin 2" 
         timeout="10" 
         callerId="555-555-5555">
         NUMBER1
    </Dial>
</Response>


Twimlbin 2:
<Response>
    <Dial 
         action="http://www.ourapp.com/webhook;FailUrl=/Twimlbin 3" 
         timeout="10" 
         callerId="555-555-5555">
         NUMBER2
    </Dial>
</Response>

... Repeat N times for each agent ...

Thank you :-)

Marcus
  • 675
  • 2
  • 8
  • 24

1 Answers1

1

Twilio developer evangelist here.

TwiML Bins are great for static bits of TwiML, but your use case needs a bit more than that.

I recommend you check out Twilio Functions which allow you to run Node.js code in Twilio's infrastructure. I've built and tested a version of this that works with Twilio Functions.

Here's an explanation of how it works:

Start with an array of your numbers:

const numbers = [...];

Then, in the function, check if the callstatus is completed and hang up if it is.

exports.handler = function(context, event, callback) {
  const response = new Twilio.twiml.VoiceResponse();
  if (event.DialCallStatus === "complete" || event.finished) {
    // Call was answered and completed or no one picked up
    response.hangup();
  } else {

If it's not, we work out the next number to call. If you have the next number in the URL. If you do save it to a variable, otherwise pick the first number in the array:

    const numberToDial = event.nextNumber ? event.nextNumber : numbers[0];

Then, assign the next number to dial from the array.

    let url;
    const currentNumberIndex = numbers.indexOf(numberToDial);
    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);
    }

Then generate the TwiML to Dial the next number and pass the URL as the action. You can add your own URL as the statusCallbackUrl to keep a track of the statuses.

    const dial = response.dial({ action: url });
    dial.number({ statusCallback: "https://yourapp.com/statuscallback" }, numberToDial);
  }

  callback(null, response);
}

I can't promise this will work, but I hope you see where I'm going with it. Let me know if it helps at all.

philnash
  • 70,667
  • 10
  • 60
  • 88
  • It nearly works! But it's calling the same number each time. Somehow it's not incrementing when running the url "hunt?nextNumber=" Any ideas gratefully received. – Marcus Jul 26 '17 at 07:11
  • Also there was a } missing in the first code block: " else {" should be "} else {" – Marcus Jul 26 '17 at 07:12
  • I think I've fixed that, realised that the numbers will always be within the array and I needed to test for the current number being last in the array rather than not in it at all. I've updated the code around the bit that starts `let url; const currentNumberIndex ... `. Let me know if that solves it. – philnash Jul 26 '17 at 08:28
  • BOOM! That did it. Thank you. Only issue now is that I get: Attribute 'statusCallback' is not allowed to appear in element 'Dial'. if the statusCallback is in there. (I changed statusCallbackUrl to statusCallback) – Marcus Jul 26 '17 at 08:40
  • Ah, ok. We can do a `statusCallback` for `` instead. I'll update the answer. – philnash Jul 26 '17 at 08:43
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/150158/discussion-between-marcus-and-philnash). – Marcus Jul 26 '17 at 08:52
  • Check out [the fully tested version of this](https://github.com/philnash/useful-twilio-functions/tree/master/hunt) including an option to provide a URL to redirect to if no-one answers. – philnash Jul 26 '17 at 11:23