' This is sample IVR application written in "classic" Visual Basic. It speaks the current weather ' condition to a caller whose has identified the locality whose weather he wants by entering its ' ZIP code on his telephone's keypad. ' ' Please note that while the sample may not be considered short, that has to do with what the ' sample does and not the form of its user interface. To put that another way, the entirety of ' the voice user interface code is held in the short (3 dozen exectuable lines) subroutine named ' Answer() which is immediately below. Sub Answer(kall As ComClientCall) Dim i As Integer Dim Ok As Boolean Dim Zip As String Dim Syn As ComSynthesizer Dim Char As String Dim Forecast As String ' Get an instance of the synthesizer and greet the caller Set Syn = kall.getSynthesizer() Syn.speak ("Welcome to the weather demonstration application.") Syn.wait (-1) Do ' Ask the user for a ZIP code Syn.speak ("Please enter a five digit ZIP code or press the pound key to quit.") Syn.wait (-1) ' Wait for 5 strokes or a terminator but not more than 20 seconds Ok = kall.inputWait1(5, "#", 20000) ' If the time out elapses or the caller hangs up we are done If Not Ok Then Exit Do ' We have no patience if he gave us less than 5 digits If kall.inputAvailable() < 5 Then Exit Do ' Build a string from the key strokes ' But if there is a '#' key in there we are done ' We should check for the '*' key as well but we are being lazy here Zip = "" For i = 1 To 5 ' Get the next key that the user pressed Char = kall.getChar() ' We should check for '*' too but we are lazy and this is just a sample If Char = "#" Then Exit Do Else Zip = Zip + Char End If Next i ' Tell the caller to wait Syn.speak ("Please wait ...") ' Amuse him with "music on hold" kall.loopMessage ("strumming") ' Get his forecast while he listens to music Forecast = DoRequest(kall, Zip) ' Stop playing music and put a delay between the music and the speech kall.stopPlaying kall.wait (500) ' Speak the forecast and display it for debugging Syn.speak (Forecast) kall.writeln (Forecast) ' Log the input and output to the call detail records table Ok = kall.cdrStatusMessage(0, Zip) Ok = kall.cdrStatusMessage(1, Forecast) ' Let him hear the forecast before we ask if he wants to go again Syn.wait (-1) Loop ' If he is still on the line we will say good bye If Not kall.isDisconnected() Then Syn.speak ("Good bye.") Syn.wait (-1) End If End Sub ' Access a web service to retrieve the weather Function DoRequest(kall As ComClientCall, ZipCode As String) As String Dim QueryString As String Dim ObjXmlHttp As Object Dim ObjXmlDoc As Object On Error GoTo UtOh ' Build a query string by appending a specific ZIP code to the base QueryString = "http://weather.yahooapis.com/forecastrss?p=" + ZipCode ' We use the XML HTTP object to send the request and fetch the response Set ObjXmlHttp = CreateObject("Msxml2.XMLHTTP") ObjXmlHttp.open "GET", QueryString, False ObjXmlHttp.send ' Either apologize if we failed to get the forecast or ' or build an intelligible response if we succeeded If ObjXmlHttp.Status <> 200 Then DoRequest = "We are sorry but we had trouble determining the weather for your ZIP code. " + _ "If the ZIP code is valid you can try again later." kall.writeln ("The weather service fails us: " + ObjXmlHttp.statusText + "(" + Str(ObjXmlHttp.Status) + " )") Else Set ObjXmlDoc = CreateObject("Msxml2.DomDocument.4.0") ObjXmlDoc.async = False ObjXmlDoc.loadXML (ObjXmlHttp.responseText) Call ObjXmlDoc.SetProperty("SelectionLanguage", "XPath") Call ObjXmlDoc.SetProperty("SelectionNamespaces", "xmlns:yweather='http://xml.weather.yahoo.com/ns/rss/1.0'") DoRequest = TranslateXMLtoForecast(ObjXmlDoc) GoTo Done End If UtOh: DoRequest = "We are sorry but we had trouble determining the weather for your ZIP code. " + _ "If the ZIP code is valid you can try again later." kall.writeln (Err.Description) Call Err.Clear Done: On Error GoTo 0 End Function ' Crack open the XML document Function TranslateXMLtoForecast(XML As Object) As String Dim City As String Dim State As String Dim Outlook As String Dim Temperature As String ' For now we are interested in the city, wind speed and direction, ' current condition and temperature City = GetCity(XML) State = GetState(XML) Wind = GetWind(XML) Outlook = GetOutlook(XML) Temperature = GetTemperature(XML) ' Build two sentences from the five components above TranslateXMLtoForecast = "In " + City + " " + State + _ " the weather is " + Outlook + _ " with a temperature of " + Temperature + _ ". The winds are " + Wind + "." End Function ' Pull the city information from the XML Function GetCity(XML As Object) As String Dim Node As Object Dim Attr As Object Set Node = XML.selectSingleNode("//channel/yweather:location") Set Attr = Node.Attributes.getNamedItem("city") GetCity = Attr.Text End Function ' Pull the state information from the XML Function GetState(XML As Object) Dim Node As Object Dim Attr As Object Set Node = XML.selectSingleNode("//channel/yweather:location") Set Attr = Node.Attributes.getNamedItem("region") GetState = ExpandState(Attr.Text) End Function ' Pull the wind information from the XML Function GetWind(XML As Object) Dim Node As Object Dim Attr As Object Dim Speed As String Dim Degrees As String Set Node = XML.selectSingleNode("//channel/yweather:wind") Set Attr = Node.Attributes.getNamedItem("speed") Speed = Attr.Text Set Attr = Node.Attributes.getNamedItem("direction") Degrees = Attr.Text GetWind = "from the " + Direction(Val(Degrees)) + " at " + Speed + " miles per hour" End Function ' Pull the forecast from the XML Function GetOutlook(XML As Object) Dim Node As Object Dim Attr As Object Set Node = XML.selectSingleNode("//channel/item/yweather:condition") Set Attr = Node.Attributes.getNamedItem("text") GetOutlook = Attr.Text End Function ' Pull the temperature information from the XML Function GetTemperature(XML As Object) Dim Node As Object Dim Attr As Object Set Node = XML.selectSingleNode("//channel/item/yweather:condition") Set Attr = Node.Attributes.getNamedItem("temp") GetTemperature = Attr.Text + " degrees Fahrenheit" End Function