Различия
Показаны различия между двумя версиями страницы.
Предыдущая версия справа и слева Предыдущая версия | |||
work:telephony:cisco-ivr-tcl [2024/07/10 11:36] – rolland | work:telephony:cisco-ivr-tcl [2025/05/22 16:52] (текущий) – rolland | ||
---|---|---|---|
Строка 3: | Строка 3: | ||
Сегодня речь о голосовом меню (**IVR**) для маршрутизаторов Cisco, которое мы будем писать на языке TCL, и подключать на Cisco 3845. | Сегодня речь о голосовом меню (**IVR**) для маршрутизаторов Cisco, которое мы будем писать на языке TCL, и подключать на Cisco 3845. | ||
====== Итак, для начала давайте разберемся в азах ====== | ====== Итак, для начала давайте разберемся в азах ====== | ||
+ | |||
\\ | \\ | ||
Cisco начиная с версии **IOS** 12 поддерживает как **VXML** так и **TCL** скрипты для работы с голосовым меню. Однако, | Cisco начиная с версии **IOS** 12 поддерживает как **VXML** так и **TCL** скрипты для работы с голосовым меню. Однако, | ||
Строка 9: | Строка 10: | ||
==== FSM ==== | ==== FSM ==== | ||
+ | |||
\\ | \\ | ||
Первое это **FSM** переходы.\\ | Первое это **FSM** переходы.\\ | ||
Finite-State Machines — абстрактный автомат, | Finite-State Machines — абстрактный автомат, | ||
Выглядит это примерно так: | Выглядит это примерно так: | ||
- | |||
< | < | ||
+ | |||
set ivr_fsm(CALLCOMES, | set ivr_fsm(CALLCOMES, | ||
+ | |||
</ | </ | ||
Строка 25: | Строка 28: | ||
< | < | ||
set array(CURRSTATE, | set array(CURRSTATE, | ||
+ | |||
</ | </ | ||
Строка 36: | Строка 40: | ||
Самое главное в этом — это то, что текущее событие и состояние сравниваются со всеми описанными **FSM** переходами **одновременно**. Т.е. для Cisco не имеет значения порядок, | Самое главное в этом — это то, что текущее событие и состояние сравниваются со всеми описанными **FSM** переходами **одновременно**. Т.е. для Cisco не имеет значения порядок, | ||
==== Функции ==== | ==== Функции ==== | ||
+ | |||
\\ | \\ | ||
Второй момент, | Второй момент, | ||
Строка 42: | Строка 47: | ||
===== 1) Инициализация скрипта ===== | ===== 1) Инициализация скрипта ===== | ||
+ | |||
\\ | \\ | ||
Начало любого TCL IVR скрипта содержит процедуру // | Начало любого TCL IVR скрипта содержит процедуру // | ||
- | |||
< | < | ||
+ | |||
proc init { } { | proc init { } { | ||
puts "\n proc Init start" | puts "\n proc Init start" | ||
global param | global param | ||
} | } | ||
+ | |||
</ | </ | ||
Строка 57: | Строка 64: | ||
\\ | \\ | ||
Последней исполняемой строкой скрипта должна быть строка определения стартового **FSM** перехода и стартового состояния. В нашем случае это: | Последней исполняемой строкой скрипта должна быть строка определения стартового **FSM** перехода и стартового состояния. В нашем случае это: | ||
- | |||
< | < | ||
fsm define ivr_fsm CALLCOMES | fsm define ivr_fsm CALLCOMES | ||
+ | |||
</ | </ | ||
Строка 108: | Строка 115: | ||
timer start named_timer $numbers(waiting_time) t1 | timer start named_timer $numbers(waiting_time) t1 | ||
} | } | ||
+ | |||
</ | </ | ||
- | Здесь довольно подробно все описано. | ||
- | Результатом выполнения данной процедуры будет подключение | + | Здесь довольно подробно все описано. |
- | Тут же запускается процесс сбора нажатых клавиш **//leg collectdigit// | + | |
- | И проверяется | + | Результатом выполнения данной процедуры будет подключение входящей линии к Cisco за счет команд //**leg setupack, leg proceeding, leg connect, |
+ | И проверяется рабочее сейчас время или нет, вызывая функцию // | ||
< | < | ||
proc GetDate { } { | proc GetDate { } { | ||
Строка 138: | Строка 145: | ||
Так как стартовое состояние задано в нашем случае как //**fsm define ivr_fsm CALLCOMES**// | Так как стартовое состояние задано в нашем случае как //**fsm define ivr_fsm CALLCOMES**// | ||
< | < | ||
+ | |||
set ivr_fsm(CALLCOMES, | set ivr_fsm(CALLCOMES, | ||
set ivr_fsm(CALLCOMES, | set ivr_fsm(CALLCOMES, | ||
set ivr_fsm(CALLCOMES, | set ivr_fsm(CALLCOMES, | ||
+ | |||
</ | </ | ||
Строка 148: | Строка 157: | ||
\\ | \\ | ||
Таймер, | Таймер, | ||
- | |||
< | < | ||
#Тип таймера named_timer, | #Тип таймера named_timer, | ||
timer start named_timer $numbers(waiting_time) t1 | timer start named_timer $numbers(waiting_time) t1 | ||
+ | |||
</ | </ | ||
После своего окончания сгенерирует событие // | После своего окончания сгенерирует событие // | ||
- | |||
< | < | ||
set ivr_fsm(CALLCOMES, | set ivr_fsm(CALLCOMES, | ||
+ | |||
</ | </ | ||
Строка 235: | Строка 244: | ||
} | } | ||
} | } | ||
+ | |||
</ | </ | ||
- | В процедуре CheckDestanation, | + | В процедуре CheckDestanation, |
- | \ | + | < |
- | Все состояния, | + | set ivr_fsm(CALLCONNECTED, |
- | + | ||
- | < | + | |
set ivr_fsm(TORECEPTION, | set ivr_fsm(TORECEPTION, | ||
set ivr_fsm(TRYAGAIN, | set ivr_fsm(TRYAGAIN, | ||
set ivr_fsm(TRYING, | set ivr_fsm(TRYING, | ||
set ivr_fsm(TRYING, | set ivr_fsm(TRYING, | ||
+ | |||
</ | </ | ||
Строка 261: | Строка 270: | ||
leg setup $numbers(reception) callinfo leg_incoming | leg setup $numbers(reception) callinfo leg_incoming | ||
} | } | ||
+ | |||
</ | </ | ||
Строка 280: | Строка 290: | ||
leg setup $digit callInfo leg_incoming | leg setup $digit callInfo leg_incoming | ||
} | } | ||
+ | |||
</ | </ | ||
Строка 312: | Строка 323: | ||
} | } | ||
} | } | ||
+ | |||
</ | </ | ||
Данная функция вызывается следующим FSM переходом: | Данная функция вызывается следующим FSM переходом: | ||
- | |||
< | < | ||
+ | |||
set ivr_fsm(CALLCONNECTED, | set ivr_fsm(CALLCONNECTED, | ||
+ | |||
</ | </ | ||
Строка 351: | Строка 364: | ||
} | } | ||
} | } | ||
+ | |||
</ | </ | ||
- | Данная функция проверяет какой раз ошибается звонящий, | + | Данная функция проверяет какой раз ошибается звонящий, |
- | \ | + | < |
- | Данная функция вызывается следующими **FSM**: | + | set ivr_fsm(TRYAGAIN, |
- | + | ||
- | < | + | |
set ivr_fsm(TRYING, | set ivr_fsm(TRYING, | ||
set ivr_fsm(TRYING, | set ivr_fsm(TRYING, | ||
+ | |||
</ | </ | ||
Строка 369: | Строка 382: | ||
call close | call close | ||
} | } | ||
+ | |||
</ | </ | ||
Вызывается следующими **FSM**: | Вызывается следующими **FSM**: | ||
- | |||
< | < | ||
set ivr_fsm(any_state, | set ivr_fsm(any_state, | ||
Строка 379: | Строка 392: | ||
set ivr_fsm(CALLDISCONNECTED, | set ivr_fsm(CALLDISCONNECTED, | ||
set ivr_fsm(CALLDISCONNECTED, | set ivr_fsm(CALLDISCONNECTED, | ||
+ | |||
</ | </ | ||
Строка 386: | Строка 400: | ||
Подключение на маршрутизаторе Cisco проходит в 2 этапа.\\ | Подключение на маршрутизаторе Cisco проходит в 2 этапа.\\ | ||
**Первое**, | **Первое**, | ||
- | |||
< | < | ||
application | application | ||
Строка 407: | Строка 420: | ||
param file_noworking flash: | param file_noworking flash: | ||
param file_takenumber flash: | param file_takenumber flash: | ||
+ | |||
</ | </ | ||
- | **Второе**, | + | **Второе**, |
- | + | < | |
- | < | + | dial-peer voice 200 pots |
| | ||
| | ||
| | ||
+ | |||
</ | </ | ||
Строка 428: | Строка 443: | ||
####################################################### | ####################################################### | ||
# | # | ||
- | # Для дебага скрипта | + | # Для дебага скрипта |
- | # debug voip application script | + | # debug voip application script |
- | # | + | # Более полный дебага (не рекомендуется, |
- | # debug voip ivr | + | # |
- | # | + | # |
# Скрипт должен быть запущен со следующими параметрами: | # Скрипт должен быть запущен со следующими параметрами: | ||
- | # param allowed_pattern 5[5-7].. | + | # |
- | # param fastto_reception 1 | + | # |
- | # param reception_number 5501 | + | # |
- | # param fastto_ckp 2 | + | # param fastto_ckp 2 |
- | # param ckp_number 5604 | + | # |
- | # param fastto_fax 3 | + | # |
- | # param fax_number 5555 | + | # |
- | # param waiting_time 20 | + | # |
- | # param max_try 3 | + | # |
- | # param file_welcome flash: | + | # |
- | # param file_takenumber flash: | + | # |
- | # param file_after flash: | + | # |
- | # param file_busy flash: | + | # |
- | # param file_noexist flash: | + | # |
- | # param file_noanswer flash: | + | # |
- | # param file_onhold flash: | + | # |
- | # param file_noworking flash: | + | # param file_noworking flash: |
# | # | ||
Строка 460: | Строка 475: | ||
# | # | ||
proc init_perCallVars { } { | proc init_perCallVars { } { | ||
- | global pattern | + | |
- | global numbers | + | global numbers |
- | global playng_files | + | global playng_files |
- | + | ||
- | ##### | + | ##### |
- | #Если в параметрах скрипта не указана допустимая нумерация, | + | #Если в параметрах скрипта не указана допустимая нумерация, |
- | if {[infotag get cfg_avpair_exists allowed_pattern]} { | + | if {[infotag get cfg_avpair_exists allowed_pattern]} { |
- | set pattern(1) [string trim [infotag get cfg_avpair allowed_pattern]] | + | set pattern(1) [string trim [infotag get cfg_avpair allowed_pattern]] |
- | puts "\n\n IVR - Allowed pattern set as: $pattern(1) \n\n" | + | puts "\n\n IVR - Allowed pattern set as: $pattern(1) \n\n" |
- | } else { | + | } else { |
- | set pattern(1) .... | + | set pattern(1) .... |
- | puts "\n\n IVR - Allowed pattern set as DEFAULT: $pattern(1) \n\n" | + | puts "\n\n IVR - Allowed pattern set as DEFAULT: $pattern(1) \n\n" |
- | } | + | } |
- | ##### | + | ##### |
- | # | + | # |
- | if {[infotag get cfg_avpair_exists reception_number]} { | + | if {[infotag get cfg_avpair_exists reception_number]} { |
- | set numbers(reception) [string trim [infotag get cfg_avpair reception_number]] | + | set numbers(reception) [string trim [infotag get cfg_avpair reception_number]] |
- | puts "\n\n IVR - reception number set as: $numbers(reception) \n\n" | + | puts "\n\n IVR - reception number set as: $numbers(reception) \n\n" |
- | } else { | + | } else { |
- | set numbers(reception) 0000 | + | set numbers(reception) 0000 |
- | puts "\n\n IVR - reception number set as DEFAULT: $numbers(reception) \n\n" | + | puts "\n\n IVR - reception number set as DEFAULT: $numbers(reception) \n\n" |
- | } | + | } |
- | #ЦКП | + | #ЦКП |
- | if {[infotag get cfg_avpair_exists ckp_number]} { | + | if {[infotag get cfg_avpair_exists ckp_number]} { |
- | set numbers(ckp) [string trim [infotag get cfg_avpair ckp_number]] | + | set numbers(ckp) [string trim [infotag get cfg_avpair ckp_number]] |
- | puts "\n\n IVR - ckp number set as: $numbers(ckp) \n\n" | + | puts "\n\n IVR - ckp number set as: $numbers(ckp) \n\n" |
- | } else { | + | } else { |
- | set numbers(ckp) 0000 | + | set numbers(ckp) 0000 |
- | puts "\n\n IVR - ckp number set as DEFAULT: $numbers(ckp) \n\n" | + | puts "\n\n IVR - ckp number set as DEFAULT: $numbers(ckp) \n\n" |
- | } | + | } |
- | #Факс | + | #Факс |
- | if {[infotag get cfg_avpair_exists fax_number]} { | + | if {[infotag get cfg_avpair_exists fax_number]} { |
- | set numbers(fax) [string trim [infotag get cfg_avpair fax_number]] | + | set numbers(fax) [string trim [infotag get cfg_avpair fax_number]] |
- | puts "\n\n IVR - fax number set as: $numbers(fax) \n\n" | + | puts "\n\n IVR - fax number set as: $numbers(fax) \n\n" |
- | } else { | + | } else { |
- | set numbers(fax) 0000 | + | set numbers(fax) 0000 |
- | puts "\n\n IVR - fax number set as DEFAULT: $numbers(fax) \n\n" | + | puts "\n\n IVR - fax number set as DEFAULT: $numbers(fax) \n\n" |
- | } | + | } |
- | # | + | # |
- | if {[infotag get cfg_avpair_exists fastto_reception]} { | + | if {[infotag get cfg_avpair_exists fastto_reception]} { |
- | set numbers(fast_reception) [string trim [infotag get cfg_avpair fastto_reception]] | + | set numbers(fast_reception) [string trim [infotag get cfg_avpair fastto_reception]] |
- | puts "\n\n IVR - fast to reception set as: $numbers(fast_reception) \n\n" | + | puts "\n\n IVR - fast to reception set as: $numbers(fast_reception) \n\n" |
- | } else { | + | } else { |
- | set numbers(fast_reception) 1 | + | set numbers(fast_reception) 1 |
- | puts "\n\n IVR - fast to reception set as DEFAULT: $numbers(fast_reception) \n\n" | + | puts "\n\n IVR - fast to reception set as DEFAULT: $numbers(fast_reception) \n\n" |
- | } | + | } |
- | # | + | # |
- | if {[infotag get cfg_avpair_exists fastto_ckp]} { | + | if {[infotag get cfg_avpair_exists fastto_ckp]} { |
- | set numbers(fast_ckp) [string trim [infotag get cfg_avpair fastto_ckp]] | + | set numbers(fast_ckp) [string trim [infotag get cfg_avpair fastto_ckp]] |
- | puts "\n\n IVR - fast to ckp set as: $numbers(fast_ckp) \n\n" | + | puts "\n\n IVR - fast to ckp set as: $numbers(fast_ckp) \n\n" |
- | } else { | + | } else { |
- | set numbers(fast_ckp) 2 | + | set numbers(fast_ckp) 2 |
- | puts "\n\n IVR - fast to ckp set as DEFAULT: $numbers(fast_ckp) \n\n" | + | puts "\n\n IVR - fast to ckp set as DEFAULT: $numbers(fast_ckp) \n\n" |
- | } | + | } |
- | # | + | # |
- | if {[infotag get cfg_avpair_exists fastto_fax]} { | + | if {[infotag get cfg_avpair_exists fastto_fax]} { |
- | set numbers(fast_fax) [string trim [infotag get cfg_avpair fastto_fax]] | + | set numbers(fast_fax) [string trim [infotag get cfg_avpair fastto_fax]] |
- | puts "\n\n IVR - fast to fax set as: $numbers(fast_fax) \n\n" | + | puts "\n\n IVR - fast to fax set as: $numbers(fast_fax) \n\n" |
- | } else { | + | } else { |
- | set numbers(fast_fax) 3 | + | set numbers(fast_fax) 3 |
- | puts "\n\n IVR - fast to fax set as DEFAULT: $numbers(fast_fax) \n\n" | + | puts "\n\n IVR - fast to fax set as DEFAULT: $numbers(fast_fax) \n\n" |
- | } | + | } |
- | # | + | #Время ожидания введения номера (должно быть больше времени проигрыша всех файлов приветствия) |
- | if {[infotag get cfg_avpair_exists waiting_time]} { | + | if {[infotag get cfg_avpair_exists waiting_time]} { |
- | set numbers(waiting_time) [string trim [infotag get cfg_avpair waiting_time]] | + | set numbers(waiting_time) [string trim [infotag get cfg_avpair waiting_time]] |
- | puts "\n\n IVR - wait number set as: $numbers(waiting_time) \n\n" | + | puts "\n\n IVR - wait number set as: $numbers(waiting_time) \n\n" |
- | } else { | + | } else { |
- | set numbers(waiting_time) 10 | + | set numbers(waiting_time) 10 |
- | puts "\n\n IVR - wait number set as DEFAULT: $numbers(waiting_time) \n\n" | + | puts "\n\n IVR - wait number set as DEFAULT: $numbers(waiting_time) \n\n" |
- | } | + | } |
- | # | + | # |
- | if {[infotag get cfg_avpair_exists max_try]} { | + | if {[infotag get cfg_avpair_exists max_try]} { |
- | set numbers(max_try) [string trim [infotag get cfg_avpair max_try]] | + | set numbers(max_try) [string trim [infotag get cfg_avpair max_try]] |
- | puts "\n\n IVR - max try set as: $numbers(max_try) \n\n" | + | puts "\n\n IVR - max try set as: $numbers(max_try) \n\n" |
- | set numbers(cur_try) 0 | + | set numbers(cur_try) 0 |
- | } else { | + | } else { |
- | set numbers(max_try) 5 | + | set numbers(max_try) 5 |
- | puts "\n\n IVR - max try set as DEFAULT: $numbers(max_try) \n\n" | + | puts "\n\n IVR - max try set as DEFAULT: $numbers(max_try) \n\n" |
- | set numbers(cur_try) 0 | + | set numbers(cur_try) 0 |
- | } | + | } |
- | ##### | + | ##### |
- | #Файл приветствия | + | #Файл приветствия |
- | if {[infotag get cfg_avpair_exists file_welcome]} { | + | if {[infotag get cfg_avpair_exists file_welcome]} { |
- | set playng_files(welcome) [string trim [infotag get cfg_avpair file_welcome]] | + | set playng_files(welcome) [string trim [infotag get cfg_avpair file_welcome]] |
- | puts "\n\n IVR - file_welcome set as: $playng_files(welcome) \n\n" | + | puts "\n\n IVR - file_welcome set as: $playng_files(welcome) \n\n" |
- | } else { | + | } else { |
- | #Если файл не найден, | + | #Если файл не найден, |
- | set playng_files(welcome) %s1 | + | set playng_files(welcome) %s1 |
- | puts "\n\n IVR - file_welcome set as DEFAULT: $playng_files(welcome) \n\n" | + | puts "\n\n IVR - file_welcome set as DEFAULT: $playng_files(welcome) \n\n" |
- | } | + | } |
- | #Файл запроса ввести требуемый номер | + | #Файл запроса ввести требуемый номер |
- | if {[infotag get cfg_avpair_exists file_takenumber]} { | + | if {[infotag get cfg_avpair_exists file_takenumber]} { |
- | set playng_files(takenumber) [string trim [infotag get cfg_avpair file_takenumber]] | + | set playng_files(takenumber) [string trim [infotag get cfg_avpair file_takenumber]] |
- | puts "\n\n IVR - file_takenumber set as: $playng_files(takenumber) \n\n" | + | puts "\n\n IVR - file_takenumber set as: $playng_files(takenumber) \n\n" |
- | } else { | + | } else { |
- | #Если файл не найден, | + | #Если файл не найден, |
- | set playng_files(takenumber) %s1 | + | set playng_files(takenumber) %s1 |
- | puts "\n\n IVR - file_takenumber set as DEFAULT: $playng_files(takenumber) \n\n" | + | puts "\n\n IVR - file_takenumber set as DEFAULT: $playng_files(takenumber) \n\n" |
- | } | + | } |
- | #Файл " | + | #Файл " |
- | if {[infotag get cfg_avpair_exists file_after]} { | + | if {[infotag get cfg_avpair_exists file_after]} { |
- | set playng_files(callafter) [string trim [infotag get cfg_avpair file_after]] | + | set playng_files(callafter) [string trim [infotag get cfg_avpair file_after]] |
- | puts "\n\n IVR - file_after set as: $playng_files(callafter) \n\n" | + | puts "\n\n IVR - file_after set as: $playng_files(callafter) \n\n" |
- | } else { | + | } else { |
- | #Если файл не найден, | + | #Если файл не найден, |
- | set playng_files(callafter) %s1 | + | set playng_files(callafter) %s1 |
- | puts "\n\n IVR - file_after set as DEFAULT: $playng_files(callafter) \n\n" | + | puts "\n\n IVR - file_after set as DEFAULT: $playng_files(callafter) \n\n" |
- | } | + | } |
- | #Файл " | + | #Файл " |
- | if {[infotag get cfg_avpair_exists file_busy]} { | + | if {[infotag get cfg_avpair_exists file_busy]} { |
- | set playng_files(busy) [string trim [infotag get cfg_avpair file_busy]] | + | set playng_files(busy) [string trim [infotag get cfg_avpair file_busy]] |
- | puts "\n\n IVR - file_busy set as: $playng_files(busy) \n\n" | + | puts "\n\n IVR - file_busy set as: $playng_files(busy) \n\n" |
- | } else { | + | } else { |
- | #Если файл не найден, | + | #Если файл не найден, |
- | set playng_files(busy) %s1 | + | set playng_files(busy) %s1 |
- | puts "\n\n IVR - file_busy set as DEFAULT: $playng_files(busy) \n\n" | + | puts "\n\n IVR - file_busy set as DEFAULT: $playng_files(busy) \n\n" |
- | } | + | } |
- | #Файл " | + | #Файл " |
- | if {[infotag get cfg_avpair_exists file_noexist]} { | + | if {[infotag get cfg_avpair_exists file_noexist]} { |
- | set playng_files(noexist) [string trim [infotag get cfg_avpair file_noexist]] | + | set playng_files(noexist) [string trim [infotag get cfg_avpair file_noexist]] |
- | puts "\n\n IVR - file_noexist set as: $playng_files(noexist) \n\n" | + | puts "\n\n IVR - file_noexist set as: $playng_files(noexist) \n\n" |
- | } else { | + | } else { |
- | #Если файл не найден, | + | #Если файл не найден, |
- | set playng_files(noexist) %s1 | + | set playng_files(noexist) %s1 |
- | puts "\n\n IVR - file_noexist set as DEFAULT: $playng_files(noexist) \n\n" | + | puts "\n\n IVR - file_noexist set as DEFAULT: $playng_files(noexist) \n\n" |
- | } | + | } |
- | #Файл " | + | #Файл " |
- | if {[infotag get cfg_avpair_exists file_toreception]} { | + | if {[infotag get cfg_avpair_exists file_toreception]} { |
- | set playng_files(toreception) [string trim [infotag get cfg_avpair file_toreception]] | + | set playng_files(toreception) [string trim [infotag get cfg_avpair file_toreception]] |
- | puts "\n\n IVR - file_toreception set as: $playng_files(toreception) \n\n" | + | puts "\n\n IVR - file_toreception set as: $playng_files(toreception) \n\n" |
- | } else { | + | } else { |
- | #Если файл не найден, | + | #Если файл не найден, |
- | set playng_files(toreception) %s1 | + | set playng_files(toreception) %s1 |
- | puts "\n\n IVR - file_toreception set as DEFAULT: $playng_files(toreception) \n\n" | + | puts "\n\n IVR - file_toreception set as DEFAULT: $playng_files(toreception) \n\n" |
- | } | + | } |
- | #Файл " | + | #Файл " |
- | if {[infotag get cfg_avpair_exists file_noanswer]} { | + | if {[infotag get cfg_avpair_exists file_noanswer]} { |
- | set playng_files(noanswer) [string trim [infotag get cfg_avpair file_noanswer]] | + | set playng_files(noanswer) [string trim [infotag get cfg_avpair file_noanswer]] |
- | puts "\n\n IVR - file_noanswer set as: $playng_files(noanswer) \n\n" | + | puts "\n\n IVR - file_noanswer set as: $playng_files(noanswer) \n\n" |
- | } else { | + | } else { |
- | #Если файл не найден, | + | #Если файл не найден, |
- | set playng_files(noanswer) %s1 | + | set playng_files(noanswer) %s1 |
- | puts "\n\n IVR - file_noanswer set as DEFAULT: $playng_files(noanswer) \n\n" | + | puts "\n\n IVR - file_noanswer set as DEFAULT: $playng_files(noanswer) \n\n" |
- | } | + | } |
- | #Файл музыки, | + | #Файл музыки, |
- | if {[infotag get cfg_avpair_exists file_onhold]} { | + | if {[infotag get cfg_avpair_exists file_onhold]} { |
- | set playng_files(onhold) [string trim [infotag get cfg_avpair file_onhold]] | + | set playng_files(onhold) [string trim [infotag get cfg_avpair file_onhold]] |
- | puts "\n\n IVR - file_onhold set as: $playng_files(onhold) \n\n" | + | puts "\n\n IVR - file_onhold set as: $playng_files(onhold) \n\n" |
- | } else { | + | } else { |
- | #Если файл не найден, | + | #Если файл не найден, |
- | set playng_files(onhold) %s1 | + | set playng_files(onhold) %s1 |
- | puts "\n\n IVR - file_onhold set as DEFAULT: $playng_files(onhold) \n\n" | + | puts "\n\n IVR - file_onhold set as DEFAULT: $playng_files(onhold) \n\n" |
- | } | + | } |
- | #Файл музыки, | + | #Файл музыки, |
- | if {[infotag get cfg_avpair_exists file_noworking]} { | + | if {[infotag get cfg_avpair_exists file_noworking]} { |
- | set playng_files(noworking) [string trim [infotag get cfg_avpair file_noworking]] | + | set playng_files(noworking) [string trim [infotag get cfg_avpair file_noworking]] |
- | puts "\n\n IVR - file_noworking set as: $playng_files(noworking) \n\n" | + | puts "\n\n IVR - file_noworking set as: $playng_files(noworking) \n\n" |
- | } else { | + | } else { |
- | #Если файл не найден, | + | #Если файл не найден, |
- | set playng_files(noworking) %s1 | + | set playng_files(noworking) %s1 |
- | puts "\n\n IVR - file_noworking set as DEFAULT: $playng_files(noworking) \n\n" | + | puts "\n\n IVR - file_noworking set as DEFAULT: $playng_files(noworking) \n\n" |
- | } | + | } |
} | } | ||
proc GetDate { } { | proc GetDate { } { | ||
- | global workingtime | + | |
- | + | ||
- | #Час | + | #Час |
- | set houris [clock format [clock seconds] -format %H] | + | set houris [clock format [clock seconds] -format %H] |
- | #День недели | + | #День недели |
- | set dayis [clock format [clock seconds] -format %A] | + | set dayis [clock format [clock seconds] -format %A] |
- | # | + | # |
- | if {$houris > 17 || $houris < 8 || $dayis==" | + | if {$houris> |
- | set workingtime 0 | + | set workingtime 0 |
- | } else { | + | } else { |
- | set workingtime 1 | + | set workingtime 1 |
- | } | + | } |
} | } | ||
Строка 642: | Строка 657: | ||
proc Play_Welcome { } { | proc Play_Welcome { } { | ||
puts "\n\n IVR - proc Play_Welcome start \n\n" | puts "\n\n IVR - proc Play_Welcome start \n\n" | ||
- | global playng_files | + | |
- | global param | + | global param |
- | global pattern | + | global pattern |
- | global numbers | + | global numbers |
- | global workingtime | + | global workingtime |
- | + | ||
- | # | + | # |
- | init_perCallVars | + | init_perCallVars |
- | + | ||
- | # | + | # |
- | GetDate | + | GetDate |
- | #В зависимости рабочее сейчас время или нет, устанавливаем приветствие | + | #В зависимости рабочее сейчас время или нет, устанавливаем приветствие |
- | if {$workingtime} { | + | if {$workingtime} { |
- | set after_welcome $playng_files(takenumber) | + | set after_welcome $playng_files(takenumber) |
- | } else { | + | } else { |
- | set after_welcome $playng_files(noworking) | + | set after_welcome $playng_files(noworking) |
- | } | + | } |
- | + | ||
- | # | + | # |
- | set param(interruptPrompt) true | + | set param(interruptPrompt) true |
- | set param(abortKey) * | + | set param(abortKey) * |
- | set param(terminationKey) # | + | set param(terminationKey) # |
- | + | ||
- | # | + | # |
leg setupack leg_incoming | leg setupack leg_incoming | ||
leg proceeding leg_incoming | leg proceeding leg_incoming | ||
leg connect leg_incoming | leg connect leg_incoming | ||
- | + | ||
- | # | + | # |
- | leg collectdigits leg_incoming param pattern | + | leg collectdigits leg_incoming param pattern |
- | # | + | # |
- | # | + | # |
- | # | + | #будет событие ev_collectdigits_done |
media play leg_incoming %s500 $playng_files(welcome) $after_welcome $playng_files(onhold) | media play leg_incoming %s500 $playng_files(welcome) $after_welcome $playng_files(onhold) | ||
- | # | + | |
- | timer start named_timer $numbers(waiting_time) t1 | + | timer start named_timer $numbers(waiting_time) t1 |
} | } | ||
Строка 683: | Строка 698: | ||
proc Play_TakeNumber { } { | proc Play_TakeNumber { } { | ||
puts "\n\n IVR - proc Play_TakeNumber start \n\n" | puts "\n\n IVR - proc Play_TakeNumber start \n\n" | ||
- | global playng_files | + | |
- | global numbers | + | global numbers |
- | global param | + | global param |
- | global pattern | + | global pattern |
- | + | ||
- | # | + | # |
- | if {$numbers(cur_try) <= $numbers(max_try)} { | + | if {$numbers(cur_try) <= $numbers(max_try)} { |
- | puts "\n\n IVR - proc Play_TakeNumber current try is: $numbers(cur_try) \n\n" | + | puts "\n\n IVR - proc Play_TakeNumber current try is: $numbers(cur_try) \n\n" |
- | incr numbers(cur_try) | + | incr numbers(cur_try) |
- | # | + | # |
- | leg collectdigits leg_incoming param pattern | + | leg collectdigits leg_incoming param pattern |
- | # | + | # |
- | media play leg_incoming $playng_files(takenumber) | + | media play leg_incoming $playng_files(takenumber) |
- | # | + | # |
- | timer start named_timer $numbers(waiting_time) t1 | + | timer start named_timer $numbers(waiting_time) t1 |
- | + | ||
- | #Если попытка больше чем $numbers(max_try) - разъединяем | + | #Если попытка больше чем $numbers(max_try) - разъединяем |
- | } else { | + | } else { |
- | fsm setstate CALLDISCONNECTED | + | fsm setstate CALLDISCONNECTED |
- | media play leg_incoming $playng_files(callafter) | + | media play leg_incoming $playng_files(callafter) |
- | } | + | } |
} | } | ||
# | # | ||
proc GoToReception { } { | proc GoToReception { } { | ||
- | puts "\n\n IVR - proc GoToReception start \n\n" | + | |
- | global numbers | + | global numbers |
- | # | + | # |
- | media stop leg_incoming | + | media stop leg_incoming |
- | # | + | # |
- | fsm setstate CALLCONNECTED | + | fsm setstate CALLCONNECTED |
- | + | ||
- | set digit $numbers(reception) | + | set digit $numbers(reception) |
- | + | ||
- | # | + | # |
- | CheckCallersAndConnect $digit | + | CheckCallersAndConnect $digit |
} | } | ||
- | #Здесь проверяем введенные или не введенные звонящим цифры | + | #Здесь проверяем введенные или не введенные звонящим цифры |
proc CheckDestanation { } { | proc CheckDestanation { } { | ||
puts "\n\n IVR - proc CheckDestanation start \n\n" | puts "\n\n IVR - proc CheckDestanation start \n\n" | ||
- | global playng_files | + | |
- | global numbers | + | global numbers |
- | global digit | + | global digit |
- | # | + | # |
- | media stop leg_incoming | + | media stop leg_incoming |
- | + | ||
- | # | + | # |
set status [infotag get evt_status] | set status [infotag get evt_status] | ||
- | set digit [infotag get evt_dcdigits] | + | |
- | + | ||
- | # | + | # |
- | #Если введенная цифра соответствует той, что задана в $numbers(fast_reception), | + | #Если введенная цифра соответствует той, что задана в $numbers(fast_reception), |
- | # | + | # |
- | # предварительно изменив статус на CALLCONNECTED, | + | # предварительно изменив статус на CALLCONNECTED, |
- | # благодаря которому, | + | # благодаря которому, |
- | # будет отработана процедура CallIsConnect | + | # будет отработана процедура CallIsConnect |
- | if {$digit == $numbers(fast_reception)} { | + | if {$digit == $numbers(fast_reception)} { |
- | puts "\n\n IVR - proc CheckDestanation digit = $digit\nGoing to next reception \n\n" | + | puts "\n\n IVR - proc CheckDestanation digit = $digit\nGoing to next reception \n\n" |
- | fsm setstate CALLCONNECTED | + | fsm setstate CALLCONNECTED |
- | set digit $numbers(reception) | + | set digit $numbers(reception) |
- | # | + | # |
- | CheckCallersAndConnect $digit | + | CheckCallersAndConnect $digit |
- | #Если введенная цифра соответствует той, что задана в $numbers(fast_ckp), | + | #Если введенная цифра соответствует той, что задана в $numbers(fast_ckp), |
- | # | + | #через CheckCallersAndConnect |
- | } elseif {$digit == $numbers(fast_ckp)} { | + | } elseif {$digit == $numbers(fast_ckp)} { |
- | puts "\n\n IVR - proc CheckDestanation digit = $digit\nGoing to next CKP \n\n" | + | puts "\n\n IVR - proc CheckDestanation digit = $digit\nGoing to next CKP \n\n" |
- | fsm setstate CALLCONNECTED | + | fsm setstate CALLCONNECTED |
- | set digit $numbers(ckp) | + | set digit $numbers(ckp) |
- | # | + | # |
- | CheckCallersAndConnect $digit | + | CheckCallersAndConnect $digit |
- | #Если введенная цифра соответствует той, что задана в $numbers(fast_fax), | + | #Если введенная цифра соответствует той, что задана в $numbers(fast_fax), |
- | # | + | #через CheckCallersAndConnect |
- | } elseif {$digit == $numbers(fast_fax)} { | + | } elseif {$digit == $numbers(fast_fax)} { |
- | puts "\n\n IVR - proc CheckDestanation digit = $digit\nGoing to next fax \n\n" | + | puts "\n\n IVR - proc CheckDestanation digit = $digit\nGoing to next fax \n\n" |
- | fsm setstate CALLCONNECTED | + | fsm setstate CALLCONNECTED |
- | set digit $numbers(fax) | + | set digit $numbers(fax) |
- | # | + | # |
- | CheckCallersAndConnect $digit | + | CheckCallersAndConnect $digit |
- | #Если статус = cd_004 (введены корректные цифры номера) - подключаем к нужному номеру | + | #Если статус = cd_004 (введены корректные цифры номера) - подключаем к нужному номеру |
- | # | + | #через CheckCallersAndConnect |
- | } elseif {$status == " | + | } elseif {$status == " |
- | puts "\n\n IVR - proc CheckDestanation status = $status digit = $digit \n\n" | + | puts "\n\n IVR - proc CheckDestanation status = $status digit = $digit \n\n" |
- | fsm setstate CALLCONNECTED | + | fsm setstate CALLCONNECTED |
- | # | + | # |
- | CheckCallersAndConnect $digit | + | CheckCallersAndConnect $digit |
- | #Если статус = cd_005 (совпадение с dial plan) - подключаем к нужному номеру | + | #Если статус = cd_005 (совпадение с dial plan) - подключаем к нужному номеру |
- | # | + | #через CheckCallersAndConnect |
- | } elseif {$status == " | + | } elseif {$status == " |
- | puts "\n\n IVR - proc CheckDestanation status = $status digit = $digit \n\n" | + | puts "\n\n IVR - proc CheckDestanation status = $status digit = $digit \n\n" |
- | fsm setstate CALLCONNECTED | + | fsm setstate CALLCONNECTED |
- | # | + | # |
- | CheckCallersAndConnect $digit | + | CheckCallersAndConnect $digit |
- | #Если статус = cd_006 (набран не существующий номер) - играем в линию $playng_files(noexist) | + | #Если статус = cd_006 (набран не существующий номер) - играем в линию $playng_files(noexist) |
- | #и изменяем статус на TRYAGAIN, при действии которого и наступлении события ev_media_done | + | #и изменяем статус на TRYAGAIN, при действии которого и наступлении события ev_media_done |
- | # | + | # |
- | } elseif {$status == " | + | } elseif {$status == " |
- | puts "\n\n IVR - proc CheckDestanation status = $status digit = $digit \n\n" | + | puts "\n\n IVR - proc CheckDestanation status = $status digit = $digit \n\n" |
- | fsm setstate TRYAGAIN | + | fsm setstate TRYAGAIN |
- | media play leg_incoming $playng_files(noexist) | + | media play leg_incoming $playng_files(noexist) |
- | #Во всех остальных случаях изменяем статус на TORECEPTION, | + | #Во всех остальных случаях изменяем статус на TORECEPTION, |
- | # | + | # |
- | } else { | + | } else { |
- | # | + | # |
- | fsm setstate TORECEPTION | + | fsm setstate TORECEPTION |
- | media play leg_incoming $playng_files(toreception) | + | media play leg_incoming $playng_files(toreception) |
- | puts "\n\n IVR - proc CheckDestanation status = $status \n\n" | + | puts "\n\n IVR - proc CheckDestanation status = $status \n\n" |
- | } | + | } |
} | } | ||
# | # | ||
proc CheckCallersAndConnect {digit} { | proc CheckCallersAndConnect {digit} { | ||
- | puts "\n\n IVR - proc CheckCallersAndConnect start \n\n" | + | |
- | + | ||
- | set callernumber [infotag get leg_ani] | + | set callernumber [infotag get leg_ani] |
- | + | ||
- | switch $callernumber { | + | |
- | " | + | |
- | " | + | |
- | default {} | + | |
- | } | + | } |
- | + | ||
- | leg setup $digit callInfo leg_incoming | + | leg setup $digit callInfo leg_incoming |
} | } | ||
# | # | ||
proc CallIsConnect { } { | proc CallIsConnect { } { | ||
- | puts "\n\n IVR - proc CallIsConnect start \n\n" | + | |
- | global playng_files | + | global playng_files |
- | # | + | |
- | set status [infotag get evt_status] | + | set status [infotag get evt_status] |
- | + | ||
- | #Если статус равен ls_000 (успешное соединение с требуемым номером), | + | #Если статус равен ls_000 (успешное соединение с требуемым номером), |
- | if {$status == " | + | if {$status == " |
- | fsm setstate CALLACTIVE | + | fsm setstate CALLACTIVE |
- | + | ||
- | #Если статус равен ls_002 (никто не ответил на звонок), | + | #Если статус равен ls_002 (никто не ответил на звонок), |
- | } elseif {$status == " | + | } elseif {$status == " |
- | fsm setstate TRYAGAIN | + | fsm setstate TRYAGAIN |
- | media play leg_incoming $playng_files(noanswer) | + | media play leg_incoming $playng_files(noanswer) |
- | #Если статус - неверный номер, запускаем процедуру запроса номера | + | #Если статус - неверный номер, запускаем процедуру запроса номера |
- | } elseif {$status == " | + | } elseif {$status == " |
- | fsm setstate TRYAGAIN | + | fsm setstate TRYAGAIN |
- | media play leg_incoming $playng_files(noexist) | + | media play leg_incoming $playng_files(noexist) |
- | #Если статус равен ls_007 (абонент занят), | + | #Если статус равен ls_007 (абонент занят), |
- | } elseif {$status == " | + | } elseif {$status == " |
- | fsm setstate TRYAGAIN | + | fsm setstate TRYAGAIN |
- | media play leg_incoming $playng_files(busy) | + | media play leg_incoming $playng_files(busy) |
- | } | + | } |
} | } | ||
# | # | ||
proc AbortCall { } { | proc AbortCall { } { | ||
- | puts "\n\n IVR - proc AbortCall start \n\n" | + | |
- | call close | + | call close |
} | } | ||
Строка 847: | Строка 862: | ||
#Это набор состояний и возникающих при данных состояних событий | #Это набор состояний и возникающих при данных состояних событий | ||
#По сути именно это и описывает работу скрипта | #По сути именно это и описывает работу скрипта | ||
- | + | ||
- | #Если в любом состоянии возникнет событие отключения ev_disconnected, | + | #Если в любом состоянии возникнет событие отключения ev_disconnected, |
- | set ivr_fsm(any_state, | + | set ivr_fsm(any_state, |
- | + | ||
- | #Если в состоянии CALLCOMES возникнет событие ev_setup_indication (входящий вызов) | + | #Если в состоянии CALLCOMES возникнет событие ev_setup_indication (входящий вызов) |
- | # | + | # |
- | set ivr_fsm(CALLCOMES, | + | set ivr_fsm(CALLCOMES, |
- | + | ||
- | #Если в состоянии CALLCOMES возникнет событие ev_collectdigits_done (закончен ввод цифр) | + | #Если в состоянии CALLCOMES возникнет событие ev_collectdigits_done (закончен ввод цифр) |
- | # | + | # |
- | set ivr_fsm(CALLCOMES, | + | set ivr_fsm(CALLCOMES, |
- | + | ||
- | #Если в состоянии CALLCOMES возникнет событие ev_named_timer (закончился таймер ожидания ввода цифр) | + | #Если в состоянии CALLCOMES возникнет событие ev_named_timer (закончился таймер ожидания ввода цифр) |
- | # | + | # |
- | set ivr_fsm(CALLCOMES, | + | set ivr_fsm(CALLCOMES, |
- | + | ||
- | #Если в состоянии TORECEPTION возникнет событие ev_media_done (закончился проигрыш файла) | + | #Если в состоянии TORECEPTION возникнет событие ev_media_done (закончился проигрыш файла) |
- | # | + | # |
- | set ivr_fsm(TORECEPTION, | + | set ivr_fsm(TORECEPTION, |
- | + | ||
- | # | + | # |
- | set ivr_fsm(TRYAGAIN, | + | set ivr_fsm(TRYAGAIN, |
- | set ivr_fsm(TRYING, | + | set ivr_fsm(TRYING, |
- | set ivr_fsm(TRYING, | + | set ivr_fsm(TRYING, |
- | + | ||
- | #Если в состоянии CALLCONNECTED возникнет событие ev_setup_done | + | #Если в состоянии CALLCONNECTED возникнет событие ev_setup_done |
- | # | + | # |
- | set ivr_fsm(CALLCONNECTED, | + | set ivr_fsm(CALLCONNECTED, |
- | + | ||
- | #Эти события отрабатывают отключение линии | + | #Эти события отрабатывают отключение линии |
- | set ivr_fsm(CALLACTIVE, | + | set ivr_fsm(CALLACTIVE, |
- | set ivr_fsm(CALLDISCONNECTED, | + | set ivr_fsm(CALLDISCONNECTED, |
- | set ivr_fsm(CALLDISCONNECTED, | + | set ivr_fsm(CALLDISCONNECTED, |
- | set ivr_fsm(CALLDISCONNECTED, | + | set ivr_fsm(CALLDISCONNECTED, |
fsm define ivr_fsm CALLCOMES | fsm define ivr_fsm CALLCOMES | ||
+ | |||
</ | </ | ||
+ | |||
Источник [[https:// | Источник [[https:// | ||