
L'IP ATC Asterisk est un puissant combine dans le domaine de la téléphonie IP. L'interface web FreePBX, conçue pour Asterisk, simplifie considérablement la configuration et réduit la barrière d'entrée dans le système.
Si vous pouvez imaginer une tâche liée à la téléphonie IP, il est presque certain qu'elle peut être réalisée avec Asterisk. Mais soyez assuré qu'il vous faudra de la persévérance et de la patience.
Nous avons pour mission de configurer des notifications par e-mail pour les appels manqués. Plus précisément, notifier par e-mail les cas où un appel entrant a été mis en attente, mais aucun agent n'a répondu à cet appel entrant.
À notre grande surprise, nous n'avons pas trouvé de solutions intégrées à FreePBX pour résoudre cette tâche. Je vais expliquer comment nous avons résolu ce problème ci-dessous.
Préface
Avant d'aborder la tâche de manière directe, nous avons bien sûr recherché des informations sur Internet, mais nous n'avons pas trouvé de solution clé en main (peut-être que notre recherche était maladroite, mais que pouvons-nous faire…).
Les compétences de travail directement dans Asterisk ne sont pas aussi nombreuses que nous le souhaiterions, donc la solution proposée , n'a pas été pleinement réfléchie et a été abandonnée.
Nous avons aimé la solution proposée par , même si elle n'a pas fonctionné. D'où l'on souligne qu'il faut travailler dans Asterisk dans le contexte des files d'attente [ext-queues]. Étant donné que nous travaillons avec FreePBX, il faut intervenir dans le fichier de configuration « extensions_override_freepbx.conf ». Nous avons remarqué qu'il est pratique de 'capturer les appels manqués' avant l'événement hangupcall (fin de l'appel).
En lisant la discussion , l'idée est apparue que nous devrions filtrer dans CDR la variable « Disposition » pour tous les agents dans la file d'attente. Après avoir lu les informations, des étapes concrètes ont été formulées pour résoudre la tâche assignée.
Ce que nous avons :
Nous avons FreePBX 13.0.197, qui utilise Asterisk 13.12.1. La version du système d'exploitation est SHMZ release 6.6 (Final). La distribution est basée sur CentOS.
Dans Asterisk, un IVR (menu vocal) est configuré pour distribuer les appels entrants dans différentes files d'attente. Des agents sont assignés à chaque file d'attente, c'est-à-dire des opérateurs.
Théorie
Que se passe-t-il dans Asterisk
Lorsque Asterisk reçoit un appel entrant, cet appel arrive dans l'IVR. L'appelant fait un choix en appuyant sur un chiffre spécifique sur le téléphone et se retrouve dans une file d'attente déterminée. Après cela, tous les agents disponibles de la file d'attente reçoivent simultanément l'appel.
Pour mieux comprendre ce qui se passe à ce moment-là et ce qui se passe ensuite, consultons le Report CDR (Fig. 1).

