Asterisk dialplan - LumenVox Pizza Demo voice application

Pizza Demo dialplan description


The Pizza Demo voice application is developed to demonstrate how to use speech recognition functions in Asterisk dial plan.
It also makes use of speech recognition in AGI, the Asterisk Gateway Interface.
You will need the LumenVox Speech Engine for Asterisk installed in order to run this voice application.

This voice application is developed using Visual Dialplan for Asterisk.
You can use the code below and deploy it manually to your Asterisk server or use VDP file (Visual Dialplan file) and deploy it from Visual Dialplan with a single press of a button.
Full functional free of charge trial version of Visual Dialplan is available for download at www.apstel.com.
The output of the Visual Dialplan is standard Asterisk "extensions.conf" file and grammar files.

If you decide to deploy it manually you will have to place the files in the proper directories:
  • Grammars: These files contain the words that will be recognized by the Speech Engine. They need to be placed in the /etc/asterisk/grammars/ directory.
  • Sounds: These files need to be placed in the /var/lib/asterisk/sounds/ directory.
  • Dial Plan: The extensions.conf file is the dial plan file that contains the application code. Either move the file into /etc/asterisk/ or copy the code into your existing extensions.conf file.
  • AGI: The say-ingredients.agi file contains Perl script that parses the ingredients spoken by callers and then reads them back. It needs to be placed in the /var/lib/asterisk/agi-bin/ directory. You also need to make this file executable. From inside of the /var/lib/asterisk/agi-bin/ directory, type chmod +x say-ingredients.agi and press enter. You will need administrative privileges to execute this command.

If you decide to use the Visual Dialplan the Grammars and Dial Plan files will be deployed automatically at appropriate places.
You would only need to deploy Sounds and AGI manually.

In both ways you would need to download Sound files an AGI file from here.

Contexts description

pizza
This is the entry point for the pizza demo IVR.
To open a port at the Speech Engine you need to do a SpeechCreate first before you can do any of the other Speech applications.
After opening a port the call flow will continue with order-pizza menu.
Image

order-pizza
This context will play the welcome message, set treshold variable and proceed to the pizza-delivery menu.
Image

pizza-delivery
This context loads and activates "order" grammar and asks for the delivery method.
Image

pizza-size
This context loads and activates "size" grammar and asks for a pizza size.
Image

confirm-order
This context is used to confirm the order.
Image

pizza-crust
After we know what size pizza callers want, it is time for them to decide which crust style they want.
Image

speciality-or-custom
This context asks the caller to select one of specialty pizzas or to create a custom selection.
Image

select-speciality
This context asks the caller to select one of specialty pizzas.
Image

select-toppings
This context asks the user to select a topping.
Image

arso
ARSO (Add Remove or Start Over): we want to see where in the order process callers want to make changes.
Add a topping, remove a topping, change the size, crust, or just start over.
Image

complete-order
When the order is confirmed we tell the caller how to expect receipt of the pizza.
We perform some clean-up on the speech object and the call by the SpeechDestroy and Hangup command lines.
Image

add_topping
This context will get any new topping(s) from the caller.
Image

remove_topping
This will capture the topping(s) to be removed from the pizza.
Image

speech-confirm
This macro will perform confirmation on recognitions if the confidence score falls below the THRESHOLD value.
Image

ASR grammars


arso

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $arso;

$delivery	= delivery {out = "delivery"};
$size = size {out = "size"};
$crust = crust {out = "crust"};
$so = start over {out = "startover"};
$add_topping = (add [a] topping) {out = "add_topping"};
$rem_topping = (remove [a] topping) {out = "rem_topping"};

$arso = [$GARBAGE]
		($delivery | $size | $crust | $so | $add_topping | $rem_topping)
		{out = rules.latest();};

crust

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $crust;

