Asterisk and sending missed in Telegram / Slack / E-mail

There is a call center. There is Asterisk / FreePBX with configured queues. There are agents who should service calls. But there are so many potential customers, and there are so few agents that the first can not get through to the second in any way - hang-hang in line for a minute, and even turn off.

But for some reason they called! Maybe they want to bring money to the company? Let's try to return both customers and their money using the FreePBX example.

In the queue settings, you can specify Fail Over Destination - where to send the call when the queue is full, the timeout period has elapsed, etc. But it often happens that the caller disconnects before he can be redirected to Fail Over Destination - you never know, the connection is disconnected. There is no ready-made solution for such cases. Therefore, we go under the cut and write our own - with sending an alert to Telegram / Slack / E-mail / somewhere else there.

And the first thing we need to understand is how FreePBX writes queue logs. In the simplest case, this is the text file / var / log / asterisk / queue_log.

So, a regular call is written to the log from the subscriber 8964467XXXXX, who called 302221XXXX, who is in line No. 603 to the first position, which Agent Girl answered 8 seconds later. They talked 133 seconds and the subscriber was the first to hang up - everyone would have such polite managers!

1584318765|1584318747.89449|603|NONE|DID|302221
1584318765|1584318747.89449|603|NONE|ENTERQUEUE||8964467|1
1584318774|1584318747.89449|603|Agent Girl|CONNECT|9|1584318765.89450|8
1584318907|1584318747.89449|603|Agent Girl|COMPLETECALLER|9|133|1

And here is a slightly different story when a subscriber 8996453XXXXX phoned 302257XXXXX, hung 10 seconds in line No. 210 in the first position and disconnected. I didn’t even listen to the voice menu!

1581728710|1581728690.59367|210|NONE|DID|302257
1581728710|1581728690.59367|210|NONE|ENTERQUEUE||8996453|1
1581728720|1581728690.59367|210|NONE|ABANDON|1|1|10

That's about him, we will write in the messenger.

To do this, we need to catch the occurrence of the ABANDON event in the log file. I puzzled for a long time how this can be done, but then quite by chance I came across a wonderful tool - MONIT . In our case, it will monitor the queue log, and as soon as the line “ABANDON” appears in it, it will call the script for processing this event.

To do this, after installing the package:

yum install monit

Set it up - create the file /etc/monit.d/queue_log and write just three lines into it:

check file queue_log with path /var/log/asterisk/queue_log
    if content = "ABANDON" then
        exec "/var/lib/asterisk/agi-bin/qlogevent.sh $EVENT"

Thus, when the word “ABANDON” appears in the queue log, which tells us to prematurely disconnect the subscriber, the /var/lib/asterisk/agi-bin/qlogevent.sh script with the $ EVENT parameter will be called, which is nothing other than completely the line in which this word appeared.
It's simple.

And now it’s not chess that starts - you need to think about it.

The line passed to the script does not contain information about the number of the caller:

1581728720|1581728690.59367|210|NONE|ABANDON|1|1|10

It has only Timestamp (1581728720), a unique call ID (1581728690.59367), a queue number (210), the event itself and a few other non-essential parameters. Those. We will have to search for the subscriber number ourselves. And in what way? And it’s very simple, because we have a UID of a call!

Let us again turn to the log of this call, specifically, to the line in which the subscriber falls into the queue:

1581728710|1581728690.59367|210|NONE|ENTERQUEUE||8996453|1

When the “ENTERQUEUE” event occurs, one of the parameters is the subscriber number we need. We can only find this line in the queue_log file. This is exactly what the bash script is doing, which MONIT carefully called for us:

#!/bin/bash
#MONIT_DESCRITION - ,      .
# timestamp    - ( №1).
timedate=$(echo $MONIT_DESCRIPTION | cut -d\| -f1 | cut -d\: -f2 | gawk '{print strftime("%d.%m.%Y %H:%M:%S",$0);}')
# UID ( №2)
call_id=$(echo $MONIT_DESCRIPTION | cut -d\| -f2)
#   ( №3)
qnum=$(echo $MONIT_DESCRIPTION | cut -d\| -f3)

#      
case $qnum in
    210)
        qname=" 1"
        ;;
    220)
        qname=" 2"
        ;;
esac

#      UID,     ENTERQUEUE
str=$(grep "|$call_id|$qnum|.*|ENTERQUEUE" /var/log/asterisk/queue_log)
#      ( №7)
caller_id=$(echo $str | cut -d\| -f7)
#     ( №1)
time_enter=$(echo $str | cut -d\| -f1)
#     ( №1   ABANDON)
time_abandon=$(echo $MONIT_DESCRIPTION | cut -d\| -f1 | cut -d\: -f2)
# 
data=" $caller_id $timedate   $qname,       $(($time_abandon-$time_enter)) ."
#    /.     Slack.
/usr/bin/curl -X POST -H 'Content-type: application/json' --data '{"text":"'"$data"'"}' "https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

Actually, that's all!

True, there is one incident - MONIT, designed to monitor everything and everything; it itself needs monitoring, because periodically falls.

All Articles