[СТАТЬЯ] Оценка работы оператора FreePBX+Asterisk | 2019

Asterisk, FreePBX

Оценка работы оператора FreePBX+Asterisk

ocenka-raboty-operatora-freepbxasterisk

ocenka-raboty-operatora-freepbxasterisk



Задача:

1) Есть группа операторов Call-центра, нужно сделать возможность после разговора, оценивать звонок.
2) Максимальная интеграция с FreePBX.

Решение:

В Интернете много вариантов, все они ориентированы на чистый Asterisk.
Примеры:
https://wiki.merionet.ru/ip-telephoniya/55/ocenka-raboty-operatora-posle-zvonka-na-asterisk/
https://habr.com/ru/post/147122/
http://asterisk-service.com/blog/asterisk-1/post/2-0-53
Моя же реализация заключается в том, что все настройки можно делать в Web-интерфейсе FreePBX.
Реализация тестировалась и работает на:
— версии Asterisk 1.8.10.1
— FreePBX версии 12.0.76.6
— PHP версии 5.3.10-1ubuntu3.26
— библиотека PHPAGI версии 2.20 2010/09/30 02:21:00 (качаем тут: phpagi.zip)

Первым делом нам нужно определить как генерируется постановка вызова в очередь. Выполняем на сервере Asterisk:
nano /etc/asterisk/extensions_additional.conf
Ищем контекст с названием [ext-queues]. Внутри должны быть строки вида

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
[ext-queues]
include => ext-queues-custom
exten => 11,1,Macro(user-callerid,)
exten => 11,n,Answer
exten => 11,n,Macro(blkvm-set,reset)
exten => 11,n,ExecIf($["${REGEX("(M[(]auto-blkvm[)])" ${DIAL_OPTIONS})}" != "1"]?Set(_DIAL_OPTIONS=${DIAL_OPTIONS}M(auto-blkvm)))
exten => 11,n,Set(__NODEST=${EXTEN})
exten => 11,n,Set(QCIDPP=${IF($[${LEN(${VQ_CIDPP})}>0]?${VQ_CIDPP}: )})
exten => 11,n,Set(VQ_CIDPP=)
exten => 11,n,ExecIf($["${QCIDPP}"!=""]?Macro(prepend-cid,${QCIDPP}))
exten => 11,n,Set(QAINFO=${IF($[${LEN(${VQ_AINFO})}>0]?${VQ_AINFO}: )})
exten => 11,n,Set(VQ_AINFO=)
exten => 11,n,ExecIf($["${QAINFO}"!=""]?Set(__ALERT_INFO=${QAINFO}))
exten => 11,n,Set(QJOINMSG=${IF($[${LEN(${VQ_JOINMSG})}>0]?${IF($["${VQ_JOINMSG}"!="0"]?${VQ_JOINMSG}: )}:custom/zednannja-vstanovleno)})
exten => 11,n,Set(VQ_JOINMSG=)
exten => 11,n,Set(QRINGOPTS=r)
exten => 11,n,Set(QRETRY=${IF($[${LEN(${VQ_RETRY})}>0]?${VQ_RETRY}:n)})
exten => 11,n,Set(VQ_RETRY=)
exten => 11,n(qoptions),Set(QOPTIONS=${IF($[${LEN(${VQ_OPTIONS})}>0]?${VQ_OPTIONS}:t)}${QCANCELMISSED}${QRINGOPTS}${QRETRY})
exten => 11,n,Set(VQ_OPTIONS=)
exten => 11,n(qgosub),Set(QGOSUB=${IF($[${LEN(${VQ_GOSUB})}>0]?${VQ_GOSUB}:${QGOSUB})})
exten => 11,n,Set(VQ_GOSUB=)
exten => 11,n(qagi),Set(QAGI=${IF($[${LEN(${VQ_AGI})}>0]?${VQ_AGI}:${QAGI})})
exten => 11,n,Set(VQ_AGI=)
exten => 11,n(qrule),Set(QRULE=${IF($[${LEN(${VQ_RULE})}>0]?${IF($["${VQ_RULE}"!="0"]?${VQ_RULE}: )}:${QRULE})})
exten => 11,n,Set(VQ_RULE=)
exten => 11,n(qposition),Set(QPOSITION=${IF($[${LEN(${VQ_POSITION})}>0]?${VQ_POSITION}:${QPOSITION})})
exten => 11,n,Set(VQ_POSITION=)
exten => 11,n,Gosub(sub-record-check,s,1(q,11,dontcare))
exten => 11,n,ExecIf($["${QJOINMSG}"!=""]?Playback(${QJOINMSG}, ))
exten => 11,n,QueueLog(11,${UNIQUEID},NONE,DID,${FROM_DID})
exten => 11,n,Set(QAANNOUNCE=${IF($[${LEN(${VQ_AANNOUNCE})}>0]?${IF($["${VQ_AANNOUNCE}"!="0"]?${VQ_AANNOUNCE}: )}: )})
exten => 11,n,Set(VQ_AANNOUNCE=)
exten => 11,n,Set(QMOH=${IF($["${VQ_MOH}"!=""]?${VQ_MOH}: )})
exten => 11,n,Set(VQ_MOH=)
exten => 11,n,ExecIf($["${QMOH}"!=""]?Set(__MOHCLASS=${QMOH}))
exten => 11,n,ExecIf($["${MOHCLASS}"!=""]?Set(CHANNEL(musicclass)=${MOHCLASS}))
exten => 11,n,Set(QMAXWAIT=${IF($[${LEN(${VQ_MAXWAIT})}>0]?${VQ_MAXWAIT}: )})
exten => 11,n,Set(VQ_MAXWAIT=)
exten => 11,n,Set(QUEUENUM=11)
exten => 11,n,Set(QUEUEJOINTIME=${EPOCH})
exten => 11,n(qcall),Queue(11,${QOPTIONS},,${QAANNOUNCE},${QMAXWAIT},${QAGI},,${QGOSUB},${QRULE},${QPOSITION})
exten => 11,n,Macro(blkvm-clr,)
exten => 11,n,Gosub(sub-record-cancel,s,1())
exten => 11,n,Set(__NODEST=)
exten => 11,n,Set(_QUEUE_PRIO=0)
exten => 11,n,Set(QRINGOPTS=)
exten => 11,n,Set(QDEST=${VQ_DEST})
exten => 11,n,Set(VQ_DEST=)
exten => 11,n(gotodest),GotoIf($["${QDEST}"=""]?ext-group,505,1:${CUT(QDEST,^,1)},${CUT(QDEST,^,2)},${CUT(QDEST,^,3)})

