На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА
1. Раздел предназначен для обсуждения ПО.
2. Поиск кряков, серийников, варезных версий ПО - запрещен.
3. Холивары также не приветствуются - для этого есть соответствующий раздел.
4. При создании тем в разделе настоятельно рекомендуется придерживаться следующего шаблона оформления.
5. Ссылки для скачивания дистрибутивов ПО должны вести на официальный сайт! Запрещено размещение ссылок на файлы, находящиеся на файлообменниках типа RapidShare, iFolder, DepositFiles, Sms4File, VipFile и прочих "условно-бесплатных" ресурсах.
Модераторы: winsoft
  
> WebRTC или как мы научил нашу CRM звонить на телефоны , Настройка звонков у нас заняла почти месяц, пусть мой рассказ поможет другим
    Компания, в которой мне довелось поработать, занимается продажей услуг по интернету. Каждое утро дежурная смена разбирает общий стек накопившихся заявок и начинается обзвон клиентов для уточнения заказов. В течение дня операторы еще и принимают входящие звонки. До начала нашей затеи они использовали для звонков такой десктопный SIP-клиент:

    user posted image

    Эта звонилка устанавливалась на компьютере каждого сотрудника, принимала звонки и звонила, куда надо. Чтобы сделать какие-либо изменения в настройках, нужно было обойти все машины и сделать все вручную. При этом, если сотрудник работает удаленно, приходилось его консультировать по телефону, как это все сделать. И часто это было довольно непросто.

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

    Возникла идея объединить в одной системе и базе данных всю внутреннюю работу и звонки. Я долго допиливал нашу CRM с функцией встроенной звонилки c записью разговоров.
    Для реализации звонков рассмотрел ряд технологий и пришел к выводу, что их не так уж и много. Нашлась пара опенсорсных и коммерческих реализаций, а так же несколько SAAS сервисов, которые не подходили в силу внутренних политик безопасности - обрабатывать звонки через собственный сервер.
    В начале пытались использовать sipml5

    user posted image

    Документацию пришлось собирать по кускам из сети. В результате получили более менее рабочий телефон с SIP стэком на стороне браузера:

    user posted image

    Установка, тестирование и настройки длились около 2 недель(спасибо нашему Linux админу, который мужественно провел этот ресерч), в результате нашли ряд мелких, но неприятных багов, которые так и не удалось обойти, например один из них был связан с настройками Websockets через SSL. А после выхода Chrome браузера 35 версии web телефон отказался работать совсем.

    Кроме этого мы не хотели раскрывать SIP аккаунты операторам, а SIP стэк на стороне браузера предполагает их открытое использование и отправку через Websockets. Даже если Websockets работают через SSL у потенциального злоумышленника есть возможность отдебажить js код и вытащить SIP пароль. Был вариант - делегировать SIP Digest аутентификацию нашему Web серверу, но до его реализации добраться так и не удалось.

    Так выглядят SIP запросы на стороне браузера в отладочной консоли:

    user posted image

    Полный доступ к SIP стэку из Javascript иметь в общем не плохо. В этом есть свои преимущества, например можно попытаться поправить какой-нибудь интеграционный баг в JS SIP сигналинге. Но здесь есть один нюанс. Чуть более чем 90% SIP вендоров не поддерживают в настоящий момент спецификацию The WebSocket Protocol as a Transport for the Session Initiation Protocol (SIP) RFC 7118 датируемую январем 2014 года по которой работает JS SIP, а это означает что webrtc2sip модуль должен работать как stateful SIP прокси и фактически дублировать поддержку SIP стэка на стороне сервера.

    Такой расклад показался сильно сложным для дальнейшей работы и поддержки и решили уйти от SIP стэка на стороне браузера и найти какое-нибудь более простое и понятное API для таких задач с серверной частью, которую можно было бы хостить у себя.
    В результате начали тестировать Web Call Server. Это не SAAS и позволяет обрабатывать звонки через свой сервер, что в данном случае и требовалось:

    user posted image

    По функциям примерно то же самое что и у sipml5, те же WebRTC звонки на SIP и обратно. Есть еще поддержка Flash, но в ней не было необходимости, так как все операторы используют в основном Chrome и Firefox браузер, а тем кто использует IE пришлось пересесть на более “правильные” браузеры.
    В нагрузку дается софтфон на JS с открытым исходным кодом, который можно перерисовать и адаптировать для web-страницы.
    Оснонвное отличие от sipml5 - это взаимодействие с сервером через API, а не через SIP over Websockets. Т.е. SIP стэка на стороне браузера нет. Он располагается только на стороне сервера. Это немного облегчило задачу front-end разработчику, т.к. SIP стэк на стороне браузера повергал его в смятение, а при работе с Javascript API и CSS стало возможным сосредоточиться на интерфейсной части.

    user posted image

    И так, как мы все это внедряли.

    1. Взяли вот такой сервер на Amazon EC2:
    Памяти и дискового пространства много не требуется. Разве что для логов. А вычислительные мощности CPU в таких задачах могут быть важны, поэтому взяли не самый слабый инстанс.

    user posted image

    2. Подняли Apache для web-интерфейса установили и запустили WCS сервер.

    user posted image

    3. На странице хрома появился стандартный web-телефон, код которого находится на github
    Интерфейс телефона нам не очень понравился, сразу же решили его редизайнить, а отладочная консоль справа оказалась вполне полезной. Жаль что позже ее пришлось убрать чтобы не пугать нормального пользователя.

    user posted image

    4. Протестировали web-телефон на способность звонить. Использовали для этого наши прежние SIP-аккаунты. Все работает, как надо. И на мобильники звонит, и на SIP-телефоны, и удерживание звонков и трансфер, и блэкджек и...

    user posted image

    Похожим образом работает созвон с мобильным телефоном.

    5. Адаптировали код web-телефона для своей web-CRM, перерисовали его дизайн и теперь он выглядит так:

    user posted image

    На адаптации стоит остановиться подробнее, т.к. перерисовкой дизайна дело не ограничилось.
    Первой же серьезной задачей стала автоматическая регистрация web-телефона на SIP сервере. В противном случае, оператору пришлось бы вводить SIP логин и пароль повторно, уже после того, как он ввел логин и пароль для CRM системы. Встал вопрос, как интегрировать.

    Оказалось, что в API есть для этого специальная функция loginByToken:

    ExpandedWrap disabled
          function loginByToken(token) {
          trace("Phone - loginByToken "+ token);
          connectingViewBeClosed = false;
          var result = flashphoner.loginByToken(flashphonerLoader.urlServer, token, document.URL);
          closeLoginView();
          openConnectingView("Connecting...", 0);
      }


    Для того чтобы разобраться, как эта функция работает, пришлось хорошо постараться.
    C помощью документации и примеров удалось выяснить что это работает примерно так:

    user posted image

    1) При создании токена на стороне CRM используется алгоритм шифрования AES, которым зашифровывается строка, включающая SIP логин и пароль пользователя, а так же другую необходимую информацию.
    Ключ шифрования известен только нашему серверу, где развернута CRM, а так же WCS серверу. Кроме того, срок действия токена задается специальным атрибутом expires для того, чтобы не было возможности им повторно воспользоваться.
    Криптование токена происходит в AES CTR mode. Ниже пример c openssl, в котором происходит генерация шифрованного токена с передачей SIP пароля:

    ExpandedWrap disabled
      echo -ne '<root status="ok" description="test" registerRequired="true" login="user5" authenticationName="user5" password="password" outboundProxy="proxy.my" domain="proxy.my" port="5060" visibleName="AAA" api_key="App1" expires="1394839040761100000"/>' | openssl enc -aes-128-ctr -nosalt -K 8263D535FFFFFFFF7B0F60 -iv 00000000000000000000000000000000 | xxd -p


    В результате получим что-то вроде:

    ExpandedWrap disabled
      CRM:cf4693eedaafda1390b261dcf29d45bd3556d64b1f69cd84db8c3ac8721e7e139b80be75e39da18154e897596e9317084faee0d24d6a6197b62a93a2647b263059167b2664179a5866738260c77372e04fe22104ebe1c7530e9215f50d111fd24384755d28d06673e866159c0b6b83289c045619e8481f9c2a6b56b182f393a7dea06b38b7856436895402a5b40f0525a17822ae0f3204b606e4f0169d1ca9176e8e1b696683d12c7db8208946c204e94f3c8ff285f2bcef4ca9b12187cf541ce37d508d3663ef65f944b01db9aea5c0f10002a376d051cbf1b19bc34f76b6d2a4e1ad1450ae412b51b3af1d3860167f5416b3d2c9eeff94d60b82279e8685beb543893e8a09dee640d7366e478d0d1ee7368e0b63b511


    Слева название нашего приложения “CRM”, а справа созданый ранее токен.
    Вставляем этот токен в конфиг flashphoner.xml web-телефона в таком виде:

    ExpandedWrap disabled
      <token>CRM:cf4693eed...</token>


    В этом случае процедура автоматической регистрации по токену начнется сразу же после перезагрузки страницы.
    2 и 3) loginByToken и расшифровка.
    На стороне сервера в конфиге прописаны ключи шифрования для AES

    ExpandedWrap disabled
      CRM=8263D535FFFFFFFF7B0F60


    Таким образом, когда приходит токен с префиксом “CRM:” для его расшифровки используется соответствующий ключ.

    В результате расшифровки WCS сервер получает зашифрованную ранее строка строку:

    ExpandedWrap disabled
      <root status="ok" description="test" registerRequired="true" login="user5" authenticationName="user5" password="password" outboundProxy="proxy.my" domain="proxy.my" port="5060" visibleName="AAA" api_key="App1" expires="1394839040761100000"/>


    и из этой XML строки берет все данные необходимые для SIP регистрации.

    3) Как только сервер расшифровал данные, он посылает SIP REGISTER запрос на SIP и на 401 ответ отдает уже нормальную Digest аутентификацию с использованием расшифрованных на предыдущем шаге SIP логина и пароля.

    ExpandedWrap disabled
      REGISTER sip:sipnet.ru;lr SIP/2.0
      Call-ID: 345ec5157b1a66de3a3a275bdba36197@192.168.1.90
      CSeq: 2 REGISTER
      From: <sip:crm1@sipnet.ru>;tag=73a499a8
      To: <sip:crm1@sipnet.ru>
      Via: SIP/2.0/UDP 192.168.1.90:30000;branch=z9hG4bK2622ce723c34760d6a3f43dd631329e1
      Max-Forwards: 70
      User-Agent: WebRTC
      Allow: UPDATE,MESSAGE,BYE,ACK,REFER,INVITE,NOTIFY,INFO,OPTIONS,CANCEL
      Contact: <sip:crm1@192.168.1.90:30000>;expires=3600
      Expires: 3600
      Authorization: Digest username="crm1",realm="etc.tario.ru",nonce="4A0674BEDF81E0B3F65D",uri="sip:sipnet.ru;lr",response="0762b862c544007f4fb7c43277312a3d",algorithm=MD5,opaque="opaq",qop=auth,cnonce="1234567890",nc=00000001
      Content-Length: 0


    В этом случае SIP логин и пароль знают только сама CRM и Web Call Server. На браузер эти данные в открытом виде не попадают.
    Таким образом нам удалось внедрить телефон в страницу оператора, не заставляя его хранить два разных аккаунта - один для CRM другой для SIP, потому что это очень неудобно. Теперь сразу после загрузки страницы вызывается loginByToken и телефон переходит в состояние готовности.

    Некоторые результаты:

    1. Звонки теперь делаются с сайта и принимаются на сайте, где все действия фиксируются в системе.
    2. Стало возможным прослушивание записанных разговоров, что помогает разрешать конфликтные ситуации с клиентами и разногласия между сотрудниками. Это важно для нашего распределенного офиса.
    3. Количество принятых звонков увеличилось примерно на 20%. Стало понятно, что операторы не всегда поднимали трубку при звонке клиента.
    На текущий момент можно сказать, что все работает, как задумано. Проблемные ситуации удалось разрешить без серьезного погружения в SIP матчасть.
    Из недостатков можно отметить невозможность установки под Windows. Кстати, с установкой под Linux и интеграцией тоже пришлось повозиться и, похоже, что осилит ее только продвинутый пользователь/разработчик.
    WebRTC аудио звонки работают стабильно и без каких-либо дополнительных браузерных плагинов типа Flash Player. Так что можно сказать что нам удалось реализовать задуманную интеграцию и месяц работы был потрачен не зря.
    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
    0 пользователей:


    Рейтинг@Mail.ru
    [ Script execution time: 0,0340 ]   [ 16 queries used ]   [ Generated: 28.03.24, 14:26 GMT ]