Интеграция 1С:CRM и Asterisk с помощью PHP-AGI и веб-сервисов 1C

08.02.13

Интеграция - Телефония, SIP

Давно зрел вопрос, можно ли встроить в диалплан Asterisk обращение к 1С:CRM системе для выполнения каких-либо управляющих действий и можно ли из 1С управлять IP АТС? Схема работы простейшая — при входящем звонке спросить у 1С что с ним делать, и если 1С ответила, то выполнить команду или продолжить стандартное выполнение маршрута вызова.

В качестве IP АТС мы используем Askozia — это один из дистрибутивов широко известного Asterisk, про Askozia мы писали в этом посте.
В качестве CRM системы используется продукт 1С: Управление торговлей и взаимоотношениями с клиентами 8 в режиме клиент-сервер. Давно зрел вопрос, можно ли встроить в диалплан Asterisk обращение к 1С:CRM системе для выполнения каких-либо управляющих действий и можно ли из 1С управлять IP АТС?

Схема работы простейшая — при входящем звонке спросить у 1С что с ним делать, и если 1С ответила, то выполнить команду или продолжить стандартное выполнение маршрута вызова.
Попробуем выполнить простейшее действие — установить название клиента по номеру телефона из CRM системы и записать это значение в CDR базу Asterisk.

Исходные данные

1С: Предприятие 8.2 (8.2.17.143)
“Управление торговлей и взаимоотношениями с клиентами” ( CRM + УТ )
Около 10000 контрагентов.
СУБД MS SQL
Web сервер IIS

АТС Askozia CFE 2.1: 
Asterisk 1.8.4.4
PHP 4.4.9
AGI phpagi.php,v 2.14

В Askozia уже имеется механизм установки CallerID на основании данных “записной книжки” во внутренней базе данных Asterisk. Для реализации этого варианта мы использовали “SDK компонента связи 1С и Asterisk”.

Пример функции, позволяющей записать данные в AstDB:

Пример вызова функции, применимо к текущей задаче:

// Записывает в базу данных Asterisk контактную информацию //
// dbFamily - “cidname” // наша “записная книжка”
// dbKey - Ключ переменной помещаемой в семейство, номер телефона строкой, содержит только цифры
// dbValue - Имя контакта латинскими буквами
ЗаписатьПараметрВБД("cidname", “74952293042”, “OOO MIKO”);

Это первый вариант реализации. Мы запустили его в работу в нашей организации. После синхронизации контактов на всех телефонах офиса при звонке видно, с кем мы разговариваем (конечно, если есть номер в базе). Разумеется CallerID возможно видеть только на телефонах с дисплеем :).


Недостатки:
Необходима периодическая синхронизация данных AstDB и 1С. Данные устаревают.
Askozia — ReadOnly система. В этом ее преимущество и недостаток. После перезагрузки AstDB приводится в “Исходное” состояние — до записи списка клиентов из 1С. 

В силу перечисленных недостатков мы отказались от этого варианта реализации. Но для "голого" Asterisk этот вариант вполне рабочий. 
 

Вариант онлайн взаимодействия через AGI и Web сервисы 1С: Предприятия 8

 

Создаем веб-сервис 1С

При поступлении звонка на наш внешний номер в маршруте вызова Asterisk возможно вызвать AGI скрипт. В скрипте обратиться к веб-сервису 1С и установить значение CallerID(name).

Разработан простой web сервис 1С:
Имя — MIKO_identify_number

пространство имен: wiki.miko.ru/doc:1cajam:identifynumber
имя файла публикации: 1C_MIKO_identify_number.1cws



У сервиса будет только одна простая операция (функция)



свойства операции:



содержит один входной параметр «Number», собственно в него и будет передаваться номер звонящего клиента.


