Skip to main content


Build a Virtual Call Center in 10 Minutes or Less

Learn how to create a virtual call center and customer IVR call-flow with just a few lines of code.

Webinar Transcription

Hi everyone. I hope you’re as excited as I am for our webinar today. First off, I just want to welcome you to our webinar, how to build a virtual call center in 10 minutes, and thank you for taking the time to attend today. I’d like to introduce Dan Tolbert, a member of our developer experience team.

Dan has been a member of Bandwidth for four years where he’s taken on roles varying from developer, developer evangelists and most recently heading up our development experience team here. He has a vast knowledge of Voice and Messaging APIs, and we’re super pumped to have him running the demo today. Now I’m going to hand everything over to Dan to jump into that demo.

Build a Virtual Call Center: The Basic Setup

All right, today we’re going to go through and create a very, very basic IVR using Bandwidth XML or BXML. We’re clocking in right around 10 minutes. I do have some stuff saved in a copy/paste buffer, so I will be using those as we go through in order to speed things up, but we’ll go over everything that we’re doing today.

As Tyler sent out, there is a ‘get repo’ on GitHub for IVR Webinar, at the end of that, I’ll show you the differences and everything we did today, so you can take a look at that to see the completed code. Alright. With that, let’s go ahead and get started.

Assuming we have all our prerequisites set up, the first thing we need to do today is launch ngrok. If we don’t know what ngrok is, ngrok, is a reverse proxy that lets you hit your local host with webhooks and kind of helps keep everything up to snuff like that.

With that, we’re going to go ahead and just copy this ngrok URL here, and we’re gonna go to our Bandwidth application platform and we’re going to create an application. An application here, lets us direct where we want to send callbacks when things happen to phone numbers. In this case, when an incoming call hits the phone number. I will go ahead and give this a name: “Live Webinar”, and in order to use BXML we want to go to voice or application type and we have to change our callback request method to GitHub to make sure that we get that XML. We also need to make sure that the ‘automatically answer incoming calls’ is set to true.

Now we can go ahead and paste that ngrok URL there. If we open our code, our incoming call-in point I have set up, and some relatively straightforward xNode and express boiler plate code, I have a couple paths already set up by default, we really want to focus on Bandwidth flow instead of setting up an application here.

I’m just going to copy this end point here, head back over to here, paste it in and click ‘create’. That now has an application, boom, “Live Webinar”, and we need to add a phone number to that application, so we’re going to head over to the numbers tab and I’m going to buy a new number to use for us here.

I’m going to search for 919, that’s local to us and I’ll grab this first one here, doesn’t really matter, and then I’ll go click ‘get numbers’ and that’ll order that number to my account. You can also do all of this via the API. Now that I have this new number at the top here, I’m going to click that and I want to associate this to “Live Webinar”. If I click update, boom, and now we’re done with the UI here.

Quick Demo

Just to come to a quick demo, I’m gonna hop over to my tab here and I’m going to npm-start and in theory if I call this number, we should get a “Hello from Bandwidth”. I’m going to pull out my phone and dial. If we take a look at that right there, that’s our handle incoming call path, and “Hello from Bandwidth” using speak sentence.

Alright, so in order to do an IVR, we need to first setup a gather, a gather according to our documentation is a verb like this, gather, that requires a request URL. This is where it’s going to send the information from the gather. You can specify things like max digits and inter-digit time out. For ours we’re only going to set the max digit to 1 because we’re going to set up an IVR to do Raleigh takeout.

Raleigh takeout is going to let you call into a phone number that we just ordered, select from either pizza or burgers, and then it’ll forward you along as you may see fit. We’re going to hop into our code here and based on what we need, we need a next URL, so let’s go ahead and do that next URL and that’s going to equal our base URL plus IVR choice, and that’s going to direct that correctly and we no longer need this BXML here. We want to use our gather, and paste that gather in right there.

Now you can see we have our request. You’re always going to point back to this handler down here and we’re speaking a sentence and we need that sentence. This is going to be the prompt that is sent to the user, so again I have that saved to my paste buffer.