Fig. 1
Lorsque l'appel entrant entre dans la file d'attente, la variable « Disposition » de tous les agents devient « NO ANSWER », à condition que les agents ne soient pas occupés à ce moment-là. La variable « Disposition » peut prendre d'autres valeurs (voir ), à l'exception de « ANSWERED ». Au moment où l'un des agents répond à l'appel entrant, la valeur de la variable « Disposition » de cet agent devient « ANSWERED ».
Dans le rapport CDR, on peut remarquer que lorsque l'appel passe dans la file d'attente (la colonne App devient « Queue »), tous les événements apparaissent avec le même « uniqueid » (colonne Système).
Brève présentation du CDR
Il est important de comprendre ce qu'est le CDR et à quel moment les données que nous observons dans le rapport CDR y sont enregistrées. Le CDR, par rapport au système d'exploitation, est une base de données dans laquelle Asterisk enregistre un rapport détaillé des appels (voir ). Dans notre cas, il s'agit de la base nommée asteriskcdrdb, qui se trouve dans MySQL. Par expérimentation, nous avons établi que les données d'un appel avec un « uniqueid » spécifique ne sont pas enregistrées dans asteriskcdrdb immédiatement après qu'un événement se soit produit, mais après l'événement hangupcall (fin d'appel).
Principe de fonctionnement de la solution créée
Comme nous avons plus de connaissances en bash qu'en Asterisk, l'idée principale est la suivante. Avant l'événement hangupcall, appeler un script bash. Ce script recevra 3 paramètres. Le premier paramètre est « uniqueid », pour filtrer les données obtenues du CDR. Le deuxième paramètre est « CALLERID(num) » (numéro de l'appelant), pour savoir à qui rappeler. Le troisième paramètre est « NODEST » (numéro de la file d'attente), où l'appel a été reçu, afin de savoir de quoi il s'agissait et à qui envoyer une notification par e-mail concernant l'appel manqué.
Le script bash doit se connecter à la base asteriskcdrdb dans MySQL et extraire toutes les valeurs de la variable « Disposition » avec un « uniqueid » spécifique. Les valeurs suivantes doivent être exclues : « NO ANSWER », « BUSY », « FAILED », « UNKNOWN ». En conséquence, il ne restera que « ANSWERED » — l'appel entrant a été répondu, ou rien du tout — appel manqué.
Ensuite, si l'appel a été manqué, le script doit envoyer une notification par e-mail.
Pour aller droit au but, je vais souligner un point important. Asterisk exécute les commandes de manière séquentielle, en attendant leur exécution (ce qui est en fait logique). Nous allons appeler le script bash avant que la commande hangupcall ne soit exécutée. Ainsi, au moment de l'exécution immédiate du script, aucune information sur le « uniqueid » que nous recherchons n'a encore été enregistrée dans le CDR. Pour résoudre ce problème, nous allons appeler le script bash avec le paramètre « & », afin qu'Asterisk passe immédiatement à l'étape suivante, c'est-à-dire hangupcall. Et au début du script bash, nous allons établir un léger délai afin de laisser le temps à Asterisk d'enregistrer les données concernant le « uniqueid » qui nous intéresse dans le CDR.
Pratique
Avant de passer à la configuration d'Asterisk et à la création du script bash, il faut configurer l'envoi de notifications par e-mail. Pour cela, nous allons utiliser l'outil postfix.
Configuration de postfix
Nous avons un domaine de messagerie « lucky.ru », situé chez Yandex. Nous allons configurer postfix en mode client smtp et envoyer des e-mails depuis le compte asterisk@lucky.ru.
La solution est basée sur celle-ci : .
Commencez par installer/mettre à jour/vérifier la disponibilité des paquets :
yum install postfix
yum install mailx
yum install cyrus-sasl cyrus-sasl-lib cyrus-sasl-plainNous ne vais pas écraser le fichier de configuration principal de postfix « /etc/postfix/main.cf », mais plutôt créer une sauvegarde :
cp /etc/postfix/main.cf /etc/postfix/main.cf.savModifiez le fichier « /etc/postfix/main.cf » pour qu'il prenne la forme suivante :
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
#####################Il n'est pas possible de commenter chaque ligne dans « /etc/postfix/main.cf ». Les commentaires dans certaines lignes ne sont pas reconnus par le parseur et sont donc transmis pour traitement, ce qui peut entraîner des erreurs. Il est préférable de se passer de commentaires dans ce fichier. Vous pouvez expérimenter avec cela en lançant dans une autre fenêtre « tail -f /var/log/messages ».
Je tiens à souligner la ligne « smtputf8_autodetect_classes = all ». Cet enregistrement active par défaut l'utf-8, ce qui permet d'utiliser le cyrillique à la fois dans le corps du message et dans le sujet sans manipulations supplémentaires (Voir. ).
Créons un répertoire pour les fichiers de configuration :
mkdir /etc/postfix/privateModifiez le fichier «/etc/postfix/private/sender_relay». Nous devons y spécifier le serveur SMTP auquel nous devons nous référer lors de l'utilisation de notre domaine de messagerie :
nano /etc/postfix/private/sender_relay
#####################
@lucky.ru smtp.yandex.ru
#####################Modifiez le fichier «/etc/postfix/private/sasl_passwd». Nous y indiquerons l'adresse e-mail que nous allons utiliser pour envoyer des messages, ainsi que le nom d'utilisateur et le mot de passe de ce compte (le nom d'utilisateur et le mot de passe sont séparés par deux-points) :
nano /etc/postfix/private/sasl_passwd
#####################
asterisk@lucky.ru asterisk@lucky.ru:password_asterisk
#####################Modifiez le fichier «/etc/postfix/generic». Nous y écrirons les règles de substitution de l'adresse d'expéditeur (voir. ):
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'adresse d'expédition d'origine dépend du contenu de «/etc/hosts» et de «/etc/hostname», ainsi que du nom d'utilisateur qui enverra le message. C'est-à-dire que, même si nous utilisons un client SMTP et envoyons des messages depuis asterisk@lucky.ru, Postfix insérera toujours «quelque chose de son côté» dans l'adresse de l'expéditeur, et cela doit être corrigé par les règles dans ce fichier de configuration.
Voici le contenu de mon fichier «/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
#####################Il est important que le serveur ait un domaine (une valeur après le point), car l'utilitaire mail «cherche» le nom de domaine dans «/etc/hosts», et s'il «ne le trouve pas» tout de suite, il continuera à le chercher pendant encore quelques minutes avant d'envoyer le message. Cela signifie que si le domaine n'est pas enregistré, le message sera retardé de plusieurs minutes.
Voici le contenu de mon fichier «/etc/hostname» :
cat /etc/hostname
#####################
asterisk
#####################Ensuite, il est nécessaire de convertir les fichiers de configuration créés en bases de données indexées, pour cela exécutons la commande suivante :
postmap /etc/postfix/generic && postmap /etc/postfix/private/{sasl_passwd,sender_relay}Ensuite, nous devons télécharger et placer sur le serveur le certificat smtp.yandex.ru, pour cela exécutons la commande suivante :
openssl s_client -starttls smtp -crlf -connect smtp.yandex.ru:25 > /etc/postfix/ca.pemMais après que les informations techniques s'affichent à l'écran, l'équipe continuera à « buguer ». Appuyez sur Ctrl+C pour l'interrompre.
Nous allons maintenant supprimer manuellement tous les déchets du fichier résultant et ne garder que le certificat. Cela devrait ressembler à quelque chose comme :
nano /etc/postfix/ca.pem
#####################
-----BEGIN CERTIFICATE-----
MIIGazCCBVOgAwIBAgIQcUU9mJXW4OUs5Gf0JfLtsjANBgkqhkiG9w0BAQsFADBf
...
nRG0DfdqYIuPGApFORYe
-----END CERTIFICATE-----
#####################Et enfin, redémarrons postfix :
service postfix restartNous envoyons un mail de test :
echo "Ceci est le corps du mail" | mail -s "Ceci est le sujet" admin@lucky.ruadmin@lucky.ru — l'adresse de destination
La configuration de postfix est terminée.
Écrivons un script bash
Créons un répertoire pour stocker le script bash (ici, où cela convient le mieux) :
mkdir /home/asterisk/scriptsCréons le fichier du script bash :
touch /home/asterisk/scripts/noanswer.shDonner les droits d'exécution au fichier script :
chmod +x /home/asterisk/scripts/noanswer.shS'il y a un doute sur les droits du fichier, on peut temporairement donner un accès complet au fichier pour le débogage. Mais ce n'est « pas sécurisé ».
chmod 777 /home/asterisk/scripts/noanswer.shLe texte du 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="concernant une question importante"
;;
63100)
address="debian@lucky.ru"
subject="pour des questions sur linux debian"
;;
63200)
address="windows@lucky.ru"
subject="pour des questions sur windows"
;;
63300)
address="freebsd@lucky.ru"
subject="pour des questions sur freebsd"
;;
63400)
address="ubuntu@lucky.ru"
subject="pour des questions sur linux ubuntu"
;;
63500)
address="centos@lucky.ru"
subject="pour des questions sur linux centos"
;;
*)
address="admin@lucky.ru"
error_kod=1
;;
esac
case $error_kod in
0)
echo "Appel manqué de l'abonné $2, appelant $subject." | mail -s "Appel manqué de $2" $address
echo "Appel manqué pour $address de l'abonné $2, appelant $subject. uid=$1" | mail -s "Appel manqué de $2" admin@lucky.ru
;;
1)
echo "Appel manqué de l'abonné $2. File inconnue. uid=$1" | mail -s "Appel manqué de $2" admin@lucky.ru
;;
esac
fi
#####################Petit aperçu du script :
"sleep 7" :
C'est le délai dont j'ai parlé plus tôt. Nous avons un délai de 7 secondes. Bien que, je pense qu'une seule seconde devrait suffire.
"res_sql="SELECT disposition FROM cdr WHERE uniqueid = '$1'" :Nous avons sorti la requête mysql dans une variable séparée pour plus de confort.
Ensuite, nous faisons une requête dans mysql et filtrons la sortie obtenue. Nous supprimons toutes les options sauf «ANSWERED», s'il y en a une. S'il y a plusieurs valeurs «ANSWERED», nous devons en garder qu'une seule. À la fin, la variable «answer» contiendra soit «ANSWERED», soit «».
Si la valeur de la variable «answer» n'est pas égale à «ANSWERED», alors cela signifie un appel manqué. En fonction du numéro de la file d'attente, nous utiliserons l'instruction case pour définir à qui exactement il est nécessaire d'envoyer une notification par e-mail, et ce que doit contenir ce message (partie modifiable du message).
Nous examinons maintenant le cas où la file d'attente est définie dans Asterisk, mais n'est pas décrite dans le script. Dans ce cas, admin@lucky.ru recevra un e-mail informant que la file d'attente n'est pas connue du script.
Si la file d'attente est décrite, un e-mail sera envoyé à la destination prévue et un e-mail en double sur admin@lucky.ru indiquant «uniqueid», afin de pouvoir suivre les événements à propos de cet appel si nécessaire.
Ceci conclut le script.
Je note que pour se connecter à mysql, nous avons utilisé un identifiant et un mot de passe que nous avons préalablement obtenus. Dans FreePBX, pour savoir quel est l'identifiant de l'utilisateur Asterisk dans mysql, exécutez la commande suivante :
cat /etc/amportal.conf | grep AMPDBUSEREt pour savoir quel est le mot de passe de l'utilisateur Asterisk dans mysql, exécutez la commande suivante :
cat /etc/amportal.conf | grep AMPDBPASSConfiguration d'Asterisk
Nous utilisons FreePBX. Dans FreePBX, il existe différents types de fichiers de configuration (voir ), certains d'entre eux sont réécrits par FreePBX lors du redémarrage, tandis que d'autres ne le sont pas (ils sont appelés custom), car ils sont spécialement destinés à l'utilisateur.
Nous allons travailler avec le fichier de configuration «extensions_override_freepbx.conf», car il appartient au type custom.
Pour commencer, assurons-nous que le fichier «/etc/asterisk/extensions.conf» inclut le fichier «extensions_override_freepbx.conf». Pour ce faire, exécutons la commande suivante :
cat /etc/asterisk/extensions.conf | grep extensions_override_freepbx.conf
#####################
#include extensions_override_freepbx.conf
#####################Modifions le fichier «/etc/asterisk/extensions_override_freepbx.conf» et apportons-lui les modifications suivantes :
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,)
#####################Comme je l'ai écrit précédemment, le symbole «&» à la fin est obligatoire. Étant donné que nous allons travailler dans un script bash avec les données CDR directement à partir de la base mysql, et que ces données sont enregistrées dans mysql uniquement après l'exécution de «exten => h,2,Macro(hangupcall,)», il est donc nécessaire de ne pas attendre la fin de l'exécution du script bash, mais de passer à l'étape suivante dans Asterisk. Le script bash lui-même doit contenir un délai avant d'exécuter sa partie principale.
Pour que les modifications apportées au fichier de configuration «/etc/asterisk/extensions_override_freepbx.conf» prennent effet, il est nécessaire de redémarrer le cœur d'Asterisk avec la commande suivante :
/usr/sbin/asterisk -rx "core restart now"Cela doit être fait après que le script bash a été créé.
Conclusion
C'est probablement le 1001ème moyen de « attraper les appels manqués » dans Asterisk. Partagez dans les commentaires comment vous résolvez cette tâche. Et que pensez-vous pourrait être amélioré / retravaillé / optimisé. Nous apprécierions les idées constructives.
Source : habr.com