тип параметра и возвращаемого значения “string (http://www.w3.org/2001/XMLSchema)
Публикуем веб-сервис (отдельная тема, как это сделать, не будем на ней останавливаться, можно почитать здесь). После публикации проверим работу сервиса с помощью веб браузера, откроем wsdl описание по ссылке:

http://IP_WEB_SERVER_1C/TestComponenta/ws/1C_MIKO_identify_number.1cws?wsdl

Если все правильно, то результат будет таким:



В модуле объекта сервиса пропишем простейший обработчик операции:

Функция identify(Number)
    Результат = "";
    Возврат ПолучитьИмяКонтатаПоНомеруТелефона(Number);
КонецФункции

// примитивный пример получения имени контакта, 
// реальный код зависит от конкретной информационной базы

Функция ПолучитьИмяКонтатаПоНомеруТелефона(Number)
    ОтветСервера = "OOO MIKO " + Number+ "";
    Возврат ОтветСервера;
КонецФункции

Возьмем cURL и проверим работу нашего WEB сервиса «в лоб».
В общем случае команда будет выглядеть следующим образом:

curl --header <заголовки> -d '<XML структура>' <адрес сервиса

Отправляем запрос:
curl --header "Content-Type: text/xml; charset=utf-8" -d ' 74952293042' http://IP_WEB_SERVER_1C/TestComponenta/ws/1C_MIKO_identify_number.1cws 

В этом примере не используется аутентификация (в базе 1С нет пользователя).

Пример ответа сервера:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header/><soap:Body>
    <m:identifyResponse xmlns:m="http://wiki.miko.ru/doc:1cajam:identifynumber">
        <m:return xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">OOO MIKO 74952293042m:return>
    <m:identifyResponse><soap:Body>
<soap:Envelope>

Работает!

Создаем AGI скрипт

К сожалению, в Askozia очень примитивные возможности PHP, нет даже cURL расширения, да и PHP используется достаточно древней 4.4.9 версии. Тем не менее, мы попробовали победить все ограничения, потому просьба сильно не ругаться на код описанные ниже.

#!/usr/bin/php -f
get_variable($_varName);
  if(!$v['result'] == 0){
    $agi->verbose($_varName.' ---> '.$v['data'], 10);
    return $v['data'];
  }
  else{
    $agi->verbose($_varName.' not set', 10);
    return "";
  }
} // GetVarChannnel($_agi, $_varName)

// объект класса agi, его описание содержит файл phpagi.php
$agi = new AGI();

// базовые переменные, параметры подключения к сервису
$path   = '/TestComponenta/ws/1C_MIKO_identify_number.1cws';
$server = 'IP_WEB_SERVER_1C';
$port   = 80;
$number = GetVarChannnel($agi, "CALLERID(num)");;
$user_1c= "1C_USERNAME";
$pass_1c= '1C_PASSWORD';

$auth = base64_encode($user_1c.':'.$pass_1c);
$crlf = "\r\n"; 

