Courseware:IT Plus - Creating your own script
Let's have a look what you have to know before you start your own script
Getting started
In this book we will focus on how to create your own voicemail script. Before we start, we want to give you some useful tips that will help you with your project.
URL Query String Variables
You can add additional variables as parameters to the voicemail object URL. This allows you to pass various options directly to the script. You'll find the list  in our wiki
 in our wiki
 in our wiki
 in our wikiVoicemail schema
To get an overview of all functions and possibilities of the voicemail script, we provide a documentation, which can be found  here. We recommend that you look at this page any time you are not sure how a function works or if you need an example of how to use it.
 here. We recommend that you look at this page any time you are not sure how a function works or if you need an example of how to use it.
 here. We recommend that you look at this page any time you are not sure how a function works or if you need an example of how to use it.
 here. We recommend that you look at this page any time you are not sure how a function works or if you need an example of how to use it.Setting up a custom voicemail object
 To have something to play with in our exercise, we will create
 To have something to play with in our exercise, we will create  a second voicemail object. Please create the following object.
 a second voicemail object. Please create the following object.- Name: Voicemail script
- SIP: voicemail-script
- Number: 99
- PBX: hq
- Node: root
- default PIN: <empty>
- email notifications: Off
- custom: On
Access custom folder
 To create our own voicemail script, we need access to the custom folder we just created by creating the custom voicemail app. Therefore, we need to have the appropriate authorization. This means that we need to  configure a custom password in the settings part of the voicemail plugin. Please make sure that you do not set the password on the voicemail object in the PBX, because every object in the PBX needs the same password to talk to the voicemail app service. You only need to configure it in the plugin, all other objects will get the new password automatically.
 configure a custom password in the settings part of the voicemail plugin. Please make sure that you do not set the password on the voicemail object in the PBX, because every object in the PBX needs the same password to talk to the voicemail app service. You only need to configure it in the plugin, all other objects will get the new password automatically.
 Of course, in real life, you would configure a strong and secure password, but in this case we will use ip411
 Of course, in real life, you would configure a strong and secure password, but in this case we will use ip411
 After changing the password, make sure that
 After changing the password, make sure that  both voicemail apps are still connected. If not, open and save them again.
 both voicemail apps are still connected. If not, open and save them again.
 Please configure the following options to get access to the custom folder in your voicemail app service.
 Please configure the following options to get access to the custom folder in your voicemail app service.   If you receive a SSL Handshake failed', please re-enter the Advanced options and go to Connection/TLS/SSL and lower the Minimum TLS Version from 'TLS 1.2' to 'TLS 1.1'
 If you receive a SSL Handshake failed', please re-enter the Advanced options and go to Connection/TLS/SSL and lower the Minimum TLS Version from 'TLS 1.2' to 'TLS 1.1'  
   If you receive a certificate error, please click yes and proceed.
 If you receive a certificate error, please click yes and proceed.  
   The configured path consists of the domain name of the AP, followed by the name of the app service instance (which is different for each language), and then custom. The ending custom is a fixed value.
 The configured path consists of the domain name of the AP, followed by the name of the app service instance (which is different for each language), and then custom. The ending custom is a fixed value.    
 In this course, we have created a simplified, size reduced voicemail folder that you can download
 In this course, we have created a simplified, size reduced voicemail folder that you can download  here. Please use it for this course otherwise the config checker will fail in retrieving the database content.
 here. Please use it for this course otherwise the config checker will fail in retrieving the database content.
 Please go ahead and download the voicemail archive and extract it.
 Please go ahead and download the voicemail archive and extract it.  Upload the contents (all voicemail files and all xml script files) to the custom folder using WinSCP.
 Upload the contents (all voicemail files and all xml script files) to the custom folder using WinSCP.
 To see if your custom voicemail is working call 9914 from John Doe (IP111). You will reach John Doe's voicebox after you entered the default PIN 8765.
 To see if your custom voicemail is working call 9914 from John Doe (IP111). You will reach John Doe's voicebox after you entered the default PIN 8765.
 
  Refresh the custom folder in WinSCP. With the call to John Doe's voicemail box you created a folder vm_files and in it a folder John Doe. This is the location of all of his stored voice messages.
 Refresh the custom folder in WinSCP. With the call to John Doe's voicemail box you created a folder vm_files and in it a folder John Doe. This is the location of all of his stored voice messages. 
 configure a custom password in the settings part of the voicemail plugin. Please make sure that you do not set the password on the voicemail object in the PBX, because every object in the PBX needs the same password to talk to the voicemail app service. You only need to configure it in the plugin, all other objects will get the new password automatically.
 configure a custom password in the settings part of the voicemail plugin. Please make sure that you do not set the password on the voicemail object in the PBX, because every object in the PBX needs the same password to talk to the voicemail app service. You only need to configure it in the plugin, all other objects will get the new password automatically. Of course, in real life, you would configure a strong and secure password, but in this case we will use ip411
 Of course, in real life, you would configure a strong and secure password, but in this case we will use ip411 After changing the password, make sure that
 After changing the password, make sure that  both voicemail apps are still connected. If not, open and save them again.
 both voicemail apps are still connected. If not, open and save them again.WebDAV connection
