28.10.2015

Transfer

Взято у IGORG, чтоб не забыть.
Оригинал


Самой важной задачей, которую выполняет АТС предприятия — принять звонок, передать необходимому сотруднику и совершить обмен информацией. Совершенно неприемлемой ситуацией является, когда звонок по какой-либо причине теряется. Лояльности это уж точно не добавит.
Одной из важнейших функций PBX является функция перевода вызова, которая, к сожалению в Asterisk работает не так, как, скажем, в традиционном для российского офиса Panasonic. В этом я убедился устанавливая Asterisk в компании на 60 человек, в которой эта функция была критична, но не работала как надо ни на адаптерах, ни на Asterisk. Решилось тогда административными мерами: человек, переводящий звонок, должен был дождаться ответа третьей стороны. Но это не решение, решение далее.
В версии 1.6 усилиями разработчиков появилась функция, позволяющая возвращать вызов сотруднику, делавшему перевод вызова, если на другой стороне вызов принят не был. При этом при возврате вызова Asterisk может сделать несколько вызовов, ведь он может уже быть занят новым разговором. Вот опции, отвечающие за работу:
  • atxferdropcall. Допустим кто-либо осуществляет перевод вызова с согласованием и ложит трубку до того как вызов соединён. Если выбрано значение «yes», то используется старое поведение — при невозможности соединить позвонившего вызов сбрасывается. Если выбрано «no», то система вернёт вызов обратно осуществлявшему transfer.
  • atxfernoanswertimeout. Таймаут, в течении которого система пытается соединиться со третей стороной. По-молчанию 15 секунд.
  • atxferloopdelay. Задержка перед повторным возвратом вызова делавшему transfer сотруднику.
  • atxfercallbackretries. Количество попыток возврата вызова, по-умолчанию 2.
Оказывается можно сделать аналогичным образом и в 1.4 с помощью только функций и переменных диал-плана. Вот пример extensions.conf:
  1. [globals]  
  2. XFERNOANSTIMEOUT=15  
  3. XFERRETRIES=2  
  4. XFERLOOPDELAY=10  
  5.   
  6. [office]  
  7. exten => _XXX,1,Set(TRANSFER_CONTEXT=office-xfer)  
  8. exten => _XXX,n,Dial(SIP/${EXTEN},,Tt)  
  9. [office-xfer]  
  10. exten => _XXX,1,Set(RETRIES=0)  
  11. exten => _XXX,n,ChanIsAvail(SIP/${EXTEN},s)  
  12. exten => _XXX,n,GotoIf($[${LEN(${AVAILCHAN})} = 0]?ret)  
  13. exten => _XXX,n,Dial(SIP/${EXTEN},${XFERNOANSTIMEOUT},Tt)  
  14. exten => _XXX,n(ret),GotoIf($[${BRIDGEPEER} = ${TRANSFERERNAME}]?(h,1))  
  15. exten => _XXX,n,Dial(SIP/${TRANSFERERNAME:4:3},${XFERNOANSTIMEOUT},Tt)  
  16. exten => _XXX,n,Set(RETRIES=$[${RETRIES}+1])  
  17. exten => _XXX,n,GotoIf($[${RETRIES} < ${XFERRETRIES}]?ret)  
  18. exten => _XXX,n,Wait(${XFERLOOPDELAY})  
  19. exten => _XXX,n,Playback(sorry)  
  20. exten => _XXX,n,Hangup()  
  21. exten => h,1,Hangup()  
Такое решение более гибко, чем настройки в features.conf, так как вы можете вместо обратного вызова припарковать клиента или отправить сообщение менеджеру на Jabber о том, что перевод вызова не удался.
В приведённом примере достаточно много шелухи, если постараться то все дополнения уместятся в три-четыре строки. Ключевым здесь является использование переменной. Вот ещё некоторые переменные, которые вы можете использовать:
  • BRIDGEPEER — переменная с именем канала, в данный момент соединённого с данным
  • BLIND_TRANSFER — переменная с именем пира, осуществившего перевод вызова в-слепую
  • TRANSFERERNAME — переменная содержащая имя канала. осуществляющего transfer (это относится только к attented transfer)
 

RHVoice установка

Требуемые пакеты: scons flite libunistring pkgconfig libsndfile libsamplerate pulseaudio и свежий gcc
Исходники берем здесь https://github.com/Olga-Yakovleva/RHVoice

Дальше все по инструкции:
https://github.com/Olga-Yakovleva/RHVoice/wiki/Building-on-Linux-%28Russian%29

scons
scons install
ldconfig

Проверка
echo "Хотите выключить свет на кухне?" | RHVoice-test -p Elena -o 1.wav




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

Озвучивает намного лучше чем Festival и Espeak.

22.10.2015

Espeak + Asterisk


Для установки Easpeak на Gentoo требуется:

emerge -pv libsndfile libsamplerate

USE="flac ao id3tag wavpack mp3rtp" CPU_FLAGS_X86="mmx sse" emerge -vp espeak

Либо тащим с http://espeak.sourceforge.net/
App для астера берем с http://asterisk-espeak.sourceforge.net/ либо http://zaf.github.io/Asterisk-eSpeak/
оно же https://github.com/zaf/Asterisk-eSpeak

Последовательность установки:
Астер, espeak, libsndfile, libsamplerate, app_espeak


Описание чего делать с espeak  чтоб он нормально говорил лежит вот тут http://archlinux.org.ru/forum/topic/8621/?page=2


Качество очень сильно проигрывает RHvoice.

27.05.2015

Макрос записи.

Макрос записи разговора.