здесь нас интересует строка: exten => 11,n(qcall),Queue(11,${QOPTIONS},,${QAANNOUNCE},${QMAXWAIT},${QAGI},,${QGOSUB},${QRULE},${QPOSITION})
Приложение Queue() генерирует постановку вызова в очередь. Как видим с примера — приложению передаются параметры, которые были сгенерированные перед выполнением приложения Queue(). Смотрим в документацию: https://asterisk-pbx.ru/wiki/asterisk/app/queue
Как видим по документации, если при выполнении приложения Queue(), добавить в аргумент «options» параметр «c», то диаплан продолжит свое выполнения, когда вызываемый (оператор) положил трубку. В нашем случае — диаплан перейдет на пункт «Fail Over Destination» в FreePBX.
По контексту определяем, что если перед поступлением звонка в очередь, мы установим значение «c» переменной VQ_OPTIONS, то приложение Queue() згенерирует постановку вызова в очередь с этим параметом.

Приступаем к выполнению

nano /etc/asterisk/extensions_custom.conf
Создаем собственный контекст с установкой значения переменной VQ_OPTIONS:

1
2
3
4
[queue-call-begin]
exten => s,1,Set(VQ_OPTIONS=tc) ;на первом приоритете, мы устанавливаем значение переменной. Параметром "t" - я разрешаю оператору переводить звонки
exten => s,n,System(php /var/www/call/call.php incall ${UNIQUEID} ${CALLERID(num)} ${CHANNEL} &) ;запуск фонового php скрипта на выполнения
exten => s,n,Return ;возвращаемся на предыдущий контекст, откуда был вызван

