Кнопка звонка в Miranda NG через Asterisk AMI

В нашей компании используется связка Openfire (сервер) + Miranda (клиенты). Поскольку телефония у нас на базе Asterisk, появилась необходимость сделать кнопку "Позвонить" в меню контакта в Миранде. По этой кнопке мы будем инициировать звонок через Asterisk Management Interface (AMI). Это более правильный подход, чем использование call-файлов.

Когда сотрудников в компании больше 150, это довольно удобно - не искать каждый раз номер телефона человека.
План действий следующий:
  1. Напишем скрипт на php, который совершит набор номер через AMI Asterisk. При этом номера телефонов обоих абонентов мы узнаем сделав запрос в Active Directory по имени сотрудников.
  2. Опубликуем скрипт на внутреннем сервере, доступном только в локальной сети.
  3. Добавим в Miranda NG кнопку, по которой произойдет обращение к скрипту, ему передадутся имена абонентов (кому и от кого набрать номер). Скрипт передаст данные в астер. Далее Asterisk наберет номер сотрудника, который нажал кнопку и когда тот поднимет трубку от него произойдет набор требуемого абонента.
Для чтения базы Active Directory, нам нужно создать в домене пользователя с минимальным набором привилегий. В нашем случае, это пользователь ldap с паролем Lpad-pass123.

Также нам нужен пользователь в астериске для работы с AMI. Для этого нужно добавить в файл /etc/asterisk/manager.conf примерно следующее (можете самостоятельно уточнить параметры), у меня так, но это избыточно только для звонка:

[general]
enabled = yes ;AMI включен
port = 5038 ;принимает соединения на порт 5038
bindaddr = 0.0.0.0 ;на все IP-адреса хоста
displayconnects=no ;подключения к AMI не отображаются командной строке

[adminsip] ;имя пользователя
secret = sippassword ;пароль
deny=0.0.0.0/0.0.0.0 ;подсеть, из которой запрещен доступ к AMI
permit=127.0.0.1/255.255.255.0 ;подсеть, из которой разрешен доступ к AMI
read=system,call,log,verbose,command,agent,user,config,command,dtmf,reporting,cdr,dialplan,originate ;привилегии на чтение
write=system,call,log,verbose,command,agent,user,config,command,dtmf,reporting,cdr,dialplan,originate ;привилегии на запись
Теперь скрипт:
<?php
/* Подключение к ldap */
$LDAP_BINDDN = "ldap@domain.local";
$LDAP_PASS = "Lpad-pass123";
$LDAP_BASE_DN = "DC=domain,DC=local";

function ConnectToServer()
{
  $LDAP_SERVER = "192.168.0.200";
  $LDAP_PORT = "389";
  $ds=ldap_connect($LDAP_SERVER, $LDAP_PORT);
  ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
  ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
  return $ds;
}

/* Переменные для получения логинов */
$jabbernameto = $_GET['nameto'];
$jabbernamefrom = $_GET['namefrom'];

/* Если задали имена, то ищем в домене номера телефонов
 phoneto - кому позвонить, phonefrom - от кого звонок */

if ($jabbernameto != "" && $jabbernamefrom != "") {
$ds=ConnectToServer();
$ldapbind = ldap_bind($ds, $LDAP_BINDDN , $LDAP_PASS);

if ($ldapbind) {
    $filterto = "(&(samaccountname=$jabbernameto)(objectClass=top)(objectClass=user)(objectClass=organizationalPerson)(objectClass=person))";
    $sr=ldap_search($ds, $LDAP_BASE_DN, $filterto, array("telephonenumber"));
    $info = ldap_get_entries($ds, $sr);

    for($i=0; $i<$info["count"]; $i++) {
 $phoneto =$info[$i]["telephonenumber"][0];
    }

    $filterfrom = "(&(samaccountname=$jabbernamefrom)(objectClass=top)(objectClass=user)(objectClass=organizationalPerson)(objectClass=person))";
    $srfrom=ldap_search($ds, $LDAP_BASE_DN, $filterfrom, array("telephonenumber"));
    $info = ldap_get_entries($ds, $srfrom);

    for($i=0; $i<$info["count"]; $i++) {
        $phonefrom = $info[$i]["telephonenumber"][0];
    }
}
ldap_close($ds);
}

