7.0 IVR - Example Workflow: Get the Weather

Expand / Collapse

7.0 IVR - Example Workflow: Get the Weather

Article ID: 52022 - Last Review: August 28, 2013


NOTE:  MiContact Center Product Support can assist with questions regarding process and best practices in IVR, however building workflows, troubleshooting PowerShell scripts, or custom SQL queries fall outside their boundaries of support.

The following walkthrough will demonstrate how to build a workflow that leverages:

  • Setting and comparing of variables
  • Executing PowerShell
  • Dynamically playing back messages from a path
  • Performing a web service SOAP call to a publicly accessible web service

By the end of this exercise, you will have designed a workflow that will look a little something like this:

The workflow itself is composed of two main sections, a call flow containing a menu and set-variable activities (seen above), and a subroutine called srGetWeather2.  Whenever a process contains many activities, or has repeating tasks, a subroutine should always be used.  This reduces the memory footprint of the workflow when a new call is picked up by the IVR Port.

In this instance, we run the same process whether we go down the "1-Check ANI" or the "Any '10' Digits" branch of the menu, we just set a different variable depending on the condition.

First, let's explain what the end goal of the call flow is.  In its most basic explanation, the workflow will be used to give users two option, both of which will present them with the current weather temperature of a city.  If the caller presses 1, the workflow will determine their dialing number to determine the city, while the caller can also simply enter a 10 digit phone number and the system will use that to determine the city.

To start, we need to give the workflow an answer and hang-up, as well as configure the menu activity for the caller to choose whether to use their own incoming digits, or an external number that they prefer to enter.

Next, configure a the properties and options of the menu activity.  We'll give it a more appropriate name, as well as associated settings and a prompt to playback a message for the caller.

Once our Menu activity is all configured, we can move on to creating our two menu options.  The first one will be for callers pressing "1", while the second will be for exactly 10 digits.  Because we have the DTMF Multi Digit Delay, the system will wait 1 second after hearing the first DTMF tone from the caller to see if another will be pressed before processing the call.  This allows IVR Routing to accept a large number of types of calls.

Once added, you will have two custom branches for your menu.


Since each branch will perform the same action, we will need to tell the system which telephone numbers to use.  To do that, we will leverage the Set Variable activity.  Set Variable gives IVR Routing the ability to set a custom variable either a predefined value, or the same value as another call variable.  For both options, we will be setting the custom variable (of type Unspecified) RW_ANI to a specified value depending on the branch.  When you use custom variables, try to make them as descriptive as possible without making them too long.  For instance, we have a variable named "RW_City".  This shows me the workflow that it will be used in (RW is short for ReadWeather) and that it will contain the name of the City.


Below is the custom variables we will be creating and, how the custom variable is configured under the Variable section.

Drag a Set Variable activity to each branch and assign them an appropriate name.  Then, right click on the activity, and choose Set Variable. Set the activity "RW_ANI==ANI" and "RW_ANI==LastMenuC…" accordingly:

Now that this is set, you will have two branches that set the same variable, which means we can then act on this activity in the same manor. Enter the subroutine. To create a new subroutine, choose "Subroutine" from the Visual Workflow Manager tab, and choose "Add" then "Voice" to create a new Voice subroutine. A blank Canvas will open.

Our subroutine we will be creating has 4 distinct sections, each performing their own intricate action:

  1. PowerShell Script to strip out the Area Code and City Exchange digits
  2. SQL call to CCMData database to retrieve City and Country name
  3. Web Service Call to public weather web service
  4. Generation and Playing of custom WAV file

NOTE: ReadWeather has been built to leverage North American style numbers. Results may vary for other sites.

The first thing we need to do is take the 10 digit number passed in by the main workflow and split out the Area Code and City Exchange. This will be used later on to determine the city and country. For this, a PowerShell script was created.  (See RW_PrepANI.ps1, attached at the bottom of this article)

