Инструменты пользователя

Инструменты сайта


configure_freepbx_for_cloud_version

Различия

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

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
configure_freepbx_for_cloud_version [2017/09/14 09:34]
Евгений Романенко
configure_freepbx_for_cloud_version [2023/02/16 13:47] (текущий)
Евгений Романенко
Строка 2: Строка 2:
  
 ==== Вводная ==== ==== Вводная ====
-  * Данная инструкция написана используя FreePBX версии 13.0.191.11 с Asterisk 13.14.0 на борту. \\ При возникновении каких-либо сложностей/​вопросов с более ранними/​поздними версиями системы,​ просьба написать нам на <​support@vistep.ru>​.+  * Данная инструкция написанаиспользуя FreePBX версии 13.0.191.11 с Asterisk 13.14.0 на борту. \\ При возникновении каких-либо сложностей/​вопросов с более ранними/​поздними версиями системы,​ просьба написать нам на <​support@vistep.ru>​.
   * Для выполнения описанных ниже действий понадобится:​ \\ - умение подключиться к серверу по ssh \\ - умение редактировать файлы в текстовом редакторе (nano/​vim/​emacs/​etc) \\ - ясная голова и хорошее настроение ;-)   * Для выполнения описанных ниже действий понадобится:​ \\ - умение подключиться к серверу по ssh \\ - умение редактировать файлы в текстовом редакторе (nano/​vim/​emacs/​etc) \\ - ясная голова и хорошее настроение ;-)
  
 ==== Настройка ==== ==== Настройка ====
-В поставке по умолчанию (что называется "из коробки"​) FreePBX ведет БД asteriskcdrdb,​ а точнее табличку cdr, не совсем так, как это нужно для правильной работы системы статистики ViStep.RU. Такжеона совсем не ведет записи ​в таблицу queue_log, что является необходимым. \\ Поэтому нам потребуется выполнить несколько шагов настройки,​ для достижения нужного поведения FreePBX.+В поставке по умолчанию (что называется "из коробки"​) FreePBX ведет БД asteriskcdrdb,​ а точнее табличку cdr, не совсем так, как это нужно для правильной работы системы статистики ViStep.RU. Также она совсем не пишет в таблицу queue_log, что является необходимым. \\ Поэтому нам потребуется выполнить несколько шагов настройки,​ для достижения нужного поведения FreePBX.
   - Начнем с таблицы cdr. \\ Подключимся к серверу по ssh, а затем к консоли MySQL-сервера <code bash>​[root@localhost ~]# mysql asteriskcdrdb ​   - Начнем с таблицы cdr. \\ Подключимся к серверу по ssh, а затем к консоли MySQL-сервера <code bash>​[root@localhost ~]# mysql asteriskcdrdb ​
 Welcome to the MySQL monitor. ​ Commands end with ; or \g. Welcome to the MySQL monitor. ​ Commands end with ; or \g.
Строка 28: Строка 28:
 END $$ END $$
 DELIMITER ; DELIMITER ;