As a next step we need a tool to access the custom folder via WebDAV. We recommend the use of WinSCP,  which you can download here.
 which you can download here.
 which you can download here.
 which you can download here.When you start WinSCP you receive a dialog that allows you to  set up a New Site.
 set up a New Site.
 set up a New Site.
 set up a New Site. Please configure the following options to get access to the custom folder in your voicemail app service.
 Please configure the following options to get access to the custom folder in your voicemail app service.- Select the File Protocol -> WebDAV
- Set the Encryption to TLS/SSL Implicit encryption
- Enter apps-dvl-ckl2.training.innovaphone.com as Host name
- Set the user name and password to the same user name and password for the voicemail app service that we just entered above.
- Enter voicemail_en as User name
- Enter ip411 as password
- Before you proceed please enter the Advanced options and  go to Environment/Directories go to Environment/Directories
- Enter /dvl-ckl2.net/voicemail_en/custom as Remote Directory
- Press OK
- Click on Login
 If you receive a SSL Handshake failed', please re-enter the Advanced options and go to Connection/TLS/SSL and lower the Minimum TLS Version from 'TLS 1.2' to 'TLS 1.1'
 If you receive a SSL Handshake failed', please re-enter the Advanced options and go to Connection/TLS/SSL and lower the Minimum TLS Version from 'TLS 1.2' to 'TLS 1.1' If you receive a certificate error, please click yes and proceed.
 If you receive a certificate error, please click yes and proceed. The configured path consists of the domain name of the AP, followed by the name of the app service instance (which is different for each language), and then custom. The ending custom is a fixed value.
 The configured path consists of the domain name of the AP, followed by the name of the app service instance (which is different for each language), and then custom. The ending custom is a fixed value.Voicemail script