$Filler = ((I want) | (I'd like) | (Give me))[a];

$hand = ((hand tossed) | "{HH AE N T AA S T:hand tossed}" | tossed) {out = "HandTossed"};
$pan = (chciago [style] | deep [dish] | pan ([baked] | [pizza] | $NULL)) {out = "Pan"};
$thin = (new york [style] | thin [crust]) {out = "Thin"};

$crust = [($Filler | $NULL)] ($hand | $pan | $thin) {out = rules.latest();};

order

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $deliveryortakeout;

$delivery = delivery {out = "Delivery"};
$takeout = takeout {out = "Pickup"};
$deliveryortakeout = ($delivery | $takeout) {out = rules.latest();};

pizza

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $FullToppingGrammar;

$Filler = [and] (I want | I'd like | Give me) [a];

$Half = [([on] one | [and] [on] the other | and )] (half | side);

$anchovie 	= ([and | an] (anchovies | anchovie)) {out = "anchovies"};
$artichoke 	= ([and | an] artichoke [hearts]) {out = "artichoke"};
$canadianbacon = ([and | an] [canadian] bacon) {out = "canadianbacon"};
$everything 	= ([and | an] everything [on it]) {out = "everything"};
$extracheese 	= ([and | an] [extra] cheese) {out = "extracheese"};
$garlic 		= ([and | an] garlic) {out = "garlic"};
$goatcheese 	= ([and | an] goat cheese) {out = "goatcheese"};
$bellpepper	= ([and | an] ([green | bell]) pepper) {out = "bellpepper"};
$mango 		= ([and | an] mango) {out = "mango"};
$mushroom 	= ([and | an] (mushroom|mushrooms)) {out = "mushroom"};
$olives 		= ([and | an] [black] olives) {out = "olives"};
$ | an] (onions|onion)) {out = "onions"};
$pepperoni 	= ([and | an] pepperoni) {out = "pepperoni"};
$pickle 		= ([and | an] pickle[s]) {out = "pickles"};
$pineapple 	= ([and | an] pineapple) {out = "pineapple"};
$salami 		= ([and | an] salami) {out = "salami"};
$sausage 		= ([and | an] [italian] sausage) {out = "sausage"};
$shrimp 		= ([and | an] shrimp) {out = "shrimp"};
$spinach 		= ([and | an] spinach) {out = "spinach"};
$ham 		= ([and | an] ham) {out = "ham"};

$Ingredients = ($bellpepper | $pepperoni | $sausage | $ham | $anchovie | 
			$artichoke | $canadianbacon | $everything | $extracheese | 
			$garlic | $goatcheese | $mango | $mushroom | $olives | 
			$onions | $pickle | $pineapple | $salami | $shrimp | $spinach)
			{out = rules.latest();};

$Modifier = ((extra | double) {out = "double"} | 
			no {out = "no"} | light {out = "light"});

$Topping = [$Modifier {out.modifier = rules.latest()}] 
		 $Ingredients {out.ingredient = rules.latest()};
 
$Toppings = {out.toppinglist = new Array} 
		  ($Topping {out.toppinglist.push(rules.latest())} )<1-> 
		  	[and $Topping{out.toppinglist.push(rules.latest())}];

$HalfTopping = ($Half $Toppings | $Toppings $Half) 
			{out = rules.Toppings; out.half = true};

$FullToppingGrammar = {out = new Array} 
				  [$Filler] 
				  ($Toppings | $HalfTopping){out.push(rules.latest())}
				  [$Filler][$HalfTopping {out.push(rules.latest())}];

size

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $size;

$extralarge = extra large {out = "ExtraLarge"};
$large = large  {out = "Large"};
$medium = medium {out = "Medium"};
$small = small {out = "Small"};
$totallyhumongous = (huge|humongous | 
				([the] biggest [(you have) | (you've got)]) | 
				totally humongous) {out = "TotallyHumongous"};

$size = ($extralarge | $large | $medium | $small | $totallyhumongous)
		{out=rules.latest()};

speciality

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $speciality;

$hawaiian = ((Hawaiian | 
			"{H AX V AY IY AX N:Hawaii}" | 
			"{H AX W AX IY AX N:Hawaii}" | 
			"{H AX V AX IY AX N:Hawaii}") 
			[pizza]) {out = "Hawaiian"};
			
$meatlovers = ((meat [lovers])[pizza]) {out = "MeatLovers"};
$pickle = ((pickle|"world famous pickle") [pizza]) {out = "Pickle"};
$salvadordali = (([salvador] dolly | dali) [pizza]) {out = "Dali"};
$vegetarian = ((veggie | vegetarian) [pizza]) {out = "Vegetarian"};

$speciality = ($hawaiian | $meatlovers | $pickle | $salvadordali | $vegetarian)
			{out=rules.latest()};

specialityorcustom

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $SpecialityorCustom;

$speciality = ((speciality|specialty) [pizza]) {out = "Speciality"};
$custom = (("pick my own"|custom) [pizza]) {out = "Custom"};

$SpecialityorCustom = [$GARBAGE]($speciality|$custom)
					{out=rules.latest()};

yesno

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $yesorno;

$yes = (yes $GARBAGE | yep | yeah | sure | correct) {out = "yes"};
$no = (no $GARBAGE | nope) {out = "no"};
$yesorno = ($yes | $no) 
			{out=rules.latest()};

Note:

All of the above - the dialplan instructions (contexts, macros/subroutines, variables ect.) and ASR grammars are contained in this VDP file and will be deployed once you deploy the dialplan using Visual Dialplan.


Pizza Demo dialplan

You can use the code below and deploy it manually to your Asterisk server or use VDP file (Visual Dialplan file) and deploy it from Visual Dialplan with a single press of a button.


; Generated with Visual Dialplan Professional.


[general]
static=yes
writeprotect=no
priorityjumping=no
autofallthrough=yes
clearglobalvars=no

[globals]


;This is the entry point for the pizza demo IVR.
;To open a port the the Speech Engine you need to do a 
;SpeechCreate first before you can do any of the other Speech applications.
[pizza]

exten => s,1,Answer()
exten => s,n,Wait(1)
exten => s,n,SpeechCreate
exten => s,n,Goto(order-pizza,s,1)

;Play the welcome message.
[order-pizza]

exten => s,1,Playback(GP-Greeting)
exten => s,n,Set(THRESHOLD=500)
exten => s,n,Goto(pizza-delivery,s,1)

;Ask for the delivery method.
[pizza-delivery]

exten => s,1,SpeechLoadGrammar(order,<path>/grammars/order.gram)
exten => s,n,SpeechActivateGrammar(order)
exten => s,n(lbl_pizza-delivery_0),SpeechStart()
exten => s,n(lbl_pizza-delivery_1),SpeechBackground(GP-DeliveryorTakeout,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_pizza-delivery_2)
exten => s,n,Playback(GP-NoDeliveryorTake-out)
exten => s,n,Goto(lbl_pizza-delivery_0)
exten => s,n(lbl_pizza-delivery_2),Set(TEXT=${SPEECH_TEXT(0)})
exten => s,n,GotoIf($["${SPEECH_SCORE(0)}" <= "${THRESHOLD}"]?:lbl_pizza-delivery_3)
exten => s,n,Gosub(speech-confirm,s,1,(${SPEECH_TEXT(0)}))
exten => s,n,GotoIf($["${CONFIRM}" = "no"]?:lbl_pizza-delivery_4)
exten => s,n,Goto(lbl_pizza-delivery_1)
exten => s,n(lbl_pizza-delivery_4),NoOp(speech_score=${SPEECH_SCORE(0)})
exten => s,n(lbl_pizza-delivery_3),Set(TYPE_OF_ORDER=${TEXT})
exten => s,n,SpeechDeactivateGrammar(order)
exten => s,n,SpeechUnloadGrammar(order)
exten => s,n,GotoIf($["${ARSO}" = "1"]?:lbl_pizza-delivery_5)
exten => s,n,Goto(confirm-order,s,1)
exten => s,n(lbl_pizza-delivery_5),Goto(pizza-size,s,1)

;Ask for pizza size
[pizza-size]

exten => s,1,SpeechLoadGrammar(size,<path>/grammars/size.gram)
exten => s,n,SpeechActivateGrammar(size)
exten => s,n(lbl_pizza-size_0),SpeechStart()
exten => s,n(lbl_pizza-size_1),SpeechBackground(GP-Size,15)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_pizza-size_2)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_pizza-size_0)
exten => s,n(lbl_pizza-size_2),Set(TEXT=${SPEECH_TEXT(0)})
exten => s,n,GotoIf($["${SPEECH_SCORE(0)}" <= "${THRESHOLD}"]?:lbl_pizza-size_3)
exten => s,n,Gosub(speech-confirm,s,1,(${SPEECH_TEXT(0)}))
exten => s,n,GotoIf($["${CONFIRM}" = "no"]?:lbl_pizza-size_3)
exten => s,n,Goto(lbl_pizza-size_1)
exten => s,n(lbl_pizza-size_3),Set(SIZE=${TEXT})
exten => s,n,SpeechDeactivateGrammar(size)
exten => s,n,SpeechUnloadGrammar(size)
exten => s,n,GotoIf($["${ARSO}" = "1"]?:lbl_pizza-size_4)
exten => s,n,Goto(confirm-order,s,1)
exten => s,n(lbl_pizza-size_4),Goto(pizza-crust,s,1)

;Confirm order
[confirm-order]

exten => s,1,SpeechLoadGrammar(yesno,<path>/grammars/yesno.gram)
exten => s,n,SpeechActivateGrammar(yesno)
exten => s,n(lbl_confirm-order_0),SpeechStart()
exten => s,n,Playback(GP-You_ordered_a)
exten => s,n,Playback(${SIZE})
exten => s,n,Playback(${CRUST})
exten => s,n,GotoIf($["${SORC}" = "Speciality"]?:lbl_confirm-order_1)
exten => s,n,Playback(${TOPPING})
exten => s,n,Playback(pizza)
exten => s,n(lbl_confirm-order_2),NoOp(${TOPPING})
exten => s,n,SpeechBackground(GP-WasThisRight,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_confirm-order_3)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_confirm-order_0)
exten => s,n(lbl_confirm-order_3),GotoIf($["${SPEECH_TEXT(0)}" = "no"]?:lbl_confirm-order_4)
exten => s,n,SpeechDeactivateGrammar(yesno)
exten => s,n,SpeechUnloadGrammar(yesno)
exten => s,n,Goto(arso,s,1)
exten => s,n(lbl_confirm-order_4),Goto(complete-order,s,1)
exten => s,n(lbl_confirm-order_1),Playback(pizza)
exten => s,n,Playback(GP-With)
exten => s,n,AGI(say_ingredients.agi,${TOPPING})
exten => s,n,Goto(lbl_confirm-order_2)

;After we know what size pizza callers want, it is time for 
;them to decide which crust style they want.
[pizza-crust]

exten => s,1,SpeechLoadGrammar(crust,<path>/grammars/crust.gram)
exten => s,n,SpeechActivateGrammar(crust)
exten => s,n(lbl_pizza-crust_0),SpeechStart()
exten => s,n(lbl_pizza-crust_1),SpeechBackground(GP-Crust,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_pizza-crust_2)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_pizza-crust_0)
exten => s,n(lbl_pizza-crust_2),Set(TEXT=${SPEECH_TEXT(0)})
exten => s,n,GotoIf($["${SPEECH_SCORE(0)}" <= "${THRESHOLD}"]?:lbl_pizza-crust_3)
exten => s,n,Gosub(speech-confirm,s,1,(${SPEECH_TEXT(0)}))
exten => s,n,GotoIf($["${CONFIRM}" = "no"]?:lbl_pizza-crust_3)
exten => s,n,Goto(lbl_pizza-crust_1)
exten => s,n(lbl_pizza-crust_3),Set(CRUST=${TEXT})
exten => s,n,SpeechDeactivateGrammar(crust)
exten => s,n,SpeechUnloadGrammar(crust)
exten => s,n,GotoIf($["${ARSO}" = "1"]?:lbl_pizza-crust_4)
exten => s,n,Goto(confirm-order,s,1)
exten => s,n(lbl_pizza-crust_4),Goto(speciality-or-custom,s,1)

