Jump to content

Tom Wellige

Root Moderator
  • Posts

    4,309
  • Joined

  • Last visited

  • Days Won

    117

 Content Type 

Profiles

SwyxPEDIA Wiki

Zendesk Integration

Persistent Variables

Longest Waiting

VBScript build in functions

GSE build in functions (VBScript)

Server Script API (VBScript)

GSE build in functions (Lua)

Server Script API (Lua)

Function Collection (VBScript)

Function Collection (Lua)

IPS Integration

Jira Service Integration

Forums

Blogs

Downloads

Blog Entries posted by Tom Wellige

  1. Tom Wellige
    VBScript Lua
     
    After having brought the Server Script API and the GSE build-in function documentation into a new format for VBScript and Lua based call routing, the next logical step was to do the same with the huge function collection from the ECR - Useful Link Collection page.
     
    So here you have it:
     
    Function Collection (VBScript) Function Collection (Lua)  
     
    And of course you will find it also easily reachable in the page menu:
     

     

     
     
  2. Tom Wellige
    VBScript Lua
     
    Some time ago I created already a documentation for the Server Script API and GSE build-in functions for VBScript based call routing. With Lua based call routing peeking around the corner I decided to bring this documentation into a new format to be able to differ easily between VBScript and Lua. And of course also created all documentation for Lua based call routing as well.
     
    So here you go!
     
    VBScript based call routing
     
    Server Script API GSE build-in functions  
    Lua based call routing
     
    Server Script API GSE build-in functions  
     
    You can also reach this documentation easily any time via the page menu:
     

     

     
     
  3. Tom Wellige
    VBScript Lua
     
    To give an early impression of the new Lua based call routing with SwyxWare, I have updated the
     
    Zendesk Integration  
    project here on Swyx Forum. It comes now with its full feature set for VBScript based call routing as well as for Lua based call routing.
     
    Althouth the Lua based call routing is still in BETA state in SwyxWare 13.10 and should not be used in productive environments, you can use the new version to get an idea of Lua based call routing, how to handle web requests and how to handle Json formatted data. You will see, it really is easy.
     
    To do so, just download version 1.4.0 and take a look into the
     
    Lua based\ase\Zendesk.lua  
     file from the download package. Of course, if you want to see how to handle web requests and Json formatted data in VBScript, you can do that as well. In this case just take a look into the
     
    VBScript based\ase\Zendesk.vbs  
    file.
     
    Btw, the new version of the Zendesk Integration project also comes with a new feature: automatically open a Zendesk ticket in an agent's web browser (taken what he has already a browser window opened in which he his logged in into his Zendesk account).
     
     
    Enjoy!
     
  4. Tom Wellige

    Lua
    Lua
     
    No, winter is not coming, but Lua is.
     
    The current SwyxWare 13.10 includes a beta version of a new Lua Call Routing engine which adds to the existing VBSript engine. It will not replace VBScript, but will be just another language that can be used for the SwyxWare Call Routing. The Call Routing of a user will be either VBScript or LUA, it can't be a mix of both. Existing users with VBScript Call Routing will simply continue to use the VBScript call routing. New users will from some point on (not yet!) be based on LUA. It will always be possible to switch a user from VBScript to LUA and vice versa.
     
    If you want to take a look on the beta version of the Lua Call Routing within SwyxWare 13.10 you need to have a login into the Enreach Help Center and follow this link:
     
    Beta-Lua Testing (SwyxWare 13.10)  
    Over the next weeks and months I want to use this new blog article series to showcase the LUA language as also its usage within the SwyxWare Call Routing.
     
    So, stay tuned!
     
  5. Tom Wellige

    General
    VBScript Lua
     
    Days on which you can stay in bed in the morning are usually weekends, vacations or public/bank holidays. 
     
    While you can plan your call routing for weekends and vacations quite easily, as they have fixed/planned dates, things get a little bit more difficult with public/bank holidays. There are of course public/bank holidays with fixed dates, like "Labor day (01.05.)" or "Day of German reunification (03.10.)" or "Christmas (25.12./26.12.)", but there are also "moving" public/bank holidays, the church holidays. These holidays are all tight to Easter, either at a fixed distance before or after it (Good Friday, Pentecost, etc.). Problem is, Easter is every year on a different date. I spare you the history behind this,  lets just accept it as it is.
     
    So, to solve the problem of public/bank/church holidays from a call routing perspective many people (incl. me) came up with simple solutions, all based on prepared lists of such holidays (in text files or databases). My solution to this problem for example is still available in the Swyx Knowledgebase.
     
    All these attempts with prepared lists of public/bank/church holidays all share the same problem: these lists have an end. Regardless for how many years you put these dates in advance into the list, if the final date is reached and you forgot about this list, your call routing will not know about holidays. I saw many cases where this happened, where after a couple of years it was forgotten to maintain the holidays list.
     
    In comes the solution for this problem: calculate the moving church holidays. Do it exactly like it is done in reality. In 1800 Carl Friedrich Gauss published his "Easter algorithm" to calculate the Julian or Gregorian Easter. If you want to learn how this algorithm works, just follow the previous link. 
     
     
    For VBScript based Call Routing:
     
    In 2014 the forum user JoergG glued the Gauss algorithm into VBScript along with a framework to check for any holiday (fixed or moving) in any of the German federal states. And he was very kind to offer this function to the community! In 2018 the forum user kroni99 adapted this function for Austria. Both these functions are of course available here on Swyx Forum:
     
    IsPublicHolidayAT (Austria, including Federal States) IsPublicHolidayDE (Germany, including Federal States)  
    If you have adapted the "IsPublicHoliday" function for another country it would be quite nice of you if you would share it with the community. Either post it yourself of just get in touch with me.
     
    So, if you need to know in your call routing if today is a public holiday you can directly call this function from within an "Evaluate" block:
     

     

     
     
     
     
    The entire usage instructions for the "IsPublicHoliday" function are given in the above stated links to the functions for Austria and Germany. so I will save you from all the details here. 
     
    It can't get any more easy: you setup this call routing (which is not more than a little bit of Copy&Paste, according to the linked instructions) and then you can forget about the public/bank/church holidays again. You don't need to update your call routing anymore in a couple of years.
     
     
    For Lua based Call Routing:
     
    For Lua based Call Routing the SwyxWare comes already with a build-in function IsHolidayInGermany(). Unlike the two above mentioned VBScript functions, this function comes with a slightly improved Gauss formula by Heinrich Lichtenberg.
     
    The usage is more or less the same. So, if you need to know in your call routing if today is a public holiday you can directly call this function from within an "Evaluate" block:
     

     

     
    As Lua supports optional parameters, it is possible to omit the second parameter. By doing so, the current date will be checked. If you want to check another date, just pass it as second parameter.
     
    For complete usage instructions of this functions, just follow the above given link.
     
    It can't get any more easy: just use the included function and then you can forget about the public/bank/church holidays again. You don't need to update your call routing anymore in a couple of years.
     
     
    Of course you shouldn't forget about them if you want to stay in bed a little bit longer  
     
     
    Enjoy!
     
    PS: don't miss to take a look into the ECR Useful Link Collection
     
  6. Tom Wellige

    General
    VBScript Lua
     
    Have you ever had the necessity to create a call routing that somehow identifies the callers language and then provide all announcements afterwards in that language and maybe also connect to different destinations within the SwyxWare?
     
    In this article I would like to show some approaches on how this could be done and also point out their pros and cons.
     
    Lets assume you have a simple call routing that plays a welcome message, afterwards provide an IVR/DTMF menu and then connects the call to the selected user group or the operator if the caller can't decide or can't send DTMF:
     

     
    VBScript based Call Routing
    Multi_Language_1.rse
     
    Lua based Call Routing
    Multi_Language_1_Lua.rse
     
    In this example of course you have the announcements fixed and therefore in one language only.
     
    But as you have business in lots of different countries you have to differ a few languages your callers might speak: English, German, Italian, French, Spanish, Portuguese Greek, Swedish or Dutch. 9 languages all together (I ❤️ Europe!).
     
    Select Language
    The easiest way to decide what language should be used is of course by checking from where the call comes from, i.e. its country code. Of course there are countries where multiple of the above listed languages are spoken (e.g. Switzerland or Belgium) but for the ease of the call routing they will get one language. 
     
    With using the "Insert Script Code" block we can implement the language selection quite easily:
     

     
    The following code goes into the "Parameters" page of the block.
     
    For VBScript based Call Routing:
    Dim sCountryCode sCountryCode = "0044" ' United Kingdom, Default Langauge English If Len(IpPbx.CallingNumber) > 4 then sCountryCode = Left(IpPbx.CallingNumber, 4) Select Case sCountryCode Case "0044" ' United Kingdom UseExit = 0 ' -> English Case "0049" ' Germany UseExit = 1 ' -> German Case "0043" ' Austria UseExit = 1 ' -> German Case "0041" ' Switzerland UseExit = 1 ' -> German Case "0039" ' Italy UseExit = 2 ' -> Italian Case "0033" ' France UseExit = 3 ' -> French Case "0032" ' Belgium UseExit = 3 ' -> French Case "0034" ' Spain UseExit = 4 ' -> Spanish Case "0035" ' Portugal UseExit = 5 ' -> Portuguese Case "0030" ' Greece UseExit = 6 ' -> Greek Case "0046" ' Sweden UseExit = 7 ' -> Swedish Case "0031" ' The Netherlands UseExit = 8 ' -> Dutch Case Else ' Every other country / own country / no number signalled UseExit = 0 ' -> English End Select  
    For Lua based Call Routing:
    local sCountryCode = "0044" -- United Kingdom, Default Langauge English if (StringLen(IpPbx.CallingNumber()) > 4) then sCountryCode = StringLeft(IpPbx.CallingNumber(), 4) end if (sCountryCode == "0044") then -- United Kingdom UseExit = 0 -- -> English elseif (sCountryCode == "0049") then -- Germany UseExit = 1 -- -> German elseif (sCountryCode == "0043") then -- Austria UseExit = 1 -- -> German elseif (sCountryCode == "0041") then -- Switzerland UseExit = 1 -- -> German elseif (sCountryCode == "0041") then -- Italy UseExit = 2 -- -> Italian elseif (sCountryCode == "0033") then -- France UseExit = 3 -- -> French elseif (sCountryCode == "0032") then -- Belgium UseExit = 3 -- -> French elseif (sCountryCode == "0034") then -- Spain UseExit = 4 -- -> Spanish elseif (sCountryCode == "0035") then -- Portugal UseExit = 5 -- -> Portuguese elseif (sCountryCode == "0030") then -- Greece UseExit = 6 -- -> Greek elseif (sCountryCode == "0046") then -- Sweden UseExit = 7 -- -> Swedish elseif (sCountryCode == "0031") then -- The Netherlands UseExit = 8 -- -> Dutch else -- Every other country / own country / no number signalled UseExit = 0 -- -> English end  
    Within the code the property IpPbx.CallingNumber / IpPbx.CallingNumber() is used. It provides the number of the caller.
     
    You might or might not have noticed that I only differed 9 languages so far. Believe it or not, I did that intentionally  If you need to differ more than 10 languages you could do something like this, and for that I need the tenth exit of the first "Insert Script Code" block to be free to use it to route to the next one.
     

     
    Feel free to add any number of more languages here. The above is just a quick example, no discrimination intended.
     
    Now that we know the language of the caller we need to implement our call routing accordingly. 
     
    Language aware Call Routing (1)
    The most straight forward approach for the call routing would look like this
     

     
    with having for each language the complete initial script with announcement, menu and connect to, e.g.
     

     
    VBScript based Call routing
    Multi_Language_2.rse
     
    Lua based Call routing
    Multi_Language_2_Lua.rse
     
     
    Lets take a look into the pros and cons of this straight forward approach:
    Pros straight forward for each language a separate call routing therefore it is possible to have different call routing per language, not just different announcements Cons the script is huuuuuuuge therefore not easy to understand when taking a look on it the first time therefore it is easy to break it when trying to modify it relatively huge amount of work to add new languages  
    I don't know about you, but I like things a little bit more easy to grasp at a first glance. Something like the very first screenshot on this page. So this brings me to a second possible approach for this.
     
    Language aware Call Routing (2)
    As said, I want to come back to the initial script, easy to grasp, just a hand full of blocks.
     
    The idea now is to replace the announcements and destination numbers in blocks as we need them. This is easily be done by taking the announcements and number from variables and all we need to do at the beginning of the script is to initialize those variables properly. 
     
    We use the "Start" block to define the needed variables.
     
    For VBScript based Call Routing:
    Dim sMsgWelcome Dim sMsgMenu Dim sNumSupport Dim sNumSales Dim sNumOperator  
    For Lua based Call Routing:
    local sMsgWelcome local sMsgMenu local sNumSupport local sNumSales local sNumOperator  
    Without having them already initialized (will follow soon) we can change all 5 blocks in the script to make use of the variables, instead of using hard coded file names or numbers. 
     
    The welcome announcement:

     
    The IVR/DTMF menu:

     
    And the connect blocks to get the call where it should go to:

     
     
    With having this done we can start thinking about the initialization of these variables i.e. the language selection and definition what values should be used for the variables. With a small VBScript function in the "Start" block this can be quickly done. You might notice that the code looks quite similar to what we have done in the first example in the "Insert Script Code" block. This is because we still use the same principle of language selection.
     
    For VBScript based Call Routing:
    Function Initialize Dim sCountryCode sCountryCode = "0044" ' United Kingdom, Default Langauge English If Len(IpPbx.CallingNumber) > 4 then sCountryCode = Left(IpPbx.CallingNumber, 4) Select Case sCountryCode Case "0044" ' United Kingdom -> English sMsgWelcome = "MSG_WELCOME_EN.wav" sMsgMenu = "MSG_WELCOME_EN.wav" sNumSupport = "201" sNumSales = "301" sNumOperator = "101" Case "0049" ' Germany -> German sMsgWelcome = "MSG_WELCOME_DE.wav" sMsgMenu = "MSG_WELCOME_DE.wav" sNumSupport = "202" sNumSales = "302" sNumOperator = "102" Case "0043" ' Austria -> German sMsgWelcome = "MSG_WELCOME_DE.wav" sMsgMenu = "MSG_WELCOME_DE.wav" sNumSupport = "202" sNumSales = "302" sNumOperator = "102" Case "0041" ' Switzerland -> German sMsgWelcome = "MSG_WELCOME_DE.wav" sMsgMenu = "MSG_WELCOME_DE.wav" sNumSupport = "202" sNumSales = "302" sNumOperator = "102" Case "0039" ' Italy -> Italian sMsgWelcome = "MSG_WELCOME_IT.wav" sMsgMenu = "MSG_WELCOME_IT.wav" sNumSupport = "203" sNumSales = "303" sNumOperator = "103" Case "0033" ' France -> French sMsgWelcome = "MSG_WELCOME_FR.wav" sMsgMenu = "MSG_WELCOME_FR.wav" sNumSupport = "204" sNumSales = "304" sNumOperator = "104" Case "0032" ' Belgium -> French sMsgWelcome = "MSG_WELCOME_FR.wav" sMsgMenu = "MSG_WELCOME_FR.wav" sNumSupport = "204" sNumSales = "304" sNumOperator = "104" Case "0034" ' Spain -> Spanish sMsgWelcome = "MSG_WELCOME_ES.wav" sMsgMenu = "MSG_WELCOME_ES.wav" sNumSupport = "205" sNumSales = "305" sNumOperator = "105" Case "0035" ' Portugal -> Portuguese sMsgWelcome = "MSG_WELCOME_PT.wav" sMsgMenu = "MSG_WELCOME_PT.wav" sNumSupport = "206" sNumSales = "306" sNumOperator = "1064" Case "0030" ' Greece -> Greek sMsgWelcome = "MSG_WELCOME_GR.wav" sMsgMenu = "MSG_WELCOME_GR.wav" sNumSupport = "207" sNumSales = "307" sNumOperator = "107" Case "0046" ' Sweden -> Swedish sMsgWelcome = "MSG_WELCOME_SE.wav" sMsgMenu = "MSG_WELCOME_SE.wav" sNumSupport = "208" sNumSales = "308" sNumOperator = "108" Case "0031" ' The Netherlands -> Dutch sMsgWelcome = "MSG_WELCOME_NL.wav" sMsgMenu = "MSG_WELCOME_NL.wav" sNumSupport = "209" sNumSales = "309" sNumOperator = "109" Case Else ' Every other country / own country / no number signalled -> English sMsgWelcome = "MSG_WELCOME_EN.wav" sMsgMenu = "MSG_WELCOME_EN.wav" sNumSupport = "201" sNumSales = "301" sNumOperator = "101" End Select End Function  
    For Lua based Call Routing:
    function Initialize() local sCountryCode = "0044" -- United Kingdom, Default Langauge English if StringLen(IpPbx.CallingNumber() > 4) then sCountryCode = StringLeft(IpPbx.CallingNumber(), 4) end if (sCountryCode == "0044") then -- United Kingdom -> English sMsgWelcome = "MSG_WELCOME_EN.wav" sMsgMenu = "MSG_WELCOME_EN.wav" sNumSupport = "201" sNumSales = "301" sNumOperator = "101" elseif (sCountryCode == "0049") then -- Germany -> German sMsgWelcome = "MSG_WELCOME_DE.wav" sMsgMenu = "MSG_WELCOME_DE.wav" sNumSupport = "202" sNumSales = "302" sNumOperator = "102" elseif (sCountryCode == "0043") then -- Austria -> German sMsgWelcome = "MSG_WELCOME_DE.wav" sMsgMenu = "MSG_WELCOME_DE.wav" sNumSupport = "202" sNumSales = "302" sNumOperator = "102" elseif (sCountryCode == "0041") then -- Switzerland -> German sMsgWelcome = "MSG_WELCOME_DE.wav" sMsgMenu = "MSG_WELCOME_DE.wav" sNumSupport = "202" sNumSales = "302" sNumOperator = "102" elseif (sCountryCode == "0041") then -- Italy -> Italian sMsgWelcome = "MSG_WELCOME_IT.wav" sMsgMenu = "MSG_WELCOME_IT.wav" sNumSupport = "203" sNumSales = "303" sNumOperator = "103" elseif (sCountryCode == "0033") then -- France -> French sMsgWelcome = "MSG_WELCOME_FR.wav" sMsgMenu = "MSG_WELCOME_FR.wav" sNumSupport = "204" sNumSales = "304" sNumOperator = "104" elseif (sCountryCode == "0032") then -- Belgium -> French sMsgWelcome = "MSG_WELCOME_FR.wav" sMsgMenu = "MSG_WELCOME_FR.wav" sNumSupport = "204" sNumSales = "304" sNumOperator = "104" elseif (sCountryCode == "0034") then -- Spain -> Spanish sMsgWelcome = "MSG_WELCOME_ES.wav" sMsgMenu = "MSG_WELCOME_ES.wav" sNumSupport = "205" sNumSales = "305" sNumOperator = "105" elseif (sCountryCode == "0035") then -- Portugal -> Portuguese sMsgWelcome = "MSG_WELCOME_PT.wav" sMsgMenu = "MSG_WELCOME_PT.wav" sNumSupport = "206" sNumSales = "306" sNumOperator = "106" elseif (sCountryCode == "0030") then -- Greece -> Greek sMsgWelcome = "MSG_WELCOME_GR.wav" sMsgMenu = "MSG_WELCOME_GR.wav" sNumSupport = "207" sNumSales = "307" sNumOperator = "107" elseif (sCountryCode == "0046") then -- Sweden -> Swedish sMsgWelcome = "MSG_WELCOME_SE.wav" sMsgMenu = "MSG_WELCOME_SE.wav" sNumSupport = "208" sNumSales = "308" sNumOperator = "108" elseif (sCountryCode == "0031") then -- The Netherlands -> Dutch sMsgWelcome = "MSG_WELCOME_NL.wav" sMsgMenu = "MSG_WELCOME_NL.wav" sNumSupport = "209" sNumSales = "309" sNumOperator = "109" else -- Every other country / own country / no number signalled -> English sMsgWelcome = "MSG_WELCOME_EN.wav" sMsgMenu = "MSG_WELCOME_EN.wav" sNumSupport = "201" sNumSales = "301" sNumOperator = "101" end end  
    Within the code the function IpPbx.CallingNumber / IpPbx.CallingNumber() is used. It provides the number of the caller.
     
    To start the initialization function we can directly use the "Start" block. By simply calling this function within the "Start" block it will automatically be called when the script starts.
     
    For VBScript based Call Routing:
    ' start the initialization automatically when the script starts Initialize  
    For Lua based Call Routing:
    -- start the initialization automatically when the script starts Initialize()  
     
    With having all the above 3 code snippets in the "Start" block our call routing script looks like this:
     

     
    For VBScript based Call Routing:
    Multi_Language_3.rse
     
    For Lua based Call Routing:
    Multi_Language_3_Lua.rse
     
     
    Lets take a look into the pros and cons of this approach:
    Pros small and easy to grasp script easy to maintain, easy to add new languages Cons as it uses the exact same call routing for every language it might be a little bit tricky to implement exceptions in the call routing for different languages if you are not too happy with a little bit of VBScript code it could be difficult to maintain  
     
    Conclusion
    Of course it matters how many languages you have to differ and how many blocks you have in your call routing which differ per language. I created the examples in here with lots of languages purposely to show you where you could end up sooner or later if the number of supported languages grow over the time.
     
    If you feel more comfortable with GSE blocks instead of a little bit of code there is nothing wrong with the first attempt. It has its pros as it has its cons. As the second one has its pros and cons.
     
    Personally I would always tend to the second approach. But that is just me. 
     
     
    Enjoy!
     
    PS: don't miss to take a look into the ECR Useful Link Collection
     
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and have taken note of our Privacy Policy.
We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.