Click2Call на Mac OS X

Еще до появления в инфраструктуре нашей организации Asterisk-сервера у меня регулярно возникало желание совершать звонки с помощью отдельно стоящего на столе телефона на номера, которые я вижу на экране монитора не набирая их на аппарате. Далее речь пойдет о реализации этого функционала на связке Mac OS X + Asterisk.

Читатели могут возразить: подключение гарнитуры к компьютеру и настройка программного SIP-клиента решает проблему.

Но лично для меня есть несколько причин решить задачу иначе:

  1. пока еще сильна привычка говорить по телефону держа трубку в руке (при необходимости можно включить громкую связь;
  2. был опыт использования проводной и беспроводной гарнитуры, но не прижилось из-за периодически возникающих технических неувязок;
  3. удобной фичей может быть перенаправление звонка на SIP-клиент мобильника и тогда, например, можно говорить с любимой не в кабинете при коллегах, а в коридоре или находящемся за стеной кафе (даже bluetooth гарнитура в этом сценарии не подойдет).

Теория

Первым делом я попытался найти уже существующее Asterisk совместимое Click2Call ПО, но ни один из немногих найденных проектов не заработал. Тем не менее я получил общее представление о технологии взаимодействия и будучи программистом решил освоить тему самостоятельно.

Используемые компоненты:

  • инициатор звонка — Mac OS X 10.8.2
  • веб-сервер — Apache + PHP
  • SIP сервер — Asterisk 1.6.2
  • SIP телефон — Yealink VP-2009

Процесс инициации звонка состоит из следующих этапов

  1. локальный скрипт формирует url и отправляет запрос на веб-сервер
  2. php на веб-сервере подключается к менеджеру Asterisk и формирует звонок
  3. Asterisk звонит на SIP номер моего телефона и после ответа соединяет с вызовом удалённого абонента

Поскольку я основывался на примерах настройки возможности заказа обратного звонка через сайт, то в схеме присутствует необязательный элемент — отдельный веб-сервер с PHP. Необязательный он еще и по той причине, что в текущей версии скрипта я вынужден использовать интерпретатор PHP на стороне своего Mac и, следовательно, при необходимости можно перенести весь функционал подключения к менеджеру Asterisk на локальную машину. Тем не менее я оставил 3х компонентную схему для возможности инициации звонка из браузера мобильного телефона, а не с компьютера.

Практика

Процесс настройки всех трех компонентов буду излагать в таком порядке: Asterisk, WEB, Mac OS.

1. Настраиваем Asterisk

Прежде всего нужно добиться от Asterisk возможности вызывать локального абонента А и соединять его с вызовом абонента Б. Автоматизировать этот процесс можно помещая файл с нужными параметрами вызова в папку /var/spool/asterisk/outgoing сервера Asterisk или передавая эти параметры через менеджер процессу Asterisk.

Например файл вызова может быть таким

Channel: Local/7777 MaxRetries: 1 RetryTime: 60 WaitTime: 30 Context: default Extension: +79201234567 Priority: 1 

Важно правильно указать параметр Context, который в конфигурации Asterisk соответствует, например, контексту для исходящих вызовов.

Тестирование я проводил первым способом — файловым, а боевую систему настроил с использованием второго. Для этого включаем на SIP сервере менеджер Asterisk

manager.conf

[general] enabled = yes webenabled = yes port = 5038  [asterisk] secret=mysecretpassword deny=0.0.0.0 permit=A.B.C.0                       ; адрес подсети вебсервера read=system,call,log,verbose,command,agent,user,originate write=system,call,log,verbose,command,agent,user,originate 

Не забываем в межсетевом экране открыть доступ к порту 5038 для вебсервера.

2. Готовим web

На вебсервере создаем php-скрипт

<?php $receiver = str_replace(array(" ","(", ")", "-", "."), "", $receiver);  switch (strlen($receiver)) {     case 0:         exit;     break;      case 6:         $receiver="84722".$receiver;     break;      case 10:         $receiver="8".$receiver;     break; }  // IP сервера с Asterisk $sys_ip = "1.2.3.4";  // имя пользователя для менеджера $User_str = "asterisk"; // ... и его пароль $Secret_str = "mysecretpassword"; $our_exten = "Local/$sender";  $WaitTime = "10"; $domain = "127.0.0.1"; // это будет отображено в sip-клиенте, если звонок пойдёт куда-либо на SIP/xxx $strCustdata = "Call to ".($name!=""?$name:$receiver);  $oSocket = fsockopen ($sys_ip, 5038, $errnum, $errdesc) or die ("Connection to host failed"); sleep (1);  fputs ($oSocket, "Action: login\r\n"); fputs ($oSocket, "Username: $User_str\r\n"); fputs ($oSocket, "Secret: $Secret_str\r\n\r\n");  $wrets = fgets ($oSocket,128);  echo $wrets;  fputs ($oSocket, "Events: off\r\n\r\n"); fputs ($oSocket, "Action: originate\r\n"); fputs ($oSocket, "Channel: $our_exten\r\n"); fputs ($oSocket, "WaitTime: $WaitTime\r\n"); fputs ($oSocket, "CallerId: $strCustdata\r\n"); fputs ($oSocket, "Exten: $receiver\r\n"); fputs ($oSocket, "Context: default\r\n"); fputs ($oSocket, "Async: yes\r\n"); fputs ($oSocket, "Priority: 1\r\n\r\n"); fputs ($oSocket, "Action: Logoff\r\n\r\n"); sleep (2);  fclose ($oSocket); ?> 

Важными параметрами при формировании вызова, как я уже говорил, являются Channel, Exten и Context.

3. Готовим инициатор звонков

Создаём в Apple Script Editor и сохраняем в папку ~/Library/Address Book Plug-Ins/ скрипт

using terms from application "Contacts" 	 	on action property 		return "phone" 	end action property 	 	on action title for p with e 		return "Dial from Yealink" 	end action title 	 	on should enable action for p with e 		if value of e is missing value then 			return false 		else 			return true 		end if 	end should enable action 	 	on perform action for p with e 		set theName to name of p 		set telephone to the value of e 		tell application "Terminal" 			set param to "`echo \"<?php echo 'http://webserver/click2call/call.php?sender=7777&receiver='.urlencode('" & telephone & "').'&name='.urlencode('" & theName & "')?>\" | php`" 			do shell script "/opt/local/bin/wget -q -O - " & param & " >/dev/null 2>&1 & sleep 1" 			quit saving no 		end tell 	end perform action 	 end using terms from 

Скрипт формирует URL, обращается к нему через wget и затем закрывает терминальное приложение. Мне пришлось использовать локальный PHP для кодирования UTF8 строк в URL. Все найденные функции AppleScript не справлялись с задачей в полном объёме. Если вы постоянно держите открытым Terminal.app для работы, то возможно прийдется убрать команду закрытия приложения.

Теперь в приложении Contacts в контекстном меню появится пункт «Dial from Yealink». Замечу, что после внесения правок в скрипт и его сохранения нужно каждый раз перезагружать приложение Contacts для тестирования этих правок.

Для добавления пункта в контекстное меню Services любого приложения нужно создать сервис через Automator. Добавляем блок Run Shell Script, вводим сам скрипт

/opt/local/bin/wget -q -O - "http://webserver/click2call/call.php?sender=7777&receiver=$1" > /dev/null 2>&1 

Настраиваем передачу входных данных в качестве аргументов, а не на стандартный ввод.

Итог.

Получаем возможность звонить со стационарного SIP телефона на номера которые видим на экране. Например, так у меня выглядит контекстное меню, вызванное в данной статье:

Спасибо за внимание.

ссылка на оригинал статьи http://habrahabr.ru/post/170315/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *