FreePBX. Configurazione di Asterisk per notifiche e-mail su chiamate in entrata perse in coda

FreePBX. Configurazione di Asterisk per notifiche e-mail su chiamate in entrata perse in coda
IP ATC Asterisk è un potente sistema nel campo della telefonia VoIP. L'interfaccia web FreePBX, progettata per Asterisk, semplifica notevolmente la configurazione e abbassa la barriera all'ingresso nel sistema.
Se puoi pensare a qualsiasi compito legato alla telefonia VoIP, quasi certamente può essere realizzato in Asterisk. Ma sii certo che ti serviranno determinazione e perseveranza.

Ci siamo posti l'obiettivo di configurare notifiche via e-mail per le chiamate perse. Più precisamente, avvisare via e-mail nei casi in cui una chiamata in entrata è passata in coda, ma nessuno (tra gli agenti) ha risposto a quella chiamata in arrivo.

Sorprendentemente, non abbiamo trovato strumenti predefiniti per affrontare questo compito in FreePBX. Di come abbiamo risolto questo problema parlerò sotto.

Introduzione

Prima di affrontare il problema «a muso duro», abbiamo naturalmente cercato informazioni su Internet, ma non abbiamo trovato soluzioni pronte (forse abbiamo cercato male, ma cosa possiamo farci...).

Non abbiamo molte competenze specifiche in Asterisk come vorremmo, quindi la soluzione proposta qui, non è stata completamente elaborata ed è stata scartata.

Ci è piaciuta la soluzione proposta da qui, anche se non ha funzionato. Da qui abbiamo sottolineato che lavorare in Asterisk deve essere fatto nel contesto delle code [ext-queues]. E poiché lavoriamo con FreePBX, è necessario lavorare nel file di configurazione «extensions_override_freepbx.conf». Abbiamo notato che è comodo «catturare le chiamate perse» prima dell'evento hangupcall (fine della chiamata).
Leggendo la discussione qui, è nata l'idea che dovevamo filtrare nella CDR la variabile «Disposition» per tutti gli agenti in coda. Dopo aver letto questo , si sono formati passi ben definiti per risolvere il compito assegnato.

Cosa abbiamo:

Abbiamo FreePBX 13.0.197, che utilizza Asterisk 13.12.1. La versione del sistema operativo è SHMZ release 6.6 (Final). La distribuzione si basa su CentOS.

In Asterisk è configurato un IVR (menu vocale) che smista le chiamate in arrivo su diverse Queue (code). A ciascuna coda sono assegnati Agents (agenti), ovvero operatori.

Teoria

Cosa succede in Asterisk

Quando Asterisk riceve una chiamata in arrivo, questa chiamata passa all'IVR. L'utente in chiamata fa una scelta premendo un determinato numero sul telefono e viene indirizzato a una coda specifica. Dopo di ciò, a tutti gli agenti liberi della coda arriva una chiamata contemporaneamente.

Per comprendere meglio cosa succede in quel momento e cosa accade successivamente, facciamo riferimento al Report CDR (Fig.1).

FreePBX. Configurazione di Asterisk per notifiche e-mail su chiamate in entrata perse in coda
Fig.1

Quando una chiamata in entrata entra in coda, il valore della variabile «Disposition» per tutti gli agenti diventa «NO ANSWER», se gli agenti in quel momento non erano occupati. La variabile «Disposition» può assumere anche altri valori (vedi https://asterisk-pbx.ru/wiki/asterisk/cf/cdr), tranne il valore «ANSWERED». E nel momento in cui uno degli agenti risponde alla chiamata in entrata, il valore della variabile «Disposition» di quell'agente diventa «ANSWERED».
Dalla Report CDR si può notare che quando la chiamata è passata in coda (nella colonna App il valore diventa «Queue»), tutti gli eventi figurano con lo stesso «uniqueid» (colonna System).

In breve su CDR

È importante comprendere cos'è CDR e in quale momento vengono registrati i dati che osserviamo nella Report CDR. CDR, rispetto al sistema operativo, è un database in cui Asterisk registra un rapporto dettagliato delle chiamate (vedi https://asterisk-pbx.ru/wiki/asterisk/cf/cdr). Nel nostro caso si tratta di un database chiamato asteriskcdrdb, situato in mysql. Abbiamo stabilito empiricamente che i dati di una chiamata con un certo «uniqueid» vengono inseriti in asteriskcdrdb non immediatamente dopo il verificarsi di un evento, ma dopo l'evento hangupcall (fine della chiamata).

Il principio di funzionamento della soluzione creata

Poiché abbiamo più conoscenze in bash che in Asterisk, l'idea principale è risultata la seguente. Prima dell'evento hangupcall, chiamare uno script bash. Passare a questo script 3 parametri. Il primo parametro è «uniqueid», per filtrare i dati ottenuti dal CDR. Il secondo parametro è «CALLERID(num)» (numero del chiamante), per sapere a chi richiamare. Il terzo parametro è «NODEST» (numero della coda) in cui è arrivata la chiamata, per sapere di cosa riguardava la chiamata e a chi inviare l'e-mail di notifica per la chiamata persa.
Lo script bash deve connettersi al database asteriskcdrdb in mysql e prelevare tutti i valori della variabile «Disposition» con un certo «uniqueid». Dai dati ottenuti occorre escludere i valori: «NO ANSWER», «BUSY», «FAILED», «UNKNOWN». In questo modo resteranno o «ANSWERED» — la chiamata in entrata è stata rispondere, oppure nulla — chiamata persa.

In seguito, se la chiamata risulta persa, lo script deve inviare un'e-mail di notifica.
Anticipando il punto importante, Asterisk esegue i comandi in sequenza, aspettando il loro completamento (il che ha senso). E chiameremo lo script bash prima che venga eseguita il comando hangupcall. Pertanto, nel momento in cui lo script viene eseguito, nel CDR non sarà ancora stata inserita l'informazione relativa all'«uniqueid» che stiamo cercando. Per risolvere questo problema, chiameremo lo script bash con il parametro «&», in modo che Asterisk passi subito all'esecuzione del passo successivo, ovvero hangupcall. All'interno dello script bash, all'inizio, imposteremo un piccolo ritardo temporale per dare tempo ad Asterisk di inserire i dati relativi all'«uniqueid» che ci interessa nel CDR.

Pratica

Prima di passare alla configurazione di Asterisk e alla creazione dello script bash, è necessario configurare l'invio di notifiche e-mail. Per questo utilizzeremo l'utilità postfix.

Configurazione di postfix

Abbiamo il dominio e-mail «lucky.ru», situato in Yandex. Configureremo postfix in modalità client smtp e invieremo e-mail dall'account asterisk@lucky.ru.
È stato preso come base il seguente approccio: https://www.dmosk.ru/miniinstruktions.php?mini=postfix-over-yandex.

Innanzitutto, installeremo/aggiorneremo/verificheremo la presenza dei pacchetti:

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

Non sovrascriveremo il file di configurazione principale di postfix «/etc/postfix/main.cf», ma ne creeremo una copia di backup:

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

Modificare il file «/etc/postfix/main.cf» e portarlo alla seguente forma:

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

Non ogni riga in «/etc/postfix/main.cf» può essere commentata. I commenti in alcune righe non sono riconosciuti dal parser e vengono elaborati, il che porta a errori. È meglio evitare i commenti all'interno di questo file. Puoi sperimentare con questo avviando in una finestra accanto «tail -f /var/log/messages».

Vorrei sottolineare la riga «smtputf8_autodetect_classes = all». Questa impostazione abilita utf-8 per impostazione predefinita, permettendo di utilizzare il cirillico sia nel corpo dell'e-mail che nell'oggetto senza manipolazioni aggiuntive (Si veda. http://www.postfix.org/SMTPUTF8_README.html).

Creeremo una directory per i file di configurazione:

mkdir /etc/postfix/private

Modifichiamo il file «/etc/postfix/private/sender_relay». Qui dobbiamo specificare a quale server smtp fare riferimento quando utilizziamo il nostro dominio email:

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

Modifichiamo il file «/etc/postfix/private/sasl_passwd». Qui specificheremo l'indirizzo email che utilizzeremo per inviare messaggi, oltre al nome utente e alla password di questo account (il nome utente e la password devono essere separati da due punti):

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

Modifichiamo il file «/etc/postfix/generic». Qui scriveremo le regole per la sostituzione dell'indirizzo di partenza (vedi. 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
#####################

L'indirizzo di partenza originale dipende dal contenuto di «/etc/hosts» e «/etc/hostname», così come dal nome utente che invierà l'email. Cioè, anche se utilizziamo un client smtp e inviamo email da asterisk@lucky.ru, postfix inizialmente inserirà "qualcosa di suo" nell'indirizzo del mittente e questo deve essere corretto con le regole di questo file di configurazione.

Riporto il contenuto del mio file «/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 che il server abbia un dominio (valore dopo il punto), perché l'utilità mail "cerca" il nome del dominio in «/etc/hosts» e se "non lo trova" subito, continuerà a cercarlo per alcuni minuti e solo dopo invierà l'email. Cioè, se il dominio non è registrato, l'email verrà inviata con un ritardo di alcuni minuti.

Riporto il contenuto del mio file «/etc/hostname»:

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

Dopo è necessario convertire i file di configurazione creati in database indicizzati, per fare questo eseguiamo il seguente comando:

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

Dopo dobbiamo scaricare e posizionare sul server il certificato smtp.yandex.ru, per fare questo eseguiamo il seguente comando:

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

Ma dopo che l'informazione tecnica apparirà sullo schermo, il team continuerà a «rimanere in attesa». Premi Ctrl+C per interromperlo.

Ora eliminiamo manualmente tutto il superfluo dal file risultante e lasciamo solo il certificato. Dovrebbe risultare qualcosa di simile a:

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

E infine riavviamo postfix:

service postfix restart

Invia una email di test:

echo "Questo è il corpo dell'email" | mail -s "Questo è l'oggetto" admin@lucky.ru

admin@lucky.ru — indirizzo di destinazione

Con questa configurazione, la configurazione di postfix è terminata.

Scriviamo uno script bash

Creiamo una directory per conservare lo script bash (qui ognuno può scegliere dove preferisce):

mkdir /home/asterisk/scripts

Creiamo il file dello script bash:

touch /home/asterisk/scripts/noanswer.sh

Assegniamo i permessi di esecuzione al file dello script:

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

Se hai dubbi sui permessi del file, per la fase di debug puoi concedere accesso totale al file. Ma questo è ‘non sicuro’.

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

Testo dello 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="su una questione importante"
 ;;
 63100)
 address="debian@lucky.ru"
 subject="su questioni linux debian"
 ;;
 63200)
 address="windows@lucky.ru"
 subject="su questioni windows"
 ;;
 63300)
 address="freebsd@lucky.ru"
 subject="su questioni freebsd"
 ;;
 63400)
 address="ubuntu@lucky.ru"
 subject="su questioni linux ubuntu"
 ;;
 63500)
 address="centos@lucky.ru"
 subject="su questioni linux centos"
 ;;
 *)
 address="admin@lucky.ru"
 error_kod=1
 ;;
 esac

 case $error_kod in
 0)
 echo "Chiamata persa da $2, che ha chiamato $subject." | mail -s "Chiamata persa da $2" $address
 echo "Chiamata persa per $address da $2, che ha chiamato $subject. uid=$1" | mail -s "Chiamata persa da $2" admin@lucky.ru
 ;;
 1)
 echo "Chiamata persa da $2. Coda sconosciuta. uid=$1" | mail -s "Chiamata persa da $2" admin@lucky.ru
 ;;
 esac