;Ask the caller to select one of specialty pizzas 
;or to create a custom selection.
[speciality-or-custom]

exten => s,1,SpeechLoadGrammar(specialityorcustom,<path>/grammars/specialityorcustom.gram)
exten => s,n,SpeechActivateGrammar(specialityorcustom)
exten => s,n(lbl_speciality-or-custom_0),SpeechStart()
exten => s,n(lbl_speciality-or-custom_1),SpeechBackground(GP-SpecialtyorCustom,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_speciality-or-custom_2)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_speciality-or-custom_0)
exten => s,n(lbl_speciality-or-custom_2),Set(TEXT=${SPEECH_TEXT(0)})
exten => s,n,GotoIf($["${SPEECH_SCORE(0)}" <= "${THRESHOLD}"]?:lbl_speciality-or-custom_3)
exten => s,n,Gosub(speech-confirm,s,1,(${SPEECH_TEXT(0)}))
exten => s,n,GotoIf($["${CONFIRM}" = "no"]?:lbl_speciality-or-custom_3)
exten => s,n,Goto(lbl_speciality-or-custom_1)
exten => s,n(lbl_speciality-or-custom_3),Set(SORC=${TEXT})
exten => s,n,SpeechDeactivateGrammar(specialityorcustom)
exten => s,n,SpeechUnloadGrammar(specialityorcustom)
exten => s,n,GotoIf($["${ARSO}" = "1"]?:lbl_speciality-or-custom_4)
exten => s,n,Goto(confirm-order,s,1)
exten => s,n(lbl_speciality-or-custom_4),Goto(select-toppings,s,1)

;Ask the caller to select one of specialty pizzas.
[select-speciality]

exten => s,1,SpeechLoadGrammar(speciality,<path>/grammars/speciality.gram)
exten => s,n,SpeechActivateGrammar(speciality)
exten => s,n(lbl_select-speciality_0),SpeechStart()
exten => s,n(lbl_select-speciality_1),SpeechBackground(GP-SpecialtyList,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_select-speciality_2)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_select-speciality_0)
exten => s,n(lbl_select-speciality_2),Set(TEXT=${SPEECH_TEXT(0)})
exten => s,n,GotoIf($["${SPEECH_SCORE(0)}" <= "${THRESHOLD}"]?:lbl_select-speciality_3)
exten => s,n,Gosub(speech-confirm,s,1,(${SPEECH_TEXT(0)}))
exten => s,n,GotoIf($["${CONFIRM}" = "no"]?:lbl_select-speciality_3)
exten => s,n,Goto(lbl_select-speciality_1)
exten => s,n(lbl_select-speciality_3),Set(TOPPING=${TEXT})
exten => s,n,SpeechDeactivateGrammar(speciality)
exten => s,n,SpeechUnloadGrammar(speciality)
exten => s,n,Goto(confirm-order,s,1)

;Ask the user to select a topping.
[select-toppings]

exten => s,1,SpeechLoadGrammar(pizza,<path>/grammars/pizza.gram)
exten => s,n,SpeechActivateGrammar(pizza)
exten => s,n(lbl_select-toppings_0),SpeechStart()
exten => s,n,SpeechBackground(GP-Toppings,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_select-toppings_1)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_select-toppings_0)
exten => s,n(lbl_select-toppings_1),Set(TEXT=${SPEECH_TEXT(0)})
exten => s,n,GotoIf($["${SPEECH_SCORE(0)}" <= "${THRESHOLD}"]?:lbl_select-toppings_2)
exten => s,n,Goto(lbl_select-toppings_0)
exten => s,n(lbl_select-toppings_2),Set(TOPPING=${TEXT})
exten => s,n,SpeechDeactivateGrammar(pizza)
exten => s,n,SpeechUnloadGrammar(pizza)
exten => s,n,AGI(xml-to-string.agi,${TOPPING})
exten => s,n,Goto(confirm-order,s,1)

;ARSO (Add Remove or Start Over): we want to see where 
;in the order process callers want to make changes.
;Add a topping, remove a topping, change the size, crust, 
;or just start over.
[arso]