- </​code>​ При успешном выполнении запросов все должно выглядеть примерно вот так: {{https://i.your-admin.pro/​i/​db8d2543734bb135bdf8c97348a6.png}} {{https://i.your-admin.pro/​i/​3e7f9092a8223081d718eeff6453.png}} + </​code>​ При успешном выполнении запросов все должно выглядеть примерно вот так: {{https://img.vistep.ru/​i/​db8d2543734bb135bdf8c97348a6.png}} {{https://img.vistep.ru/​i/​3e7f9092a8223081d718eeff6453.png}} 
-  - Совершим вызов и проверим,​ что поле filename заполняется {{https://i.your-admin.pro/​i/​e2659473414c0af4ae19163751fd.png}} +  - Совершим вызов и проверим,​ что поле filename заполняется {{https://img.vistep.ru/​i/​e2659473414c0af4ae19163751fd.png}} 
-  - Теперь нам необходимо ​изменить ​логику заполнения полей dst и src в таблице cdr так, чтобы в них всегда попадали ​те номерана которые/с которых поступил вызов (например,​ не номер оператора очереди,​ а наш городской номер, на который пришел вызов извне для ​dst или не номер транка,​ а номер внутреннего абонента для ​src). \\ Для этого ​отредактируем файл cdr_adaptive_odbc.conf (FreePBX не перетрет его после рестарта,​ поэтому можно смело его редактировать), добавив в самом низу строку ​<​code ​bash>alias realdst ​=> dst +  - Теперь нам необходимо ​добавить ​два новых ​поля в таблицу cdr - realdst и realsrc, в которые будут записываться ​номера ​звонящего и назначения ​(например,​ не номер оператора очереди,​ а наш городской номер, на который пришел вызов извне для ​realdst ​или не номер транка,​ а номер внутреннего абонента для ​realsrc). \\ Для этого ​выполним sql-запросы <​code ​sql>ALTER TABLE `cdr` ADD `realsrc` VARCHAR(80) NOT NULL DEFAULT '';​ 
-alias realsrc =src</​code>​ В итоге он примет вид: {{https://​i.your-admin.pro/​i/​23eeef966abc49cb214bd5795912.png}} +ALTER TABLE `cdr` ADD `realdst` VARCHAR(80) NOT NULL DEFAULT '';​ 
-  - Дабы наши действия возымели силу, модулю cdr_adaptive_mysql.so нужно подсказать,​ что его конфиг изменился. Подключаемся к консоли asterisk и релоадим модуль вот так: <code bash>​[root@localhost asterisk]# asterisk -r +UPDATE cdr SET realsrc=src; 
-localhost*CLI>​ module reload cdr_adaptive_odbc.so +UPDATE cdr SET realdst=dst;​</​code>​ 
-Module '​cdr_adaptive_odbc.so'​ reloaded successfully. +  - Пришло время последнего,​ но отнюдь не маловажного шага в разрезе конфигурирования таблицы cdr - научим АТС записывать данные во вновь ​созданные поля. \\ \\ Отредактируйте /​etc/​asterisk/​extensions_override_freepbx.confвнеся в него <​code>​[ext-did-catchall] 
-localhost*CLI>  ​</​code>​ +include => ext-did-catchall-custom 
-  - Пришло время последнего,​ но отнюдь не маловажного шага в разрезе конфигурирования таблицы cdr. \\ В web-интерфейсе FreePBX ​отправимся по пути "​Admin->​ Config Edit", где в extensions_custom.conf внесем: <​code ​bash>[from-internal+exten => _.,1,Noop(Catch-All DID Match - Found ${EXTEN} - You probably want a DID for this.) 
-exten => _X.,1,GoSub(set_right_src_dst_from-internal,start,1(${EXTEN},​${CALLERID(num)}))+exten => _.,n,Set(__FROM_DID=${EXTEN}
 +exten => _.,n,​Set(_VISTEPRUREALDST=${FROM_DID}) 
 +exten => _.,​n,​Set(_VISTEPRUREALSRC=${CALLERID(num)}) 
 +exten => _.,​n,​Set(CDR(realsrc)=${VISTEPRUREALSRC}) 
 +exten => _.,​n,​Set(CDR(realdst)=${VISTEPRUREALDST}) 
 +exten => _.,​n,​Goto(ext-did,​s,​1)
  
-[from-pstn-custom+[sub-record-check] 
-exten => _X.,1,GoSub(set_right_src_dst_from-pstn,start,1(${EXTEN},${CALLERID(num)}))+include => sub-record-check-custom 
 +exten => s,1,GotoIf($[${LEN(${FROMEXTEN})}]?​initialized) 
 +exten => s,​n,​Set(__REC_STATUS=INITIALIZED) 
 +exten => s,​n,​Set(NOW=${EPOCH}) 
 +exten => s,​n,​Set(__DAY=${STRFTIME(${NOW},,​%d)}) 
 +exten => s,​n,​Set(__MONTH=${STRFTIME(${NOW},,​%m)}) 
 +exten => s,​n,​Set(__YEAR=${STRFTIME(${NOW},,​%Y)}) 
 +exten => s,​n,​Set(__TIMESTR=${YEAR}${MONTH}${DAY}-${STRFTIME(${NOW},,%H%M%S)}) 
 +exten => s,n,Set(__FROMEXTEN=${IF($[${LEN(${AMPUSER})}]?​${AMPUSER}:​${IF($[${LEN(${REALCALLERIDNUM})}]?​${REALCALLERIDNUM}:​unknown)})}) 
 +exten => s,n,​Set(__MON_FMT=${IF($["​${MIXMON_FORMAT}"​="​wav49"​]?​WAV:​${MIXMON_FORMAT})}) 
 +exten => s,​n(initialized),​Noop(Recordings initialized) 
 +exten => s,​n,​ExecIf($[!${LEN(${ARG3})}]?​Set(ARG3=dontcare)) 
 +exten => s,​n,​Set(REC_POLICY_MODE_SAVE=${REC_POLICY_MODE}) 
 +exten => s,​n,​ExecIf($["​${BLINDTRANSFER}${ATTENDEDTRANSFER}"​ != ""​]?​Set(REC_STATUS=NO)) 
 +exten => s,​n(next),​GotoIf($[${LEN(${ARG1})}]?​checkaction) 
 +exten => s,​n(recorderror),​Playback(something-terribly-wrong,​error) 
 +exten => s,​n,​Hangup 
 +exten => s,​n(checkaction),​GotoIf($[${DIALPLAN_EXISTS(sub-record-check,​${ARG1})}]?​sub-record-check,​${ARG1},​1) 
 +exten => s,​n,​Noop(Generic ${ARG1} Recording Check - ${FROMEXTEN} ${ARG2}) 
 +exten => s,​n,​Gosub(recordcheck,​1(${ARG3},​${ARG1},​${ARG2})) 
 +exten => s,n,Return()
  
-[set_right_src_dst_from-pstn+exten => recordcheck,​1,​Noop(Starting recording check against ${ARG1}) 
-exten => start,1,Set(__FROMPSTNCALL=1+exten => recordcheck,​n,​Goto(${ARG1}) 
- same => n,​Set(CDR(realdst)=${ARG1}) +exten => recordcheck,​n(dontcare),​Return() 
- same => n,​Set(CDR(realsrc)=${ARG2}) +exten => recordcheck,​n(always),​Noop(Detected legacy "​always"​ entry. Mapping to "​force"​) 
- same => n,Return()+exten => recordcheck,​n(force),​Set(__REC_POLICY_MODE=FORCE) 
 +exten => recordcheck,​n,​GotoIf($["​${REC_STATUS}"​!="​RECORDING"​]?startrec) 
 +exten => recordcheck,n,​Return() 
 +exten => recordcheck,​n(delayed),​Noop(Detected legacy "​delayed"​ entry. Mapping to "​yes"​) 
 +exten => recordcheck,​n(yes),​ExecIf($["​${REC_POLICY_MODE}"​ = "​NEVER"​ | "​${REC_POLICY_MODE}"​ = "​NO"​ | "​${REC_STATUS}"​ = "​RECORDING"​]?​Return()) 
 +exten => recordcheck,​n,Set(__REC_POLICY_MODE=YES
 +exten => recordcheck,​n,Goto(startrec) 
 +exten => recordcheck,​n(no),​Set(__REC_POLICY_MODE=NO) 
 +exten => recordcheck,​n,​Return() 
 +exten => recordcheck,​n(never),​Set(__REC_POLICY_MODE=NEVER) 
 +exten => recordcheck,​n,​Goto(stoprec) 
 +exten => recordcheck,​n(startrec),​Noop(Starting recording: ${ARG2}, ${ARG3}) 
 +exten => recordcheck,​n,​Set(AUDIOHOOK_INHERIT(MixMonitor)=yes) 
 +exten => recordcheck,​n,​ExecIF($[${LEN(${VISTEPRUREALDST})}]?​NoOP():​Set(CDR(realdst)=${ARG3})
 +exten => recordcheck,​n,ExecIF($[${LEN(${VISTEPRUREALSRC})}]?​NoOP():​Set(CDR(realsrc)=${FROMEXTEN})) 
 +exten => recordcheck,​n,​Set(__CALLFILENAME=${ARG2}-${ARG3}-${FROMEXTEN}-${TIMESTR}-${UNIQUEID}) 
 +exten => recordcheck,​n,​MixMonitor(${MIXMON_DIR}${YEAR}/​${MONTH}/​${DAY}/​${CALLFILENAME}.${MON_FMT},​abi(LOCAL_MIXMON_ID)${MIXMON_BEEP},​${MIXMON_POST}) 
 +exten => recordcheck,​n,​Set(__MIXMON_ID=${LOCAL_MIXMON_ID}) 
 +exten => recordcheck,​n,​Set(__RECORD_ID=${CHANNEL(name)}) 
 +exten => recordcheck,​n,​Set(__REC_STATUS=RECORDING) 
 +exten => recordcheck,​n,​Set(CDR(recordingfile)=${CALLFILENAME}.${MON_FMT}) 
 +exten => recordcheck,​n,​Return() 
 +exten => recordcheck,​n(stoprec),​Noop(Stopping recording: ${ARG2}, ${ARG3}) 
 +exten => recordcheck,​n,​Set(__REC_STATUS=STOPPED) 
 +exten => recordcheck,​n,​System(${AMPBIN}/​stoprecording.php "​${CHANNEL(name)}"​) 
 +exten => recordcheck,​n,Return()
  
-[set_right_src_dst_from-internal+exten => out,​1,​Noop(Outbound Recording Check from ${FROMEXTEN} to ${ARG2}) 
-exten => start,1,ExecIF(${FROMPSTNCALL}?Set(CDR_PROP(disable)=true):​Set(CDR(realdst)=${ARG1})) +exten => out,​n,​Set(CDR(realsrc)=${FROMEXTEN}) 
- same => n,​Set(CDR(realsrc)=${ARG2}) +exten => out,​n,​Set(CDR(realdst)=${ARG2}) 
- same => n,​Return() +exten => out,​n,​Set(CUTTEDCHANNEL=${CUT(CHANNEL,,​1)}) 
-  +exten => out,​n,​Set(CUTTEDCHANNEL=${CUT(CUTTEDCHANNEL,/,​2)}) 
-</​code> ​А вот и скриндля наглядности {{:​screen_shot_2017-09-14_at_09.34.12.png|}} ​ В завершении кликнем ​Save, затем ​Apply Config, позвоним на АТС, с АТС вовне и проверим корректность заполнения поля dst.+exten => out,​n,​ExecIf($["​${FROMEXTEN}"​ = "​${ARG2}"​]?​Set(CDR(realsrc)=${CUTTEDCHANNEL})) 
 +exten => out,​n,​Set(RECMODE=${DB(AMPUSER/​${FROMEXTEN}/​recording/​out/​external)}) 
 +exten => out,​n,​ExecIf($[!${LEN(${RECMODE})} | "​${RECMODE}"​ = "​dontcare"​]?​Goto(routewins)) 
 +exten => out,​n,​ExecIf($["​${ARG3}"​ = "​never"​ | "​${ARG3}"​ = "​force"​]?​Goto(routewins)) 
 +exten => out,​n(extenwins),​Gosub(recordcheck,1(${RECMODE},out,​${ARG2})) 
 +exten => out,​n,​Return() 
 +exten => out,​n(routewins),​Gosub(recordcheck,​1(${ARG3},​out,​${ARG2})) 
 +exten => out,​n,​Return() 
 + 
 +exten => in,​1,​Noop(Inbound Recording Check to ${ARG2}) 
 +exten => in,​n,​Set(FROMEXTEN=unknown) 
 +exten => in,​n,​ExecIf($[${LEN(${FROM_DID})}]?Set(_VISTEPRUREALDST=${FROM_DID})) 
 +exten => in,n,ExecIf($[${LEN(${CALLERID(num)})}]?​Set(FROMEXTEN=${CALLERID(num)})) 
 +exten => in,​n,​ExecIf($[${LEN(${VISTEPRUREALDST})}]?​NoOp("​=== VISTEPRUREALDST has already been set ==="):Set(_VISTEPRUREALDST=${ARG2})) 
 +exten => in,​n,​ExecIf($[${LEN(${VISTEPRUREALSRC})}]?​NoOp("​=== VISTEPRUREALSRC has already been set ==="​):​Set(_VISTEPRUREALSRC=${FROMEXTEN})) 
 +exten => in,​n,​Set(CDR(realsrc)=${VISTEPRUREALSRC}) 
 +exten => in,n,Set(CDR(realdst)=${VISTEPRUREALDST}) 
 +exten => in,​n,​Gosub(recordcheck,​1(${ARG3},​in,​${ARG2})) 
 +exten => in,n,Return() 
 + 
 +exten => exten,​1,​Noop(Exten Recording Check between ${FROMEXTEN} and ${ARG2}) 
 +exten => exten,​n,​ExecIF($[${LEN(${VISTEPRUREALDST})}]?​NoOP():​Set(CDR(realdst)=${ARG2})) 
 +exten => exten,​n,​ExecIF($[${LEN(${VISTEPRUREALSRC})}]?​NoOP():​Set(CDR(realsrc)=${FROMEXTEN})) 
 +exten => exten,​n,​Set(CDR(cnum)=${FROMEXTEN}) 
 +exten => exten,​n,​Set(CALLTYPE=${IF($[${LEN(${FROM_DID})}]?​external:​internal)}) 
 +exten => exten,​n,​ExecIf(${LEN(${CALLTYPE_OVERRIDE})}?​Set(CALLTYPE=${CALLTYPE_OVERRIDE})) 
 +exten => exten,​n,​Set(CALLEE=${DB(AMPUSER/​${ARG2}/​recording/​in/​${CALLTYPE})}) 
 +exten => exten,​n,​ExecIf($[!${LEN(${CALLEE})}]?​Set(CALLEE=dontcare)) 
 +exten => exten,​n,​GotoIf($["​${CALLTYPE}"​="​external"​]?​callee) 
 +exten => exten,​n,​GotoIf($["​${CALLEE}"​="​dontcare"​]?​caller) 
 +exten => exten,​n,​ExecIf($[${LEN(${DB(AMPUSER/​${FROMEXTEN}/​recording/​priority)})}]?​Set(CALLER_PRI=${DB(AMPUSER/​${FROMEXTEN}/​recording/​priority)}):​Set(CALLER_PRI=0)) 
 +exten => exten,​n,​ExecIf($[${LEN(${DB(AMPUSER/​${ARG2}/​recording/​priority)})}]?​Set(CALLEE_PRI=${DB(AMPUSER/​${ARG2}/​recording/​priority)}):​Set(CALLEE_PRI=0)) 
 +exten => exten,​n,​GotoIf($["​${CALLER_PRI}"​="​${CALLEE_PRI}"​]?​${REC_POLICY}:​${IF($[${CALLER_PRI}>​${CALLEE_PRI}]?​caller:​callee)}) 
 +exten => exten,​n(callee),​Gosub(recordcheck,​1(${CALLEE},​${CALLTYPE},​${ARG2})) 
 +exten => exten,n,​Return() 
 +exten => exten,​n(caller),​Set(RECMODE=${DB(AMPUSER/​${FROMEXTEN}/​recording/​out/​internal)}) 
 +exten => exten,​n,​ExecIf($[!${LEN(${RECMODE})}]?​Set(RECMODE=dontcare)) 
 +exten => exten,​n,​ExecIf($["​${RECMODE}"​="​dontcare"​]?​Set(RECMODE=${CALLEE})) 
 +exten => exten,​n,​Gosub(recordcheck,​1(${RECMODE},​${CALLTYPE},​${ARG2})) 
 +exten => exten,​n,​Return() 
 + 
 +exten => conf,​1,​Noop(Conference Recording Check ${FROMEXTEN} to ${ARG2}) 
 +exten => conf,​n,​Gosub(recconf,​1(${ARG2},​${ARG2},​${ARG3})) 
 +exten => conf,​n,​Return() 
 + 
 +exten => page,​1,​Noop(Paging Recording Check ${FROMEXTEN} to ${ARG2}) 
 +exten => page,​n,​GosubIf($["​${REC_POLICY_MODE}"​="​always"​]?​recconf,​1(${ARG2},​${FROMEXTEN},​${ARG3})) 
 +exten => page,​n,​Return() 
 + 
 +exten => recconf,​1,​Noop(Setting up recording: ${ARG1}, ${ARG2}, ${ARG3}) 
 +exten => recconf,​n,​Set(__CALLFILENAME=${IF($[${CONFBRIDGE_INFO(parties,​${ARG2})}]?​${DB(RECCONF/​${ARG2})}:​${ARG1}-${ARG2}-${ARG3}-${TIMESTR}-${UNIQUEID})}) 
 +exten => recconf,​n,​ExecIf($[!${CONFBRIDGE_INFO(parties,​${ARG2})}]?​Set(DB(RECCONF/​${ARG2})=${CALLFILENAME})) 
 +exten => recconf,​n,​Set(CONFBRIDGE(bridge,​record_file)=${MIXMON_DIR}${YEAR}/​${MONTH}/​${DAY}/​${CALLFILENAME}.${MON_FMT}) 
 +exten => recconf,​n,​ExecIf($["​${ARG3}"​!="​always"​]?​Return()) 
 +exten => recconf,​n,​Set(CONFBRIDGE(bridge,​record_conference)=yes) 
 +exten => recconf,​n,​Set(__REC_STATUS=RECORDING) 
 +exten => recconf,​n,​Set(CDR(recordingfile)=${IF($[${CONFBRIDGE_INFO(parties,​${ARG2})}]?​${CALLFILENAME}.${MON_FMT}:​${CALLFILENAME}.${MON_FMT})}) 
 +exten => recconf,​n,​Noop(${MIXMONITOR_FILENAME}) 
 +exten => recconf,​n,​Set(CHANNEL(hangup_handler_push)=sub-record-hh-check,​s,​1) 
 +exten => recconf,​n,​Return() 
 + 
 +exten => recq,​1,​Noop(Setting up recording: ${ARG1}, ${ARG2}, ${ARG3}) 
 +exten => recq,​n,​Set(AUDIOHOOK_INHERIT(MixMonitor)=yes) 
 +exten => recq,​n,​Set(MONITOR_FILENAME=${MIXMON_DIR}${YEAR}/​${MONTH}/​${DAY}/​${CALLFILENAME}) 
 +exten => recq,​n,​MixMonitor(${MONITOR_FILENAME}.${MON_FMT},​${MONITOR_OPTIONS}${MIXMON_BEEP},​${MIXMON_POST}) 
 +exten => recq,​n,​Set(__REC_STATUS=RECORDING) 
 +exten => recq,​n,​Set(CDR(recordingfile)=${CALLFILENAME}.${MON_FMT}) 
 +exten => recq,​n,​Return() 
 + 
 +exten => parking,​1,​Noop(User ${ARG2} picked up a parked call) 
 +exten => parking,​n,​Set(USER=${ARG2}) 
 +exten => parking,​n,​ExecIf($[!${LEN(${ARG2})}]?​Set(USER=unknown)) 
 +exten => parking,​n,​Set(RECMODE=${DB(AMPUSER/​${ARG2}/​recording/​out/​internal)}) 
 +exten => parking,​n,​ExecIf($[!${LEN(${RECMODE})}]?​Set(RECMODE=dontcare)) 
 +exten => parking,​n,​Gosub(recordcheck,​1(${RECMODE},​parked,​${USER})) 
 +exten => parking,​n,​Return() 
 + 
 +;--== end of [sub-record-check] ==--;</​code> ​\\ после чего ​выполните команду <​code>​dialplan reload</​code>​ в консоли Asterisk \\ **Код проверен на FreePBX 13.0.191.11,​ 14.0.2.10 ​и 15.0.23.25.** \\ Если мажорная (13 в данном примере) версия FreePBX ​ у вас отличается,​ то контекст [sub-record-check] ​может быть немного другим. Напишите ​нам на <​support@vistep.ru> ​и мы поможем с написанием диалплана данного контекста
   - С cdr разобрались,​ дело за queue_log. Эта таблица нужна нам для того, чтобы понимать какие события происходили в очередях Asterisk. Перво-наперво создадим ее <code sql>​CREATE TABLE `queue_log` (   - С cdr разобрались,​ дело за queue_log. Эта таблица нужна нам для того, чтобы понимать какие события происходили в очередях Asterisk. Перво-наперво создадим ее <code sql>​CREATE TABLE `queue_log` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,​  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,​
Строка 69: Строка 196:
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;</​code>​ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;</​code>​
   - Научим FreePBX(читай Asterisk) писать туда все то, что нам нужно. \\ Отправляемся в web-интерфейс по знакомой дорожке и создаем новый файл под именем **extconfig.conf**,​ кликнув Add New File. \\ Внести в него нужно лишь одну строчку <code bash>​[settings]   - Научим FreePBX(читай Asterisk) писать туда все то, что нам нужно. \\ Отправляемся в web-интерфейс по знакомой дорожке и создаем новый файл под именем **extconfig.conf**,​ кликнув Add New File. \\ Внести в него нужно лишь одну строчку <code bash>​[settings]
-queue_log => odbc,​asteriskcdrdb</​code>​ Скрин: {{https://i.your-admin.pro/​i/​5347bc8b8a5a1f66dd9c87a7c980.png}} *не забываем про Save и Apply Configs \\ После выполнения данных действий и совершения звонков в очереди,​ запрос из консоли mysql <code sql>​select * from queue_log;</​code>​ должен вернуть вам нечто подобное {{https://i.your-admin.pro/​i/​7d2a89142a30ddd7ea0c36e2443b.png}} *на запрос в скрине не ориентируйтесь,​ там я специально добавил условие,​ чтобы сократить выхлоп +queue_log => odbc,​asteriskcdrdb</​code>​ Скрин: {{https://img.vistep.ru/​i/​5347bc8b8a5a1f66dd9c87a7c980.png}} *не забываем про Save и Apply Configs \\ После выполнения данных действий и совершения звонков в очереди,​ запрос из консоли mysql <code sql>​select * from queue_log;</​code>​ должен вернуть вам нечто подобное {{https://img.vistep.ru/​i/​7d2a89142a30ddd7ea0c36e2443b.png}} *на запрос в скрине не ориентируйтесь,​ там я специально добавил условие,​ чтобы сократить выхлоп 
-  - С препарированием нашей АТС по части БД закончили! \\ Переходим к настройке синхронизации БД и файлов записей разговоров в облако ViStep.RU. ​\\ После того, как ​вы получите ​ссылку для входа в систему,​ логин и пароль, вам необходимо авторизироваться и кликнуть меню "Настройки->​Основные" \\ В скринах это будет выглядеть так: {{https://​i.your-admin.pro/​i/​37d973a33476853c1ec5572739b8.png}} {{https://i.your-admin.pro/i/​df31b32f5c79d79b3d5e754a9e7d.png}} +  - С препарированием нашей АТС по части БД закончили! \\ Переходим к настройке синхронизации БД и файлов записей разговоров в облако ViStep.RU. ​Для этого воспользуйтесь инструкцией - https://wiki.vistep.ru/doku.php?​id=cloud_daemon_sync ​ 
-  - Укажите путь к файлам записей разговоров (в FreePBX это обычно /​var/​spool/​asterisk/​monitor/​) и нажмите кнопку "Сохранить",​ после чего появится возможность скачать архив со скриптом ​синхронизации {{https://​i.your-admin.pro/​i/​d50e6f2d0cc49e4928408647a656.png}} +  - Для входа в систему статистики используйте данные авторизации (Emailдрес/Парольиз регистрационного письма.
-  - Заугрузите на сервер скачанный архив в папку /opt (например, используя scp или FileZilla) +
-  - Далее просто листинг команд, дабы не перегружать текст <code bash>​[root@localhost ~]# cd /opt/ +
-[root@localhost opt]# mkdir -p stat.vistep.ru +
-[root@localhost opt]# mv Fb38f1218c6.zip stat.vistep.ru/​ +
-[root@localhost opt]# cd stat.vistep.ru/​ +
-[root@localhost stat.vistep.ru]#​ unzip Fb38f1218c6.zip +
-[root@localhost stat.vistep.ru]#​ rm -f Fb38f1218c6.zip +
-</​code>​ по окончании у нас должно ​получиться так {{https://​i.your-admin.pro/​i/​b400005bee1f1c47b2fe04634b4e.png}} +
-  - В скрипте **stat.vistep.ru.js** ​уже практически все учтено,​ нам остается только вбить ​данные ​доступа к БД. Откроем файл **stat.vistep.ru.js** ​в любимом текстовом ​редакторе и внесем нужные ​изменения в строках 393-397 <code javascript>//​ Исправляем все что ниже под себя +
-"​dbhost":"​localhost",​ +
-"​dbuser":"​freepbxuser",​ +
-"​dbpassword":"​1230239dkl8c5ef2rf497aeb523f1d117cdb",​ +
-"​db":"​asteriskcdrdb",​ // <​--- ​имя БД +
-"​timezone":"​Europe/​Moscow",​ // <--- часовой пояс +
-"​fileMask": ​ /\.*/  // <​--- ​регулярка, ​если нужно синкать все файлы +
- +
-//  далее ничего не трогаем</​code>​ *Логин и пароль ​для доступа к БД вы найдете в файле **/​etc/​asterisk/​res_odbc_additional.conf** +
-  - Мы почти у цели, остался последний штрих. \\ Скрипт нужно ​запустить,​ но не только запустить,​ а еще и форкнуть ​его (говоря по-русски нужно чтобы ​скрипт остался в работе после того, как мы отключимся от сервера,​ т.е. работал бы как любой другой демон в ОС). \\ Такой функционал обеспечит замечательный ​ [[http://​pm2.keymetrics.io|proccess meneger pm2]]. \\ Установим pm2 и отдадим в его руки управление скриптом <code bash>npm install pm2 -g  +
-pm2 start /opt/stat.vistep.ru/​stat.vistep.ru.js --name "​ViStep.RU stat"​ +
-pm2 startup centos6 +
-pm2 save</​code>​+
  
-На этом все настройки завершены. \\ Если вы все сделали правильно,​ то через какое-то время (зависит от размера БД) сможете воспользоваться всеми отчетами системы статистики ViStep.RU в своем личном кабинете. \\ Повторюсь,​ если у вас остались вопросы и/или есть предложения/​замечания,​ пишите нам на <​support@vistep.ru>​. +На этом все настройки завершены. \\ Если вы все сделали правильно,​ то через какое-то время (зависит от размера БД) сможете воспользоваться всеми отчетами системы статистики ViStep.RU в своем личном кабинете. \\ Повторюсь,​ если у вас остались вопросы и/или есть предложения/​замечания,​ пишите нам на <​support@vistep.ru>​. ​
- +
configure_freepbx_for_cloud_version.1505356480.txt.gz · Последние изменения: 2017/09/14 09:34 — Евгений Романенко