如何从 Asterisk 的 CDR 表(mysql)中提取未应答的呼叫?
Posted
技术标签:
【中文标题】如何从 Asterisk 的 CDR 表(mysql)中提取未应答的呼叫?【英文标题】:How to extract unanswered calls from Asterisk's CDR table (mysql)? 【发布时间】:2012-02-06 13:33:47 【问题描述】:我正在尝试制作一个网页,其中列出来自 CDR 的未应答呼叫。在来电时,所有软电话和一些手机同时响铃。 Asterisk 版本是 1.8.5。
以下是单个 ANSWERED 调用写入 CDR 表的内容:
╔═════════════════════╦══════╦═════════␦═══ ═════════╦═══════════════════════════╦════════════ ═══════════════╦═════════╦═══════════════════════╦ ══════════╦═════════╦═════════════╦══════════╦════ ═════════╦═══════════╦════════════════╦══════════╗ ║ calldate ║ clid ║ src ║ dst ║ dcontext ║ channel ║ dstchannel ║ lastapp ║ lastdata ║ 持续时间 ║ billsec ║ disposition ║ amaflags ║ accountcode ║ userfield ║ uniqueid ║ imported ║ ╠═════════════════════╬══════╬═════════╬═════╬════ ══════╬═══════════════════════════╬═══════════════ ════════════╬═════════╬═══════════════════════╬═══ ═══════╬═════════╬═════════════╬══════════╬═══════ ══════╬═══════════╬════════════════╬═══════════════ ║ 2012-02-06 12:40:45 ║ ║ 5020971 ║ 595 ║ 外出 ║ 本地/595@OUTGOING-5d9a;2 ║ SIP/help.desk-000000b8 ║ 拨号 ║ SIP/help.desk/595,,Tt ║ 8 ║ 0 ║ 已回答 ║ 3 ║ ║ ║ 1328524845.301 ║ 0 ║ ║ 2012-02-06 12:40:45 ║ ║ 5020971 ║ 599 ║ 外出 ║ 本地/599@OUTGOING-038b;2 ║ SIP/help.desk-000000b9 ║ 拨号 ║ SIP/help.desk/599,,Tt ║ 8 ║ 0 ║ 没有答案 ║ 3 ║ ║ ║ 1328524845.303 ║ 1 ║ ║ 2012-02-06 12:40:44 ║ ║ 5020971 ║ s ║ to_tech ║ SIP/help.desk-000000b6 ║ 本地/595@OUTGOING-5d9a;1 ║ 队列 ║ TECH,Tt,,,300 ║ 111 ║ 1 ║ 已回答║ 3 ║ ║ ║ 1328524844.298 ║ 0 ║ ╚═════════════════════╩══════╩═════════╩═════╩════ ══════╩═══════════════════════════╩═══════════════ ════════════╩═════════╩═══════════════════════╩═══ ═══════╩═════════╩═════════════╩══════════╩═══════ ══════╩═══════════╩════════════════╩══════════════════ >获取未接电话的 SQL 如下:
SELECT * FROM cdr WHERE disposition = 'NO ANSWER' AND imported='0'
不用说,我在实际接听的电话中得到了误报。 :-)我看到的唯一链接是 NO ANSWER 和 ANSWERED 行之间的时间间隔很短(并且它们共享相同的 src 号)。
现在,在我开始检查是否有来自同一号码的一些已接听电话且时间间隔很近(例如 3 秒)之前,我想知道是否有人知道解决此问题的更好方法。
我在 extensions.conf 中说得不是很流利,实际上制定我们的拨号方案的人早已不在,但我在 extensions.conf 中注意到了这一点:
[class1] exten => s,n,SET(CDR(accountcode)=$UNIQUEID) 包括 => 帐户 包括 => 传出
如果我明白这一点,那么扩展行应该将 CDR 表中的 accountcode 字段设置为传入呼叫的唯一 ID 的值吗?无论如何,它不起作用,因为帐户代码字段从未填写在表格中。
【问题讨论】:
【参考方案1】:如果我正确读取了该输出,则似乎来电并已放入队列,然后 Queue() 应用程序将呼叫转移到未接听的代理 (599),因此当时呼叫转移到另一个座席 (595),然后他接听了电话。
此外,似乎每次调用由 Queue() 应用程序处理时,都会被赋予一个新的调用 id,因此很难跟踪。
对于队列的这个特定问题,我的建议是使用可以与 SQL 集成的 QueueLog 功能。然后,您可以在 QueueLog 表中跟踪调用,并在 QueueLog SQL 表中跟踪和传输每个步骤。
然后就可以构造一个 SQL 查询来将 QueueLog 表与 cdr 表连接起来,以查看哪些独特的呼叫未被应答,而不是像您目前的情况那样。
编辑:
可在以下位置找到分步说明:http://www.voip-info.org/wiki/view/Asterisk+queue_log+on+mysql。然后将队列事件插入到一个表中,如下所示:
mysql> select * from queue_log;
+----+------------+--------------+------------------+-------+------------+-------+
| id | time | callid | queuename | agent | event | data |
+----+------------+--------------+------------------+-------+------------+-------+
| 1 | 1198356717 | 1198356717.0 | voipsolutions.ru | NONE | ENTERQUEUE | |serg |
| 2 | 1198356719 | 1198356717.0 | voipsolutions.ru | NONE | ABANDON | 1|1|2 |
+----+------------+--------------+------------------+-------+------------+-------+
然后您可以使用此表跟踪队列活动。
希望有所帮助。
【讨论】:
来电时,所有电话同时响铃,直到有人接听或来电者挂断。在此期间,来电者会听到保留的音乐。每 30 秒后,Asterisk 将向呼叫者宣布一条预先录制的消息。在此期间,没有电话响起。宣布后,所有电话再次响起。 如果您可以通过如何实际完成此操作的步骤扩展您的答案,我们将不胜感激。【参考方案2】:上午 00:01 通过电子邮件查询报告)
<?php
/* Переменные для соединения с базой данных */
$hostname = "localhost";
$username = "asteriskcdruser";
$password = "asteriskcdrpass";
$dbName = "asteriskcdrdb";
/* Таблица MySQL, в которой хранятся данные */
$cdrtable = "cdr";
/* Переменные для определения вчерашней даты */
$time = mktime(date('H'), date('i'), date('s'), date('m'), date('d')-1, date('Y'));
$ydate = date("d.m.Y", $time);
/* создать соединение */
mysql_connect($hostname,$username,$password) OR DIE("Не могу создать соединение ");
/* выбрать базу данных. Если произойдет ошибка - вывести ее */
mysql_select_db($dbName) or die(mysql_error());
/* запрос данных . номерация у нас трехзначная, поэтому LENGTH( `src` ) >3, отсекаем исходящие вызовы */
$query = "SELECT `dst` , `src` , `duration` , `dstchannel` , `calldate`
FROM `cdr`
WHERE DATE_SUB( CURDATE( ) , INTERVAL 1 DAY ) <= `calldate`
AND CURDATE( ) > `calldate`
AND `disposition` = 'NO ANSWER'
AND LENGTH( `src` ) >3";
/* Выполнить запрос. Если произойдет ошибка - вывести ее. */
$res=mysql_query($query) or die(mysql_error());
/* Как много нашлось строк */
$number = mysql_num_rows($res);
/* заголовок письма */
$mes="Отчет о пропущенных вызовах за $ydate.\r\n\r\n";
/* готовим текст письма*/
if ($number == 0)
$mes .= "Пропущенных вызовов не было";
else
/* Получать по одной строке из таблицы в массив $row, пока строки не кончатся */
while ($row=mysql_fetch_array($res))
$mes .= " ".$row['calldate'].". От ".$row['src'];
$mes .= " Абонент ".mb_substr($row['dstchannel'],4,3);
$mes .= ". Ожидание ".$row['duration']." сек.\r\n";
/* Отправляем письмо */
mail('name@domain.com.ua', $ydate.' Missed calls report', $mes);
echo "Отчеты были отправлены на почту...";
?>
【讨论】:
【参考方案3】:只有未接来电使用mysql请求:
SELECT `src`,`dst` , `duration` , `dstchannel` , `calldate`
FROM `cdr`
WHERE DATE_SUB( CURDATE( ) , INTERVAL 1 DAY ) <= `calldate`
AND CURDATE( ) > `calldate`
AND `disposition` = 'NO ANSWER'
AND LENGTH( `dst` ) <4 AND LENGTH( `src` ) >3 ;
【讨论】:
以上是关于如何从 Asterisk 的 CDR 表(mysql)中提取未应答的呼叫?的主要内容,如果未能解决你的问题,请参考以下文章