The voicemail app uses a voicemail script file that you can download from  
 store.innovaphone.com: release/download.htm . Just click on Apps and select the voicemail app in your language. The downloaded httpfiles.zip contains the script file and all voice prompts.
 
  In this course, we have created a simplified, size reduced voicemail folder that you can download
 In this course, we have created a simplified, size reduced voicemail folder that you can download  here. Please use it for this course otherwise the config checker will fail in retrieving the database content.
 here. Please use it for this course otherwise the config checker will fail in retrieving the database content. Please go ahead and download the voicemail archive and extract it.
 Please go ahead and download the voicemail archive and extract it.  Upload the contents (all voicemail files and all xml script files) to the custom folder using WinSCP.
 Upload the contents (all voicemail files and all xml script files) to the custom folder using WinSCP. To see if your custom voicemail is working call 9914 from John Doe (IP111). You will reach John Doe's voicebox after you entered the default PIN 8765.
 To see if your custom voicemail is working call 9914 from John Doe (IP111). You will reach John Doe's voicebox after you entered the default PIN 8765. 
  Refresh the custom folder in WinSCP. With the call to John Doe's voicemail box you created a folder vm_files and in it a folder John Doe. This is the location of all of his stored voice messages.
 Refresh the custom folder in WinSCP. With the call to John Doe's voicemail box you created a folder vm_files and in it a folder John Doe. This is the location of all of his stored voice messages.Custom changes on the voicemail script
 Before we create our own voicemail script, let's look at two common custom voicemail scenarios.
   Can you edit the vm.xml file you downloaded (vm-en.zip) to change the maximum length to 3 minutes? Please upload and replace the vm.xml file after editing.
 Can you edit the vm.xml file you downloaded (vm-en.zip) to change the maximum length to 3 minutes? Please upload and replace the vm.xml file after editing.
  
 Can you edit the vm.xml to find a solution? To test this, create a CFU to John Doe on the Richard Roe's user object. John Doe should have a CFU to 99. So when you call Richard Roe from Jane Doe, you will be redirected to John, which then forwards the call to the voicemail box of Richard Roe.
 Can you edit the vm.xml to find a solution? To test this, create a CFU to John Doe on the Richard Roe's user object. John Doe should have a CFU to 99. So when you call Richard Roe from Jane Doe, you will be redirected to John, which then forwards the call to the voicemail box of Richard Roe. 
 
Maximum Message Length
By default, the maximum length of a voice message is 50 seconds. This may be not long enough for some customer scenarios. This value can be increased in the voicemail script.
To do this let's have a look at the  pbx-record element. The documentation tells us that there are 3 different attributes to be used (url, sec, barge-in) in this element.
 pbx-record element. The documentation tells us that there are 3 different attributes to be used (url, sec, barge-in) in this element.
 pbx-record element. The documentation tells us that there are 3 different attributes to be used (url, sec, barge-in) in this element.
 pbx-record element. The documentation tells us that there are 3 different attributes to be used (url, sec, barge-in) in this element.- url: This attribute specifies a location of a file a voice recording is written to. This can be hardcoded or a variable (e.g $vm).
- sec: This attribute specifies the maximum length of a voice recording
 Can you edit the vm.xml file you downloaded (vm-en.zip) to change the maximum length to 3 minutes? Please upload and replace the vm.xml file after editing.
 Can you edit the vm.xml file you downloaded (vm-en.zip) to change the maximum length to 3 minutes? Please upload and replace the vm.xml file after editing.If you need a little help you can take a look in  our wiki.
 our wiki.
 our wiki.
 our wiki.Leave Message to the Voicemail box of the original called User
By default, a voice message is written to the voicemail box of the user who performs the forwarding to the voicemail object. Therefore, if you configure a CFU on John Doe to the voicemail object, the recorded message is written to John Doe's voicemail box. But imagine a different customer requirement where the voice message should be written to the voicemail box of the original called party.
To find a solution for this task you should have a look at the  pbx-getcallinfo element. This element reads information from the current call, and obviously you can read a lot from it. Let's focus on these 4 attributes.
 pbx-getcallinfo element. This element reads information from the current call, and obviously you can read a lot from it. Let's focus on these 4 attributes.
 pbx-getcallinfo element. This element reads information from the current call, and obviously you can read a lot from it. Let's focus on these 4 attributes.
 pbx-getcallinfo element. This element reads information from the current call, and obviously you can read a lot from it. Let's focus on these 4 attributes.- out-cgpn: This attribute contains the calling party number of the call
