Представим себе сферический колцентр в вакууме, есть голосовое меню и прочие навороты и есть абонент (то же в вакууме) звонящий в этот самый колцентр который пытается куда-то там и зачем-то там дозвониться, внезапно ему наскучивает слушать говор синтетического человека и абонент кладет трубку..
А теперь представим, что колцентр обслуживает абонентов некого оператора связи где каждый абонент на счету и администрация люто печется о качестве сервиса и желает перезвонить не терпеливому абоненту и спросить, что тот хотел.
Замутим логирование кодов закрытия канала связи..
Что есть : Asterisk 1.4 , Python 2.5 , MySQL 5.1
Создадим табличку для MySQL в которую и будем складывать высеры Астериска.
Будем сохранять:
callerid – собственно номер звонившего
date_stamp – timestamp обрыва канала (HANGUP,CANCEL, etc..)
cause – код причины
status и comment – зело не обязательно, статус записи (типа обслужено или нет) и комментарий
`id` INT(11) NOT NULL AUTO_INCREMENT,
`callerid` VARCHAR(11) DEFAULT NULL,
`date_stamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`cause` VARCHAR(15) DEFAULT NULL,
`status` tinyint(1) DEFAULT '0',
`comment` text,
PRIMARY KEY (`id`),
KEY `call_index` (`callerid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
Теперь сварганим махонький python agi скрипт который непосредственно сохранять данный в базу..
'''
Created on 05.08.2011
@author: valor
'''
import MySQLdb
import sys
class CallFailLog:
DBHOST = "192.168.158.160"
DBUSER = "agi"
DBPASS = "asterisk"
DBNAME = "asterisk"
def __init__(self):
pass
def db_init(self):
connect = MySQLdb.connect(db=self.DBNAME, host=self.DBHOST, user=self.DBUSER, passwd=self.DBPASS)
return connect
def main(self,callerid, datestamp, cause):
sql = '''INSERT INTO call_fail_log (`callerid`,`date_stamp`,`cause`) VALUES(%s,FROM_UNIXTIME(%s),%s)'''
cursor = self.db_init().cursor()
cursor.executemany(sql,[(callerid,datestamp,cause)])
self.db_init().close()
if __name__ == '__main__':
app = CallFailLog()
app.main(sys.argv[1], sys.argv[2], sys.argv[3])
Как видим все просто и легко..
Теперь лезем в extensions.conf и сделаем макрос обработки кодов + посмотрим откель его можно вызвать..
Собственно макрос:
exten => s,1,GotoIF($["${ARG1}" = "16"]?goin:end)
exten => s,n(goin),DeadAGI(callfaillog.py,${CALLERID(num)},${EPOCH},${ARG1})
exten => s,n(end),NoOp(>>> Unknown cause ${ARG1})
exten => s,n,Hangup()
Код завершения 16 NORMAL_CLEARING – есть не что иное как положенная абонентом трубка.
Вызвать его можно в любом контексте, например так..
exten => h,1,Macro(logfailcall,${HANGUPCAUSE})
...
a: Вызывается, когда пользователь нажимает ‘*’ во время проигрывания приветствия системы голосовой почты.
h: Вызывается, по завершению вызова.
i: Вызывается, при попытке вызова неизвестного екстеншена.
o: Расширение оператора, используется для обработки нажатия нуля в системе голосовой почты.
s: Стартовое расширение в контексте.
t: Вызывается, при наступлении состояния таймаута.
T: Вызывается, при наступлении состояния абсолютного таймаута, заданного функцией AbsolutTimeout?.
e: Перехват расширений i,t и T для обработки ошибки в едином месте. Для выяснения типа ошибки может быть использована функция EXCEPTION(?)
failed: Используется, если auto-dial out вызов завершился неудачно (который имеет определённый контекст, приоритет и расширение).
fax: Используется для определения факса на Zap каналах.
talk: Используется в конъюнкции с BackgroundDetect?.
Полезные ссылки : Коды причин закрытия канала
Удачи..