fi
#####################

Breve analisi dello script:
«sleep 7»:

Questo è il ritardo temporale di cui ho parlato in precedenza. Abbiamo impostato un ritardo di 7 secondi. Anche se, penso, che un secondo sia sufficiente.

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

Abbiamo estratto la query in mysql in una variabile separata per comodità.

Successivamente, facciamo una richiesta a mysql e filtriamo l'output ricevuto. Rimuoviamo tutte le opzioni tranne "ANSWERED", se esiste. Se ci sono più valori "ANSWERED", dobbiamo lasciarne solo uno. Alla fine, nella variabile "answer" otteniamo o "ANSWERED" o "".
Se il valore della variabile "answer" non è uguale a "ANSWERED", si tratta di una chiamata persa. A seconda del numero della coda, utilizzeremo l'operatore case per definire l'indirizzo a cui inviare la notifica via e-mail e cosa scrivere in questo messaggio (parte modificabile del messaggio).

Successivamente, esaminiamo il caso in cui la coda sia definita in Asterisk, ma non descritta nello script. In questo caso, admin@lucky.ru riceverà un'email che informa che la coda non è conosciuta dallo script.

Se la coda è descritta, verrà inviata un'email all'indirizzo designato e un'email duplicata a admin@lucky.ru con l'indicazione di "uniqueid", in modo da poter monitorare gli eventi relativi a questa chiamata, se necessario.

