Asterisk® SCF™ + LUA: Dialplan em LUA
Saudações a todos. Era uma vez, um tópico de usar a linguagem de programação LUA para escrever um Dialplan no Asterisk® SCF™, era muito difícil para mim. O fato é que eu não gosto muito de trabalhar com GUIs (como FreePBX, Issabel, Trixbox, etc.) ao configurar o Asterisk® SCF™.
Quando configurei tudo pela primeira vez, funcionou com as extensões lineares usuais (extensions.conf). Com o passar do tempo, a demanda por funcionalidade de telefonia cresceu. Aos poucos fui aprendendo a linguagem LUA. E então comecei a trabalhar como administrador em uma grande empresa em nossa cidade (uma grande imobiliária) - havia cerca de 45 filiais naquela época, cerca de 650-700 usuários, incluindo intermunicipais, etc. O Asterisk® SCF™, já estava lá, mas tudo foi configurado usando o FreePBX. Uma lastima!
As condições em que a "estação" funcionou:
- CPU: intel xeon e5520 (se não me engano);
- RAM: 24gb;
- E outros parâmetros de "hardware", incluindo duas interfaces de rede Gigabit e e uma rede VPN;
- Assinantes internos: cerca de 700;
- Número de troncos: cerca de 10 (dos quais 2 são ITSP/VoIP, o resto são Gateways GSM/GoIP);
- O número de "cidades": cerca de 200 (150 números de um ITSP/VoIP e cerca de 50 ou um pouco mais do segundo ITSP/VoIP).
Os números das cidades aqui foram atribuídos a cada filial. Alguns ramos têm até dois ou três números. Como todas as chamadas da cidade chegaram em contexto, analisei por DID e passei a chamada para a agência desejada.
Usando APPs no Dialplan LUA, implementei grupos de toque, fiz duas opções para ligar para um assinante - aleatório e na ordem de listagem no grupo (exceto para assinantes ocupados). Eu configurei o LUA-SQL para gravar minha própria base de chamadas (além do CDR em ARA). Isso foi feito pelo seguinte motivo: o funcionário liga para o cliente no celular, o cliente não quer falar agora (ocupado ou outra coisa); depois de um tempo, ele liga para um número previamente definido e deve falar com o mesmo funcionário que ligou para ele antes. Eu fiz um registro do evento "call to mobile" em um banco de dados separado. Quando um cliente liga de volta de seu celular, eu atendo a última ligação do evento “ligação de celular” e mando o cliente para o funcionário certo. Apenas um desses funcionários foi lembrado. Essa. se outro funcionário ligar para este cliente. então, consequentemente, a chamada retornará para ele.
Agora não trabalho mais naquela empresa, e onde estou agora, mudei o antigo PABX para um Softswitch PBX IP baseado em Asterisk® SCF™ e, claro, usei meu desenvolvimento do meu antigo trabalho. Lembrei-me que o assunto não era interessante só para mim. Bom, como há muito pouca informação sobre esse assunto, resolvi postar esse post aqui, de repente ele vai ser útil para alguém. Ou até mesmo para mim. Quem sabe?
Agora, irei ao cerne do assunto - codificação em LUA. Não vou descrever o estágio de ativação do módulo pbx_lua.so - há muitas informações aqui. Por exemplo, agora que tenho Centos 7.8, já tem LUA no repositório do mesmo. Eu apenas adicionei o pacote LUA-DEVEL e incluí o módulo pbx_lua.so em menuselect.
Além disso, se alguém vai usar uma conexão manual com o mysql (ou com outro banco de dados), então é melhor baixar o pacote LUA-SQL, tendo instalado o LUAROCKS previamente e baixando este add-on de lá.
Mais adiante no próprio plano de discagem, você pode descrever usuários e regras de discagem, algo assim:
extensions = { }; local_ext = { -- Quando um assinante externo pegou o telefone e discou para outro assinante externo -- h = function() -- Manipulador do HangUp() -- app.stopmixmonitor() d_status = channel["DIALSTATUS"]:get() if d_status ~= nil then app.noop("Status do Dial...:"..d_status) -- Por exemplo, se o assinante não conseguir, então sobrescreveremos o nome do arquivo no bando de dados (CDR) -- if d_status ~= "ANSWER" then channel["CDR(recordingfile)"]:set("") end app.noop("Boa Compra!") app.hangup() end; app.hangup() end; ["_14XXX"] = call_local; ["_21XX"] = call_local; ["_4595"] = call_all; -- Esta não é a descrição de um número, mas um grupo de números. Ao discar, ligamos para um número aleatório do grupo -- ["_*99"] = function() -- Isso foi adicionado especialmente para forçar a ativação do DND (muito interessante). -- local cid, dnd app.answer() cid = channel["CALLERID(num)"]:get() dnd = channel["DB(DND/"..cid.."/)"]:get() app.noop("DND:"..dnd) if dnd == "1" then channel["DB_DELETE(DND/"..cid.."/)"]:get() app.playback("beep") app.playback("beep") app.hangup() else channel["DB(DND/"..cid.."/)"]:set("1") app.playback("beep") app.wait(1) app.hangup() end end; include = {"mobile_out"}; };
Por que uso o método aleatório de chamar chamadores de grupos? As filiais são, em essência, gerentes de vendas. Se você incluir uma chamada sequencial para funcionários da filial, o primeiro da lista sempre terá mais vendas do que os outros (isso seria uma trapaça). A situação é semelhante com o método mem-primari (ao que parece), em que o usuário que respondeu pela última vez será ignorado. O método de mistura aleatória é mais honesto e coloca todos os vendedores em pé de igualdade. Você pode, claro, ligar para todos (ligar para todos ao mesmo tempo), mas aí as filiais começam a reclamar que todos os telefones da filial “gritam” ao mesmo tempo, isso não é conveniente, barulhento, etc.
Você também pode usar filas para uma chamada aleatória, mas dificilmente as uso. Não sei porque não confio no metodo round robin.
Aqui, envolvo todas as entradas externas em foo.
Por enquanto, acho que é código suficiente para dar uma luz sobre o Dialplan em LUA. Se alguém tiver interesse em migrar do antigo Dialplan para a LUA, acho que em um proximo post, consiga esclarecer algumas coisas com mais detalhes. Porém, se alguém já sabe programar em LUA, não haverá problema algum.
Para concluir, quero dizer que, claro, hoje existe um monte de diferentes soluções sofisticadas, como VoxImplant e similares. Muitas pessoas geralmente não estão acostumadas a trabalhar no console e a programar algo próprio. Mas quero observar que, quando o tamanho da empresa é grande (de 50 assinantes ou mais), construir a lógica da "estação" usando botões e caixas de seleção na interface gráfica pode levar a problemas. Acima, no início do artigo, dei exemplos sobre gorgolejos e penhascos. O Dialplan LUA deste projeto ficou com um peso de apenas 24kb, 968 linhas.
Quase 700 assinantes trabalharam nele sem problemas.
Deixe um comentário