- out-cdpn: This attribute contains the called party number of the call
- out-leg2: This attribute contains the redirecting number.
- out-leg2-orig: This attribute contains the first redirecting number.
After reading the values you want to change the value of out-leg2 to the value of out-leg2-orig. You can achieve this by using the  element switch and the
 element switch and the  element assign.
 element assign.
 element switch and the
 element switch and the  element assign.
 element assign. Can you edit the vm.xml to find a solution? To test this, create a CFU to John Doe on the Richard Roe's user object. John Doe should have a CFU to 99. So when you call Richard Roe from Jane Doe, you will be redirected to John, which then forwards the call to the voicemail box of Richard Roe.
 Can you edit the vm.xml to find a solution? To test this, create a CFU to John Doe on the Richard Roe's user object. John Doe should have a CFU to 99. So when you call Richard Roe from Jane Doe, you will be redirected to John, which then forwards the call to the voicemail box of Richard Roe. If you need a little help you can have a look in  our wiki.
 our wiki.
 our wiki.
 our wiki.Creating your own script
 Before we start writing our own script, let's prepare it a bit.
 Do the following steps
 Do the following steps   We will explain the trace options we just set in the next chapter.
 We will explain the trace options we just set in the next chapter. 
 Do the following steps
 Do the following steps- Download the   Hello World voicemail script
 Create a directory called script in the custom folder of our voicemail app service. (use WinSCP) Create a directory called script in the custom folder of our voicemail app service. (use WinSCP)
- Copy the Hello World script into this folder.
- Go to Voicemail PBX Manager Plugin and  add a new voicemail object add a new voicemail object
- Configure Training script as Name
- Configure training-script as SIP
- Configure 98 as number
- Select hq as PBX and root as Node
- Enable the custom option
- Click OK
- Afterwards go to PBX/Objects on the advanced UI of your IP411LEFT
- Open the  training-script object and go to Voicemail tab training-script object and go to Voicemail tab
- Please change the Script URL to this one: https://apps-dvl-ckl2.training.innovaphone.com/dvl-ckl2.net/voicemail_en/custom/script/script.xml?$_trace=123
- While we are at it, please enable to Trace option as well.
- Click OK
 We will explain the trace options we just set in the next chapter.
 We will explain the trace options we just set in the next chapter.Basics
 Open
 Open  the Hello World file (script.xml) in any editor you are comfortable with and let's discuss the elements we are seeing in this script. I personally use
 the Hello World file (script.xml) in any editor you are comfortable with and let's discuss the elements we are seeing in this script. I personally use  notepad++ with the XML Tools plugin, in case you are curious.
 notepad++ with the XML Tools plugin, in case you are curious.The first line is the  XML declaration, which can be left as is.
 XML declaration, which can be left as is.
 XML declaration, which can be left as is.
 XML declaration, which can be left as is.Voicemail tag
 This tag is the root element at the top of every voicemail script. Only two child elements are allowed in this tag. These elements can be either a
 This tag is the root element at the top of every voicemail script. Only two child elements are allowed in this tag. These elements can be either a  function tag or an
 function tag or an  assign tag
 assign tagMain function
As an entry point, we need to define the main function. Every voicemail script has to have a main function. This is where the magic begins.
Debug possibilities
 The dbg tag is used to print any string you define. This will help you when debugging your script, as it will allow you to understand where the code didn't work as it was supposed to. You just have to insert the dbg statements, followed by the string="" attribute, in your code to see if your script reached that tag or not.
 The dbg tag is used to print any string you define. This will help you when debugging your script, as it will allow you to understand where the code didn't work as it was supposed to. You just have to insert the dbg statements, followed by the string="" attribute, in your code to see if your script reached that tag or not.You may be wondering where the element prints the output. The answer is simple, into the trace buffer, but you will only see it if you have the trace flag enabled in the voicemail object. As a pro tip, we have also added the URL parameter $_trace=123, which will also dump the voicemail script statements, allowing you to trace the voicemail script execution even better.
 To see the trace output just go to Maintenance/Diagnostics/Tracing on your IP411LEFT, enable the HTTP client option as well, then OK and
 To see the trace output just go to Maintenance/Diagnostics/Tracing on your IP411LEFT, enable the HTTP client option as well, then OK and  then click on trace (continuous) link. If you click the trace (continuous) button again, the trace output will be clean without previous packets.
 then click on trace (continuous) link. If you click the trace (continuous) button again, the trace output will be clean without previous packets. Of course, you can also use Wireshark because it allows you to filter. This is like a fashion choice, and it is up to you if you want to go that route.
 Of course, you can also use Wireshark because it allows you to filter. This is like a fashion choice, and it is up to you if you want to go that route.Simple Blacklist