Переменные ${CALLFILENAME},${monopt} выставляются в основном диалплане.
Надо переделать чтоб выставлялись в макросе.
[macro-en-record-test]
exten => s,1,NoOp(CHANNEL(from):${CHANNEL(from)})
exten => s,n,MYSQL(Connect connid localhost user pass db)
exten => s,n,MYSQL(Query resultid ${connid}  SELECT `record`  FROM `sippeers` WHERE defaultuser = '${CHANNEL(peername)}')
exten => s,n,MYSQL(Fetch fetchid ${resultid} record )
exten => s,n,MYSQL(Clear ${resultid})
exten => s,n,MYSQL(Disconnect ${connid})

exten => s,n,Gotoif($["${record}" = "no"]?dis-rec)
exten => s,n,Gotoif($["${record}" = ""]?dis-rec)
exten => s,n(monitor),MixMonitor(${CALLFILENAME}.wav,b,${monopt});

exten => s,n,MacroExit
exten => s,n(dis-rec),MacroExit
exten => s,n,Hangup

Макрос включения/выключения абонента


Макрос включения/отключения абонента.

[macro-en-peer]
exten => s,1,NoOp(CHANNEL(from):${CHANNEL(from)})
exten => s,n,MYSQL(Connect connid localhost user pass db)
exten => s,n,MYSQL(Query resultid ${connid}  SELECT `enable_peer`  FROM `sippeers` WHERE defaultuser = '${CHANNEL(peername)}')
exten => s,n,MYSQL(Fetch fetchid ${resultid} enable_peer )
exten => s,n,MYSQL(Clear ${resultid})
exten => s,n,MYSQL(Disconnect ${connid})
exten => s,n,Gotoif($["${enable_peer}" = "no"]?dis-peer)
exten => s,n,MacroExit
exten => s,n(dis-peer),Congestion(10)
exten => s,n,Hangup

 

15.04.2015

IVR-стандартный

Это стандартный IVR  для работы с пачкой виртуальных АТС на одном сервере.
same => n,Set(TIMEOUT(digit)=5)  ; Set Digit Timeout to 5 seconds
same => n,Set(TIMEOUT(response)=5)  ; Set Response Timeout to 10 seconds
same => n,Read(EXT,/sound/${CONTEXT:3}/ivr/name_file,3)
same => n,GotoIf($["${LEN(${EXT})}" = "3"]?vnum)
same => n,GotoIf($["${EXT}" = "1"]?num1)
same => n,GotoIf($["${EXT}" = "2"]?num2)
same => n,GotoIf($["${EXT}" = "3"]?num3)
same => n,GotoIf($["${EXT}" = "4"]?num4)
same => n,GotoIf($["${EXT}" = "5"]?num5)
same => n,GotoIf($["${EXT}" = "6"]?num6)
same => n,Dial(Local/101@out_${CONTEXT:3}/n&Local/102@out_${CONTEXT:3}/n&Local/103@out_${CONTEXT:3}/n)
same => n,Hangup

same => n(num1),Dial(Local/101@out_${CONTEXT:3}/n&Local/102@out_${CONTEXT:3}/n&Local/103@out_${CONTEXT:3}/n)
same => n,Hangup
same => n(num2),Dial(Local/201@out_${CONTEXT:3}/n&Local/202@out_${CONTEXT:3}/n&Local/203@out_${CONTEXT:3}/n)
same => n,Hangup
same => n(num3),Dial(Local/304@out_${CONTEXT:3}/n&Local/305@out_${CONTEXT:3}/n)
same => n,Hangup
same => n(num4),Dial(Local/304@out_${CONTEXT:3}/n&Local/305@out_${CONTEXT:3}/n)
same => n,Hangup

same => n(num5),Dial(Local/303@out_${CONTEXT:3}/n)
same => n,Hangup
          same => n(vnum),Dial(Local/${EXT}@out_${CONTEXT:3}/n)
          same => n,Hangup


05.03.2015

Макрос переадресации


Макроc переадресации:
Работает при выставление времени в 0 как безусловная.
Если время не 0 то по не ответу.


[macro-redirect-time]
exten => s,1,NoOp(CHANNEL(from):${CHANNEL(from)})
same => n,MYSQL(Connect connid localhost user pass db)
same => n,MYSQL(Query resultid ${connid}  SELECT `r_callerid`,`r_number`,`r_time`  FROM `redirect` WHERE client = '${CUT(ARG1,_,2)}' AND  r_callerid = '${ARG2}')
same => n,MYSQL(Fetch fetchid ${resultid} r_callerid r_number r_time)
same => n,MYSQL(Clear ${resultid})
same => n,MYSQL(Disconnect ${connid})
same => n,GotoIf($["${r_number}" = ""]?rtime)
same => n,GotoIf($["${r_time}" = "0"]?redir:rtime)
same => n(rtime),NoOp(Mark RTIME)
same => n,Dial(SIP/${CUT(ARG1,_,2)}${ARG2},${r_time},Tt)
same => n,GotoIf($["${r_time}" = ""]?exit)
same => n,GotoIf($["${r_time}" = "0"]?exit)
same => n(redir),NoOp(Mark REDIR)
same => n,Dial(Local/${r_number}@${ARG1})
same => n(exit),MacroExit
Вызывается  exten => _XXX,n,Macro(redirect-time,${CONTEXT},${EXTEN})

База в MySQL:

CREATE TABLE `redirect` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `r_callerid` decimal(3,0) DEFAULT '0',
  `r_number` decimal(11,0) DEFAULT '0',
  `r_time` decimal(3,0) NOT NULL DEFAULT '120',
  `client` varchar(20) DEFAULT NULL,
   PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8