exten => s,1,SpeechLoadGrammar(arso,<path>/grammars/arso.gram)
exten => s,n,SpeechActivateGrammar(arso)
exten => s,n,SpeechStart()
exten => s,n,Playback(GP-Wanted=No)
exten => s,n(lbl_arso_0),SpeechBackground(GP-ARSO,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_arso_1)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_arso_0)
exten => s,n(lbl_arso_1),GotoIf($["${SPEECH_TEXT(0)}" = "delivery"]?:lbl_arso_2)
exten => s,n,Set(ARSO=1)
exten => s,n,Goto(pizza-delivery,s,1)
exten => s,n(lbl_arso_2),GotoIf($["${SPEECH_TEXT(0)}" = "size"]?:lbl_arso_3)
exten => s,n,Set(ARSO=1)
exten => s,n,Goto(pizza-size,s,1)
exten => s,n(lbl_arso_3),GotoIf($["${SPEECH_TEXT(0)}" = "crust"]?:lbl_arso_4)
exten => s,n,Set(ARSO=1)
exten => s,n,Goto(pizza-crust,s,1)
exten => s,n(lbl_arso_4),GotoIf($["${SPEECH_TEXT(0)}" = "startover"]?:lbl_arso_5)
exten => s,n,Set(ARSO=0)
exten => s,n,Goto(order-pizza,s,1)
exten => s,n(lbl_arso_5),GotoIf($["${SPEECH_TEXT(0)}" = "add_topping"]?:lbl_arso_6)
exten => s,n,Set(ARSO=1)
exten => s,n,Goto(add_topping,s,1)
exten => s,n(lbl_arso_6),GotoIf($["${SPEECH_TEXT(0)}" = "rem_topping"]?:lbl_arso_0)
exten => s,n,Set(ARSO=1)
exten => s,n,Goto(remove_topping,s,1)

;When the order is confirmed we tell the caller how to expect receipt of the pizza. 
;We perform some clean-up on the speech object and the 
;call by the SpeechDestroy and Hangup command lines.
[complete-order]

exten => s,1,Playback(${TYPE_OF_ORDER})
exten => s,n,Playback(GP-ThankYou)
exten => s,n,SpeechDestroy()
exten => s,n,Wait(1)
exten => s,n,Hangup()

;This context will get any new topping(s) from the caller
[add_topping]

exten => s,1,SpeechLoadGrammar(pizza,<path>/grammars/pizza.gram)
exten => s,n,SpeechActivateGrammar(pizza)
exten => s,n(lbl_add_topping_0),SpeechStart()
exten => s,n,GotoIf($["${SORC}" = "Speciality"]?:lbl_add_topping_1)
exten => s,n,Playback(GP-ChangeSpec)
exten => s,n,Goto(speciality-or-custom,s,1)
exten => s,n(lbl_add_topping_1),SpeechBackground(GP-Adding,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_add_topping_2)
exten => s,n,Goto(lbl_add_topping_0)
exten => s,n(lbl_add_topping_2),Set(NEWTOPPING=${SPEECH_TEXT(0)})
exten => s,n,SpeechDeactivateGrammar(pizza)
exten => s,n,SpeechUnloadGrammar(pizza)
exten => s,n,AGI(xml-to-string-newtopping.agi,${NEWTOPPING})
exten => s,n,AGI(add_topping.agi,${TOPPING} ${NEWTOPPING})
exten => s,n,Goto(confirm-order,s,1)

;This will capture the topping(s) to be removed from the pizza.
[remove_topping]

exten => s,1,SpeechLoadGrammar(pizza,<path>/Desktop/grammars/pizza.gram)
exten => s,n,SpeechActivateGrammar(pizza)
exten => s,n(lbl_remove_topping_0),SpeechStart()
exten => s,n,GotoIf($["${SORC}" = "Speciality"]?:lbl_remove_topping_1)
exten => s,n,Playback(GP-ChangeSpec)
exten => s,n,Goto(speciality-or-custom,s,1)
exten => s,n(lbl_remove_topping_1),SpeechBackground(GP-Remove,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_remove_topping_2)
exten => s,n,Goto(lbl_remove_topping_0)
exten => s,n(lbl_remove_topping_2),Set(NEWTOPPING=${SPEECH_TEXT(0)})
exten => s,n,SpeechDeactivateGrammar(pizza)
exten => s,n,SpeechUnloadGrammar(pizza)
exten => s,n,AGI(xml-to-string-newtopping.agi,${NEWTOPPING})
exten => s,n,AGI(remove_topping.agi,${TOPPING} ${NEWTOPPING})
exten => s,n,Goto(confirm-order,s,1)

;Install instructions.
[README]


;This macro will perform confirmation on recognitions
;if the confidence score falls below the THRESHOLD value
[speech-confirm]

exten => s,1,SpeechLoadGrammar(yesno,<path>/grammars/yesno.gram)
exten => s,n,SpeechActivateGrammar(yesno)
exten => s,n,Set(TEMPSPEECH_TEXT=${TEXT})
exten => s,n,Set(CONFARG=Confirm${txt})
exten => s,n,SpeechStart()
exten => s,n(lbl_macro-speech-confirm_0),SpeechBackground(${CONFARG},5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_macro-speech-confirm_1)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_macro-speech-confirm_0)
exten => s,n(lbl_macro-speech-confirm_1),Set(CONFIRM=${SPEECH_TEXT(0)})
exten => s,n,Set(TEXT=${TEMPSPEECH_TEXT})
exten => s,n,SpeechDeactivateGrammar(yesno)
exten => s,n,SpeechUnloadGrammar(yesno)
exten => s,n,Return()



About Visual Dialplan

Image

Visual Dialplan for AsteriskĀ® is modern rapid application development platform for Asterisk dial plan development.
It is perfect tool for building Asterisk voice applications
It comes with drag-and-drop visual modeling environment and large component library, voice grammar editor, handy dial plan samples, powerful validation engine, and single button deployment functionality. It even learns about Asterisk server configuration - Asterisk server configuration reading module connects to the Asterisk server, pools the server configuration data and then pre-populates library components with configuration objects. Visual Dialplan detects remote Asterisk server version and accommodates its behavior accordingly. And there are other cool features like export graphical presentation of the dial plan to image file etc.

Visual Dialplan is the only Asterisk GUI that provides full access to Asterisk dial plan potential.

About Visual Dialplan Code Zone

Visual Dialplan Code Zone is a website for developers to find solutions, share ideas and solve problems.
It includes a wiki containing tutorials, code snippets, dial plan examples and tools to simplify development and testing.
Visual Dialplan Code Zone

Download full functional trial

Full functional free of charge trial version of Visual Dialplan is available for the download.
Download Visual Dialplan, or learn more at www.Apstel.com.

Pizza Demo dialplan description


The Pizza Demo voice application is developed to demonstrate how to use speech recognition functions in Asterisk dial plan.
It also makes use of speech recognition in AGI, the Asterisk Gateway Interface.
You will need the LumenVox Speech Engine for Asterisk installed in order to run this voice application.

