IP ATC Asterisk is a powerful IP telephony processor. And the FreePBX web-interface, created for Asterisk, greatly simplifies configuration and lowers the threshold for logging into the system.
If you can come up with some kind of task related to IP-telephony, then almost certainly it can be implemented in Asterisk. But be sure that you will need perseverance and endurance.
We faced the task of setting up e-mail notifications of missed calls. More precisely, to notify via e-mail of those cases when an incoming call has been queued, but no one (from the agents) has answered this incoming call.
Surprisingly, we did not find any regular tools to solve this problem in FreePBX. Iâll talk about how we solved this problem under the cut.
Foreword
Before solving the problem âhead-onâ, we certainly searched for information on the Internet, but did not find turnkey solutions (maybe they were looking poorly, but what can you do ...).
There are not as many work skills directly in Asterisk as we would like, so the solution offered
here was not fully understood and was discarded.
I liked the solution proposed
here , although it did not work. From here it was emphasized that work in Asterisk is necessary in the context of queues [ext-queues]. And since we work in Freepbx, we need to work in the configuration file âextensions_override_freepbx.confâ. We noticed that it is convenient to âcatch missed callsâ before the hangupcall event (end of a call).
After reading the discussion
here , the idea came up that we need to filter the âDispositionâ variable in the CDR for all agents in the queue. And after reading
this information, quite specific steps have been taken to solve the problem.
What do we have:
There is FreePBX 13.0.197 that uses Asterisk 13.12.1. OS version SHMZ release 6.6 (Final). The distribution is based on CentOS.
Asterisk is configured with IVR (voice menu) scattering incoming calls into different Queues (queues). Agents (agents) are assigned to each queue, i.e., agents.
Theory
What is going on at Asterisk
When an incoming call arrives at Asterisk, that call goes to IVR. The caller makes a choice by pressing a specific number on the phone, and falls into a specific queue. After that, all free agents of the queue simultaneously receive a call.
In order to better understand what is happening at this moment and what happens next, turn to Report CDR (Fig. 1).
Fig. 1
When an incoming call fell into the queue, for all agents, the value of the variable "Disposition" became equal to "NO ANSWER" if the agents were not busy at that moment. The variable "Disposition" could take other values ââ(see
https://asterisk-pbx.ru/wiki/asterisk/cf/cdr ), except for the value "ANSWERED". And at the moment when one of the agents answers an incoming call, the value of the âDispositionâ variable of this agent becomes equal to âANSWEREDâ.
From the Report CDR, you can notice that when the call is queued (in the App column, the value becomes âQueueâ), then all events appear with the same âuniqueidâ (System column).
CDR in brief
It is important to understand what a CDR is, and at what point in the CDR the data that we observe in the Report CDR is entered. The CDR, relative to the operating system, is the database into which Asterisk writes a detailed call report (see
https://asterisk-pbx.ru/wiki/asterisk/cf/cdr ). In our case, this is a database called asteriskcdrdb, which is located in mysql. Empirically, we found that data about a call with a certain âuniqueidâ is not entered into asteriskcdrdb immediately after the occurrence of any event, but after the hangupcall event (end of the call).
The principle of the created solution
Since we have more knowledge in bash than knowledge in Asterisk, the main idea is as follows. Before the hangupcall event, invoke the bash script. Pass 3 parameters to this script. The first parameter is âuniqueidâ, to filter data received from the CDR. The second parameter is âCALLERID (num)â (the number of the caller) to know who to call back. The third parameter is âNODESTâ (queue number), to which the call arrived, in order to know on what issue there was a call, and to whom to send an e-mail notification of a missed call.
The bash script should connect to the asteriskcdrdb database in mysql and take all the values ââof the "Disposition" variable with a specific "uniqueid". From the obtained data, it is necessary to exclude the values: âNO ANSWERâ, âBUSYâ, âFAILEDâ, âUNKNOWNâ. As a result, either âANSWEREDâ will remain - they answered the incoming call, or nothing at all - the missed call.
Further, if the call was missed, the script should send an e-mail notification.
Looking ahead, I note an important point. Asterisk executes the commands sequentially, waiting for their execution (which is generally logical). And we will call the bash script before the hangupcall command is executed. Thus, at the moment the script is directly executed, the information about the âuniqueidâ we are looking for will not be entered into the CDR yet. To solve this problem, we will call the bash script with the â&â parameter so that Asterisk immediately proceeds to the next step, that is, hangupcall. And inside the bash script, at the very beginning, we will set a small time delay to give time for Asterisk to enter the data with the âuniqueidâ of interest to us in the CDR.
Practice
Before proceeding to configure Asterisk and create a bash script, you need to configure the sending of e-mail notifications. For this, we will use the postfix utility.
Postfix setup
We have a mail domain "lucky.ru" located in Yandex. We will configure postfix in smtp-client mode and will send letters from the asterisk@lucky.ru account.
The solution is taken from here:
https://www.dmosk.ru/miniinstruktions.php?mini=postfix-over-yandex .
First install / update / check for packages:
yum install postfix yum install mailx yum install cyrus-sasl cyrus-sasl-lib cyrus-sasl-plain
We will not overwrite the main postfix configuration file â/etc/postfix/main.cfâ, but back it up:
cp /etc/postfix/main.cf /etc/postfix/main.cf.sav
We edit the file â/etc/postfix/main.cfâ and bring it to the following form:
nano /etc/postfix/main.cf
Not every line in "/etc/postfix/main.cf" can be commented on. Comments in some lines are not determined by the parser and are passed to processing, and this leads to errors. It is better to refuse comments inside this file. You can experiment with this by running âtail -f / var / log / messagesâ in the next window.
Iâll mark the line âsmtputf8_autodetect_classes = allâ. This entry includes utf-8 by default, which allows you to use the Cyrillic alphabet both in the body of the message and in the subject line without additional manipulations (See
http://www.postfix.org/SMTPUTF8_README.html ).
Create a directory for the configuration files:
mkdir /etc/postfix/private
We edit the file "/ etc / postfix / private / sender_relay". In it, you need to specify which smtp server you need to refer to when using our mail domain:
nano /etc/postfix/private/sender_relay
We edit the file "/ etc / postfix / private / sasl_passwd". In it we will indicate the e-mail address that we will use to send letters, as well as the username and password for this account (we specify the username and password through a colon):
nano /etc/postfix/private/sasl_passwd
Editing the file / etc / postfix / generic. In it we will write down the rules for replacing the outgoing address (see
https://wiki.merionet.ru/ip-telephoniya/30/postfix-nastrojka-otpravki-pochty-v-asterisk/ ):
nano /etc/postfix/generic
The initial outgoing address depends on the contents of â/ etc / hostsâ and â/ etc / hostnameâ, as well as on the name of the user who will send the letter. That is, despite the fact that we use the smtp client and send letters from asterisk@lucky.ru, all the same, the postfix sender will initially substitute âsomething of his ownâ and this should be corrected with the rules from this configuration file.
Here is the contents of my / etc / hosts file:
cat /etc/hosts
It is important that the server has any domain (the value after the period), because the mail utility âlooks forâ the domain name in â/ etc / hostsâ and if it does not âfindâ it immediately, it will continue to do this for several more minutes and only then send a letter. That is, if the domain is not registered, then the letter will leave with a delay of several minutes.
I will list the contents of my â/ etc / hostnameâ file:
cat /etc/hostname
Next, you need to transfer the created configuration files to indexed databases, to do this, run the following command:
postmap /etc/postfix/generic && postmap /etc/postfix/private/{sasl_passwd,sender_relay}
Next, we need to download and place the smtp.yandex.ru certificate on the server, for this we execute the following command:
openssl s_client -starttls smtp -crlf -connect smtp.yandex.ru:25 > /etc/postfix/ca.pem
But after the technical information appears on the screen, the team will "continue to hang." Press Ctrl + C to abort it.
Now manually delete all the garbage from the resulting file and leave only the certificate. You should get something like this:
nano /etc/postfix/ca.pem
Finally, restart postfix:
service postfix restart
We send a test letter:
echo " " | mail -s " " admin@lucky.ru
admin@lucky.ru - destination address
This completes the posfix configuration.
Writing a bash script
Create a directory for storing a bash script (here someone likes it where):
mkdir /home/asterisk/scripts
Create a bash script file:
touch /home/asterisk/scripts/noanswer.sh
Give the script file the right to execute:
chmod +x /home/asterisk/scripts/noanswer.sh
If there are doubts about the rights to the file, then during debugging you can give full access to the file. But it is "not safe."
chmod 777 /home/asterisk/scripts/noanswer.sh
The text of the bash script:
nano /home/asterisk/scripts/noanswer.sh
A brief analysis of the script:
"Sleep 7":
This is the same time delay that I wrote about earlier. We have a delay of 7 seconds. Although, I think, one second is quite enough.
«res_sql="SELECT disposition FROM cdr WHERE uniqueid = '$1'"»:
The query in mysql we put into a separate variable for convenience.
Next, we make a request in mysql and filter the resulting output. We remove all options except "ANSWERED", if any. If there are several âANSWEREDâ values, then only one should be left. At the end, in the variable âanswerâ we get either âANSWEREDâ or ââ.
If the value of the variable âanswerâ is not equal to âANSWEREDâ, then this is a missed call. Depending on the queue number, using the case operator we will set the address to whom it is necessary to send an e-mail notification, and what to write in this message (variable part of the message).
The following is an option when the queue is set in Asterisk, but not described in the script. In this case, admin@lucky.ru will receive a letter stating that the queue is not known to the script.
If the queue is described, then a letter of destination and a duplicate letter will be sent to admin@lucky.ru indicating âuniqueidâ, so that you can track events on this call, if necessary.
This ends the script.
I note that to connect to mysql we used the username and password, which we recognized in advance. In FreePBX, in order to find out the Asterisk user login in mysql, run the following command:
cat /etc/amportal.conf | grep AMPDBUSER
And in order to find out the password of the Asterisk user in mysql, run the following command:
cat /etc/amportal.conf | grep AMPDBPASS
Configure Asterisk
We use FreePBX. FreePBX has different types of configuration files (see
https://asterisk-pbx.ru/wiki/freepbx/files ), some of them are overwritten by FreePBX upon reboot, and some are not overwritten (they are called custom), as they are specially designed for the user.
We will work with the configuration file âextensions_override_freepbx.confâ, since it is of type custom.
First, make sure that the file âextensions_override_freepbx.confâ is connected in the file â/etc/asterisk/extensions.confâ. To do this, run the following command:
cat /etc/asterisk/extensions.conf | grep extensions_override_freepbx.conf
We edit the file â/etc/asterisk/extensions_override_freepbx.confâ and bring it to the following form:
nano /etc/asterisk/extensions_override_freepbx.conf
As I wrote earlier, the â&â symbol at the end is required. Since we will work in a bash script with CDR data directly from the mysql database, and this data is entered into mysql only after executing âexten => h, 2, Macro (hangupcall,)â, we need not to wait for the completion of the bash script , and proceed to the next step in Asterisk. And the bash script itself must contain a time delay before executing its main part.
In order for the changes in the configuration file â/etc/asterisk/extensions_override_freepbx.confâ to take effect, you need to restart the Asterisk kernel with the following command:
/usr/sbin/asterisk -rx "core restart now"
This needs to be done after the bash script has been created.
Conclusion
This is probably the 1001st way to âcatch missed callsâ in Asterisk. Share in the comments how you solve this problem. And what, in your opinion, can be improved / redone / optimized. We will be grateful for the constructive ideas.