For PowerShell scripting, a few things are needed to keep in mind. First, PowerShell by default does not allow you to run user created scripts. On the IVR Routing server, open PowerShell x86 (IVR Routing leverages the x86 version of PowerShell) and run the following command: 'Set-executionpolicy Unrestricted'. This will allow PowerShell scripts to be run on the IVR Routing server. Scripts should also be kept on the IVRDirectory share on the IR Routing server. A subfolder of \Scripts\ should be created if it does not already exist. Copy all PowerShell scripts to \\<IVRROUTINGIP>\IVRDirectory\Scripts\

When writing custom scripts, logging out any pertinent information to a separate file can be pertinent to troubleshooting issues. To this end, Mitel has supplied the following function calls to log output log entries and objects out to a *.LOG folder. Insert the following in your script, and the system will automatically create the SE subfolder to write the file SE_ProServ.log file to. Place the section in your script after the main param entry (parameter definitions, if used), and before other functions or the main body of your script.

Follow these other guidelines when logging in your custom script:

  •  Start first entry in script file with the following log entry#
    •  Write-Log "START" "Script Called with parameter <LIST PARAMETER NAMES AND VALUES>"
  •  Call the appropriate logging function call correctly:
    •  Write-log "<SEVERITY>" "<TEXT>"
        •  INFO: Generic logging of information
        •  WARNING: Used to denote possible problems
        •  ERROR: Used to denote errors
      •  <TEXT>
        •  Any pertinent explanation of the entry.  Add variables to see values by referencing them in the string passed in as $variable
    • Write-Obj <OBJ>
      •  <OBJ>
        •  Passed in object, will write output to log
  •  If wanting to sepearate PowerShell script logs, change "SE_ProServ.log" to new log name
  •  Change <SCRIPT_NAME> to name of script.  Must always log out as name of script

When returning values  under a success or failure branching system, use the following pre-determined template for return values:

  •  Return (-1)
    •  A return value of -1 will indicate an error doing whatever the scripts main intention was
  •  Return (0)
    •  A return value of 0 will indicate that the script completed what its main purpose was, however it encountered warnings in the script.
  •  Return (1)
    •  Anything above 1 indicates the script completed its main purpose.

NOTE: Values can be returned to IVR Routing in any format, and scripts can be created in any fashion.  Mitel recommends certain best practices with regards to server software, but does not insist compliance.

Now that we've gotten all of that out of the way, let's go back to our RW_PrepANI.ps1 script.  Let's pop it open and take a look at the body:

The script will take the passed in ANI digits, and convert them into the Area Code (first 3 digits) and the City Exchange number (second set of 3 digits). Now let's go back to the Canvas and see how this is designed in Visual Workflow Manager.

First, drop in a new Execute activity. Right click on the activity, and choose New Process->PowerShell Script.

The Process Setup window will open. Browse to and choose the script (remember, we place all scripts in the \IvrDirectory\ share \Scripts\ subdirectory), and then select any input parameters. For this script, we need to pass in the full 10 digit number. Based on the way we wrote the script, we are able to reference a parameter or leave it blank knowing that its looking for the first passed in value. Click 'Add' and choose the appropriate parameters. Based on what we set up in the main workflow with the Set Variable activity, we know we will be passing in the RW_ANI value. We can use any 10 digit phone number as a test value.

Click Execute to run the PowerShell script. The success parameters will be shown based on the test value entered.

Once this is successfully run, you will now have a new lower pane titled "Output Mappings". Based on the information from the Success Branch, associate the appropriate PSObject[x] entries to the new variables. For instance, 613 would be the area code, and 599 would be the city exchange. Based on my test run, I would assign the variables RW_AreaCode and RW_Exchange accordingly.

Once we have our area code and city exchange, we will want to convert them to a real world City and Country name. Luckily, we have a built in database on the main MiContact Center server that already has a wealth of information regarding phone numbers: the Call Accounting database.

