FreePBX Configurando o Asterisk para notificações por email de chamadas perdidas na fila

imagem
IP ATC Asterisk é um poderoso processador de telefonia IP. E a interface baseada na Web FreePBX criada para o Asterisk simplifica muito a configuração e reduz o limite de logon.
Se você pode criar algum tipo de tarefa relacionada à telefonia IP, quase certamente ela pode ser implementada no Asterisk. Mas certifique-se de que perseverança e resistência serão exigidas de você.

Enfrentamos a tarefa de configurar notificações por email de chamadas perdidas. Mais precisamente, para notificar por e-mail os casos em que uma chamada recebida foi colocada na fila, mas ninguém (dos agentes) respondeu a essa chamada.

Surpreendentemente, não encontramos nenhuma ferramenta regular para resolver esse problema no FreePBX. Vou falar sobre como resolvemos esse problema por baixo.

Prefácio

Antes de resolver o problema "de frente", certamente procuramos informações na Internet, mas não encontramos soluções prontas para o uso (talvez elas estivessem mal, mas o que você pode fazer ...).

Não existem tantas habilidades de trabalho diretamente no Asterisk quanto gostaríamos, portanto a solução proposta aqui não foi totalmente compreendida e foi descartada.

Gostei da solução proposta aqui , embora não tenha funcionado. Por isso, enfatizaram que trabalhar no Asterisk é necessário no contexto de [ext-queues]. E como trabalhamos no Freepbx, precisamos trabalhar no arquivo de configuração "extensions_override_freepbx.conf". Percebemos que é conveniente "capturar chamadas perdidas" antes do evento hangupcall (final de uma chamada).
Depois de ler a discussão aqui , surgiu a idéia de que precisamos filtrar a variável "Disposition" no CDR para todos os agentes na fila. E depois de ler essas informações, etapas bastante específicas foram formadas para resolver a tarefa.

O que temos:

Existe o FreePBX 13.0.197 que usa o Asterisk 13.12.1. Versão do SO SHMZ versão 6.6 (Final). A distribuição é baseada no CentOS.

O Asterisk é configurado com IVR (menu de voz), espalhando as chamadas recebidas em diferentes filas (filas). Os agentes (agentes) são atribuídos a cada fila, ou seja, agentes.

Teoria

O que está acontecendo no Asterisk

Quando uma chamada de entrada chega ao Asterisk, essa chamada vai para o IVR. O chamador faz uma escolha pressionando um número específico no telefone e entra em uma fila específica. Depois disso, todos os agentes livres da fila recebem simultaneamente uma chamada.

Para entender melhor o que está acontecendo neste momento e o que acontece a seguir, passamos ao Report CDR (Fig. 1).

imagem
Fig. 1

