Extensions LUA (primeiros passos).



extensions.lua

CONSOLE = "Console/DSP -- Interface do console para demonstração.
--CONSOLE = "DAHDI/1"
--CONSOLE = "Phone/phone0"

IAXINFO = "guest"       -- IAX ToIP modo trunk=yes (username/password).
--IAXINFO = "myuser:mypass"

TRUNK = "DAHDI/G2"
TRUNKMSD = 1
-- TRUNK = "IAX2/user:pass@provider"

A interface do console para demostração de extensões (extensions) deve ser definida em uma tabela global chamada "extensions". A tabela "extensions" deve conter um grupo de tabelas, cada qual, representando um contexto (context). As extensões são definidas em cada contexto. Ver abaixo  os exemplos.

Os nomes de extensões podem ser números, letras ou combinações dos mesmos. E se um nome de extensão é precedido por um caractere '_', é interpretado como um padrão ao invés de um literal. Nos padrões, alguns caracteres têm significados especiais:

X = qualquer dígito de 0 a 9;
Z = qualquer dígito de 1 a 9;
N = qualquer dígito de 2 a 9;
[1235-9] = qualquer dígito entre colchetes (neste exemplo, 1,2,3,5,6,7,8,9);
. (ponto)curinga, corresponde a qualquer coisa restante (por exemplo, _9011. qualquer coisa que comece com 9011, excluindo o próprio 9011);
! (exclamação) curinga, faz com que o processo de correspondência seja concluído assim que pode determinar inequivocamente que nenhuma outra correspondência é possível.

Por exemplo, a extensão _NXXXXXXX corresponderia a 8 dígitos normais (um número fixo local por exemplo: 4004 2222). Já padrões para chamadas, _55ZZNXXXXXXXX (exemplo: 55 11 4004 2222), representaria o código do pais, mais o código de área e o telefone do assinante, repare que ambos os padrões estão sendo precedido pelo carácter de informação do padrão "_" (subscribe).

Caso tenha alguma dúvida sobre padrões, recomendo ler o artigo sobre Numeração Telefônica da Teleco

Se a sua extensão tiver caracteres especiais, como '.' (ponto) e '!' (exclamação) você deve explicitamente fazer uma string na definição da tabela:

["_special."] = function;
["_special!"] = function;

Não há prioridades. Todas as extensões do Asterisk® SCF™ parecem ter uma única prioridade, ou seja consistem de fato, em uma única prioridade.
 
Cada contexto é definido como uma tabela na tabela de extensões. Os nomes de contexto devem ser cadeias de caracteres.

Um contexto pode ser incluído em outro contexto usando a extensão "includes". Esta extensão deve ser definida para uma tabela que contém uma lista de nomes de contexto. Não coloque referências a tabelas na tabela de inclusão.

include = {"ddl", "ddd", "ddi"};

ddl = discagem direta local;
ddd = discagem direta à distancia;
ddi = discagem direta internacional.

As variáveis de canal podem ser acessadas através da tabela global de 'canais'.

v = channel.var_name
v = channel["var_name"]
v.value
v: get ()


channel.var_name = "value"
channel["var_name"] = "value"
v:set("value")

channel.func_name(1,2,3):set("value")
value = channel.func_name(1,2,3):get()
channel["func_name(1,2,3)"]:set("value")
channel["func_name(1,2,3)"] = "value"
value = channel["func_name(1,2,3)"]:get()

Observe o uso do operador ':' (dois pontos) para acessar os métodos get() e set().

Observe também a ausência das seguintes construções dos exemplos acima:
channel.func_name (1,2,3) = "value" - isso NÃO funcionará;
value = channel.func_name (1,2,3) - isso NÃO funcionará conforme o esperado.

Os aplicativos do Dialplan podem ser acessados através da tabela global 'app'.

app.Dial("DAHDI/1")
app.dial("DAHDI/1")
app["dial"]("DAHDI/1")

Um serviço automático é executado automaticamente enquanto o código LUA está em execução. O serviço automático pode ser parado e reiniciado usando as funções autoservice_stop() e autoservice_start(). O serviço automático deve estar em execução antes de iniciar operações de execução longa. O serviço automático será automaticamente interrompido antes de executar aplicativos e funções do plano de marcação (Dialplan) e será reiniciado posteriormente. A função autoservice_status() pode ser usada para verificar o status atual do serviço automático e retornará true se um serviço automático estiver em execução no momento.