Также создаем контексты с оценками

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[assessment-1]
exten => s,1,Set(__OcenkaOper=1) ;выполняем необходимое действие
exten => s,n,Return ;возвращаемся на предыдущий контекст, откуда был вызван
 
[assessment-2]
exten => s,1,Set(__OcenkaOper=2) ;выполняем необходимое действие
exten => s,n,Return ;возвращаемся на предыдущий контекст, откуда был вызван
 
[assessment-3]
exten => s,1,Set(__OcenkaOper=3) ;выполняем необходимое действие
exten => s,n,Return ;возвращаемся на предыдущий контекст, откуда был вызван
 
[assessment-4]
exten => s,1,Set(__OcenkaOper=4) ;выполняем необходимое действие
exten => s,n,Return ;возвращаемся на предыдущий контекст, откуда был вызван
 
[assessment-5]
exten => s,1,Set(__OcenkaOper=5) ;выполняем необходимое действие
exten => s,n,Return ;возвращаемся на предыдущий контекст, откуда был вызван


После exten => s,1,Set(__OcenkaOper=X) можем выполнять еще команды. Например отправить сообщение в телеграмм:
exten => s,n,System(curl -s -X POST "https://api.telegram.org/bot545454443:AAAAAAAAAAAAAAAABBBBBBBBBBBCCC/sendmessage" -F chat_id="20202020" -F text="Оставлена оценка оператору: 5" &)
Или можно запустить php скрипт, который возвращает значение. Это значение присвоим переменной:
exten => s,n,Set(CallId=${SHELL(php /var/www/call/call.php inCallRegister ${CALLERID(num)})})

Логично, что если звонок не состоялся (оператор не взял трубку), то предлагать оценивать вызов не нужно. Для этого, создадим еще один контекст:

1
2
3
4
5
[queue-call-end]
exten => s,1,GotoIf($[${QUEUESTATUS}=TIMEOUT]?timeout:answered); очередь по завершению получает переменную QUEUESTATUS, от значения которого мы можем определить был ли принят звонок
exten => s,n(timeout),Goto(app-announcement-18,s,1) ; если звонок не был принят, направим его на app-announcement-18,s,1 - это приветствие, в котором говорим, что сейчас все операторы заняты и мы ему перезвоним. После, терминируем звонок (hangup) - обязательно. 
exten => s,n(answered),Noop(return to queue-call-end) ; если статус звонка отличается от "TIMEOUT", сделаем вывод, что звонок состоялся, и переходим на следующий приоритет
exten => s,n,Return ;возвращаемся на предыдущий контекст, откуда был вызван

Сохраняем изменения в файле /etc/asterisk/extensions_custom.conf и выходим с редактора nano — Ctrl+o, Ctrl+x.
Следующим этапом нам нужно зафиксировать созданные контексты в FreePBX.
Заходим в FreePBX → АДМИНИСТРАТОР (Admin) → Дополнительные назначения (Custom Destination)
Добавляем созданные ранее назначения:
Для примера опишу добавление контекста [queue-call-begin]
— в поле Спецназначение: указываем «queue-call-begin,s,1»
— в поле Описание: указываем «queue-call-begin» — название понятное Вам
— в поле Примечания: указываем описание для назначения понятное Вам
— Обязательно ставим галочку «Return», после чего появится выпадающий список дальнейших назначений — направляем в очередь (можно в другое место).

По аналогии, добавляем остальные назначения:
[assessment-1]
Спецназначение: assessment-1,s,1
Return: Приветствие → «Спасибо за оценку» → Терминовать звонок (Положить трубку).




[assessment-2]
Спецназначение: assessment-2,s,1
Return: Приветствие → «Спасибо за оценку» → Терминовать звонок (Положить трубку).

