Tutorial: Dynamisches VoiceXML
Übersicht
Dieses Tutorial beschreibt die Erstellung von dynamischem VoiceXML, und gibt darüber hinaus eine Einführung, wie man VoiceXML
Code dynamisch gestaltet.
Inhalt:
1 Was ist statisches/dynamisches VoiceXML?
2 Wie macht man eine VoiceXML Anwendung dynamisch ?
2.1 VoiceXML dynamisch erstellen
2.2 Ausführen einer dynamischen Seite
2.3 Parameter übergeben
2.4 Zugriff / Weiterverwendung der gesendeten Parameter in serverseitigem Skript
2.5 Testen im Browser
3 Beispiele
3.1 PHP
3.2 JSP
3.3 ASP
4 Zusammenfassung und weitere Links zum Thema
1 Was ist statisches/dynamisches VoiceXML?
Ruft man eine VoiceXML Applikation an, oder benötigt eine laufende VoiceXML Anwendung eine neues Dokument (unter Verwendung
von <goto>, <submit> usw.), wird die neue Seite durch den
VoiceXML Browser vom Webserver angefordert.
Fall 1: Die angeforderte Seite ist vollständig in VoiceXML geschrieben. In diesem Fall wird die Seite direkt zum
VoiceXML Browser gesendet, dort interpretiert und ausgeführt.
Dieses Szenario wird statisches VoiceXML genannt, weil sich die Seite niemals ändert.
Diese Vorgehensweise ist für viele VoiceXML Anwendungen ausreichend. Info-Hotlines, viele Spiele oder Soundbibliotheken,
wie z.B. das Vorspielen von Hörbüchern, fallen in diese Kategorie.
Möchte man jedoch:
- Aus einer Datei oder Datenbank lesen
- In eine Datei oder Datenbank schreiben
- Emails lesen oder senden
- Information einer Webseite lesen/verarbeiten
- Variablen von einer VoiceXML Seite an eine andere übergeben
- ...
so können diese nicht unmittelbar mit VoiceXML gelöst werden, da VoiceXML dafür nicht entwickelt wurde.
Es gibt jedoch eine Reihe von Webtechnologien, die dieses erfüllen, wie z.B. CGI, PHP, JSP, ASP.
Zu Erstellung von dynamischem VoiceXML bedient man sich dieser Technologien. Der eigentliche Output an den Voice Browser
ist wieder pures VoiceXML.
Fall 2: Die vom Voice Browser angeforderte Seite auf dem Webserver ist mit serverseitigen Code ausgestattet (PHP, JSP, ASP).
Jetzt wird, bevor die Seite an den Voice Browser gesendet wird, erst einmal der serverseitige Code auf der Applikationsserver-Komponente
des Webservers ausgeführt und als Ergebnis statischer VoiceXML Code generiert, der zum Voice Browser gesendet wird.
Diese Prozedur wird dynamisches VoiceXML genannt, da die Ergebnisseite bei jedem Aufruf neu generiert wird.
2 Wie macht man eine VoiceXML Anwendung dynamisch ?
Wer bereits mit den serverseitigen Sprachen dynamisches HTML generiert hat, der hat es relativ einfach:
Der Skriptsprache ist es völlig egal, ob sie HTML oder VoiceXML generiert!
Wer jedoch noch nie mit den serverseitigen Skriptsprachen in Berührung gekommen ist, der weiß wahrscheinlich jetzt nicht,
wo er anfangen soll.
Dieses Tutorial gibt nur einen kurzen Einblick in dynamisches VoiceXML. Es erhebt nicht den Anspruch, VoiceXML oder irgendeine
Skriptsprache zu lehren. Um gezielt eine Skriptsprache zu erlernen, sollte man auf entsprechende Literatur zurückgreifen.
Wichtig ist weiterhin, dass nicht jeder Internetserver jede Skriptsprache unterstützt, es hängt von der Architektur des
Applikationsservers ab:
- PHP wird, weil kostenlos und lizenzfrei verfügbar, gerne auf Linux/Unix basierten Servern eingesetzt
- ASP findet auf Windows Servern Anwendung
- JSP (JAVA) ist mehr eine professionelle Architektur
- CGI ist veraltet und langsam, es wird so gut wie nicht mehr verwendet
Wenn sie einen Service Provider benutzen, so unterliegen sie gewissen Einschränkungen und können nur die vom Service Provider
verwendete Architektur benutzen.
2.1 VoiceXML dynamisch erstellen
Grundsätzlich existieren zwei Möglichkeiten zur Generierung von dynamischem VoiceXML:
Methode 1: Explizite Ausgabe jeder VoiceXML Zeile mittels Skriptsprache
Beispiel in JSP:
<%
... beliebiger jsp code ...
out.println ("<?xml version="1.0"?>");
out.println ("<vxml version="2.0" xml:lang="de-DE">");
out.println ("<form>");
out.println ( "<block>");
out.println ( "Die Datenbank wurde aktualisiert.");
out.println ( "</block>");
out.println ("</form>");
out.println ("</vxml>");
%>
Führt der Apllikationsserver diesen JSP Code aus, so generiert er folgenden VoiceXML Code:
<?xml version="1.0"?>
<vxml version="2.0" xml:lang="de-DE">
<form>
</block>
Die Datenbank wurde aktualisiert.
</block>
</form>
</vxml>
Die Seite wird zum VoiceXML Interpreter gesendet und besteht dort nur noch aus reinem VoiceXML.
Methode 2: Serverseitigen Code identifizieren
Hier wird auf die Tatsache zurückgegriffen, dass Skriptsprachen meist nur "ihren" Anteil interpretieren, und Codefragmente,
die nicht als Skriptsprache gekennzeichnet sind unverändert an den Webserver gesendet werden.
Dasselbe Beispiel in JSP, diesmal ist nur der JSP Code als solcher ausgezeichnet
<%
... beliebiger jsp code ...
%>
<?xml version="1.0"?>
<vxml version="2.0" xml:lang="de-DE">
<form>
<block>
Die Datenbank wurde aktualisiert.
</block>
</form>
</vxml>
2.2 Ausführen einer dynamischen Seite
Der Aufruf einer dynamischen Seite in VoiceXML ist vergleichbar mit dem Aufruf einer statischen Seite:
<goto next="http://…/test.jsp"/>
bzw.
<submit next=".../test.jsp" namelist="farbe form" method="post"/>
2.3 Parameter übergeben
Dynamische Seiten werden erst so richtig dynamisch, wenn sie mit Parametern aus dem VoiceXML Dialog versorgt werden.
Um diese Werte an das serverseitige Skript zu übermitteln, kann man diese direkt an die <goto> URL hängen
oder wie Formulardaten mittels <submit> versenden.
Beispiel für direkten URL Anhang:
http://.../test.jsp?farbe=gruen&form=rund
Hinweis: Jedes Sonderzeichen in Variablenname und -wert muss URL-encoded sein (z.b. Leerzeichen = %20%).
Nachteil dieser Geschichte ist die geringe Sicherheit, denn jeder der den HTTP-Request lesen kann, kann auch die Daten erkennen.
Bei kritischen Daten, oder wenn sie sowieso schon als Variablen im VoiceXML vorliegen, empfiehlt sich daher die zweite
Methode mittels <submit>.
Dabei werden VoiceXML Variablen wie in einem Webformular versendet, in dem man lediglich die zu übermittelnden Variablen angibt;
die Werte werden dann vom VoiceXML Interpreter eingesetzt. Sollten die Werte nicht als Variablen vorliegen, müssen sie somit erst
in einer Variablen gespeichert werden.
Beispiel:
<var name="form" expr="'rund'"/>
<field name="farbe">
<grammar src="farben.txt"/>
<prompt> Welche Farbe? </prompt>
<filled>
<submit next=".../test.jsp" namelist="farbe form" method="post"/>
</filled>
</field>
Mit dem Attribut method kann man die Art der Übermittlung festlegen. Bei method="get"
werden die Variablen an die URL gehängt, bei method="post" werden sie versteckt - und somit weitaus sicherer - übertragen.
2.4 Zugriff / Weiterverwendung der gesendeten Parameter in serverseitigem Skript
Jede serverseitige Sprache hat ihre eigenen Regeln, wie sie auf übermittelte Variablen zugreifen kann.
Beispiele:
JSP:
String farbe = request.getParameter("farbe");
String form = request.getParameter("form");
ASP:
Dim farbe, form
farbe = Request.QueryString("farbe")
form = Request.QueryString("form")
PHP:
PHP gestattet den direkten Zugriff auf die Variablen:
$farbe
$form
Diese Zuordnungen werden meist an erster Stelle im Dokument durchgeführt, um sie global zur Verfügung zu stellen.
2.5 Testen im Browser
Bei der Verwendung von dynamischen Code ist es manchmal äußerst schwierig, Fehler zu finden, da die Seite vor der Abfrage nicht
vorhanden ist und erst zur Laufzeit generiert wird.
Eine fehlerbehaftete Seite wird im Sprachdialog nicht ausgeführt, man erhält ein lapidares "Es ist ein Fehler aufgetreten.
Auf Wiederhören." Eine Fehlersuche auf diesem Weg wird somit erschwert.
Auch wenn der dynamisch generierte Code ohne syntaktische Fehler ausgeführt werden kann, garantiert dies noch lange nicht einen
erfolgreichen Dialog. Die Ausgabe kann weiterhin fehlerbehaftet sein, indem der Dialog z.B. Aktionen ausführt, die so nicht gewollt
sind, oder bei der Erstellung wurde auf Daten zurückgegriffen, die beim Zeitpunkt des Zugriffes nicht vorhanden oder aktuell waren.
Eine bessere Methode für Test und Fehlersuche ist es, die Seite in einem konventionellen Webbrowser (Internet Explorer, Netscape, etc.)
zu öffnen. Dabei verwendet man dieselbe URL (und Parameter), die auch der Sprachdialog aufrufen würde.
Der Aufruf über den Webbrowser erzwingt ebenso die Ausführung des serverseitigen Skripts. Für den Fall, dass der Code nicht ausgeführt
werden kann, erhält man im Browserfenster eine detaillierte Fehlerbeschreibung. Wurde das Skript erfolgreich ausgeführt, so erscheint
im Browserfenster (bei keiner Anzeige über den Weg ‚Seitenquelltext anzeigen') der VoiceXML Code, der auch an den Voice Browser gesendet
würde.
Darüber hinaus kann die Seite mit verschiedenen (auch ungültigen Parameterwerten) ausgetestet werden, um die korrekte Generierung des
gewünschten VoiceXML Dialogs zu überprüfen.
3 Beispiele
Das nachfolgende Beispiel testet die Genauigkeit eines Spracherkennungssystems. Dazu spricht der Anrufer wahllos Ziffern und die
Erkennungswahrscheinlichkeit des Spracherkenners wird gespeichert.
Das Beispiel beginnt mit einem VoiceXML Dialog, der die Eingabe vom Anrufer sammelt. Der VoiceXML Dialog übermittelt dann die vom
Anrufer eingegebenen Daten an ein serverseitiges JSP, PHP bzw. ASP- Skript. Alle drei Skripte besitzen exakt dieselbe Funktion: Es
fügt die Eingaben des Anrufers einer Datei hinzu und generiert eine VoiceXML Seite, welche zur ursprünglichen VoiceXML Seite
zurückspringt. Diese Schleife wird solange wiederholt, bis der Anrufer auflegt.
Hinweis: Die URLs im nachfolgenden Code sind relativ. In Abhängigkeit vom Speicherort der Dateien, des verwendeten Servers, usw.
müssen diese relativen URLs ggf. angepasst werden.
test.vxml
Einer der drei Zeilen muss je nach verwendetem Skripttyp (JSP, PHP, ASP) auskommentiert werden.
<?xml version="1.0"?>
<vxml version="2.0">
<form>
<field name="field1" type="number">
<prompt>
Please say any number.
</prompt>
<filled>
<var name="confidence" expr="field1$.confidence"/>
<!-- submit next="collectdata.html" namelist="field1 confidence"/ -->
<!-- submit next="collectdata.jsp" namelist="field1 confidence"/ -->
<!-- submit next="collectdata.asp" namelist="field1 confidence"/ -->
</filled>
</field>
</form>
</vxml>
3.1 PHP
<?php
// Parameter $field1 und können direkt verwendet werden
$utterance = $field1;
$conf = $confidence;
// Anhand der confidence auf 'niedrig', 'mittel' oder ‚hoch' setzen
if ( < 0.7)
$region = "low";
elsif ($confidence >=0.7 && $confidence <0.9)
$region = "medium";
else
//$confidence ist größer oder gleich 0.9
$region = "high";
// Aussage des Anrufers und Confidence an Datei anhängen
$fp = fopen("data.txt","w+");
fwrite ($fp, "$field1, $confidence
");
fclose($fp);
// Endes des PHP Skriptes, VoiceXML generieren
echo "<?xml version=\"1.0\"?>";
?>
<vxml version="2.0">
<form>
<block>
<prompt>
Die Erkennungsgenauigkeit war war <? echo $region ?>..
</prompt>
<goto next="test.vxml"/>
</block>
</form>
</vxml>
3.2 JSP
<%@ page import="java.io.*"%>
<%
// Gesendete Parameter abfragen
String utterance = request.getParameter("field1");
String confidence = request.getParameter("confidence");
double conf = (new Double(confidence)).doubleValue();
// Anhand der confidence $medium auf 'niedrig', 'mittel' oder ‚hoch' setzen
String region = "";
if (conf<0.7) {
region = "niedrig";
} else if (conf>=0.7 && conf<0.9) {
region = "mittel";
region = "hoch";
}
// Aussage des Anrufers und Confidence an Datei anhängen
try {
String path = "data.txt"; // Replace this with absolute path
boolean append = true;
PrintStream data = new PrintStream(new FileOutputStream(path, append));
data.println(utterance + ", " + confidence);
data.close();
} catch (IOException e) {}
// Endes des JSP Skriptes, VoiceXML generieren
%>
<?xml version="1.0"?>
<vxml version="2.0">
<form>
<block>
<prompt>
Die Erkennungsgenauigkeit war <%=region%>.
</prompt>
<goto next="test.vxml"/>
</block>
</form>
</vxml>
3.3 ASP
<% @Language = "VBScript" %>
<% Response.buffer = true %>
<%
' Gesendete Parameter abfragen
Dim utterance, conf
utterance = Request.QueryString("field1")
conf = Request.QueryString("confidence")
'Anhand der confidence auf 'niedrig', 'mittel' oder ‚hoch' setzen
Dim region
If conf<0.7 Then
region = "niedrig"
ElseIf conf>=0.7 And conf<0.9 Then
region = "mittel"
ElseIf conf>=0.9 Then
region = "hoch"
End If
'Aussage des Anrufers und Confidence an Datei anhängen
Dim objFSO, objData
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objData = objFSO.OpenTextFile(Server.MapPath("data.txt"), 8, True)
objData.writeline(utterance & ", " & conf)
objData.Close
Set objData = Nothing
Set objFSO = Nothing
'Endes des ASP Skriptes, VoiceXML generieren
%>
<?xml version="1.0"?>
<vxml version="2.0">
<form>
<block>
<prompt>
Die Erkennungsgenauigkeit war <%=region%>.
</prompt>
<goto next="test.vxml"/>
</block>
</form>
</vxml>
4 Zusammenfassung und weitere Links zum Thema
Das Tutorial beschreibt die grundsätzliche Vorgehensweise bei der Erstellung von dynamischem VoiceXML, und wie die verschiedenen
Skriptsprachen verwendet werden.
Die serverseitigen Skriptsprachen sind mächtige Werkzeuge, und jede hat ihre Vor- und Nachteile. Für eine weitergehende Einführung kann nur
auf die nachfolgenden Links verwiesen werden:
JSP
http://www.jsp-develop.de/links/
http://www.jsptutorial.org/
PHP
http://de.wikipedia.org/wiki/PHP
http://www.html.net
ASP
http://www.aspextra.de/asp/Default.html
|