PBX gratuito. Configurar Asterisk para notificaciones por correo electrónico sobre llamadas entrantes perdidas en la cola

PBX gratuito. Configurar Asterisk para notificaciones por correo electrónico sobre llamadas entrantes perdidas en la cola
IP ATC Asterisk es una poderosa máquina en el campo de la telefonía IP. Y la interfaz web FreePBX, creada para Asterisk, simplifica enormemente la configuración y reduce la barrera de entrada al sistema.
Si se le ocurre alguna tarea relacionada con la telefonía IP, es casi seguro que se puede implementar en Asterisk. Pero tenga la seguridad de que necesitará perseverancia y resistencia.

Nos enfrentamos a la tarea de configurar notificaciones por correo electrónico sobre llamadas perdidas. Más precisamente, notificar por correo electrónico sobre aquellos casos en los que una llamada entrante entró en la cola, pero nadie (de los agentes) respondió a esta llamada entrante.

Sorprendentemente, no encontramos ninguna herramienta estándar para resolver este problema en FreePBX. Te contaré debajo del corte cómo resolvimos este problema.

prefacio

Antes de resolver el problema de frente, por supuesto, buscamos información en Internet, pero no encontramos una solución llave en mano (tal vez no buscamos bien, pero qué se puede hacer...).

No hay tantas habilidades para trabajar directamente en Asterisk como nos gustaría, por eso la solución ofrecida aquí, no fue comprendido del todo y fue descartado.

Me gustó la solución propuesta. aquí, aunque no funcionó. Por lo tanto, enfatizaron que es necesario trabajar en Asterisk en el contexto de colas [ext-queues]. Y como trabajamos en Freepbx, necesitamos trabajar en el archivo de configuración “extensions_override_freepbx.conf”. Notamos que “captar llamadas perdidas” es conveniente antes del evento de colgar la llamada (fin de la llamada).
Después de leer la discusión aquí, surgió la idea de que era necesario filtrar la variable “Disposición” en el CDR por todos los agentes en la cola. Y después de leer este información, se formaron pasos muy específicos para resolver el problema.

Que tenemos:

Existe FreePBX 13.0.197, que utiliza Asterisk 13.12.1. La versión del sistema operativo es SHMZ release 6.6 (Final). La distribución se basa en CentOS.

Asterisk está configurado con un IVR (menú de voz) que distribuye las llamadas entrantes a diferentes colas. A cada cola se le asignan Agentes, es decir, operadores.

Теория

¿Qué está pasando en Asterisco?

Cuando Asterisk recibe una llamada entrante, la llamada pasa al IVR. La persona que llama toma una decisión presionando un número determinado en el teléfono y se coloca en una cola determinada. Después de esto, todos los agentes libres en la cola reciben una llamada simultáneamente.

Para comprender mejor lo que está sucediendo en este momento y lo que sucederá después, recurramos al Informe CDR (Fig. 1).

PBX gratuito. Configurar Asterisk para notificaciones por correo electrónico sobre llamadas entrantes perdidas en la cola
Ris.1