[assessment-3]
Спецназначение: assessment-3,s,1
Return: Приветствие → «Спасибо за оценку» → Терминовать звонок (Положить трубку).

[assessment-4]
Спецназначение: assessment-4,s,1
Return: Приветствие → «Спасибо за оценку» → Терминовать звонок (Положить трубку).

[assessment-5]
Спецназначение: assessment-5,s,1
Return: Приветствие → «Спасибо за оценку» → Терминовать звонок (Положить трубку).

[queue-call-end]
Спецназначение: queue-call-end,s,1
Return: IVR → «Оцените работу оператора».

Настройка Очереди:
Все настройки делаем на свое усмотрение, но в «Назначение при неответе», устанавливаем «Дополнительные назначения» → «queue-call-end».

Настройка IVR «Оцените работу оператора»:

Применяем настройки. В терминале сервера можно выполнить asterisk -rx "dialplan reload"

Что у нас получается на этот момент:
Поступает звонок. Первым делом — направляем его на «Дополнительные назначения» → «queue-call-begin», где присваиваем переменной VQ_OPTIONS значение «tc» (параметр c — продолжение выполнения диалплана после того, как оператор положил трубку). Далее звонок поступает в очередь, где генерируются вызовы агентам (операторам). Оператор поднял трубку → разговор → положил трубку. Звонок попадает в «Назначение при неответе» → «Дополнительные назначения» → «queue-call-end», где мы проверяем был ли отвечен звонок. Если звонок не был принят (TIMEOUT), направляем его на Приветствие app-announcement-18 (у Вас будет другое, ищите в nano /etc/asterisk/extensions_additional.conf).Если статус звонка (QUEUESTATUS) отличается от «TIMEOUT», продолжаем выполнение диалплана, где попадаем в Return Дополнительного назначения «queue-call-begin» → IVR «Оцените работу оператора». Здесь мы озвучиваем запись «Поставьте оценку от 1-го до 5-ти», ждем ввода. Если клиент ничего не ввел, либо ввел неверно, Терминируем звонок (Положить трубку). Если нажал одну с оценок, переходим в «Дополнительные назначение» → «assessment-X», где присваиваем переменной OcenkaOper определенное значение, и возвращаемся в поле Return Дополнительного назначения «assessment-X» → Приветствие «Спасибо за оценку». Приветствие «Спасибо за оценку» воспроизводит запись о благодарности за оценку и Терминирует звонок (Положить трубку).

Посмотреть логи прохождения звонка можно командой asterisk -rvvvv




Теперь нам нужно следить за звонком. Создаем каталог «call» в /var/www/, внутри него создаем php файл с именем call.php. Также внутри каталога call создаем каталог src и в корень его кладем файлы библиотеки PHPAGI
nano /var/www/call/call.php
Вставляем код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php
 
require('/var/www/call/src/phpagi.php');
 
/*
следующие строки - подключение к asterisk AMI, доступы посмотреть можно здесь: /etc/asterisk/manager.conf, либо создать дополнительный доступ:  https://wiki.merionet.ru/ip-telephoniya/13/nastrojka-ami-v-freepbx-13/
*/
$service_port = "5038";
$address = "127.0.0.1";
$user_ami = "admin";
$pass_ami = "admin";
 
$token_telegram='44444444444:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-UaaUUUU';
$chat_id_telegram='222222222222';
 