Now that we have covered the basics and can see the result of our script, we will edit our script.xml to stop John Doe from calling Jane Doe. In other words, we will create a little blacklist script.
Identify the caller
In order to write a blacklist script, we need to read the calling number, of course. We will use the  pbx-getcallinfo element for this. This tag may look familiar, as we used it when we customized the vm.xml script.
 pbx-getcallinfo element for this. This tag may look familiar, as we used it when we customized the vm.xml script.
 pbx-getcallinfo element for this. This tag may look familiar, as we used it when we customized the vm.xml script.
 pbx-getcallinfo element for this. This tag may look familiar, as we used it when we customized the vm.xml script.So how do we use the element?
We have to add the pbx-getcallinfo tag to our main function and  use the out-cgpn attribute to write the output of this attribute to a variable. The content of the variable will then be printed by the dbg element.
 use the out-cgpn attribute to write the output of this attribute to a variable. The content of the variable will then be printed by the dbg element.
 use the out-cgpn attribute to write the output of this attribute to a variable. The content of the variable will then be printed by the dbg element.
 use the out-cgpn attribute to write the output of this attribute to a variable. The content of the variable will then be printed by the dbg element. Please edit the script.xml so that the calling party is read and then printed. To test your solution, simply drag and drop the script.xml into the WinSCP (custom/script) directory. Afterwards call 98 from John Doe and see if the trace tells you that 14 called.
 Please edit the script.xml so that the calling party is read and then printed. To test your solution, simply drag and drop the script.xml into the WinSCP (custom/script) directory. Afterwards call 98 from John Doe and see if the trace tells you that 14 called.If you need help, please have a look into script2_1.xml which you can find in the  
 Solutions to the Scripting Exercises  archive.
 
 Calling Jane
Instead of calling the voicemail script, we want to call Jane, which should then trigger the script. As a result, the call to Jane must be redirected to the voicemail object. To do this, we will use a CFU.
 Create a CFU on Jane Doe to reroute the call to the voicemail object (98).
 Create a CFU on Jane Doe to reroute the call to the voicemail object (98).The next step is to read the leg2 info from the call, which is the number of the object redirecting the call. This should be Jane's number.
 Extend the script.xml to print the leg2-info in the same way you printed out the calling party number in the previous exercise. We can even use the same pbx-getcallinfo tag that already reads the cgpn for our solution and add the out-leg2 attribute to that tag. To test your solution, call 12 (Jane Doe) from John Doe after uploading the edited script.xml file.
 Extend the script.xml to print the leg2-info in the same way you printed out the calling party number in the previous exercise. We can even use the same pbx-getcallinfo tag that already reads the cgpn for our solution and add the out-leg2 attribute to that tag. To test your solution, call 12 (Jane Doe) from John Doe after uploading the edited script.xml file.To see our solution, have a look into the  script2_2.xml file.
 script2_2.xml file.
 script2_2.xml file.
 script2_2.xml file.Forward the call to Jane anyway
As a next step, the script should forward the call to Jane even though she has a CFU. This can be done by using the  pbx-fwd element. So add the <pbx-fwd/> tag to the end of the main function and add the e164="" or name="" attribute to specify the destination. Do not use both (e164 and and name) attributes in the same pbx-fwd tag.
 pbx-fwd element. So add the <pbx-fwd/> tag to the end of the main function and add the e164="" or name="" attribute to specify the destination. Do not use both (e164 and and name) attributes in the same pbx-fwd tag.
 pbx-fwd element. So add the <pbx-fwd/> tag to the end of the main function and add the e164="" or name="" attribute to specify the destination. Do not use both (e164 and and name) attributes in the same pbx-fwd tag.
 pbx-fwd element. So add the <pbx-fwd/> tag to the end of the main function and add the e164="" or name="" attribute to specify the destination. Do not use both (e164 and and name) attributes in the same pbx-fwd tag. To test your solution, please call 12 from John Doe. Jane should ring regardless of her CFU configuration.
 To test your solution, please call 12 from John Doe. Jane should ring regardless of her CFU configuration.To see our solution, have a look into the  script2_3.xml file.
 script2_3.xml file.
 script2_3.xml file.
 script2_3.xml file.Read blacklist information