Cuando una llamada entrante ingresaba a la cola, el valor de la variable “Disposición” para todos los agentes pasaba a ser igual a “SIN RESPUESTA” si los agentes no estaban ocupados en ese momento. La variable “Disposición” podría tomar otros valores (ver. https://asterisk-pbx.ru/wiki/asterisk/cf/cdr), excepto el valor “RESPONDIDO”. Y en el momento en que uno de los agentes contesta una llamada entrante, el valor de la variable “Disposición” de este agente pasa a ser igual a “RESPONDIDO”.
Desde el CDR de Informe puede ver que cuando la llamada está en cola (en la columna Aplicación el valor se vuelve igual a "Cola"), todos los eventos aparecen con el mismo "únicoid" (columna Sistema).

Brevemente sobre CDR

Es importante entender qué es un CDR y en qué punto exactamente se ingresan en el CDR los datos que observamos en el Informe CDR. El CDR, en relación con el sistema operativo, es una base de datos en la que Asterisk escribe un informe de llamadas detallado (ver. https://asterisk-pbx.ru/wiki/asterisk/cf/cdr). En nuestro caso, se trata de una base de datos llamada asteriskcdrdb, que se encuentra en mysql. Hemos establecido empíricamente que los datos sobre una llamada con un determinado "uniqueid" se ingresan en asteriskcdrdb no inmediatamente después de que ocurre cualquier evento, sino después del evento hangupcall (fin de la llamada).

El principio de funcionamiento de la solución creada.

Como tenemos más conocimiento en bash que en Asterisk, la idea principal resultó ser la siguiente. Antes del evento hangupcall, llame a un script bash. Pase 3 parámetros a este script. El primer parámetro es “uniqueid”, para filtrar los datos recibidos del CDR. El segundo parámetro es “CALLERID(num)” (número de llamada), para saber a quién devolver la llamada. El tercer parámetro es “NODEST” (número de cola) en el que se recibió la llamada, para saber de qué problema se trataba y a quién enviar una notificación por correo electrónico de la llamada perdida.
El script bash debe conectarse a la base de datos asteriskcdrdb en mysql y tomar todos los valores de la variable “Disposición” con un determinado “uniqueid”. De los datos recibidos debe excluir los siguientes valores: "SIN RESPUESTA", "OCUPADO", "FALLADO", "DESCONOCIDO". Como resultado, quedará "RESPONDIDO" (se respondió la llamada entrante) o nada en absoluto: una llamada perdida.

A continuación, si se pierde la llamada, el script debería enviar una notificación por correo electrónico.
De cara al futuro, señalaré un punto importante. Asterisk ejecuta comandos secuencialmente, esperando a que se completen (lo cual generalmente es lógico). Y llamaremos al script bash antes de ejecutar el comando hangupcall. Así, en el momento de la ejecución directa del script, la información sobre el “uniqueid” que estamos buscando no se introducirá en el CDR. Para resolver este problema, llamaremos al script bash con el parámetro “&” para que Asterisk inmediatamente proceda a realizar el siguiente paso, es decir, hangupcall. Y dentro del script bash, al principio, estableceremos un pequeño retraso para darle tiempo a Asterisk para ingresar datos con el "uniqueid" que nos interesa en el CDR.

Práctica

Antes de continuar con la configuración de Asterisk y la creación de un script bash, debe configurar el envío de notificaciones por correo electrónico. Para ello utilizaremos la utilidad postfix.

Configurar sufijo

Tenemos un dominio de correo "lucky.ru" ubicado en Yandex. Configuraremos postfix en modo cliente smtp y enviaremos correos desde la cuenta asterisk@lucky.ru.
La solución se basa en esto: https://www.dmosk.ru/miniinstruktions.php?mini=postfix-over-yandex.

Primero, instalemos/actualicemos/busquemos paquetes:

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

No sobrescribamos el archivo de configuración principal de Postfix “/etc/postfix/main.cf”, sino que creemos una copia de seguridad del mismo:

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

Editamos el archivo “/etc/postfix/main.cf” y lo llevamos al siguiente formulario:

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
#####################

No se pueden comentar todas las líneas de “/etc/postfix/main.cf”. El analizador no detecta los comentarios en algunas líneas y los envía para su procesamiento, lo que genera errores. Es mejor rechazar los comentarios dentro de este archivo. Puedes experimentar con esto ejecutando "tail -f /var/log/messages" en la siguiente ventana.

Marcaré la línea “smtputf8_autodetect_classes = all”. Esta entrada incluye utf-8 por defecto, lo que le permite usar cirílico tanto en el cuerpo de la carta como en el asunto de la carta sin manipulaciones adicionales (Ver. http://www.postfix.org/SMTPUTF8_README.html).

Creemos un directorio para los archivos de configuración:

mkdir /etc/postfix/private

Edite el archivo “/etc/postfix/private/sender_relay”. En él debe indicar a qué servidor smtp debe vincularse cuando utiliza nuestro dominio de correo:

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

Edite el archivo “/etc/postfix/private/sasl_passwd”. En él indicaremos la dirección de correo electrónico que utilizaremos para enviar cartas, así como el login y contraseña de esta cuenta (indicamos el login y contraseña separados por dos puntos):

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

Edite el archivo “/etc/postfix/generic”. En él anotaremos las reglas para reemplazar la dirección saliente (ver. 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
#####################

La dirección saliente inicial depende del contenido de "/etc/hosts" y "/etc/hostname", así como del nombre del usuario que enviará el correo electrónico. Es decir, a pesar de que utilizamos un cliente SMTP y enviamos cartas desde asterisk@lucky.ru, Postfix inicialmente sustituirá “algo propio” en la dirección del remitente, y esto debe corregirse utilizando las reglas de este archivo de configuración.

Aquí está el contenido de mi archivo “/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
#####################

Es importante que el servidor tenga algún tipo de dominio (el valor después del punto), porque la utilidad de correo “busca” el nombre de dominio en “/etc/hosts” y si no lo “encuentra” inmediatamente, lo Seguirá haciéndolo unos minutos más y recién entonces enviará la carta. Es decir, si el dominio no está registrado, la carta se enviará con un retraso de varios minutos.

Aquí está el contenido de mi archivo “/etc/hostname”:

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

A continuación, debe transferir los archivos de configuración creados a bases de datos indexadas; para ello, ejecute el siguiente comando:

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

A continuación, debemos descargar y colocar el certificado smtp.yandex.ru en el servidor; para ello, ejecute el siguiente comando:

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

Pero después de que aparezca la información técnica en la pantalla, el comando “seguirá bloqueándose”. Presione Ctrl+C para cancelarlo.

Ahora eliminemos manualmente toda la basura del archivo resultante y dejemos solo el certificado. Debería verse así:

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

Y finalmente reinicie postfix:

service postfix restart

Envío de una carta de prueba:

echo "Это тело письма" | mail -s "Это тема" admin@lucky.ru

admin@lucky.ru — dirección de destino

Esto completa la configuración de posfix.

Escribir un script bash

Cree un directorio para almacenar el script bash (aquí es donde más le guste):

mkdir /home/asterisk/scripts

Cree un archivo de script bash:

touch /home/asterisk/scripts/noanswer.sh

Le damos al archivo script permisos para ejecutar:

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

Si hay dudas sobre los derechos de un archivo, puede otorgar acceso completo al archivo durante la depuración. Pero esto “no es seguro”.

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

Texto del 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
#####################

Breve análisis del guión:
"dormir 7":

Este es el mismo retraso de tiempo sobre el que escribí antes. Tenemos un retraso establecido en 7 segundos. Aunque creo que un segundo es suficiente.

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

Movimos la consulta en MySQL a una variable separada por conveniencia.

A continuación, realizamos una consulta en mysql y filtramos la salida resultante. Eliminamos todas las opciones excepto “RESPONDIDO”, si es que existe alguna. Si hay varios valores “RESPONDIDOS”, entonces solo debe quedar uno. Al final, recibiremos "RESPONDIDO" o "" en la variable "respuesta".
Si el valor de la variable "respuesta" no es "RESPUESTA", entonces es una llamada perdida. Dependiendo del número de cola, usando la declaración de caso especificaremos la dirección a quién exactamente se debe enviar la notificación por correo electrónico y qué escribir en este mensaje (la parte variable del mensaje).

A continuación, consideramos el caso cuando la cola está definida en Asterisk, pero no se describe en el script. En este caso, admin@lucky.ru recibirá una carta indicando que la cola es desconocida para el script.

Si se describe la cola, se enviará una carta al destino y una carta duplicada a admin@lucky.ru con la indicación “uniqueid”, para que sea posible rastrear los eventos de esta llamada, si es necesario.

Aquí termina el guión.

Observo que para conectarnos a MySQL utilizamos un nombre de usuario y una contraseña que aprendimos de antemano. En FreePBX, para conocer el inicio de sesión del usuario de Asterisk en mysql, ejecute el siguiente comando:

cat /etc/amportal.conf | grep AMPDBUSER

Y para averiguar la contraseña del usuario de Asterisk en MySQL, ejecute el siguiente comando:

cat /etc/amportal.conf | grep AMPDBPASS

Configurando asterisco

Usamos FreePBX. FreePBX tiene diferentes tipos de archivos de configuración (ver https://asterisk-pbx.ru/wiki/freepbx/files), FreePBX sobrescribe algunos de ellos al reiniciar y otros no se sobrescriben (se llaman personalizados), ya que están diseñados específicamente para el usuario.

Trabajaremos con el archivo de configuración “extensions_override_freepbx.conf”, ya que es del tipo personalizado.

Primero, asegurémonos de que el archivo “extensions_override_freepbx.conf” esté incluido en el archivo “/etc/asterisk/extensions.conf”. Para hacer esto, ejecute el siguiente comando:

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

Edite el archivo “/etc/asterisk/extensions_override_freepbx.conf” y tráigalo al siguiente formulario:

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 escribí anteriormente, se requiere el símbolo "&" al final. Dado que trabajaremos en un script bash con datos CDR directamente desde la base de datos mysql, y estos datos se ingresan en mysql solo después de ejecutar “exten => h,2,Macro(hangupcall,)”, no necesitamos esperar a que bash script para finalizar el procesamiento y pasar al siguiente paso en Asterisk. Y el script bash en sí debe contener un retraso de tiempo antes de ejecutar su parte principal.

Para que los cambios en el archivo de configuración “/etc/asterisk/extensions_override_freepbx.conf” surtan efecto, debe reiniciar el kernel de Asterisk con el siguiente comando:

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

Esto debe hacerse después de que se haya creado el script bash.

Conclusión

Esta es probablemente la forma número 1001 de “captar llamadas perdidas” en Asterisk. Comparte en los comentarios cómo resuelves este problema. Y qué, en su opinión, se puede mejorar/rehacer/optimizar. Estaremos agradecidos por las ideas constructivas.

Fuente: habr.com

Compre alojamiento confiable para sitios con protección DDoS, servidores VPS VDS 🔥 Compra alojamiento web fiable con protección DDoS, servidores VPS VDS | ProHoster