$responsible=NULL;
$stat=false; //статус звонка (начат разговор=true, или нет=false). принимает значение true\false
$ocenka=NULL; //переменная, хранит в себе поставленную оценку
$Uniqueid1='0'; //Глобальная переменная, которая будет изменятся по циклу работы скрипта (перевод звонка, и т.п.)
$Uniqueid2='0'; //Глобальная переменная, которая будет изменятся по циклу работы скрипта (перевод звонка, и т.п.)
$Uniqueid='0';  //Глобальная переменная, которая НЕ будет изменятся, она статическая на все время работы скрипта (перевод звонка и т.п.)
$UniqueID='0';  //Глобальная переменная, которая будет изменятся по циклу работы скрипта (перевод звонка, и т.п.)
$CallerID1='0';  //Глобальная переменная, которая будет изменятся по циклу работы скрипта (перевод звонка, и т.п.)
$CallerID2='0';  //Глобальная переменная, которая будет изменятся по циклу работы скрипта (перевод звонка, и т.п.)
$Channel1='0';  //Глобальная переменная, которая будет изменятся по циклу работы скрипта (перевод звонка, и т.п.)
$Channel2='0';  //Глобальная переменная, которая будет изменятся по циклу работы скрипта (перевод звонка, и т.п.)
$i=true;  //Глобальная переменная, которая определяет цикл работы скрипта. true = продолжает работать скрипт, false = скрипт закончит работу
$redirekt=false; //Статус перевода звонка
$per=false; //временный статус перевода звонка
 
function telegram_message($TOKEN='',$CHAT_ID='',$MESSAGE=''){
$telegram_data = array (
    'text' => $MESSAGE,
    'chat_id' => $CHAT_ID,
    'parse_mode' => 'html'
);
file_get_contents("https://api.telegram.org/bot".$TOKEN."/sendMessage?".http_build_query($telegram_data));
}
 
function dump_incall($ecode,$data,$server,$port) {
//telegram_message($GLOBALS["token_telegram"],$GLOBALS["chat_id_telegram"],'перевод звонка '.json_encode($data));
if(((($data['Event']=='VarSet')&&($data['Value']=='tr'))&&($data['Variable']=='ARG2'))&&(($data['Channel']==$GLOBALS["Channel1"])||($data['Channel']==$GLOBALS["Channel2"])))
  $GLOBALS["per"]=true; //определяем перевод звонка
if(((($data['Event']=='VarSet')&&($GLOBALS["stat"]==true))&&($data['Variable']=='ARG3'))&&(($data['Channel']==$GLOBALS["Channel1"])||($data['Channel']==$GLOBALS["Channel2"]))){
  $GLOBALS["per"]=false;
  $GLOBALS["UniqueID"]=$data['Uniqueid'];
  $GLOBALS["stat"]=false;
  $GLOBALS["redirekt"]=true;
  //telegram_message($GLOBALS["token_telegram"],$GLOBALS["chat_id_telegram"],'перевод звонка '.json_encode($data));
}
 
if(($data['Event']=='Newstate')&&($GLOBALS["CallerIdNum"]==$data['ConnectedLineNum']))
  if(($data['ChannelStateDesc']=='Up')&&(preg_match("/^SIP/",$data['Channel']))) $GLOBALS["UniqueID"]=$data['Uniqueid'];
 
if(($GLOBALS["UniqueID"]==$data['Uniqueid2'])||($GLOBALS["UniqueID"]==$data['Uniqueid1'])||($GLOBALS["UniqueID"]==$data['Uniqueid'])||($GLOBALS["UniqueID"]==$data['UniqueID'])){
  if(($data['Event']=='Bridge')&&($data['Bridgestate']=='Link')){  //поднята трубка
    if($GLOBALS["stat"]==false){
      $GLOBALS["stat"]=true;
      $GLOBALS["responsible"]=$data['CallerID2'];       //определяем ответственного за звонок
      $GLOBALS["Uniqueid2"]=$data['Uniqueid2'];
      $GLOBALS["Uniqueid1"]=$data['Uniqueid1'];
      $GLOBALS["Channel1"]=$data['Channel1'];
      $GLOBALS["Channel2"]=$data['Channel2'];
      //telegram_message($GLOBALS["token_telegram"],$GLOBALS["chat_id_telegram"],'Поднята трубка. начат разговор '.json_encode($data));
    }
  }
  if((($data['Event']=='Dial')&&($data['SubEvent']=='Begin'))&&($GLOBALS["redirekt"]==true)){
      $GLOBALS["responsible"]=$data['Dialstring'];
      //telegram_message($GLOBALS["token_telegram"],$GLOBALS["chat_id_telegram"],'зафиксирован перевод звонка. Новые данные: CallerIDNum='.$data['CallerIDNum'].' Dialstring='.$data['Dialstring'].' '.json_encode($data));
      $GLOBALS["redirekt"]=false;
      $GLOBALS["Channel1"]=$data['Channel'];
      $GLOBALS["Channel2"]=$data['Destination'];
      $GLOBALS["UniqueID"]=$data['UniqueID'];
      $GLOBALS["Uniqueid1"]=$data['UniqueID'];
      $GLOBALS["Uniqueid2"]=$data['DestUniqueID'];
  }
}
if($GLOBALS["Uniqueid"]==$data['Uniqueid'])
  if($data['Event']=='Hangup') {
    telegram_message($GLOBALS["token_telegram"],$GLOBALS["chat_id_telegram"],'Завершена работа скрипта. выход из цыкла '.json_encode($data));
    $GLOBALS["i"]=false;
  }
}
 
