Всем доброго времени суток!
Недавно столкнулся со следующей проблемой:
имеется городской номер, при дозвоне на него должна запускаться аппликация
идет приветствие типа: "Вы позвонили в компанию ХХХ. Для соединения с абонотделом нажмите 1, для соединения с техотделом нажмите 2." При нажатии клавиши абонент должен соединяться с соответствующим отделом. При этом звонок должен уходить на соответсвующий для отдела федеральный номер. При нажатии любой другой клавиши должно проигрываться сообщения, типа выбран несуществующий пункт голосового меню. Задан таймаут в 10 секунд и если клиент ничего не нажал, либо жал не в тональном режиме, то по таймауту будет соединяться с техотделом.
Проблема в том, что с tcl никогда до этого не работал и времени на написание IVR дан очень короткий срок. Если у кого есть подобные IVR, буду очень признателен.
>Проблема в том, что с tcl никогда до этого не работал и
>времени на написание IVR дан очень короткий срок. Если у кого
>есть подобные IVR, буду очень признателен.TCL не обязательно для этого знать. Гораздо проще попользоваться VoiceXML 2.0, который поддерживается циской. Если есть CCO, с cisco.com можно скачать примеры скриптов на VoiceXML.
>TCL не обязательно для этого знать. Гораздо проще попользоваться VoiceXML 2.0, который
>поддерживается циской. Если есть CCO, с cisco.com можно скачать примеры скриптов
>на VoiceXML.
К сожалению CCO нет и к тому же руководство требует скрипт именно на tcl. Поэтому и прошу помощи.
Вот что удалось придумать за день работы:proc init { } {
# Инициализация глобальных статических переменных
puts "\n proc Init start"global param
global phonePattern
global commercePhone
global customerSupportinfotag set med_language_map 0 ru
infotag set med_location ru 0 tftp://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
infotag set med_location ru 1 tftp://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
infotag set med_language 0set param(initialDigitTimeout) 10
set param(interruptPrompt) true
set phonePattern(1) {[1,2]}# Телефонные номера служб "по умолчанию"
set customerSupport "7xxxxxxxxxx"
set commercePhone "7xxxxxxxxxx"puts "\n proc Init finish"
}
proc act_Setup { } {
# Снятие трубки и сбор цифр
global paramputs "\a proc act_Setup start"
leg setupack leg_incoming
leg proceeding leg_incoming
leg connect leg_incomingputs "\n playing welcome message and asking user for turning phone into tone mode...\n starting collection digits..."
media play leg_incoming _subscriberBusy.au %s500 _techSupport.au
# Звуковые файлы позже поменяются на нужные!
leg collectdigits leg_incoming param phonePatternputs "\n proc act_Setup finish"
}
proc act_GotDest { } {
# Проверка правильности введенного номера и установка звонкаputs "\n proc act_GotDest start "
set status [infotag get evt_status]
set digits [infotag get evt_dcdigits]switch $digits {
1 {
# Пользователь запросил соединение с абонентским отделом
puts "\n Subscriber asking connection with commerce department"
leg setup $commercePhone callinfo leg_incoming
fsm setstate CallSetupDone
set status [infotag get evt_status]puts "\n Call [infotag get con_all] got event $status"
}
2 {
# Пользователь запросил соединение с техподдержкой
puts "\n Subscriber asking connection with customer support"
leg setup $customerSupport callinfo leg_incoming
fsm setstate CallSetupDone
set status [infotag get evt_status]puts "\n Call [infotag get con_all] got event $status"
}
default {
# Несуществующий пункт меню
media play leg_incoming _wrongMenuPoint.au
fsm setstate CallClose
}
}
}
proc act_CallSetupDone { } {
# Проверка состояния установки звонкаputs "\n proc act_CallSetupDone start"
set status [infotag get evt_status]
switch $status {
ls_000 { set action "OK"}
ls_001 { set action "busy"}
ls_002 { set action "busy"}
ls_003 { set action "busy"}
ls_004 { set action "wrongnumber"}
ls_005 { set action "busy"}
ls_006 { set action "busy"}
ls_007 { set action "busy"}
ls_008 { set action "disconnect"}
ls_009 { set action "busy"}
ls_010 { set action "busy"}
ls_011 { set action "busy"}
ls_012 { set action "busy"}
ls_013 { set action "disconnect"}
ls_014 { set action "busy"}
ls_015 { set action "disconnect"}
ls_016 { set action "busy"}
default { set action "disconnect"}
}if {$action == "wrongnumber"} {
puts "\n CallSetup got event $status \n The call setup failed because of an invalid number."
media play leg_incoming _wrongMenuPoint.au
fsm setstate CallClose} elseif {$action == "busy"} {
puts "\n CallSetup got event $status - busy"
media play leg_incoming _subscriberBusy.au
fsm setstate CallClose} elseif {$action == "disconnect" } {
puts "\n CallSetup got event $status - disconnected"
fsm setstat CallClose
act_Call_Close} else {
puts "\n CallSetup got event $status - OK!"
fsm setstate CallClose}
puts "\n proc act_CallSetupDone finish"
}proc act_Call_Close { } {
# Процедура завершения звонкаcall close
}
requiredversion 2.0
init
# FSM
set fsm(any_state,ev_disconnected) "act_Call_Close same_state"
set fsm(Call_Init,ev_setup_indication) "act_Setup Got_Dest"
set fsm(Got_Dest,ev_collectdigits_done) "act_GotDest CallSetupDone"
set fsm(CallSetupDone,ev_setup_done) "act_CallSetupDone CallClose"
set fsm(CallClose,ev_disconnected) "act_Call_Close same_state"При звонке на скрипт идет fast busy и дебаг выдает следующую ошибку:
ov 13 18:04:35.706:
Nov 13 18:04:38.598: //-1//TCL2:HN863A04E0:/tcl_PutsCmd:
proc Init start
Nov 13 18:04:38.598:
Nov 13 18:04:38.602: //-1//TCL2:HN863A04E0:/tcl_PutsCmd:
proc Init finish
Nov 13 18:04:38.602:
Nov 13 18:04:38.602: //334887//TCL2:/tcl_PutsCmd: proc act_Setup start
Nov 13 18:04:38.602:
Nov 13 18:04:38.602: //334887//TCL2:/tcl_PutsCmd:
playing welcome message and asking user for turning phone into tone mode...
starting collection digits...
Nov 13 18:04:38.602:
Nov 13 18:04:38.606: //334887//TCL2:/TclInterpDriver: Tcl_Eval Failed in action=act_Setup code=1
code=ERROR
Nov 13 18:04:38.606: IVR TCL script failure
Result:
DigitCollect Command failed to intiate
Nov 13 18:04:38.606: IVR TCL script failure errorInfo:
DigitCollect Command failed to intiate
while executing
"leg collectdigits leg_incoming param phonePattern"
(procedure "act_Setup" line 15)
invoked from within
"act_Setup"Не подскажете в чём ошибка и как таймаут сделать в рамках данной задачи?
Поработал еще. Ситуация улучшается. На сегодня конфиг такой:proc init { } {
# Инициализация глобальных статических переменныхputs "\n proc Init start"
global param
global phonePattern
global commercePhone
global customerSupportinfotag set med_language_map 0 ru
infotag set med_location ru 0 tftp://хххххххххххххххххххххххххххххххх
infotag set med_location ru 1 tftp://хххххххххххххххххххххххххххххххх
infotag set med_language 0set param(initialDigitTimeout) 10
set param(interruptPrompt) true
set param(maxDigits) 1
set phonePattern(1) {[1,2]}# Телефонные номера служб "по умолчанию"
set customerSupport "7хххххххххх"
set commercePhone "7хххххххххх"puts "\n proc Init finish"
}
proc init_perCallVars { } {
# Процедура инициализирует глобальные динамические переменныеputs "\n proc Init_perCallVars start"
global SetupDone
set SetupDone 0
puts "\n proc Init_perCallVars finish"
}proc act_Setup { } {
# Процедура принимает входящий звонок и проигрывает приветсвие и просьбу о переводе телефона в тональный режим
puts "\n proc act_Setup start"
init_perCallVars
leg setupack leg_incoming
leg proceeding leg_incoming
leg connect leg_incoming
SelectMenuputs "\n proc act_Setup finish"
}
proc SelectMenu { } {
puts "\n proc SelectMenu start"
global param
global phonePatternmedia play leg_incoming %s500 _subscriberAbsent.au %s500 _subscriberBusy.au
# Первый файл в дальнейшем должен быть замещен приветствием и просьбой перевода телефона в тональный режим.
# Второй файл содержит информации по номерам
leg collectdigits leg_incoming param phonePatternputs "\n proc SelectMenu finish"
}proc CheckEnteredDigit { } {
# Процедура проверяет событиеputs "\n proc CheckEnteredDigit start"
set collect_status [infotag get evt_status]
switch $collect_status {
"cd_001" {
media play leg_incoming _nothingEntered.au
fsm setstate CALLCOMES
}
"cd_002" {
SelectMenu
fsm setstate CALLCOMES
}
"cd_005" {
fsm setstate PLACECALL
act_CallSetup
}
"cd_006" {
media play leg_incoming %s500 _wrongMenuPoint.au
fsm setstate CALLCOMES
}
}
}proc act_CallSetup { } {
# Процедура установки звонкаputs "\n proc act_CallSetup start"
global SetupDone
global customerSupport
global commercePhoneset SetupDone 1
set collect_digits [infotag get evt_dcdigits]
switch $collect_digits {
1 {
leg setup $commercePhone callinfo leg_incoming
}
2 {
leg setup $customerSupport callinfo leg_incoming
}
default {
media play leg_incoming _wrongMenuPoint.au
}
}
}proc act_CleanupT { } {
# Процедура завершения звонкаcall close
}requiredversion 2.0
init# FSM
set ivr_fsm(any_state,ev_disconnected) "act_Cleanup same_state"
set ivr_fsm(CALLCOMES,ev_setup_indication) "act_Setup same_state"
set ivr_fsm(CALLCOMES,ev_collectdigits_done) "CheckEnteredDigit CHECKENTERED"
set ivr_fsm(CHECKENTERED,ev_media_done) "SelectMenu CALLCOMES"
set ivr_fsm(PLACECALL,ev_media_done) "act_CallSetup samestate"
set ivr_fsm(CALLDISCONNECT,ev_disconnect_done) "act_Cleanup same_state"fsm define ivr_fsm CALLCOMES
На текущий момент нету следующего:
1. Необходимо после истечения таймаута проигрывать аушку типа вы ничего не набрали и будете соединены с техподдержкой и соединять с customerSupport.
2. После неверно набранной цифры, нужно сделать чтобы после проигрывания аушки "несуществующий пункт меню" абонент мог повторно нажать цифру и соединиться с нужным отделом.Буду думать дальше. Если у кого есть идеи - прошу поделиться.
>Поработал еще. Ситуация улучшается. На сегодня конфиг такой:
>
>proc init { } {
># Инициализация глобальных статических переменных
>
> puts "\n proc Init
>start"
>
> global param
> global phonePattern
> global commercePhone
> global customerSupport
>
> infotag set med_language_map 0
>ru
> infotag set med_location ru
>0 tftp://хххххххххххххххххххххххххххххххх
> infotag set med_location ru
>1 tftp://хххххххххххххххххххххххххххххххх
> infotag set med_language 0
>
>
> set param(initialDigitTimeout) 10
> set param(interruptPrompt) true
> set param(maxDigits) 1
> set phonePattern(1) {[1,2]}
>
># Телефонные номера служб "по умолчанию"
> set customerSupport "7хххххххххх"
> set commercePhone "7хххххххххх"
>
> puts "\n proc Init
>finish"
>
>}
>
>proc init_perCallVars { } {
># Процедура инициализирует глобальные динамические переменные
>
> puts "\n proc Init_perCallVars
>start"
>
> global SetupDone
>
> set SetupDone 0
>
> puts "\n proc Init_perCallVars
>finish"
>}
>
>proc act_Setup { } {
>
># Процедура принимает входящий звонок и проигрывает приветсвие и просьбу о переводе
>телефона в тональный режим
>
> puts "\n proc act_Setup
>start"
>
> init_perCallVars
> leg setupack leg_incoming
> leg proceeding leg_incoming
> leg connect leg_incoming
> SelectMenu
>
> puts "\n proc act_Setup
>finish"
>
>}
>
>proc SelectMenu { } {
>
> puts "\n proc SelectMenu
>start"
>
> global param
> global phonePattern
>
> media play leg_incoming %s500
>_subscriberAbsent.au %s500 _subscriberBusy.au
> # Первый файл в
>дальнейшем должен быть замещен приветствием и просьбой перевода телефона в тональный
>режим.
> # Второй файл содержит
>информации по номерам
> leg collectdigits leg_incoming param
>phonePattern
>
> puts "\n proc SelectMenu
>finish"
>}
>
>proc CheckEnteredDigit { } {
># Процедура проверяет событие
>
> puts "\n proc CheckEnteredDigit
>start"
>
> set collect_status [infotag get
>evt_status]
>
> switch $collect_status {
>
> "cd_001" {
>
> media play leg_incoming _nothingEntered.au
>
> fsm setstate CALLCOMES
>
> }
>
> "cd_002" {
>
> SelectMenu
>
> fsm setstate CALLCOMES
>
> }
>
> "cd_005" {
>
> fsm setstate PLACECALL
>
> act_CallSetup
>
> }
>
> "cd_006" {
>
> media play leg_incoming %s500 _wrongMenuPoint.au
>
> fsm setstate CALLCOMES
>
> }
> }
>}
>
>proc act_CallSetup { } {
># Процедура установки звонка
>
> puts "\n proc act_CallSetup
>start"
>
> global SetupDone
> global customerSupport
> global commercePhone
>
> set SetupDone 1
> set collect_digits [infotag get
>evt_dcdigits]
> switch $collect_digits {
>
> 1 {
>
> leg setup $commercePhone callinfo leg_incoming
>
> }
>
> 2 {
>
> leg setup $customerSupport callinfo leg_incoming
>
> }
>
> default {
>
> media play leg_incoming _wrongMenuPoint.au
>
> }
> }
>}
>
>proc act_CleanupT { } {
># Процедура завершения звонка
>
> call close
>}
>
>requiredversion 2.0
>init
>
># FSM
>set ivr_fsm(any_state,ev_disconnected)
> "act_Cleanup same_state"
>set ivr_fsm(CALLCOMES,ev_setup_indication)
> "act_Setup same_state"
>set ivr_fsm(CALLCOMES,ev_collectdigits_done)
> "CheckEnteredDigit CHECKENTERED"
>set ivr_fsm(CHECKENTERED,ev_media_done)
> "SelectMenu CALLCOMES"
>set ivr_fsm(PLACECALL,ev_media_done)
> "act_CallSetup samestate"
>
>set ivr_fsm(CALLDISCONNECT,ev_disconnect_done) "act_Cleanup
>same_state"
>
>fsm define ivr_fsm CALLCOMES
>
>На текущий момент нету следующего:
>1. Необходимо после истечения таймаута проигрывать аушку типа вы ничего не набрали
>и будете соединены с техподдержкой и соединять с customerSupport.
>2. После неверно набранной цифры, нужно сделать чтобы после проигрывания аушки "несуществующий
>пункт меню" абонент мог повторно нажать цифру и соединиться с нужным
>отделом.
>
>Буду думать дальше. Если у кого есть идеи - прошу поделиться.
hsq@inbox.ruЕсли у вас все получилось, пожалуйста, будьте любезны поделиться скриптом.
Финальный скрипт выглядит следующим образом:proc init { } {
# Инициализация глобальных статических переменных
puts "\n proc Init start"
global param
global phonePattern
global commercePhone
global customerSupportinfotag set med_language_map 0 ru
infotag set med_location ru 0 tftp://ххххххххххххххххххххххххххххххх
infotag set med_location ru 1 tftp://ххххххххххххххххххххххххххххххх
infotag set med_language 0set param(initialDigitTimeout) 10
set param(maxDigits) 1
set phonePattern(1) {[1,2]}
# Телефонные номера служб "по умолчанию"
set customerSupport "7хххххххххх"
set commercePhone "7хххххххххх"
puts "\n proc Init finish"}
proc init_perCallVars { } {
# Процедура инициализирует глобальные динамические переменные
puts "\n proc Init_perCallVars start"
global PressedKey
global Statusif { [info exists PressedKey] } { unset PressedKey }
if { [info exists Status] } { unset Status }
# Сразу же сбрасываем переменные на всякий случайputs "\n proc Init_perCallVars finish"
}proc act_Setup { } {
# Процедура принимает входящий звонок, т.е. снимает трубку
puts "\n proc act_Setup start"init_perCallVars
leg setupack leg_incoming
leg proceeding leg_incoming
leg connect leg_incomingPlay_Intro_Sound
puts "\n proc act_Setup finish"
}proc Play_Intro_Sound { } {
# Процедура проигрывает приветствиеputs "\n proc Play_Intro_Sound start"
media play leg_incoming %s500 _hello.au
fsm setstate CHECKENTEREDputs "\n proc Play_Intro_Sound finish"
}proc SelectMenu { } {
# Процедура проигрывает файл с информацией по номерам и собирает нажатую цифруputs "\n proc SelectMenu start"
global param
global phonePattern
global PressedKey
global Statusset param(interruptPrompt) true
# Разрешаем прервать звуковой файл
if { [info exists PressedKey] } { unset PressedKey }
if { [info exists Status] } { unset Status }
# Сбрасываем значение переменных если они уже присвоены
media play leg_incoming %s1000 _phones.au
# Файл содержит информации по номерам
leg collectdigits leg_incoming param phonePattern
# Собираем набранные цифры и проверям соответствуют ли они нашему шаблону
puts "\n proc SelectMenu finish"
}proc CheckEnteredDigit { } {
# Процедура проверяет событие
puts "\n proc CheckEnteredDigit start"global Status
global PressedKey
set Status [infotag get evt_status]
set PressedKey [infotag get evt_dcdigits]
switch $Status {
"cd_001" {
# НИчего не введено - сработал таймаут
media play leg_incoming _redirect.au
fsm setstate CALLNOTHING
}
#"cd_002" {
#SelectMenu
#fsm setstate CALLCOMES
#}
"cd_005" {
# Сделан корректный выбор - соединяем с требуемым отделом
fsm setstate PLACECALL
act_CallSetup
}
"cd_006" {
media play leg_incoming _wrongMenuPoint.au
# Выбран несуществующий пункт меню
fsm setstate CALLNOTHING
}
"cd_007" {
# Сбор цифры был прерван - пользователь повесил трубку
fsm setstate CALLDISCONNECT
}
}
puts "\n proc CheckEnteredDigit finish"
}proc act_CallSupport { } {
# После таймаута и проигрывания файла соединяем пользователя с техподдержкой
puts "\n proc act_CallSupport start"global customerSupport
leg setup $customerSupport callinfo leg_incoming
puts "\n proc act_CallSupport finish"
}
proc act_CallSetup { } {
# Процедура установки звонкаputs "\n proc act_CallSetup start"
global customerSupport
global commercePhone
global PressedKeyset PressedKey [infotag get evt_dcdigits]
switch $PressedKey {
"1" {
leg setup $commercePhone callinfo leg_incoming
}
"2" {
leg setup $customerSupport callinfo leg_incoming
}
default {
media play leg_incoming _wrongMenuPoint.au
fsm setstate CHECKENTERED
}
}
}proc act_Cleanup { } {
# Процедура завершения звонкаcall close
}requiredversion 2.0
init# FSM
set ivr_fsm(any_state,ev_disconnected) "act_Cleanup same_state"
set ivr_fsm(CALLCOMES,ev_setup_indication) "act_Setup same_state"
set ivr_fsm(CALLCOMES,ev_collectdigits_done) "CheckEnteredDigit CHECKENTERED"
set ivr_fsm(CALLNOTHING,ev_media_done) "act_CallSupport same_state"
set ivr_fsm(CHECKENTERED,ev_media_done) "SelectMenu CALLCOMES"
set ivr_fsm(PLACECALL,ev_media_done) "act_CallSetup same_state"
set ivr_fsm(CALLDISCONNECT,ev_disconnect_done) "act_Cleanup same_state"fsm define ivr_fsm CALLCOMES
А на конфиг циски взлянуть бы еще.