This voice application is developed using Visual Dialplan for Asterisk.
You can use the code below and deploy it manually to your Asterisk server or use VDP file (Visual Dialplan file) and deploy it from Visual Dialplan with a single press of a button.
Full functional free of charge trial version of Visual Dialplan is available for download at www.apstel.com.
The output of the Visual Dialplan is standard Asterisk "extensions.conf" file and grammar files.

If you decide to deploy it manually you will have to place the files in the proper directories:
  • Grammars: These files contain the words that will be recognized by the Speech Engine. They need to be placed in the /etc/asterisk/grammars/ directory.
  • Sounds: These files need to be placed in the /var/lib/asterisk/sounds/ directory.
  • Dial Plan: The extensions.conf file is the dial plan file that contains the application code. Either move the file into /etc/asterisk/ or copy the code into your existing extensions.conf file.
  • AGI: The say-ingredients.agi file contains Perl script that parses the ingredients spoken by callers and then reads them back. It needs to be placed in the /var/lib/asterisk/agi-bin/ directory. You also need to make this file executable. From inside of the /var/lib/asterisk/agi-bin/ directory, type chmod +x say-ingredients.agi and press enter. You will need administrative privileges to execute this command.

If you decide to use the Visual Dialplan the Grammars and Dial Plan files will be deployed automatically at appropriate places.
You would only need to deploy Sounds and AGI manually.

In both ways you would need to download Sound files an AGI file from here.

Contexts description

pizza
This is the entry point for the pizza demo IVR.
To open a port at the Speech Engine you need to do a SpeechCreate first before you can do any of the other Speech applications.
After opening a port the call flow will continue with order-pizza menu.
Image

order-pizza
This context will play the welcome message, set treshold variable and proceed to the pizza-delivery menu.
Image

pizza-delivery
This context loads and activates "order" grammar and asks for the delivery method.
Image

pizza-size
This context loads and activates "size" grammar and asks for a pizza size.
Image

confirm-order
This context is used to confirm the order.
Image

pizza-crust
After we know what size pizza callers want, it is time for them to decide which crust style they want.
Image

speciality-or-custom
This context asks the caller to select one of specialty pizzas or to create a custom selection.
Image

select-speciality
This context asks the caller to select one of specialty pizzas.
Image

select-toppings
This context asks the user to select a topping.
Image

arso
ARSO (Add Remove or Start Over): we want to see where in the order process callers want to make changes.
Add a topping, remove a topping, change the size, crust, or just start over.
Image

complete-order
When the order is confirmed we tell the caller how to expect receipt of the pizza.
We perform some clean-up on the speech object and the call by the SpeechDestroy and Hangup command lines.
Image

add_topping
This context will get any new topping(s) from the caller.
Image

remove_topping
This will capture the topping(s) to be removed from the pizza.
Image

speech-confirm
This macro will perform confirmation on recognitions if the confidence score falls below the THRESHOLD value.
Image

ASR grammars


arso

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $arso;

$delivery	= delivery {out = "delivery"};
$size = size {out = "size"};
$crust = crust {out = "crust"};
$so = start over {out = "startover"};
$add_topping = (add [a] topping) {out = "add_topping"};
$rem_topping = (remove [a] topping) {out = "rem_topping"};

$arso = [$GARBAGE]
		($delivery | $size | $crust | $so | $add_topping | $rem_topping)
		{out = rules.latest();};

crust

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $crust;