Nota sobre conflitos de nomenclatura:
LUA permite que você consulte as entradas da tabela usando o '.' (ponto) notação, Exemplo: app.goto(algo), apenas se a entrada não entrar em conflito com uma palavra reservada do LUA. No exemplo 'goto', com Lua 5.1 ou anterior, 'goto' não é uma palavra reservada; portanto, você chamaria o aplicativo de plano de discagem do Asterisk® SCF™ 'goto'. Agora, em LUA 5.2, ocorreu, a introdução da instrução de controle 'goto' que torna 'goto' uma palavra reservada. Isso faz com que o interpretador do LUA falhe ao analisar o arquivo e o pbx_lua.so falhará ao carregar. O mesmo se aplica a qualquer uso de tabelas reservadas ao LUA, incluindo extensões, canais e quaisquer tabelas que você criar.

Há duas maneiras de contornar isso: Como LUA diferencia maiúsculas de minúsculas, é possível usar nomes em maiúsculas, Exemplo: app.Goto(alvo) para se referir aos aplicativos, funções, etc. do Asterisk® SCF™, ou você pode usar a sintaxe completa, Exemplo: app["goto"](alvo da coisa). Ambas as sintaxes são compatíveis com versões anteriores de Lua. Para tornar seus planos de marcação (Dialplan) LUA mais fáceis de manter e reduzir a chance de futuros conflitos, convém usar a sintaxe do aplicativo app["goto"](algo da coisa) para todos os acessos à tabela.

function outgoing_local(c, e)
    app.dial("DAHDI/1/" .. e, "", "")
end

function demo_instruct()
    app.background("demo-instruct")
    app.waitexten()
end

function demo_congrats()
    app.background("demo-congrats")
    demo_instruct()
end

-- Responda ao channel e reproduza os arquivos de som demo
function demo_start(context, exten)
    app.wait(1)
    app.answer()

    channel.TIMEOUT("digit"):set(5)
    channel.TIMEOUT("response"):set(10)
    -- app.set("TIMEOUT(digit)=5")
    -- app.set("TIMEOUT(response)=10")

    demo_congrats(context, exten)
end

function demo_hangup()
    app.playback("demo-thanks")
    app.hangup()
end

extensions = {
    demo = {
        s = demo_start;
        
        ["2"] = function()
            app.background("demo-moreinfo")
            demo_instruct()
        end;
        
        ["3"] = function ()
            -- define o idioma para português.
            channel.LANGUAGE():set("br") 
            demo_congrats()
        end;
        
        ["1000"] = function()
            -- Lembre-se da nota de conflito de nomenclatura.
            app['goto']("default", "s", 1)
        end;
        
        ["1234"] = function()
            app.playback("transfer", "skip")
            -- faça um Dial aqui
        end;
        
        ["1235"] = function()
            app.voicemail("1234", "u")
        end;
        
        ["1236"] = function()
            app.dial("Console/dsp")
            app.voicemail(1234, "b")
        end;

        ["#"] = demo_hangup;
            t = demo_hangup;
            i = function()
            app.playback("invalid")
            demo_instruct()
        end;
        
        ["500"] = function()
            app.playback("demo-abouttotry")
            app.dial("IAX2/guest@misery.digium.com/s@default")
            app.playback("demo-nogo")
            demo_instruct()
        end;
        
        ["600"] = function()
            app.playback("demo-echotest")
            app.echo()
            app.playback("demo-echodone")
            demo_instruct()
        end;
        
        ["8500"] = function()
            app.voicemailmain()
            demo_instruct()
        end;
    };

    default = {
        -- por padrão, faça a demonstração.
        include = {"demo"};
    };

ATENÇÃO: Se o seu Asterisk® SCF™ estiver conectado à Internet (cloud) e você não tiver allowguest=no no sip.conf, todos os usuários poderão usar seu contexto público (public) sem autenticação. Nesse caso, você deve verificar quais serviços você oferece a seus clientes.

    public = {
           include = {"demo"};
  
    };

    ["local"] = {
        ["_NXXXXXX"] = outgoing_local;
        
    };
}

hints = {
    demo = {
        [1000] = "SIP/1000";
        [1001] = "SIP/1001";
    };
    
    default = {
        ["1234"] = "SIP/1234";
    };
}

Bom se você chegou até aqui, parabéns... Eu recomendo que você faça uma pequena leitura neste post: Aprenda LUA em 15 minutos.

E se quiser temos uma comunidade no Telegram onde estamos todos iniciando em extensions.lua. Asterisk Dialplan LUA Brasil, seja bem vindo!




Nenhum comentário

Tecnologia do Blogger.