Con questo, lo script termina.

Voglio sottolineare che per collegarci a mysql abbiamo utilizzato un nome utente e una password che abbiamo scoperto in anticipo. In FreePBX, per conoscere il nome utente di Asterisk in mysql, eseguire il seguente comando:

cat /etc/amportal.conf | grep AMPDBUSER

E per conoscere la password dell'utente Asterisk in mysql, eseguire il seguente comando:

cat /etc/amportal.conf | grep AMPDBPASS

Configurazione di Asterisk

Utilizziamo FreePBX. In FreePBX ci sono diversi tipi di file di configurazione (vedi. https://asterisk-pbx.ru/wiki/freepbx/files), alcuni di essi vengono riscritti da FreePBX al riavvio, mentre altri non vengono riscritti (sono chiamati custom), in quanto sono appositamente destinati all'utente.

Lavoreremo con il file di configurazione "extensions_override_freepbx.conf", poiché appartiene al tipo custom.

Per iniziare, assicuriamoci che nel file "/etc/asterisk/extensions.conf" sia incluso il file "extensions_override_freepbx.conf". Per questo, eseguiamo il seguente comando:

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

Modifichiamo il file "/etc/asterisk/extensions_override_freepbx.conf" e portiamolo alla seguente forma:

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

Come ho scritto in precedenza, il simbolo «&» alla fine è obbligatorio. Poiché lavoreremo in uno script bash con i dati CDR direttamente dal database mysql, e questi dati vengono inseriti in mysql solo dopo l'esecuzione di «exten => h,2,Macro(hangupcall,)», non è necessario attendere il completamento dell'elaborazione dello script bash, ma procedere con il passo successivo in Asterisk. E lo script bash deve contenere un ritardo temporale prima di eseguire la sua parte principale.

Perché le modifiche nel file di configurazione «/etc/asterisk/extensions_override_freepbx.conf» abbiano effetto, è necessario riavviare il kernel di Asterisk con il seguente comando:

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

Questo deve essere fatto dopo che lo script bash è stato creato.

Conclusione

Probabilmente, questo è il 1001° modo per «catturare le chiamate perse» in Asterisk. Condividi nei commenti come risolvi questo compito tu. E cosa, secondo te, potrebbe essere migliorato/rivisto/ottimizzato. Saremmo grati per idee costruttive.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster