Asterisk — запись исходящих звонков.

Задача: Записывать исходящие звонки от некоторого подмножества абонентов корпоративной телефонной сети.

Что есть в наличии: Asterisk 1.4* — вот с ним то и будем плясать..

Решение:  Список жертв будет храниться в бд, в моем случае это MySQL, для этого сварганим не хитрую табличку:

CREATE TABLE `asterisk`.`callout` (
`id` INT(3) NOT NULL AUTO_INCREMENT,
`callerid` INT(4) NOT NULL,
`status` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
)
ENGINE = MyISAM;

Поясню: Поле  callerid — будет хронить 4х значный номер внутреннего абонента. status — просто флаг который позволит нам например временно исключать номер из списка записывающихся..

Далее давайте напишим AGI скрипт, который будет пробивать переданный ему в качестве аргумента callerid и если таковой там имеется, то вновь созданный канал будет записан.

Пример скрипта:

#!/usr/bin/env python
'''
Created on 26.05.2011

@author: valor
'''

import MySQLdb
from asterisk.agi import AGI
import sys

class calloutrec:

DBHOST = "localhost"
DBUSER = "agi"
DBPASS = "asterisk"
DBNAME = "asterisk"

DEBUG = 3

agi = AGI()

def db_init(self):
connect = MySQLdb.connect(db=self.DBNAME, host=self.DBHOST, user=self.DBUSER, passwd=self.DBPASS)
return connect

def main(self,arg):

    self.agi.verbose(">>> start executing AGI script ", self.DEBUG)

    cursor = self.db_init().cursor()
    cursor.execute('''SELECT c.callerid FROM callout c WHERE c.status = 1 AND c.callerid =%s''',arg)
    res = cursor.fetchone()
    if res != None:
        self.agi.set_variable("ISREC", 1)
    else:
        self.agi.set_variable("ISREC", 0)

if __name__ == '__main__':
app = calloutrec()
app.main(sys.argv[1])

В основе скрипта лежит мини фреймворк pyst , один из немногих еще не здохших проектов — рекомендую, жизнь облегчит.

Теперь осталось подправить extensions.conf , для начала создадим макрос следующего содержания

[macro-calloutrec]
exten => s,1,AGI(callaoutrec.py,${ARG1})
exten => s,n,NoOp(${ISREC})
exten => s,n,GotoIF($["${ISREC}" = "1"]?rec:norec)
exten => s,n(rec),MixMonitor(/raid/outmonitor/${EPOCH}-${CALLERID(num)}.wav)
exten => s,n(norec),NoOp(${CALLERID(num)} >>> No record call)

Вот такой вот нехитрый макрос принимает в качестве аргумента callerid абонента осуществляющего исходящий звонок, далее передает его как аргумент agi скрипту и на основе возвращенного результата решает писать его или нет.

Осталось применить макрос в контексте через который идут исходящие звонки. примерно так:

exten => _XXXXXX.,n,Macro(calloutrec,${CALLERID(num)})

Вот и все.. записанные файлики в формате wav будут складываться в директорию  /raid/outmonitor/ с именем фала вида utc-callerid.wav .

ЗЫ. Для сортировки полученных фалов можно использовать скрипт из предыдущей статьи.

  1. А вам не кажется, что строка:
    exten => s,n(rec),MixMonitor(/raid/outmonitor/${EPOCH}-${CALLERID(num)}.wav)
    в макросе будет выполнятся в любом случае? Не важно равно ${ISREC} единице или нет?
    Не надо ли между последними двумя строками макроса поставить Hangup?

  2. Нет не кажется.. Более того я не понимаю зачем делать разрыв канала..

    ЗЫ. Данный пример активно используется и работает на ура..

  3. Ради достижения истины, хочется, все-таки, выяснить.
    Вот цитата из описания приложения GotoIf:

    Любое из мест назначения может быть опущено, но не оба одновремен-
    но.  Если  согласно  вычислениям  переход  должен  осуществляться  по
    месту назначения, которое не задано, Asterisk просто переходит к сле-
    дующему приоритету текущего добавочного номера.

    Получается, что место назначения, при ${ISREC} не равном единице, не задано. Следовательно курсор перейдет к следующему приоритету, который начнет запись.

  4. Да да да.. Прошу прощения, мой косяк.. У себя в конфиге поправил, а в статью изменения не внес.. Спасибо за замечание..

Оставить комментарий


Примечание - Вы можете использовать эти HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>