$Filler = ((I want) | (I'd like) | (Give me))[a];

$hand = ((hand tossed) | "{HH AE N T AA S T:hand tossed}" | tossed) {out = "HandTossed"};
$pan = (chciago [style] | deep [dish] | pan ([baked] | [pizza] | $NULL)) {out = "Pan"};
$thin = (new york [style] | thin [crust]) {out = "Thin"};

$crust = [($Filler | $NULL)] ($hand | $pan | $thin) {out = rules.latest();};

order

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $deliveryortakeout;

$delivery = delivery {out = "Delivery"};
$takeout = takeout {out = "Pickup"};
$deliveryortakeout = ($delivery | $takeout) {out = rules.latest();};

pizza

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $FullToppingGrammar;

$Filler = [and] (I want | I'd like | Give me) [a];

$Half = [([on] one | [and] [on] the other | and )] (half | side);

$anchovie 	= ([and | an] (anchovies | anchovie)) {out = "anchovies"};
$artichoke 	= ([and | an] artichoke [hearts]) {out = "artichoke"};
$canadianbacon = ([and | an] [canadian] bacon) {out = "canadianbacon"};
$everything 	= ([and | an] everything [on it]) {out = "everything"};
$extracheese 	= ([and | an] [extra] cheese) {out = "extracheese"};
$garlic 		= ([and | an] garlic) {out = "garlic"};
$goatcheese 	= ([and | an] goat cheese) {out = "goatcheese"};
$bellpepper	= ([and | an] ([green | bell]) pepper) {out = "bellpepper"};
$mango 		= ([and | an] mango) {out = "mango"};
$mushroom 	= ([and | an] (mushroom|mushrooms)) {out = "mushroom"};
$olives 		= ([and | an] [black] olives) {out = "olives"};
$ | an] (onions|onion)) {out = "onions"};
$pepperoni 	= ([and | an] pepperoni) {out = "pepperoni"};
$pickle 		= ([and | an] pickle[s]) {out = "pickles"};
$pineapple 	= ([and | an] pineapple) {out = "pineapple"};
$salami 		= ([and | an] salami) {out = "salami"};
$sausage 		= ([and | an] [italian] sausage) {out = "sausage"};
$shrimp 		= ([and | an] shrimp) {out = "shrimp"};
$spinach 		= ([and | an] spinach) {out = "spinach"};
$ham 		= ([and | an] ham) {out = "ham"};

$Ingredients = ($bellpepper | $pepperoni | $sausage | $ham | $anchovie | 
			$artichoke | $canadianbacon | $everything | $extracheese | 
			$garlic | $goatcheese | $mango | $mushroom | $olives | 
			$onions | $pickle | $pineapple | $salami | $shrimp | $spinach)
			{out = rules.latest();};

$Modifier = ((extra | double) {out = "double"} | 
			no {out = "no"} | light {out = "light"});

$Topping = [$Modifier {out.modifier = rules.latest()}] 
		 $Ingredients {out.ingredient = rules.latest()};
 
$Toppings = {out.toppinglist = new Array} 
		  ($Topping {out.toppinglist.push(rules.latest())} )<1-> 
		  	[and $Topping{out.toppinglist.push(rules.latest())}];

$HalfTopping = ($Half $Toppings | $Toppings $Half) 
			{out = rules.Toppings; out.half = true};

$FullToppingGrammar = {out = new Array} 
				  [$Filler] 
				  ($Toppings | $HalfTopping){out.push(rules.latest())}
				  [$Filler][$HalfTopping {out.push(rules.latest())}];

size

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $size;

$extralarge = extra large {out = "ExtraLarge"};
$large = large  {out = "Large"};
$medium = medium {out = "Medium"};
$small = small {out = "Small"};
$totallyhumongous = (huge|humongous | 
				([the] biggest [(you have) | (you've got)]) | 
				totally humongous) {out = "TotallyHumongous"};

$size = ($extralarge | $large | $medium | $small | $totallyhumongous)
		{out=rules.latest()};

speciality

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $speciality;

$hawaiian = ((Hawaiian | 
			"{H AX V AY IY AX N:Hawaii}" | 
			"{H AX W AX IY AX N:Hawaii}" | 
			"{H AX V AX IY AX N:Hawaii}") 
			[pizza]) {out = "Hawaiian"};
			
$meatlovers = ((meat [lovers])[pizza]) {out = "MeatLovers"};
$pickle = ((pickle|"world famous pickle") [pizza]) {out = "Pickle"};
$salvadordali = (([salvador] dolly | dali) [pizza]) {out = "Dali"};
$vegetarian = ((veggie | vegetarian) [pizza]) {out = "Vegetarian"};

$speciality = ($hawaiian | $meatlovers | $pickle | $salvadordali | $vegetarian)
			{out=rules.latest()};

specialityorcustom

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $SpecialityorCustom;

$speciality = ((speciality|specialty) [pizza]) {out = "Speciality"};
$custom = (("pick my own"|custom) [pizza]) {out = "Custom"};

$SpecialityorCustom = [$GARBAGE]($speciality|$custom)
					{out=rules.latest()};

yesno

#ABNF 1.0;
mode voice;
language en-US;
tag-format <semantics/1.0.2006>;

root $yesorno;

$yes = (yes $GARBAGE | yep | yeah | sure | correct) {out = "yes"};
$no = (no $GARBAGE | nope) {out = "no"};
$yesorno = ($yes | $no) 
			{out=rules.latest()};

Note:

All of the above - the dialplan instructions (contexts, macros/subroutines, variables ect.) and ASR grammars are contained in this VDP file and will be deployed once you deploy the dialplan using Visual Dialplan.


Pizza Demo dialplan

You can use the code below and deploy it manually to your Asterisk server or use VDP file (Visual Dialplan file) and deploy it from Visual Dialplan with a single press of a button.


; Generated with Visual Dialplan Professional.


[general]
static=yes
writeprotect=no
priorityjumping=no
autofallthrough=yes
clearglobalvars=no

[globals]


;This is the entry point for the pizza demo IVR.
;To open a port the the Speech Engine you need to do a 
;SpeechCreate first before you can do any of the other Speech applications.
[pizza]

exten => s,1,Answer()
exten => s,n,Wait(1)
exten => s,n,SpeechCreate
exten => s,n,Goto(order-pizza,s,1)

;Play the welcome message.
[order-pizza]

exten => s,1,Playback(GP-Greeting)
exten => s,n,Set(THRESHOLD=500)
exten => s,n,Goto(pizza-delivery,s,1)

;Ask for the delivery method.
[pizza-delivery]

exten => s,1,SpeechLoadGrammar(order,<path>/grammars/order.gram)
exten => s,n,SpeechActivateGrammar(order)
exten => s,n(lbl_pizza-delivery_0),SpeechStart()
exten => s,n(lbl_pizza-delivery_1),SpeechBackground(GP-DeliveryorTakeout,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_pizza-delivery_2)
exten => s,n,Playback(GP-NoDeliveryorTake-out)
exten => s,n,Goto(lbl_pizza-delivery_0)
exten => s,n(lbl_pizza-delivery_2),Set(TEXT=${SPEECH_TEXT(0)})
exten => s,n,GotoIf($["${SPEECH_SCORE(0)}" <= "${THRESHOLD}"]?:lbl_pizza-delivery_3)
exten => s,n,Gosub(speech-confirm,s,1,(${SPEECH_TEXT(0)}))
exten => s,n,GotoIf($["${CONFIRM}" = "no"]?:lbl_pizza-delivery_4)
exten => s,n,Goto(lbl_pizza-delivery_1)
exten => s,n(lbl_pizza-delivery_4),NoOp(speech_score=${SPEECH_SCORE(0)})
exten => s,n(lbl_pizza-delivery_3),Set(TYPE_OF_ORDER=${TEXT})
exten => s,n,SpeechDeactivateGrammar(order)
exten => s,n,SpeechUnloadGrammar(order)
exten => s,n,GotoIf($["${ARSO}" = "1"]?:lbl_pizza-delivery_5)
exten => s,n,Goto(confirm-order,s,1)
exten => s,n(lbl_pizza-delivery_5),Goto(pizza-size,s,1)

;Ask for pizza size
[pizza-size]

exten => s,1,SpeechLoadGrammar(size,<path>/grammars/size.gram)
exten => s,n,SpeechActivateGrammar(size)
exten => s,n(lbl_pizza-size_0),SpeechStart()
exten => s,n(lbl_pizza-size_1),SpeechBackground(GP-Size,15)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_pizza-size_2)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_pizza-size_0)
exten => s,n(lbl_pizza-size_2),Set(TEXT=${SPEECH_TEXT(0)})
exten => s,n,GotoIf($["${SPEECH_SCORE(0)}" <= "${THRESHOLD}"]?:lbl_pizza-size_3)
exten => s,n,Gosub(speech-confirm,s,1,(${SPEECH_TEXT(0)}))
exten => s,n,GotoIf($["${CONFIRM}" = "no"]?:lbl_pizza-size_3)
exten => s,n,Goto(lbl_pizza-size_1)
exten => s,n(lbl_pizza-size_3),Set(SIZE=${TEXT})
exten => s,n,SpeechDeactivateGrammar(size)
exten => s,n,SpeechUnloadGrammar(size)
exten => s,n,GotoIf($["${ARSO}" = "1"]?:lbl_pizza-size_4)
exten => s,n,Goto(confirm-order,s,1)
exten => s,n(lbl_pizza-size_4),Goto(pizza-crust,s,1)

;Confirm order
[confirm-order]

exten => s,1,SpeechLoadGrammar(yesno,<path>/grammars/yesno.gram)
exten => s,n,SpeechActivateGrammar(yesno)
exten => s,n(lbl_confirm-order_0),SpeechStart()
exten => s,n,Playback(GP-You_ordered_a)
exten => s,n,Playback(${SIZE})
exten => s,n,Playback(${CRUST})
exten => s,n,GotoIf($["${SORC}" = "Speciality"]?:lbl_confirm-order_1)
exten => s,n,Playback(${TOPPING})
exten => s,n,Playback(pizza)
exten => s,n(lbl_confirm-order_2),NoOp(${TOPPING})
exten => s,n,SpeechBackground(GP-WasThisRight,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_confirm-order_3)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_confirm-order_0)
exten => s,n(lbl_confirm-order_3),GotoIf($["${SPEECH_TEXT(0)}" = "no"]?:lbl_confirm-order_4)
exten => s,n,SpeechDeactivateGrammar(yesno)
exten => s,n,SpeechUnloadGrammar(yesno)
exten => s,n,Goto(arso,s,1)
exten => s,n(lbl_confirm-order_4),Goto(complete-order,s,1)
exten => s,n(lbl_confirm-order_1),Playback(pizza)
exten => s,n,Playback(GP-With)
exten => s,n,AGI(say_ingredients.agi,${TOPPING})
exten => s,n,Goto(lbl_confirm-order_2)

;After we know what size pizza callers want, it is time for 
;them to decide which crust style they want.
[pizza-crust]

exten => s,1,SpeechLoadGrammar(crust,<path>/grammars/crust.gram)
exten => s,n,SpeechActivateGrammar(crust)
exten => s,n(lbl_pizza-crust_0),SpeechStart()
exten => s,n(lbl_pizza-crust_1),SpeechBackground(GP-Crust,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_pizza-crust_2)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_pizza-crust_0)
exten => s,n(lbl_pizza-crust_2),Set(TEXT=${SPEECH_TEXT(0)})
exten => s,n,GotoIf($["${SPEECH_SCORE(0)}" <= "${THRESHOLD}"]?:lbl_pizza-crust_3)
exten => s,n,Gosub(speech-confirm,s,1,(${SPEECH_TEXT(0)}))
exten => s,n,GotoIf($["${CONFIRM}" = "no"]?:lbl_pizza-crust_3)
exten => s,n,Goto(lbl_pizza-crust_1)
exten => s,n(lbl_pizza-crust_3),Set(CRUST=${TEXT})
exten => s,n,SpeechDeactivateGrammar(crust)
exten => s,n,SpeechUnloadGrammar(crust)
exten => s,n,GotoIf($["${ARSO}" = "1"]?:lbl_pizza-crust_4)
exten => s,n,Goto(confirm-order,s,1)
exten => s,n(lbl_pizza-crust_4),Goto(speciality-or-custom,s,1)