Quando uma chamada recebida entra na fila, para todos os agentes, o valor da variável "Disposição" torna-se igual a "SEM RESPOSTA" se os agentes não estiverem ocupados naquele momento. A variável "Disposição" pode assumir outros valores (consulte https://asterisk-pbx.ru/wiki/asterisk/cf/cdr ), exceto o valor "RESPONDIDO". E no momento em que um dos agentes atende a chamada, o valor da variável "Disposição" desse agente se torna igual a "RESPONDIDO".
No CDR do relatório, você pode ver que quando a chamada está na fila (na coluna Aplicativo, o valor se torna "Fila"), todos os eventos aparecem com o mesmo "ID exclusivo" (coluna Sistema).

CDR em breve

É importante entender o que é um CDR e em que momento no CDR são inseridos os dados que observamos no CDR do relatório. O CDR, relativo ao sistema operacional, é o banco de dados no qual o Asterisk grava um relatório de chamadas detalhado (consulte https://asterisk-pbx.ru/wiki/asterisk/cf/cdr ). No nosso caso, este é um banco de dados chamado asteriskcdrdb, localizado no mysql. Empiricamente, descobrimos que os dados sobre uma chamada com um determinado "uniqueid" não são inseridos no asteriskcdrdb imediatamente após a ocorrência de um evento, mas após o evento hangupcall (final da chamada).

O princípio da solução criada

Como temos mais conhecimento em bash do que conhecimento em Asterisk, a idéia principal é a seguinte. Antes do evento hangupcall, chame o script bash. Passe 3 parâmetros para esse script. O primeiro parâmetro é "uniqueid", para filtrar os dados recebidos do CDR. O segundo parâmetro é "CALLERID (num)" (o número do chamador) para saber para quem ligar de volta. O terceiro parâmetro é "NODEST" (número da fila), para o qual a chamada foi recebida, para saber qual problema houve uma chamada e para quem enviar uma notificação por email de uma chamada perdida.
O script bash deve se conectar ao banco de dados asteriskcdrdb no mysql e pegar todos os valores da variável "Disposition" com um "uniqueid" específico. Dos dados obtidos, é necessário excluir os valores: “SEM RESPOSTA”, “OCUPADO”, “FALHADO”, “DESCONHECIDO”. Como resultado, “RESPONDIDO” permanecerá - eles atenderam a chamada recebida ou nada - a chamada perdida.

Além disso, se a chamada foi perdida, o script deve enviar uma notificação por email.
No futuro, observo um ponto importante. O Asterisk executa os comandos sequencialmente, aguardando sua execução (o que geralmente é lógico). E chamaremos o script bash antes que o comando hangupcall seja executado. Assim, no momento em que o script é executado diretamente, as informações sobre o ID único que estamos procurando ainda não serão inseridas no CDR. Para resolver esse problema, chamaremos o script bash com o parâmetro "&" para que o Asterisk prossiga imediatamente para a próxima etapa, ou seja, hangupcall. E dentro do script bash, no início, definiremos um pequeno atraso para que o Asterisk insira os dados com o “uniqueid” de seu interesse no CDR.

Prática

Antes de continuar configurando o Asterisk e criar um script bash, você precisa configurar o envio de notificações por email. Para isso, usaremos o utilitário postfix.

Configuração do Postfix

Temos um domínio de correio "lucky.ru" localizado em Yandex. Vamos configurar o postfix no modo smtp-client e enviaremos cartas da conta asterisk@lucky.ru.
A solução é retirada daqui: https://www.dmosk.ru/miniinstruktions.php?mini=postfix-over-yandex .

Primeiro instale / atualize / verifique os pacotes:

yum install postfix yum install mailx yum install cyrus-sasl cyrus-sasl-lib cyrus-sasl-plain 

Não sobrescreveremos o arquivo de configuração principal do postfix "/etc/postfix/main.cf", mas faremos o backup:

 cp /etc/postfix/main.cf /etc/postfix/main.cf.sav 

Editamos o arquivo “/etc/postfix/main.cf” e o trazemos para o seguinte formato:

 nano /etc/postfix/main.cf ##################### relayhost = smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/private/sasl_passwd smtp_sasl_security_options = noanonymous smtp_sasl_type = cyrus smtp_sasl_mechanism_filter = login smtp_sender_dependent_authentication = yes sender_dependent_relayhost_maps = hash:/etc/postfix/private/sender_relay smtp_generic_maps = hash:/etc/postfix/generic smtp_tls_CAfile = /etc/postfix/ca.pem smtp_use_tls = yes smtputf8_autodetect_classes = all ##################### 

Nem todas as linhas em "/etc/postfix/main.cf" podem ser comentadas. Os comentários em algumas linhas não são determinados pelo analisador e são passados ​​para o processamento, e isso leva a erros. É melhor recusar comentários dentro deste arquivo. Você pode experimentar isso executando “tail -f / var / log / messages” na próxima janela.

Vou marcar a linha "smtputf8_autodetect_classes = all". Esta entrada inclui utf-8 por padrão, que permite usar o alfabeto cirílico no corpo da letra e na linha de assunto sem manipulações adicionais (consulte http://www.postfix.org/SMTPUTF8_README.html ).

Crie um diretório para os arquivos de configuração:

 mkdir /etc/postfix/private 

Editamos o arquivo "/ etc / postfix / private / sender_relay". Nele, você precisa especificar a qual servidor smtp você deve se referir ao usar nosso domínio de email:

 nano /etc/postfix/private/sender_relay ##################### @lucky.ru smtp.yandex.ru ##################### 

Nós editamos o arquivo "/ etc / postfix / private / sasl_passwd". Nele, indicaremos o endereço de e-mail que usaremos para enviar cartas, bem como o nome de usuário e a senha dessa conta (especificamos o nome de usuário e a senha por meio de dois pontos):

 nano /etc/postfix/private/sasl_passwd ##################### asterisk@lucky.ru asterisk@lucky.ru:password_asterisk ##################### 

Editando o arquivo / etc / postfix / generic. Nele, escreveremos as regras para substituir o endereço de saída (consulte https://wiki.merionet.ru/ip-telephoniya/30/postfix-nastrojka-otpravki-pochty-v-asterisk/ ):

 nano /etc/postfix/generic ##################### root asterisk@lucky.ru root@localhost asterisk@lucky.ru root@localhost.localdomain asterisk@lucky.ru root@freepbx asterisk@lucky.ru root@freepbx.localdomain asterisk@lucky.ru root@asterisk asterisk@lucky.ru root@asterisk.localdomain asterisk@lucky.ru asterisk asterisk@lucky.ru asterisk@localhost asterisk@lucky.ru asterisk@localhost.localdomain asterisk@lucky.ru asterisk@freepbx asterisk@lucky.ru asterisk@freepbx.localdomain asterisk@lucky.ru asterisk@asterisk asterisk@lucky.ru asterisk@asterisk.localdomain asterisk@lucky.ru root@localdomain.localdomain asterisk@lucky.ru ##################### 

O endereço de saída inicial depende do conteúdo de "/ etc / hosts" e "/ etc / hostname", bem como do nome do usuário que enviará a carta. Ou seja, apesar de usarmos o cliente smtp e enviarmos cartas de asterisk@lucky.ru, o postfix substituirá inicialmente "algo próprio" no endereço do remetente e isso deve ser corrigido com as regras deste arquivo de configuração.

Vou listar o conteúdo do meu arquivo / etc / hosts:

 cat /etc/hosts ##################### 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 asterisk.localdomain 127.0.0.1 localhost.localdomain localhost ::1 asterisk localhost localhost6 ##################### 

É importante que o servidor tenha qualquer domínio (o valor após o período), porque o utilitário de correio “procura” o nome de domínio em “/ etc / hosts” e se “não o encontrar” imediatamente, continuará fazendo isso por mais alguns minutos e só então envie uma carta. Ou seja, se o domínio não estiver registrado, a carta sairá com um atraso de vários minutos.

Vou listar o conteúdo do meu arquivo / etc / hostname:

 cat /etc/hostname ##################### asterisk ##################### 

Em seguida, você precisa transferir os arquivos de configuração criados para os bancos de dados indexados; para isso, execute o seguinte comando:

 postmap /etc/postfix/generic && postmap /etc/postfix/private/{sasl_passwd,sender_relay} 

Em seguida, precisamos baixar e colocar o certificado smtp.yandex.ru no servidor, para fazer isso, execute o seguinte comando:

 openssl s_client -starttls smtp -crlf -connect smtp.yandex.ru:25 > /etc/postfix/ca.pem 

Mas depois que as informações técnicas aparecerem na tela, a equipe "continuará travando". Pressione Ctrl + C para abortá-lo.

Agora exclua manualmente todo o lixo do arquivo resultante e deixe apenas o certificado. Você deve obter algo como isto:

 nano /etc/postfix/ca.pem ##################### -----BEGIN CERTIFICATE----- MIIGazCCBVOgAwIBAgIQcUU9mJXW4OUs5Gf0JfLtsjANBgkqhkiG9w0BAQsFADBf ... nRG0DfdqYIuPGApFORYe -----END CERTIFICATE----- ##################### 

Por fim, reinicie o postfix:

 service postfix restart 

Enviamos uma carta de teste:

 echo "  " | mail -s " " admin@lucky.ru 

admin@lucky.ru - endereço de destino

Isso completa a configuração do posfix.

Escrevendo um script bash

Crie um diretório para armazenar um script bash (aqui alguém gosta onde):

 mkdir /home/asterisk/scripts 

Crie um arquivo de script bash:

 touch /home/asterisk/scripts/noanswer.sh 

Damos permissões ao arquivo de script para executar:

 chmod +x /home/asterisk/scripts/noanswer.sh 

Se houver dúvidas sobre os direitos do arquivo, durante a depuração, você poderá conceder acesso total ao arquivo. Mas não é "seguro".

 chmod 777 /home/asterisk/scripts/noanswer.sh 

O texto do script bash:

 nano /home/asterisk/scripts/noanswer.sh ##################### #!/bin/bash sleep 7 res_sql="SELECT disposition FROM cdr WHERE uniqueid = '$1'" answer=`mysql -u freepbxuser -pPassword_freepbxuser -D asteriskcdrdb -B -N -e "$res_sql" | grep -E -v "NO ANSWER|BUSY|FAILED|UNKNOWN" | head -n 1` error_kod=0 if [ "$answer" != "ANSWERED" ] then case $3 in 68800) address="big_boss@lucky.ru" subject="  " ;; 63100) address="debian@lucky.ru" subject="  linux debian" ;; 63200) address="windows@lucky.ru" subject="  windows" ;; 63300) address="freebsd@lucky.ru" subject="  freebsd" ;; 63400) address="ubuntu@lucky.ru" subject="  linux ubuntu" ;; 63500) address="centos@lucky.ru" subject="  linux centos" ;; *) address="admin@lucky.ru" error_kod=1 ;; esac case $error_kod in 0) echo "    $2,  $subject." | mail -s "   $2" $address echo "   $address   $2,  $subject. uid=$1" | mail -s "   $2" admin@lucky.ru ;; 1) echo "   $2.  . uid=$1" | mail -s "   $2" admin@lucky.ru ;; esac fi ##################### 

Uma breve análise do script:
"Dormir 7":

Este é o mesmo atraso de tempo que escrevi anteriormente. Temos um atraso de 7 segundos. Embora, eu acho, um segundo seja suficiente.

 «res_sql="SELECT disposition FROM cdr WHERE uniqueid = '$1'"»: 

A consulta no mysql é colocada em uma variável separada por conveniência.

Em seguida, fazemos uma solicitação no mysql e filtramos a saída resultante. Removemos todas as opções, exceto "RESPONDIDO", se houver. Se houver vários valores "RESPONDIDOS", apenas um deverá ser deixado. No final, na variável “resposta”, obtemos “RESPOSTA” ou “”.
Se o valor da variável de resposta não for igual a RESPONDIDO, esta será uma chamada perdida. Dependendo do número da fila, usando o operador case, definiremos o endereço para o qual é necessário enviar uma notificação por e-mail e o que escrever nesta mensagem (parte variável da mensagem).

A seguir, uma opção quando a fila é configurada no Asterisk, mas não descrita no script. Nesse caso, admin@lucky.ru receberá uma carta informando que a fila não é conhecida pelo script.

Se a fila for descrita, uma carta de destino e uma carta duplicada serão enviadas para admin@lucky.ru indicando “uniqueid”, para que você possa rastrear eventos nessa chamada, se necessário.

Isso termina o script.

Observo que, para conectar ao mysql, usamos o nome de usuário e a senha que reconhecemos previamente. No FreePBX, para descobrir o login do usuário do Asterisk no mysql, execute o seguinte comando:

 cat /etc/amportal.conf | grep AMPDBUSER 

E, para descobrir a senha do usuário do Asterisk no mysql, execute o seguinte comando:

 cat /etc/amportal.conf | grep AMPDBPASS 

Configurar o Asterisk

Nós usamos o FreePBX. O FreePBX possui diferentes tipos de arquivos de configuração (consulte https://asterisk-pbx.ru/wiki/freepbx/files ), alguns deles são substituídos pelo FreePBX após a reinicialização e outros não são substituídos (chamados de personalizados), pois são especialmente projetados para o usuário.

Trabalharemos com o arquivo de configuração “extensions_override_freepbx.conf”, pois é do tipo customizado.

Primeiro, verifique se o arquivo “extensions_override_freepbx.conf” está conectado no arquivo “/etc/asterisk/extensions.conf”. Para fazer isso, execute o seguinte comando:

 cat /etc/asterisk/extensions.conf | grep extensions_override_freepbx.conf ##################### #include extensions_override_freepbx.conf ##################### 

Editamos o arquivo "/etc/asterisk/extensions_override_freepbx.conf" e o trazemos para o seguinte formato:

 nano /etc/asterisk/extensions_override_freepbx.conf ##################### [ext-queues] exten => h,1,System(/home/asterisk/scripts/noanswer.sh ${CDR(uniqueid)} ${CALLERID(num)} ${NODEST} &) exten => h,2,Macro(hangupcall,) ##################### 

Como escrevi anteriormente, o símbolo "&" no final é necessário. Como trabalharemos em um script bash com dados CDR diretamente do banco de dados mysql, e esses dados são inseridos no mysql somente após a execução de “exten => h, 2, Macro (hangupcall,)”, não precisamos aguardar a conclusão do script bash e prossiga para a próxima etapa no Asterisk. E o próprio script bash deve conter um atraso de tempo antes de executar sua parte principal.

Para que as alterações no arquivo de configuração “/etc/asterisk/extensions_override_freepbx.conf” entrem em vigor, é necessário reiniciar o kernel do Asterisk com o seguinte comando:

 /usr/sbin/asterisk -rx "core restart now" 

Isso precisa ser feito após a criação do script bash.

Conclusão

Esta é provavelmente a maneira 1001 de "capturar chamadas perdidas" no Asterisk. Compartilhe nos comentários como você resolve esse problema. E o que, na sua opinião, pode ser melhorado / refeito / otimizado. Seremos gratos pelas idéias construtivas.

Source: https://habr.com/ru/post/pt463829/


All Articles