As a next step we want to read the information who is blacklisted and which party is not.
 Within the scripts directory, create a subfolder named blacklist. Then create a file named 14
 Within the scripts directory, create a subfolder named blacklist. Then create a file named 14  in that folder. Please add content to the file even though the content is irrelevant. The reason for this is that some WebDAV clients have problems with an empty file. In our script, we only care about the filename.
 in that folder. Please add content to the file even though the content is irrelevant. The reason for this is that some WebDAV clients have problems with an empty file. In our script, we only care about the filename.To create a solution please use the  store-getstat element. This element searches for the name of a file or directory and retrieves its properties. 3 attributes are of interest to us in this tag:
 store-getstat element. This element searches for the name of a file or directory and retrieves its properties. 3 attributes are of interest to us in this tag:
 store-getstat element. This element searches for the name of a file or directory and retrieves its properties. 3 attributes are of interest to us in this tag:
 store-getstat element. This element searches for the name of a file or directory and retrieves its properties. 3 attributes are of interest to us in this tag:- root="" : This attribute specifies the location of the file. If the file is located in a subfolder of the folder where your script file is located, you must specify it here. Here is an example: <store-getstat root="subfolder/" />
- name="" : This attribute specifies the name of the file you are searching.
- out-error="" : If the file exists, the output of this attribute is 0, which means success. If it does not exist, the output of this variable is 2, which means not_found.
 Edit the script.xml to query whether or not the filename 14 exists. Store the result (successful or not) in a variable called $error and print it.
 Edit the script.xml to query whether or not the filename 14 exists. Store the result (successful or not) in a variable called $error and print it. Afterwards test your solution again by calling Jane (12) from John Doe. If you want to see our solution, have a look into the file  script2_4.xml.
 script2_4.xml.
 script2_4.xml.
 script2_4.xml.Create a decision
As a final step, we want to create a decision to block calls from John, but still allow Richard to call Jane. This can be accomplished by using a  switch element and
 switch element and  case elements within the switch element.
 case elements within the switch element.
 switch element and
 switch element and  case elements within the switch element.
 case elements within the switch element.Inside a switch tag, you must have a var attribute, e.g. <switch var="$variable">. The content of the var attribute determines which case element is true or false.
A case tag has to be used within a switch tag. An attribute of a case tag can be equal, not-equal, greater, greater-equal, less and less-equal. 
This is an example of what a switch statement might look like:
<switch var="$variable">
<case equal="0"/>
...
<case not-equal="0"/>
...
</switch>
 To test your solution call 12 from John and from Richard. John's call should be disconnected , Richard's should work. To disconnect a call please use the
 To test your solution call 12 from John and from Richard. John's call should be disconnected , Richard's should work. To disconnect a call please use the  pbx-disc element. The <pbx-disc/> element does not have to have an attribute but you can transmit an
 pbx-disc element. The <pbx-disc/> element does not have to have an attribute but you can transmit an  cause code to the caller.
 cause code to the caller.You can see our solution in file  script2_5.xml.
 script2_5.xml.
 script2_5.xml.
 script2_5.xml.This is a very simple voicemail script. For a more sophisticated blacklist script, please  refer to our wiki, which builds on this idea we just implemented.
 refer to our wiki, which builds on this idea we just implemented.
  refer to our wiki, which builds on this idea we just implemented.
 refer to our wiki, which builds on this idea we just implemented.Talk quickly, you only got 30 seconds