This says: “Hello. Thank you for calling Raleigh take out. Please listen closely as our menu options have changed. For pizza, press one, and for Bad Daddy’s Burgers, press two”, so we have, pressing one will call however many pizza shops we have set, and then if you want to call a burger shop here in Raleigh called Bad Daddy’s, you can press two.

If we go ahead and save that and give that a ring, we should hear our new prompt. “Hello. Thanks for calling Raleigh take out”. Awesome. We’re not going to let that play too long for now. So, we have now our incoming call gather setup.

Now when someone presses a button, we need to see what that looks like, so I’m going to head over here to our documentation and look at what the gather callback has. It looks like we have an event type, state, and digits. This is what I’m looking for, so I need to collect the digits from the user so we have one and two.

I’m going to pop back over to my code and we’re going to return the BXML, go ahead and declare that variable up here, so we have it to work with. Now we’re going to do ‘if rec dot query dot digits equal equal one’, and this is going to be for pizza and then ‘else if rec dot query dot digits equal equal two’, and this is going to be for Bad Daddy’s. Then let’s add a final ‘else’ statement here that will just catch anything else that happens there.

We now have digits equal to 1, they want pizza and 2, they need Bad Daddy’s. I’ve also got the list of phone numbers for these restaurants already here for us. You can look these up online or set it up for whatever you may need, so let’s look and see what will happen next. We want to transfer the call to the pizza shops. We’re going to take a look at our documentation and the transfer verb. For this we’re gonna do a multi transfer, so it’s going to transfer, we’re not going to worry about the caller id here, and we’re going to put in up to a couple phone numbers in whichever one of those numbers answers first, collects the call, it’s like a pizza bake-off if you will.

To take a look at what that BXML is here, we have our response and we’re gonna speak a sentence to the call saying thank you for calling or transferring you to pizza. Then we’re going to transfer to one of three phone numbers. All three of these numbers will ring and the first one to answer will be connected to that call, so that’s our pizza.

And then for a connect to Bad Daddy’s, this is a little bit simpler. We don’t need three phone numbers, we just need one, so I’m gonna paste that in here, and now you want that to say transferring you to Bad Daddy’s. I’m using a template string from javascript to make that string look a little bit easier.

Then finally, for our ‘else’ to catch anything else, we’re going to just speak a sentence and then hang up. We’re going to say, “sorry I didn’t understand your choice. Please try again later” and then we’re going to hang up the call. A better scenario would be to replay the menu and go through that over and over again, but we’re not too concerned with that right now. We just want to demonstrate the IVR functionality.

I’m gonna save all this, and if I did everything correctly when I open up my phone and create a call, we should get a prompt. We will transfer ourselves to the pizza shop here, and we’ll just tell him we have the wrong number. Just confirming your number, thanks! That worked, so let’s call Bad Daddy’s as well, just to confirm that number. So now we’re going to call them. Hey, sorry, just confirming your number. Alright, so now let’s do our final ‘else’ statement and let’s hit three and see what happens. My call hung up for me, so that’s a very quick demonstration on how to do an IVR.

If you want to head to the GitHub repo, you’ll notice there’s an open pull request and there’s a branch called ‘final’ here for you. If you want to see the changes that I made here during the webinar, you can check it out here. You can download this code, you’re free to run it. I would recommend putting in some different phone numbers in the restaurants here. But of course you’re welcome to call and order a pizza if you’d like. Thank you!


Dan, thank you for that awesome demo. So as ya’ll just saw it’s pretty easy to spin up a basic custom IVR in a few minutes with Voice and Messaging APIs, so this is something you want to try yourself, you can jump over to our website and sign up for a free trial and go in there and you know, kick around some of this code that Dan just showed us.

Also, just wanted to let you guys know since this webinar has been so popular, we decided to make a mini-series out of it, actually. Again, I wanted to thank you guys for taking the time to join our webinar with us. Hope you all have a good rest of your day!

Start Your Free Trial

Build a Virtual Call Center in 10 Minutes or Less

Ready to get started?

Bandwidth APIs make it easy to build your own call center