// данные для передачи - непосредственно сам SOAP запрос
$xmlDocument = (
'

  
    
      '.$number.'
    
  
');
$contentLength = strlen($xmlDocument);
  
// создаем сокет
if (($http_soket = @fsockopen($server, $port, $errno, $errstr,1.5)) == false) 
  return;
$query  = "POST $path HTTP/1.1"                  .$crlf;
$query .= "Host: $server"                      .$crlf; 
$query .= "Content-Type: text/xml; charset=utf-8"    .$crlf; 
$query .= "Authorization: Basic $auth"            .$crlf; 
$query .= "Content-Length: $contentLength"          .$crlf;
$query .= $crlf; 
$query .= $xmlDocument; 
    
// устанавливаем таймаут на поток 1секунда
stream_set_timeout($http_soket, 1, 0); 

// отправляем запрос
fputs($http_soket, $query); 
    
$result = '';

// считываем ответ
while ($line = fgets($http_soket)) 
  $result .= $line; 
  
// отсекаем заголовки ответа
$result = substr($result, strpos($result, $crlf.$crlf) + 4); 
fclose($http_soket);

// разбор ответа

parse_response($result); 

if($ret_value != ''){
  $agi->set_variable('CALLERID(name)', $ret_value);  // Если 1С вернула значение, то записываем это значение в таблицу CDR
} 
?>

 

Подключим скрипт к Askozia, для этого в веб -интерфейсе перейдем на закладку приложения и добавим новое PHP приложение.



В поле “Логика приложения” устанавливаем текст скрипта. 
Обратите внимание “#!/usr/bin/php -f” — строка должна быть опущена. Askozia сама ее допишет. Устанавливаем имя и номер для приложения. 
Теперь необходимо узнать имя файла скрипта.  Для этого командной консоли (CLI) Asterisk выполним команду:

# dialplan show 1334444@internal

[ Context 'internal' created by 'pbx_config' ]

  '1334444' =>	1. NoOp(internal calling application: AGI_App_CallerID) [pbx_config]
                2. Set(CDR(InternalCalleridNum)=1334444)      [pbx_config]
                3. Goto(DIALPLAN-APPLICATION-176239923050fac4c5678b9,${EXTEN},1) [pbx_config]

-= 1 extension (3 priorities) in 1 context. =-

Мы выяснили, что в номере 1334444 вызывается контекст DIALPLAN-APPLICATION-176239923050fac4c5678b9

Выведем этот контекст, чтобы понять как называется наш PHP файл:

# dialplan show DIALPLAN-APPLICATION-176239923050fac4c5678b9

[ Context 'DIALPLAN-APPLICATION-176239923050fac4c5678b9' created by 'pbx_config' ]
'h' =>	1. Hangup()
's' =>	1. AGI(DIALPLAN-APPLICATION-176239923050fac4c5678b9.php)
        2. Hangup()
'_[0-9a-zA-Z*#]!' =>1. AGI(DIALPLAN-APPLICATION-176239923050fac4c5678b9.php)
                    2. Hangup()

Искомый файл найден: DIALPLAN-APPLICATION-176239923050fac4c5678b9.php
Перейдем к редактированию входящего маршрута вызова и добавим в начало маршрута блок универсальной команды:

в поле команды установить AGI(DIALPLAN-APPLICATION-176239923050fac4c5678b9.php)
в итоге мой маршрут вызова будет выглядеть следующим образом:


При входящем звонке, направленном на этот маршрут, происходит выполнение AGI скрипта с обращением к серверу 1С, сервер по переданному номеру возвращает название контрагента, и это название вписывается в поле CallerID.

В результате до внедрения история выглядела так:


После запуска web-сервиса в истории появились названия клиентов из 1С:CRM системы:


Помимо этого все нотификации Askozia о пропущенном звонке или полученном факсимильном сообщении на электронную почту стали более информативными, в заголовке письма есть название клиента, раньше был просто номер.

 

Заключение

Этот простой пример позволяет продемонстрировать возможность онлайн интеграции IP АТС и 1C, которая естественно не ограничивается только установкой имени клиента. Мы можем влиять на маршрутизацию звонка, отправлять звонок, минуя IVR сразу на менеджера, установленного в карточке клиента, воспроизводить различные рекламные сообщения в зависимости от вида деятельности клиента и многое-многое другое.

Полезные ссылки:

См. также

Управление взаимоотношениями с клиентами (CRM) Управление маркетингом (EMM) Пользователь Платформа 1С v8.3 Управленческий учет Платные (руб)

Решение 1С:CRM 3.0 предназначено для компаний с потребностью совместной работы более 5 пользователей в единой информационной базе. Решение позволяет автоматизировать все бизнес-процессы компании в соответствии с концепцией CRM, включая закупки, продажи, маркетинг, сервисное обслуживание и пр.

9700 руб.

10.11.2015    43045    28    1    

17

Управление взаимоотношениями с клиентами (CRM) Оптовая торговля Розничная торговля Пользователь Платформа 1С v8.3 Оперативный учет Управляемые формы 1С:Управление торговлей 10 1С:Розница 2 Россия Управленческий учет Платные (руб)

Подсистема призвана упростить и автоматизировать процесс расчета и начисления бонусов покупателей. Бонусная система работает с конфигурациями 1С:УТ 10.3, 1С:Розница. Механизм реализован в начале 2013г. и работает до сих пор с постоянными совершенствованиями.

30000 руб.

02.11.2015    111778    99    87    

182

Рабочее место Управление взаимоотношениями с клиентами (CRM) Оптовая торговля Розничная торговля Пользователь Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Оптовая торговля, дистрибуция, логистика Управленческий учет Платные (руб)

Данная обработка - удобный инструмент в 1С для менеджеров по продажам для повседневной работы с клиентами. Позволяет упростить весь цикл работы с клиентом: первичная консультация по наличию товара, быстрое оформление нового заказа, контроль исполнения заказов. Обработка будет особенно актуальна для компаний, работающих, в основном, с юридическими лицами.

18000 руб.

08.11.2016    60905    39    22    

61

Телефония, SIP Платформа 1С v8.3 1С:Управление нашей фирмой 3.0 Россия Управленческий учет Платные (руб)

Модуль интеграции с виртуальной телефонией Новофон для решения 1С:Управление нашей фирмой, редакция 3.0. Обновление релиза в связи с переходом на API 2.0 поставщиком сервиса. Бета-версия 2.0 до окончания перехода поставщиком на новую версию.

12000 руб.

26.02.2024    823    1    0    

2

Управление взаимоотношениями с клиентами (CRM) Телефония, SIP Облачные сервисы, хостинг Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Продукт интеграции возможностей Облачной АТС Билайн в систему 1С Предприятие 8. Звонки прямо из программы 1С, уведомления о текущих звонках, регистрация пропущенных и завершенных вызовов, ведение журнала, анализ данных об использовании мобильной связи.

12000 руб.

20.03.2019    22883    53    0    

36
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. expert.1c8 10.02.13 16:13 Сейчас в теме
Почитал про Askozia - для себя отметил, что в отличии от Asterisk система платная..
SDK для 1с из ссылки - тоже платная для любого количества пользователей..

При такой реализации нет пауз при прохождении звонка? веб-сервис 1с быстро отвечает?
2. boffart 297 10.02.13 18:59 Сейчас в теме
Почитал про Askozia - для себя отметил, что в отличии от Asterisk система платная..
SDK для 1с из ссылки - тоже платная для любого количества пользователей..


есть возможность попробовать демо версии

При такой реализации нет пауз при прохождении звонка? веб-сервис 1с быстро отвечает?


ответ приходит быстр, задержек не заметно. Поиск по базе в несколько тысяч контрагентов.
3. luchyk007 28.03.13 08:29 Сейчас в теме
интересный материал спасибо.
4. nick_krsk 18 07.07.14 13:15 Сейчас в теме
В статье описан пример, когда по запросу от IP ATC 1С отдает наименование контрагента по номеру телефона. А можно ли реализовать такой вариант: при входящем звонке в 1С отображать форму с данными о контрагенте?
5. boffart 297 07.07.14 14:10 Сейчас в теме
(4) nick_krsk,
Тут возникает ряд проблем. Описан способ оповещения через веб сервис.
Сервис "ничего не знает" о клиентских сеансах. По этой причине оповестить их в реальном времени нет возможности.
Как вариант - использовать регистр сведений для "пометки" о звонке. Клиент должен приодически "просматривать" новые записи в регистре сведений.

Мы в свое время отказались от этого варианта.
Разработали внешний компонент для взаимодействия с Asterisk
http://www.telefon1c.ru/asterisk/
6. NewLifeMan 12.12.17 11:39 Сейчас в теме
ПолучитьИмяКонтатаПоНомеруТелефона -маленькая опечатка..
ПолучитьИмяКонтактаПоНомеруТелефона

За статью - Спасибо!
Оставьте свое сообщение