In this chapter we want to extend our script.xml to allow John to talk to Jane but only for 30 seconds, then the call should be disconnected automatically and he should receive a disconnect. 
  To solve this task we will need to add a  timer and and an
 timer and and an  event that should be triggered by the timer. To create a timer, you must give the timer a name (name="") and duration in seconds (sec="").When the timer expires, an event should be called with the name of the timer. Although not mentioned in the documentation an event can also have a type="timer", which is a useful information for your solution.
 event that should be triggered by the timer. To create a timer, you must give the timer a name (name="") and duration in seconds (sec="").When the timer expires, an event should be called with the name of the timer. Although not mentioned in the documentation an event can also have a type="timer", which is a useful information for your solution. 
   timer and and an
 timer and and an  event that should be triggered by the timer. To create a timer, you must give the timer a name (name="") and duration in seconds (sec="").When the timer expires, an event should be called with the name of the timer. Although not mentioned in the documentation an event can also have a type="timer", which is a useful information for your solution.
 event that should be triggered by the timer. To create a timer, you must give the timer a name (name="") and duration in seconds (sec="").When the timer expires, an event should be called with the name of the timer. Although not mentioned in the documentation an event can also have a type="timer", which is a useful information for your solution.  The timer starts when the script is executed. If Jane needs time to pick up, that's bad luck for John.
 The timer starts when the script is executed. If Jane needs time to pick up, that's bad luck for John. Please edit the script.xml and exchange it on the voicemail app service via WinSCP. Call 12 from John Doe and wait 30 seconds. The call should be released after the timer expires.
 Please edit the script.xml and exchange it on the voicemail app service via WinSCP. Call 12 from John Doe and wait 30 seconds. The call should be released after the timer expires.To see our script, have a look at  script3_1.xml
 script3_1.xml
   script3_1.xml
 script3_1.xmlIf you like the idea, we already have a voicemail script based on this that you can find on  the wiki.
 the wiki.
 the wiki.
 the wiki.ACD
In this chapter, we will continue to extend our script.xml. This time we want to create a separate  function called agents-busy
 function called agents-busy  that will determine if a call can be routed to the waiting object with the number 66 or not. If all agents of the waiting queue are busy, the call should trigger our previously created code. If the agents are free, the call should be routed to the waiting queue object. As a hint, use the out-cause="" attribute of the pbx-fwd element to see if the waiting queue is busy or not.
 that will determine if a call can be routed to the waiting object with the number 66 or not. If all agents of the waiting queue are busy, the call should trigger our previously created code. If the agents are free, the call should be routed to the waiting queue object. As a hint, use the out-cause="" attribute of the pbx-fwd element to see if the waiting queue is busy or not.
 function called agents-busy
 function called agents-busy  that will determine if a call can be routed to the waiting object with the number 66 or not. If all agents of the waiting queue are busy, the call should trigger our previously created code. If the agents are free, the call should be routed to the waiting queue object. As a hint, use the out-cause="" attribute of the pbx-fwd element to see if the waiting queue is busy or not.
 that will determine if a call can be routed to the waiting object with the number 66 or not. If all agents of the waiting queue are busy, the call should trigger our previously created code. If the agents are free, the call should be routed to the waiting queue object. As a hint, use the out-cause="" attribute of the pbx-fwd element to see if the waiting queue is busy or not.Additionally, we need to wrap an  if clause around the code we have already created. The if clause needs to have a condition (cond="" or notcond="") to determine whether or not the code should be executed. As a tip, use an
 if clause around the code we have already created. The if clause needs to have a condition (cond="" or notcond="") to determine whether or not the code should be executed. As a tip, use an  assign tag in your agents-busy function to assign a value to a variable that can then be used by your if condition.
 assign tag in your agents-busy function to assign a value to a variable that can then be used by your if condition.
 if clause around the code we have already created. The if clause needs to have a condition (cond="" or notcond="") to determine whether or not the code should be executed. As a tip, use an
 if clause around the code we have already created. The if clause needs to have a condition (cond="" or notcond="") to determine whether or not the code should be executed. As a tip, use an  assign tag in your agents-busy function to assign a value to a variable that can then be used by your if condition.
 assign tag in your agents-busy function to assign a value to a variable that can then be used by your if condition. To test your solution call 12 from John Doe. If Richard Roe, which is the only member of the waiting queue is free Richard will receive the call; if he is busy, Jane will receive the call. To simulate Richard's busy state, simply pick up his handset.
 To test your solution call 12 from John Doe. If Richard Roe, which is the only member of the waiting queue is free Richard will receive the call; if he is busy, Jane will receive the call. To simulate Richard's busy state, simply pick up his handset.To see our solution, take a look at the  script4_1.xml file.
 script4_1.xml file.
 script4_1.xml file.
 script4_1.xml file.A voicemail script allows you to create your own automated call distribution. We have only touched on the possibilities with our little exercise. If you want to know more, you can take a look at the code of our sample ACD, which you can find  in the wiki.
 in the wiki.
 in the wiki.
 in the wiki.Exec
