Asterisk function 'CURL'

Краткий обзор

Функция Asterisk CURL() получает и передает данные по URL.

Описание Эта функция используется для получения контента по URL.

Синтаксис

CURL(url[,post-data])

Аргументы

url - URL с которого будет получаться контент.

post-data - необязательно, данные для отправки с помощью POST (по умолчанию используется GET)

Рассмотрим примеры использования этой замечательной функции,
которая позволяет получать данные из сторонних источников и передавать требуемую информацию.
Обратите также внимание на функцию SHELL().

Пример#1: Получаем данные от внешнего API

Получение информации о вызывающем абоненте.
Используя открытое API (https://kody.su), получим данные по CALLERID вызывающего абонента.

[from-curl]
exten => curltest,1,noop(***test_curl***)
   same => n,set(q=${CURL(https://www.kody.su/api/v2.1/search.json?q=+79040000000&key=test)})
   same => n,verbose(${foo})

Вывод консоли:

CLI> channel originate Local/curltest@from-curl  application hangup
    -- Called curltest@from-curl
    -- Executing [curltest@from-curl:2] Set("Local/curltest@from-curl-00000003;2", "foo={
    --     "success": true,
    --     "query": "79040000000",
    --     "quota": 76,
    --     "numbers": [
    --     {
    --         "number_current": "79040000000",
    --         "number_success": true,
    --         "number_type": 1,
    --         "def": "904",
    --         "number": "0000000",
    --         "code_start": "0000000",
    --         "code_end": "0299999",
    --         "operator": "Tele2",
    --         "operator_full": "ООО "Т2 Мобайл"",
    --         "region": "Тверская область",
    --         "time": "3.0",
    --         "bdpn": false,
    --         "bdpn_operator": ""
    --     }
    --     ]
    -- }") in new stack

API используемое в данном примере поддерживает как GET, так и POST запросы.
Для POST запроса просто перенесите данные за запятую во второй аргумент: …json,q=+79040000000&key=test

[from-curl]
exten => curltest,1,noop(***test_curl***)
   same => n,set(foo=${CURL(https://www.kody.su/api/v2.1/search.json,q=+79040000000&key=test)})
   same => n,verbose(${foo})

Далее возникает вопрос, что делать с полученным ответом. В данном примере ответ приходит в формате JSON.
Полученный объект можно разобрать при помощи third-party модуля Asterisk res_json.
Пример диалплана можно найти на marcelog.github.io.

или же передать это системному приложению:

Пример#2: Разбор данных JSON объекта

Используем JSON процессор командной строки - JQ для разбора данных.
Для этого, наперво, создадим файл curl.txt в директории локального веб-сервера и поместим туда информацию полученную нами из реального API в предыдущем примере. В дальнейшем используя этот файл, вы сможете потренироваться, имитирую получение данных в разных форматах.

cat >> /var/www/html/curl.txt << EOF 
[
 {
     "success": true,
     "query": "79040000000",
     "quota": 76,
     "numbers": [
     {
         "number_current": "79040000000",
         "number_success": true,
         "number_type": 1,
         "def": "904",
         "number": "0000000",
         "code_start": "0000000",
         "code_end": "0299999",
         "operator": "Tele2",
         "operator_full": "ООО &quot;Т2 Мобайл&quot;",
         "region": "Тверская область",
         "time": "3.0",
         "bdpn": false,
         "bdpn_operator": ""
     }
   ]
 }
]
EOF

а теперь получим значение ключа region:

[from-curl]
exten => curltest,1,noop(***test_curl***)
   same => n,set(res=${SHELL(curl http://127.0.0.1/curl.txt | jq '.[] | .numbers[] | .region')})
   same => n,verbose(${res})

Обратите внимание, что функция диалаплана CURL(), не используется, потому что она как бы уже и не нужна.
SHELL - вызывает приложение Linux Curl и передает полученный объект JQ.
В итоге получим название региона:

   -- Executing [curltest@from-curl:1] NoOp("Local/curltest@from-curl-00000047;2", "***test_curl***") in new stack
    -- Executing [curltest@from-curl:2] Set("Local/curltest@from-curl-00000047;2", "res="Тверская область"
    -- ") in new stack

Подробную информацию о использовании JQ, можно подчерпнуть в официальной документации - https://stedolan.github.io/jq/tutorial/.

Ну, а что делать с полученными данными, решать вам, например использовать как CALLERID(name).

exten => curltest,1,noop(***test_curl***)
   same => n,set(res=${SHELL(curl http://127.0.0.1/curl.txt | jq '.[] | .numbers[] | .region')})
   same => n,set(CALLERID(name)=${URIENCODE(${res})})

В URIENCODE(), я обернул, чтобы ip телефон (например DLINK dph) понял кириллицу. Приведенный пример вполне применим в реале, но использование CURL поможет вам в решении и более сложных задач:

Пример#3: Создаем собственную статистику очереди (Колл Центра) Asterisk

Используя функцию CURL() создадим пользовательскую статистику Колл-Центра Asterisk.
Будем передавать обезличенные статистические данные очереди и сохранять в базе данных.
В примере API и БД будут размещены на том же сервере, что и Asterisk, но данная схема предполагает, что они могут находится на удаленном сервере.

queues.conf

В настройках очереди инициируем переменные:

[queue_test]
setinterfacevar=yes
setqueueentryvar=yes
setqueuevar=yes
membergosub=sub-queuevar,1
;other queue settings ...

membergosub - вызовет контекст sub_queuevar при поступлении вызова в очередь. В нем будут доступны все переменные очереди. Они содержат сводные данные по очереди и ее агентам с момента последней перезагрузки или выполнения queue reset

extensions.conf

При поступлении нового вызова в очередь отправим данные API.

[sub-queuevar]
exten => s,1,noop(***QueueData***)
  same => n,set(date=${STRFTIME(,,%Y-%m-%d %H:%M:%s)})
  same => n,set(qvar=${QUEUENAME}|${QUEUEMAX}|${QUEUESTRATEGY}|${QUEUECALLS}|${QUEUEHOLDTIME}|${QUEUECOMPLETED}|${QUEUEABANDONED}|${QUEUESRVLEVEL}|${QUEUESRVLEVELPERF})
  same => n,set(qevar=${QEHOLDTIME}|${QEORIGINALPOS})
  same => n,set(ivar=${MEMBERINTERFACE}|${MEMBERNAME}|${MEMBERCALLS}|${MEMBERLASTCALL}|${MEMBERPENALTY}|${MEMBERDYNAMIC}|${MEMBERREALTIME})
  same => n,set(query=${CURL(http://127.0.0.1/queuevar.php,queuedatatoken=1234&date=${date}&uniqueid=${UNIQUEID}&qvar=${qvar}&qevar=${qevar}&ivar=${ivar})})
  same => n,verbose(--- ${query} ---)

API

И в завершении создадим минималистичное API:

queuevar.php
<?php
$conn = new mysqli("localhost","USER","PASS","qs");
 
if( $_POST['queuedatatoken'] == "1234" ) {
 
$date = $_POST['date'];
$uniqueid = $_POST['uniqueid'];
 
$qvar = explode("|", $_POST['qvar']);
$qvar = serialize($qvar);
 
$qevar = explode("|", $_POST['qevar']);
$qevar = serialize($qevar);
 
$ivar = explode("|", $_POST['ivar']);
$ivar = serialize($ivar);
 
$query = "INSERT INTO queuevar (`date`, `uniqueid`, `qvar`, `qevar`, `ivar`) VALUES ('$date', '$uniqueid', '$qvar', '$qevar', '$ivar');";
 
$conn->query($query);
 
print "SUCCESS";
 
}
MySQL
   mysql> create database qs;
 
   mysql> use qs;
 
   mysql> create table queuevar ( `id` int AUTO_INCREMENT PRIMARY KEY, `date` varchar(32), `uniqueid` varchar(32), `qvar` varchar(32), `qevar` varchar(32), `ivar` varchar(128)) engine=myisam DEFAULT CHARSET=utf8;
 
   mysql> grant all privileges on qs.* to 'USER'@'localhost' identified by 'PASS';
 
   mysql> grant select, insert on qs.queuevar to 'USER'@'localhost';
 
   mysql> flush privileges;

Нажмите, чтобы отобразить

Нажмите, чтобы скрыть

mysql> describe queuevar;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| date     | datetime     | YES  |     | NULL    |                |
| uniqueid | varchar(32)  | YES  |     | NULL    |                |
| qvar     | varchar(32)  | YES  |     | NULL    |                |
| qevar    | varchar(32)  | YES  |     | NULL    |                |
| ivar     | varchar(128) | YES  |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

Таким образом при каждом вызове, динамические данные очереди будут передаваться нашему API и сохраняться в БД.

id date uniqueid qvar qevar ivar
1 2018-12-09 14:12:1544353927 1544353927.97 a:9:{i:0;s:7:"queues_test";i:1;s:1:"0";i:2;s:7:"ringall";i:3;s:1:"1";i:4;s:1:"0";i:5;s:1:"8";i:6;s:1:"0";i:7;s:1:"3";i:8;s:5:"100.0";} a:2:{i:0;s:1:"0";i:1;s:1:"1";} a:7:{i:0;s:31:"Local/666@from-agents";i:1;s:5:"Agent_Name";i:2;s:1:"8";i:3;s:10:"1544353826";i:4;s:1:"0";i:5;s:1:"0";i:6;s:1:"0";}
2 2018-12-09 14:12:1544353957 1544353957.110 a:9:{i:0;s:7:"queue_test";i:1;s:1:"0";i:2;s:7:"ringall";i:3;s:1:"1";i:4;s:1:"0";i:5;s:1:"9";i:6;s:1:"0";i:7;s:1:"3";i:8;s:5:"100.0";} a:2:{i:0;s:1:"0";i:1;s:1:"1";} a:7:{i:0;s:31:"Local/666@from-agents";i:1;s:5:"Agent_Name";i:2;s:1:"9";i:3;s:10:"1544353936";i:4;s:1:"0";i:5;s:1:"0";i:6;s:1:"0";}
3 2018-12-09 14:12:1544353969 1544353969.121 a:9:{i:0;s:7:"queue_test";i:1;s:1:"0";i:2;s:7:"ringall";i:3;s:1:"1";i:4;s:1:"0";i:5;s:2:"10";i:6;s:1:"0";i:7;s:1:"3";i:8;s:5:"100.0";} a:2:{i:0;s:1:"0";i:1;s:1:"1";} a:7:{i:0;s:31:"Local/666@from-agents";i:1;s:5:"Agent_Name";i:2;s:2:"10";i:3;s:10:"1544353966";i:4;s:1:"0";i:5;s:1:"0";i:6;s:1:"0";}

По UNIQUEID вызова, данные могут быть соотнесены с queue_log дополняя стандартную статистику очереди.

Сами данные лога очереди тоже могут передаваться при помощи cURL, но это уже немного другая тема.


Asterisk function 'SHELL'

function 'CURLOPT'

Asterisk app: System

Asterisk: функции диалплана

  • asterisk/func/curl.txt
  • Последние изменения: 2019/06/09