if (isset($argv[1])) {
        $status=$argv[1];
}
else  echo "Введите параметры!";
if($status=='incall'){
    if ((isset($argv[2])&&isset($argv[3]))&&isset($argv[4])) {
                $Uniqueid=$argv[2];
                $CallerIdNum=$argv[3];
                $Channel=$argv[4];
                $manager = new AGI_AsteriskManager();
                $manager->connect($address, $user_ami, $pass_ami);
                //telegram_message($token_telegram,$chat_id_telegram,'Входящий звонок. id='.$Uniqueid.' caller='.$CallerIdNum.' channel='.$Channel);
                    while($i){
                      $manager->Events('on');
                      $manager->wait_response(true);
                      $manager->add_event_handler('*', 'dump_incall');
                      if(!$ocenka) {
                        $tmpOc=$manager->send_request('GetVar',array('Variable' => 'OcenkaOper', 'Channel' => $Channel));
                        if(isset($tmpOc['Value']) && ($tmpOc['Value']!='')){
                          $ocenka=$tmpOc['Value'];
                          //telegram_message($token_telegram,$chat_id_telegram,'ocenka='.json_encode($tmpOc));
                        }
                      }
                    }
                $manager->disconnect();
                if(isset($ocenka)) {
                  if($ocenka=='5') $smile="\xF0\x9F\x98\x8D";
                  if($ocenka=='4') $smile="\xF0\x9F\x98\x83";
                  if($ocenka=='3') $smile="\xF0\x9F\x98\x8F";
                  if($ocenka=='2') $smile="\xF0\x9F\x98\x96";
                  if($ocenka=='1') $smile="\xF0\x9F\x98\xA1";
                  telegram_message($token_telegram,$chat_id_telegram,$smile." Оценен входящий звонок от ".$CallerIdNum.". Ответственный оператор ".$responsible.". Оставлена оценка ".$ocenka);
                }
                //telegram_message($token_telegram,$chat_id_telegram,'Завершение скрипта по номеру канала '.$Uniqueid.'. ответственный='.$responsible);
    }
    else echo "Введите параметры!";
}
?>

Вносим свои изменения, сохраняем и выходим: CTRL+o, CTRL+x.
Что делает скрипт? Он запускается в контексте [queue-call-begin], и следит за звонком до самого его завершения. Он определяет кто поднят трубку, на кого звонок был перенапрвален, и была ли оставлена оценка. После чего — отправляет сообщение в телеграм. Вместо телеграма, можно отправлять оценку куда угодно (SQL, 1С, Битрикс24, и т.д.)
Делаем тестовый звонок, проверяем работоспособность, запускаем в продакшн.

Похожие статьи:

