При пропущено вызове, абонент перезванивает и попадает на сотрудника который ему звонил.

Видя на экране мобильного телефона пропущенный вызов c городского номера у меня практически всегда складывается впечатление что вряд ли я дозвонюсь сотруднику который хотел меня слышать. С учетом, что все звонки попадают на секретаря или группу сотрудников. В лучшем случая я услышу IVR с названием компании и уже смогу представить что и кто меня хотел услышать. Для того что бы в компании где я сейчас работаю не было подобных ситуация я решил внедрить сценарий распределения вызовов на сотрудника который разговаривал или пытался поговорить с клиентом. На хабре меня на это натолкнул один сценарий . Но к нему мы еще вернемся.

Начнем.

Нам понадобиться таблица с полями (порядковый номер, номер на который звонит сотрудник, время, внутренний номер сотрудника)
Для начала создадим табличку с следующими полями (id, number, data, agent)

Ссылка на заготовку таблицы.
Как подключить Asterisk к Mysql.

Далее необходимо настроить запросы из Asterisk в MySql. Это можно сделать двумя способами. Первый все подключение вести в сценарии extension или же как мне больше понравилось задать переменные в файл func_odbc.conf.

; Записываем внутренний номер сотрудника и номер вызываемого абонента при совершении исходящего вызова
[SET_DATA_OUT] 
dsn=aster
write=INSERT INTO asterisk.table (number,data,agent) VALUES (${EXTEN},${EPOCH},${CALLERID(num)})

--------------------------------------------------
; читаем номер вызываемого абонента
[GET_DATA_OUT] 
dsn=aster
read=SELECT agent, data, number FROM asterisk.table WHERE number="${EXTEN}"

--------------------------------------------------
; проверка номера при входящем звонке
[GET_DATA_IN] 
dsn=aster
read=SELECT agent, data, number FROM asterisk.table WHERE number="${CALLERID(num)}"

--------------------------------------------------
; обновляем время в базе при повторном звонке или при входящем от клиента
[UPDATE_TIME_OUT] 
dsn=aster
write=UPDATE asterisk.table SET data=${EPOCH} WHERE number=${EXTEN}

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

[call-out]
exten = _8NXXXXXXXXX,1,Progress()
 same = n,Set(ARRAY(AGENT,DATA,NUMBER)=${ODBC_GET_DATA_OUT(${EXTEN})}")
 same = n,GotoIf($["${NUMBER}"!=""]?call:write)
 same = n(write),Set(ODBC_SET_DATA_OUT()="${CALLERID(num)}","${EPOCH}","${EXTEN}")
 same = n,Dial(SIP/провейдер/${EXTEN},60,tT)
 same = n,HangUp()
 same = n(call),Set(ODBC_UPDATE_TIME_OUT()=${EPOCH},${EXTEN})
 same = n,Dial(SIP/провейдер/${EXTEN},60,tT)
 same = n,HangUp()

write - записываем в базу.
call - если уже есть запись в базе мы обновляем ее.

А теперь пока заняться входящими звонками.

[call-in]
exten => _X.,1,Answer()
exten => _X.,n,Set(ARRAY(AGENT,DATA,NUMBER)=${ODBC_GET_DATA_IN(${CALLERID(num)})}")
exten => _X.,n,GotoIf($["${NUMBER}"!=""]?next)
exten => _X.,n,BackGround(/var/lib/asterisk/sounds/ivr/privet)
exten => _X.,n,Goto(call_office,s,1)
exten => _X.,n(next),Set(DATERESULT=${MATH(${EPOCH}-${DATA},i)})
exten => _X.,n,n,GotoIf($[${DATERESULT} < 18000]?dialagent:dialexten)
exten => _X.,n(dialagent),Goto(call_agent,s,1)
exten => _X.,n(dialexten),Goto(call_office,s,1)

[call_agent]
exten => s,1,Dial(SIP/${AGENT},60,tTm(hold))
exten => s,2,Goto(call_office,s,1)
exten => h,1,Set(ODBC_UPDATE_TIME_OUT()=${EPOCH},${EXTEN})

[call_office]
exten => s,1,Queue(office,tT,,,120)   
exten => s,n,HangUp() 

Можно добривать IVR который будет перед соединением клиента с сотрудником будет спрашивать хочет ли он этого, просто если клиент общается с несколькими сотрудниками данный способ будет не очень хорош, потому что безусловно клиент будут попадать на одного сотрудника.

Так же я не стал заморачиваться с очисткой базы при помощи запросов из сценария. Я просто по cron-у делаю очистку базы раз в сутки.
По умолчанию я выставил соединение клиента с сотрудником в течении 5 часов, после этого времени клиент будет попадать в общую очередь.

Oleg 2016/06/26 11:49