/* Если имена не задали, пишем ошибку */

else
{
 print "error";
}

/* Тут инициируем подключение AMI Asterisk
 совершаем звонок на номера полученные из доменных имен */

$wrets="";
$strHost="127.0.0.1"; // IP Asterisk
$strUser="adminsip";
$strSecret="sippassword";
$strChannel="SIP/".$phonefrom;
$strWaitTime="10";
$strCallerId=$phonefrom;
$strReceiver=$phoneto;
$strContext="office";

  $oSocket = @fsockopen($strHost, 5038, $errnum, $errdesc)
or die("Connection to host failed");
  fputs($oSocket, "Action: login\r\n");
  fputs($oSocket, "Events: off\r\n");
  fputs($oSocket, "Username: $strUser\r\n");
  fputs($oSocket, "Secret: $strSecret\r\n\r\n");
  fputs($oSocket, "Action: originate\r\n");
  fputs($oSocket, "Channel: $strChannel\r\n");
  fputs($oSocket, "WaitTime: $strWaitTime\r\n");
  fputs($oSocket, "CallerID: $strCallerId\r\n");
  fputs($oSocket, "Exten: $strReceiver\r\n");
  fputs($oSocket, "Context: $strContext\r\n");
  fputs($oSocket, "Priority: 1\r\n\r\n");
  fputs($oSocket, "Action: Logoff\r\n\r\n");
  while (!feof($oSocket)) {
  $wrets .= fread($oSocket, 8192);
  }
 fclose($oSocket);
 echo $wrets;
  if (stripos($wrets, 'Originate successfully queued')) {
    echo "Call completed ";
  } else {
    echo "No accept call ";
  }
?>
Далее нужно опубликовать скрипт на сервере, чтобы клиенты из сети могли сделать GET запрос передав ему данные. Скрипт должен иметь возможность обратиться к Asterisk через AMI. Проще всего опубликовать его на сервере, где установлен астериск. Это настолько тривиально, что не вижу смысла описывать в рамках данной статьи. Решите для себя как вам обойти возможную проблему безопасности (скрипт открыт на общий доступ внутри сети).
Для Миранды нам понадобятся 2 дополнительных плагина: Variables и Actman. Нужно скачать dll-ки с официального сайте и положить в папку plugins. После установки заходим в Настройки - Службы - Действия и добавляем действие "Позвонить". В правой части выбираем действие "Выполнить", настройка окна "Запуск скрытым". Далее указываем путь до скрипта (ставим галочку Скрипт):
%miranda_path%\Scripts\phone.bat
Указываем аргументы скрипта (передаем ему своё имя и имя сотрудника для звонка, ставим галочку Скрипт):
%username% ?substr(!dbsetting(%subject%,?cinfo(%subject%,protocol),jid),1,?sub(?strchr(!dbsetting(%subject%,?cinfo(%subject%,protocol),jid),@),1))
Теперь нам нужно написать скрипт (phone.bat), который будет вызывать программу CURL (скачайте вариант для Windows) и передавать данные методом GET в скрипт звонка для Asterisk. Создаем в папке с Мирандой папку Scripts и в ней 2 файла: скаченный curl.exe и phone.bat со следующим содержанием (вместо ip-server укажите адрес сервера, на котором вы опубликуете php скрипт вызова для Asterisk, у меня он на сервере с астером):
@echo off
curl.exe http://ip-server/getphone.php?namefrom=%1^&nameto=%2
exit
Далее выводим кнопку для вызова скрипта в меню контакта на вкладке Использование действий:
После чего иконка появится в меню контакта и в чате. Мы, конечно, выберем для её свою картинку:
В моем случае выглядит так:


Комментариев нет:

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