Web CallBack FreePBX
Задача Создать кнопку "Перезвоните мне" на сайте, с максимальной интеграцией во FreePBX. Решение Для примера возьмем статью https://asterisk-pbx.ru/wiki/artikle/asterisk_web_callback. Принцип работы этой реализации заключается в том, что php скрипт генерирует (Originate) вызов. Первым делом отправляет вызов по каналу Channel. После того, как соединение установлено (вызов принят оператором), осуществляется ...
Мониторинг уровня сигнала SIM-карт в Openvox через Zabbix
При переходе по ссылке http://IP_OPENVOX/service?action=get_gsminfo, или http://IP_OPENVOX/X/service?action=get_gsminfo (где X - номер модуля, больше 1), можно увидеть в json-формате статус портов (span-нов). Если Web-сервер на Openvox, для авторизации использует метод Authorization: Basic, то мониторить статус портов (span-нов), можно средствами zabbix. Но на некоторых (более новых) Openvox-шлюзах ...
Отправка сообщений в Telegram
Здесь описаны возможные способы отправки сообщений в Telegram Windows CMD Для удобства отправки с командной строки, написал консольную программу на языке Pascal. Среда разработки PascalABC.NET uses System.IO, System.Net; var i:integer; html : string; chat_id: string; {:='111111111';} token: string; {:= '0000000:AAAAAAAAAAAAAAAAAAAAAA';} parse_mode: string; {:= 'html';} message: string:=''; {:='Сообщение';} url : string; begin token := ParamStr(1); chat_id := ParamStr(2); parse_mode := ...
Пересылка СМС с OpenVox в Telegram
Как пример опишу реализацию задачи "Очередь на кассе". Если очередь на кассе - отправь сообщение на номер 050XXXXXXX с текстом "2302". Когда приходит сообщение переправлять в Telegram канал. Сим-карта с номером 050XXXXXXX подключена в Openvox, который в свою очередь настроен на получение СМС. Решение Для пересылки полученных сообщений ...
Мониторинг состояния RAID массива контроллеров P420
Описание Контроллер HPE Smart Array P420 - это низкопрофильный RAID-контроллер с интерфейсом 6 Гбит/с, PCIe 3.0, Serial Attached SCSI (SAS), корпоративного класса, который обеспечивает производительность хранилища и защиту данных для стоечных серверов HPE ProLiant Gen8. Он оснащен восемью внутренними портами SAS и обеспечивает повышенное время безотказной ...
Мониторинг свободной памяти
При активном использовании ПК, иногда возникает необходимость следить за количеством свободной памяти на логических дисках. В этой статье, я расскажу как реализовать мониторинг свободной памяти логического диска, с оповещением в телеграмм. Итак, будем использовать скрипт VBS. Создадим пустой текстовый файл, и изменим его имя и расширение ...
Bitrix24 cоздание лида через API
Задача - создание лида через API запрос к облачному Bitrix24. Для решения этой задачи, будем использовать webhook. Для создания webhook переходи на портале Bitrix24 по пункту "Дополнения"→"Вебхуки" Нажимаем на кнопку "создать вебхук", из выпадающего списка выбираем "Входящий вебхук". На следующем окне нужно ввести имя вебхука ...
Мониторинг времени простоя компьютера
Чтобы реализовать мониторинг времени простоя компьютера, нужно учитывать тот факт, что пользователь обычно работает с мышкой, поэтому будем анализировать ее активность. Если мышь была не активной в течение N минут, сделаем вывод, что пользователь в настоящее время не работает с ПК. Всю статистику будем отправлять ...
Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (6 оценок, среднее: 5,00 из 5)
Загрузка...
  1. Alex

    Здравствуйте,
    я настроил по вашему мануалу, но у меня не работает.
    Я не получаю ответ в $tmpOc. В телеграме говорит $tmpOc={«Response»:»Error»,»Message»:»No such channel»}
    Я проверял через телнет, у меня ответ приходит.
    В чем может быть причина?

    • adminblog

      1) Скажите какая у Вас версия Asterisk-а и FreePBX-а?
      2) Вы создали контексты в файле /etc/asterisk/extensions_custom.conf? А именно [assessment-1],[assessment-2]…. и т.д.?
      3) После завершения разговора, Вам запрашивает поставить оценку?

Оставить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.