Configure a data provider connection to your main CCM server database. For instance:

Make sure to choose the CCMData database name.

Next, insert a Query activity into the subroutine's Canvas. Select the Data Provider as the created CCM-DB data connection. Right click on the activity and choose Edit Query Definition. Change to an Advanced Query and enter the following SQL query:

tblConfig_AreaCityCode.AreaCityCode AS [Area Code],
tblConfig_CityExchange.CityExchangeCode AS [Exchange],
tblConfig_CityExchange.Name AS [City],
tblConfig_AreaCityCode.Name AS [StateProv],
tblConfig_Country.Name AS [Country]

tblConfig_AreaCityCode INNER JOIN
tblConfig_CityExchange ON tblConfig_AreaCityCode.Pkey = tblConfig_CityExchange.FKAreaCode INNER JOIN
tblConfig_Country ON tblConfig_AreaCityCode.FKCountry = tblConfig_Country.Pkey

tblConfig_AreaCityCode.AreaCityCode = '@RW_AreaCode' AND
tblConfig_CityExchange.CityExchangeCode = '@RW_Exchange'

Click Execute, and when prompted, enter 613 and 599 for @RW_AreaCode and @RW_Exchange respectively. Click OK to run the query.

Next, go to the Parameter Assignment tab and assign the appropriate variables to the parameter names.

Now go back to the Variable Assignment tab. Since we ran the query, we are returned the Area Code, City, Country Exchange and State/Province. For now, we only need the City and Country, so we will assign those to our pre-defined custom variables.

Now that we have the data in a proper format, we can call the public SOAP-based web service. For this exercise, we will be using WebServiceX.Net's Global Weather SOAP call located at: http://www.webservicex.net/globalweather.asmx

First, drag a new Execute activity onto the Canvas. We'll drag this activity into the "Success" of the previous SQL Query to show that it should only be run if the previous SQL query was a success. From the Canvas, right click on the new Execute activity, choose New Process -> Web Service.

Enter the URI of the WebServiceX address mentioned above. Make sure the Web Service Type is set to SOAP and click "Scan". Once scanned, the "Web Method" section should be populated with the different capabilities of the web service calls.

For now, choose "GetWeather". Your Input Parameters pane will change to include the predefined parameters. Input the appropriate variables we populated in the previous SQL query, input some test parameters and click Execute.

The Execution Successful page will show you the returned XML information. Click OK, and then in the Output Mappings pane, associate the results to appropriate custom variables. For this exercise, we will only be using Time (RW_Time) and Temperature (RW_Temp). Click OK when finished.

Once we've retrieved our data, we want to confirm that something was actually retrieved from the Web Service call before acting on it. To do this, we will create a 'NULL' variable, and leverage the Compare Variable activity to see if data exists. First, we'll create a NULL variable (aptly named 'NULL').

Next, we will add a Compare Variable activity after our Web Service Call. Right click on the activity and select 'Add Compare Variable condition'. We'll add two conditions in the designer, and 'OR' them together. Click add four times. In the first section, choose 'RW_Time', '=', and 'NULL'. In the second section, choose 'RW_Temperature', '=', and 'NULL'. In the third and fourth spots, choose RW_Time and RW_Temperature again, and leave them at the default value of ''.

Next, select all line items, and choose 'Group OR'. This will group the two items together creating a logical examination of the two conditions. This means that if either of these conditions returns true, the Compare Variable activity will also return true. We'll also want to give the branch an identifying name. For this example, we will use "NULL Values Detected" to show that a null value was detected on one of the streams.

Now that we've got our Compare Variables activity configured along with all of our variables populated with data, we can create our wav file to play back to the caller. To do this, we leverage another PowerShell that will use the built-in Microsoft Speech-API.  (See attached RW_GenWavPath.ps1, at the bottom of the article)

Remember, when writing a script, we always want to log out the appropriate information. We'll do this the same in the RW_GenWav script with the following entries.