;Ask the caller to select one of specialty pizzas 
;or to create a custom selection.
[speciality-or-custom]

exten => s,1,SpeechLoadGrammar(specialityorcustom,<path>/grammars/specialityorcustom.gram)
exten => s,n,SpeechActivateGrammar(specialityorcustom)
exten => s,n(lbl_speciality-or-custom_0),SpeechStart()
exten => s,n(lbl_speciality-or-custom_1),SpeechBackground(GP-SpecialtyorCustom,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_speciality-or-custom_2)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_speciality-or-custom_0)
exten => s,n(lbl_speciality-or-custom_2),Set(TEXT=${SPEECH_TEXT(0)})
exten => s,n,GotoIf($["${SPEECH_SCORE(0)}" <= "${THRESHOLD}"]?:lbl_speciality-or-custom_3)
exten => s,n,Gosub(speech-confirm,s,1,(${SPEECH_TEXT(0)}))
exten => s,n,GotoIf($["${CONFIRM}" = "no"]?:lbl_speciality-or-custom_3)
exten => s,n,Goto(lbl_speciality-or-custom_1)
exten => s,n(lbl_speciality-or-custom_3),Set(SORC=${TEXT})
exten => s,n,SpeechDeactivateGrammar(specialityorcustom)
exten => s,n,SpeechUnloadGrammar(specialityorcustom)
exten => s,n,GotoIf($["${ARSO}" = "1"]?:lbl_speciality-or-custom_4)
exten => s,n,Goto(confirm-order,s,1)
exten => s,n(lbl_speciality-or-custom_4),Goto(select-toppings,s,1)

;Ask the caller to select one of specialty pizzas.
[select-speciality]

exten => s,1,SpeechLoadGrammar(speciality,<path>/grammars/speciality.gram)
exten => s,n,SpeechActivateGrammar(speciality)
exten => s,n(lbl_select-speciality_0),SpeechStart()
exten => s,n(lbl_select-speciality_1),SpeechBackground(GP-SpecialtyList,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_select-speciality_2)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_select-speciality_0)
exten => s,n(lbl_select-speciality_2),Set(TEXT=${SPEECH_TEXT(0)})
exten => s,n,GotoIf($["${SPEECH_SCORE(0)}" <= "${THRESHOLD}"]?:lbl_select-speciality_3)
exten => s,n,Gosub(speech-confirm,s,1,(${SPEECH_TEXT(0)}))
exten => s,n,GotoIf($["${CONFIRM}" = "no"]?:lbl_select-speciality_3)
exten => s,n,Goto(lbl_select-speciality_1)
exten => s,n(lbl_select-speciality_3),Set(TOPPING=${TEXT})
exten => s,n,SpeechDeactivateGrammar(speciality)
exten => s,n,SpeechUnloadGrammar(speciality)
exten => s,n,Goto(confirm-order,s,1)

;Ask the user to select a topping.
[select-toppings]

exten => s,1,SpeechLoadGrammar(pizza,<path>/grammars/pizza.gram)
exten => s,n,SpeechActivateGrammar(pizza)
exten => s,n(lbl_select-toppings_0),SpeechStart()
exten => s,n,SpeechBackground(GP-Toppings,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_select-toppings_1)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_select-toppings_0)
exten => s,n(lbl_select-toppings_1),Set(TEXT=${SPEECH_TEXT(0)})
exten => s,n,GotoIf($["${SPEECH_SCORE(0)}" <= "${THRESHOLD}"]?:lbl_select-toppings_2)
exten => s,n,Goto(lbl_select-toppings_0)
exten => s,n(lbl_select-toppings_2),Set(TOPPING=${TEXT})
exten => s,n,SpeechDeactivateGrammar(pizza)
exten => s,n,SpeechUnloadGrammar(pizza)
exten => s,n,AGI(xml-to-string.agi,${TOPPING})
exten => s,n,Goto(confirm-order,s,1)

;ARSO (Add Remove or Start Over): we want to see where 
;in the order process callers want to make changes.
;Add a topping, remove a topping, change the size, crust, 
;or just start over.
[arso]