One of the most interesting elements is the  exec element, as it allows you to create an HTTP GET request that can then trigger any script (e.g php) on any webserver. This in turn allows you to create even more powerful and complex solutions.
 exec element, as it allows you to create an HTTP GET request that can then trigger any script (e.g php) on any webserver. This in turn allows you to create even more powerful and complex solutions.
 exec element, as it allows you to create an HTTP GET request that can then trigger any script (e.g php) on any webserver. This in turn allows you to create even more powerful and complex solutions.
 exec element, as it allows you to create an HTTP GET request that can then trigger any script (e.g php) on any webserver. This in turn allows you to create even more powerful and complex solutions.If you are interested, please have a look  in our wiki.
 in our wiki.
 in our wiki.
 in our wiki. Please create the following object.
 Please create the following object. Please make sure that you do not set the password on the voicemail object in the PBX, because every object in the PBX needs the same password to talk to the voicemail app service. You only need to configure it in the plugin, all other objects will get the new password automatically.
 Please make sure that you do not set the password on the voicemail object in the PBX, because every object in the PBX needs the same password to talk to the voicemail app service. You only need to configure it in the plugin, all other objects will get the new password automatically. If not, open and save them again.
 If not, open and save them again.

 using WinSCP.
 using WinSCP. With the call to John Doe's voicemail box you created a folder vm_files and in it a folder John Doe. This is the location of all of his stored voice messages.
 With the call to John Doe's voicemail box you created a folder vm_files and in it a folder John Doe. This is the location of all of his stored voice messages. called script in the custom folder of our voicemail app service. (use WinSCP)
 called script in the custom folder of our voicemail app service. (use WinSCP)
 and go to Voicemail tab
 and go to Voicemail tab (script.xml) in any editor you are comfortable with and let's discuss the elements we are seeing in this script. I personally use
 (script.xml) in any editor you are comfortable with and let's discuss the elements we are seeing in this script. I personally use  If you click the trace (continuous) button again, the trace output will be clean without previous packets.
 If you click the trace (continuous) button again, the trace output will be clean without previous packets.
 The content of the variable will then be printed by the dbg element.
 The content of the variable will then be printed by the dbg element. Please add content to the file even though the content is irrelevant. The reason for this is that some WebDAV clients have problems with an empty file. In our script, we only care about the filename.
 Please add content to the file even though the content is irrelevant. The reason for this is that some WebDAV clients have problems with an empty file. In our script, we only care about the filename. to the waiting object with the number 66 or not. If all agents of the waiting queue are busy, the call should trigger our previously created code. If the agents are free, the call should be routed to the waiting queue object. As a hint, use the out-cause="" attribute of the pbx-fwd element to see if the waiting queue is busy or not.
 to the waiting object with the number 66 or not. If all agents of the waiting queue are busy, the call should trigger our previously created code. If the agents are free, the call should be routed to the waiting queue object. As a hint, use the out-cause="" attribute of the pbx-fwd element to see if the waiting queue is busy or not.