Back to Home

Asterisk + Lua - IVR and some other points

asterisk · lua · telephony

Asterisk + Lua - IVR and some other points

    Hello again! IVR - today it’s not even a chip, but a certain standard of the enterprise. In some cases, many, both customers and competitors, believe that if this IVR is not there, then “there” is a low quality of the services provided. You won’t surprise anyone with this thing now. However, we are talking about the implementation of IVR in the lua language under Asterisk. And if you are moving from a regular dial plan to Lua, then here's something to clarify.


    Suppose that you already have the necessary files for the menu and they are in the right folder. It is possible that they were even used on the old config. Then, when describing the voice menu on Lua, we do (I did) like this: We

    describe the file plate somewhere at the beginning of the file. Everything is more convenient in one place, if necessary, to change:

    mhold = {
        m_hello = "custom/message_01";        -- Приветствие
        m_menu = "custom/message_02";       -- описание меню
        m_thx = "custom/message_05";           -- Спасибо за выбор нашей компании...
        good_day = "custom/wav_gd_2";         -- типа "Хорошего вам дня"...
        comerc = "custom/com_1";                  -- Нажмите для того-то 1
        live = "custom/live_2";                          -- ну и т.д. другие варианты выбора и нажатий.
        other = "custom/other_3";
    }
    


    Thus, you described the fields indicating the files used in the nameplate. In my case - files with a greeting, some thanks words and a menu selection. There was also a backup (just in case) option, in which each menu was divided into its own file ...

    Further, in the first article, I specified ivr () in the foo () function in the description of incoming calls. So, actually in my example it worked like this:
    Event - Incoming call. Call foo (). Checking some conditions -> playing a greeting -> calling ivr (). I played the greeting before calling ivr ().

    function ivr(d)
        app.noop("Включено голосовое меню.")
        app.noop("DID: "..d)
        app.background(mhold.m_menu,"","","menu")
        app.waitexten(3)
        return
    end
    


    Not so feature-rich. app.background here is a call from the core of the asterisk voice menu. But at the same time, you also need to make a description of the menu event in extensions:

    menu = {
    	["1"] = function(c,e)
    	    app.noop("Calling from menu by 1")
    	    app.playback(mhold.m_thx)
    	    CallSKS()                                 -- на обработчик вызова СКС
    	end;
    	["2"] = function(c,e)
    	    app.noop("Calling from menu by 2")
    	    app.playback(mhold.m_thx)
    	    app.goto("local_ext","4690",1)   -- тут и далее я вызываю абонентов сразу группами.
    	end;
    	["3"] = function(c,e)
    	    app.noop("Calling from menu by 3")
    	    app.playback(mhold.m_thx)
    	    app.goto("local_ext","4579",1)
    	end;
    	["4"] = function(c,e)
    	    app.noop("Calling from menu by 4")
    	    app.playback(mhold.m_thx)
    	    CallSKS()                                   -- тоже вариант обращения в клиентскую службу.
    	end;
        };
    


    At the same time, in the description of incoming calls from_trunk you need to add timeout processing, otherwise if the client has not made a choice within the required time, the client will hear short beeps, and in the aster console you will see a code execution error.

    from_trunk = {
            t = function()
                    app.playback(mhold.m_thx)
                    app.goto("local_ext","7090",1)
            end;
    -- далее остальная часть описания событий...
    


    Everything seems to be about IVR. Now one more thing: call time limitation. Yes, unfortunately I had to do this. There were separate shots in the company, which they loved for long distances just for tens of minutes, and for a month - chatting with friends, girlfriends, brothers, etc. for hours. Of course, they were punished with the ruble, but the position of the leadership was such that it was necessary to work at work. They asked to limit the talkers in time. The following example will show how to do this globally, with direction sampling (although perhaps not the best option).

    -- где-то внутри функции trunk_test
    if string.len(num) > 7 and not string.find(string.sub(num,1,4),"8383",1) then
            app.noop("Действует ограничение на длительность звонка 10 минут!!!")
            app.dial(string.format("%s%s,60,tTL(600000:480000:60000)",trunk.startel,num))
    else
            app.noop("Звонок по городу.")
            app.dial(string.format("%s%s,60,tT",trunk.startel,num))
    end
    


    In this case, I made a selection by the number of characters in the dialed number. If the number of characters exceeds the number of characters in our city, excluding the code of our city, then this is a long-distance call. Cellular local ones are processed separately, so they don’t fall under this rule (in the last article about DEF codes). But the cell intercity - hit. In my example, a 10-minute limit applies. in 7 (or 8?) minutes, the caller hears a light beep. In this function, you can add processing only specific "villains". You can
    put these villains in a table and look at it already, or you can pull data from there into the mysql database and find it convenient for everyone ...

    That's it. Goodbye everyone!

    Read Next