exten => s,1,SpeechLoadGrammar(arso,<path>/grammars/arso.gram)
exten => s,n,SpeechActivateGrammar(arso)
exten => s,n,SpeechStart()
exten => s,n,Playback(GP-Wanted=No)
exten => s,n(lbl_arso_0),SpeechBackground(GP-ARSO,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_arso_1)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_arso_0)
exten => s,n(lbl_arso_1),GotoIf($["${SPEECH_TEXT(0)}" = "delivery"]?:lbl_arso_2)
exten => s,n,Set(ARSO=1)
exten => s,n,Goto(pizza-delivery,s,1)
exten => s,n(lbl_arso_2),GotoIf($["${SPEECH_TEXT(0)}" = "size"]?:lbl_arso_3)
exten => s,n,Set(ARSO=1)
exten => s,n,Goto(pizza-size,s,1)
exten => s,n(lbl_arso_3),GotoIf($["${SPEECH_TEXT(0)}" = "crust"]?:lbl_arso_4)
exten => s,n,Set(ARSO=1)
exten => s,n,Goto(pizza-crust,s,1)
exten => s,n(lbl_arso_4),GotoIf($["${SPEECH_TEXT(0)}" = "startover"]?:lbl_arso_5)
exten => s,n,Set(ARSO=0)
exten => s,n,Goto(order-pizza,s,1)
exten => s,n(lbl_arso_5),GotoIf($["${SPEECH_TEXT(0)}" = "add_topping"]?:lbl_arso_6)
exten => s,n,Set(ARSO=1)
exten => s,n,Goto(add_topping,s,1)
exten => s,n(lbl_arso_6),GotoIf($["${SPEECH_TEXT(0)}" = "rem_topping"]?:lbl_arso_0)
exten => s,n,Set(ARSO=1)
exten => s,n,Goto(remove_topping,s,1)

;When the order is confirmed we tell the caller how to expect receipt of the pizza. 
;We perform some clean-up on the speech object and the 
;call by the SpeechDestroy and Hangup command lines.
[complete-order]

exten => s,1,Playback(${TYPE_OF_ORDER})
exten => s,n,Playback(GP-ThankYou)
exten => s,n,SpeechDestroy()
exten => s,n,Wait(1)
exten => s,n,Hangup()

;This context will get any new topping(s) from the caller
[add_topping]

exten => s,1,SpeechLoadGrammar(pizza,<path>/grammars/pizza.gram)
exten => s,n,SpeechActivateGrammar(pizza)
exten => s,n(lbl_add_topping_0),SpeechStart()
exten => s,n,GotoIf($["${SORC}" = "Speciality"]?:lbl_add_topping_1)
exten => s,n,Playback(GP-ChangeSpec)
exten => s,n,Goto(speciality-or-custom,s,1)
exten => s,n(lbl_add_topping_1),SpeechBackground(GP-Adding,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_add_topping_2)
exten => s,n,Goto(lbl_add_topping_0)
exten => s,n(lbl_add_topping_2),Set(NEWTOPPING=${SPEECH_TEXT(0)})
exten => s,n,SpeechDeactivateGrammar(pizza)
exten => s,n,SpeechUnloadGrammar(pizza)
exten => s,n,AGI(xml-to-string-newtopping.agi,${NEWTOPPING})
exten => s,n,AGI(add_topping.agi,${TOPPING} ${NEWTOPPING})
exten => s,n,Goto(confirm-order,s,1)

;This will capture the topping(s) to be removed from the pizza.
[remove_topping]

exten => s,1,SpeechLoadGrammar(pizza,<path>/Desktop/grammars/pizza.gram)
exten => s,n,SpeechActivateGrammar(pizza)
exten => s,n(lbl_remove_topping_0),SpeechStart()
exten => s,n,GotoIf($["${SORC}" = "Speciality"]?:lbl_remove_topping_1)
exten => s,n,Playback(GP-ChangeSpec)
exten => s,n,Goto(speciality-or-custom,s,1)
exten => s,n(lbl_remove_topping_1),SpeechBackground(GP-Remove,5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_remove_topping_2)
exten => s,n,Goto(lbl_remove_topping_0)
exten => s,n(lbl_remove_topping_2),Set(NEWTOPPING=${SPEECH_TEXT(0)})
exten => s,n,SpeechDeactivateGrammar(pizza)
exten => s,n,SpeechUnloadGrammar(pizza)
exten => s,n,AGI(xml-to-string-newtopping.agi,${NEWTOPPING})
exten => s,n,AGI(remove_topping.agi,${TOPPING} ${NEWTOPPING})
exten => s,n,Goto(confirm-order,s,1)

;Install instructions.
[README]


;This macro will perform confirmation on recognitions
;if the confidence score falls below the THRESHOLD value
[speech-confirm]

exten => s,1,SpeechLoadGrammar(yesno,<path>/grammars/yesno.gram)
exten => s,n,SpeechActivateGrammar(yesno)
exten => s,n,Set(TEMPSPEECH_TEXT=${TEXT})
exten => s,n,Set(CONFARG=Confirm${txt})
exten => s,n,SpeechStart()
exten => s,n(lbl_macro-speech-confirm_0),SpeechBackground(${CONFARG},5)
exten => s,n,GotoIf($["${SPEECH(results)}" = "0"]?:lbl_macro-speech-confirm_1)
exten => s,n,Playback(GP-NI)
exten => s,n,Goto(lbl_macro-speech-confirm_0)
exten => s,n(lbl_macro-speech-confirm_1),Set(CONFIRM=${SPEECH_TEXT(0)})
exten => s,n,Set(TEXT=${TEMPSPEECH_TEXT})
exten => s,n,SpeechDeactivateGrammar(yesno)
exten => s,n,SpeechUnloadGrammar(yesno)
exten => s,n,Return()



About Visual Dialplan

Image

Visual Dialplan for AsteriskĀ® is modern rapid application development platform for Asterisk dial plan development.
It is perfect tool for building Asterisk voice applications
It comes with drag-and-drop visual modeling environment and large component library, voice grammar editor, handy dial plan samples, powerful validation engine, and single button deployment functionality. It even learns about Asterisk server configuration - Asterisk server configuration reading module connects to the Asterisk server, pools the server configuration data and then pre-populates library components with configuration objects. Visual Dialplan detects remote Asterisk server version and accommodates its behavior accordingly. And there are other cool features like export graphical presentation of the dial plan to image file etc.

Visual Dialplan is the only Asterisk GUI that provides full access to Asterisk dial plan potential.

About Visual Dialplan Code Zone

Visual Dialplan Code Zone is a website for developers to find solutions, share ideas and solve problems.
It includes a wiki containing tutorials, code snippets, dial plan examples and tools to simplify development and testing.
Visual Dialplan Code Zone

Download full functional trial

Full functional free of charge trial version of Visual Dialplan is available for the download.
Download Visual Dialplan, or learn more at www.Apstel.com.

Created by: mich.davis, Last modification: Tue 29 of Sep, 2009 (09:29 UTC)
Please update this page with new information, just login and click on the "Edit" or "Discussion" tab. Get a free login here: Register Thanks! - Find us on Google+