The scripts starts by configuring the SAPI COM Object to write the file to. It will then check to see if it received the appropriate passed in parameters.

We will be testing for a temperature, and if one is not detected, will be creating a message that states that no temperature information was found for the city in question. We will use this option when we detect 'nullness' in our Compare Variables activity. If values are found, we will split the passed in strings accordingly to get to the information we are looking for, then compose a string that states the city, country, time, and temperature.

Now that we have our string, we can write it to the SAPI COM object created at the beginning of the PowerShell script. We'll finish it off by returning the location of the SAPI file so we can play it back to the user.

With the PowerShell script in hand, we will create two Execute options: one for when we detect null values, and one when don't. Let's give them identifying names as to not confuse them.

Both will be configured identically, except that the NULL value one will not pass in a temperature value (since we detected this was a null in the previous activity). The PowerShell script will handle delivering the different messaging.

From here, we will now have a WAV path that we've assigned to the variable RW_GenWavPath. This variable is created as an Unspecified variable.

Now that we've retrieved our phone numbers location, called our web service, received the temperature, and built our WAV file, all that is left is to play back the file from a variable location. Drop in a Play activity, right click on it, and choose Greeting Prompt->Add a Variable to a Prompt. Choose the RW_GenWavPath we populated in the Execute activity. Save the Subroutine.

You now have a valid subroutine that will play the weather back to you. While testing this though, you may notice something very interesting: when testing against a valid option, and then without hanging up the call, testing against an invalid option, you may notice your old temperature is returned. This can cause some issues if the workflow is continuously asked to return values without clearing the variables. So what can we do? Clear the variables of course.

Drop in a Set Variable activity. Call it "Set Variables to NULL". Right click on the activity and select "Set Variables". Set our two main variables to an empty string value of ''

Save the subroutine. Now, when users call, they check value after value without having to worry about being read back improper values. You can use this same method in the future to clear variables that could potentially cause you problems down the line.

With our Subroutine complete, we can now call it from our two branches. Whichever branch the caller goes down, the same process will always take place, and everything will be controlled from the Set Variable activity.

Drag in a Subroutine activity. Right click, and choose "Assign Subroutine".  Choose the newly created subroutine (in my case, srGetWeather2).

Repeat the process for the second Subroutine activity. Since we may want to search for multiple entries, after our subroutine, we will drop a GoTo activity that will loop back to the main Menu. Drop a GoTo Activity, right click on it, and select Activity Name. Choose the system name of the Main Menu for the Read Weather workflow.

Once complete, you can save your workflow. You have officially finished a very complicated and in-depth IVR Routing workflow. Give yourself a pat on the back!

You can assign a port to your workflow under Port Membership. Choose an available IVR Routing compatible port, and assign the workflow.

Once configured, wait a few minutes while the port is loaded. You can now successfully call your new port and enjoy hearing about the weather all over North America!

Now that we're done our testing, and our workflow is completed, we now want to error proof our workflow. Certain circumstances can occur during a workflow to make certain activities that may work on most occasions fail. These activities will contain Failure branches, and if a caller goes down these paths, you may want to be notified and possibly stop the caller from continuing on. For ReadWeather, we created a subroutine that will play an error message to the end user, email a technician account, and hang up the call.


We'll populate the email with as much information regarding the call as possible, including live variables.


Now, anywhere a subroutine or workflow activity could potentially fail, we will add a subroutine activity and associate it to the failure branch.

And you're done! You've now created a fantastic IVR Routing workflow that includes many new features of IVR Routing, encompassing many of the best practices recommended by Mitel MiContact Center support.

Rate this Article:

Add Your Comments

Name: *
Email Address:
Web Address:
Verification Code:

Last Modified:Tuesday, January 14, 2014
Last Modified By: andrew_montpetit
Rated 3 stars based on 3 votes.
Article has been viewed 22,765 times.