WebRTC або як я навчив нашу CRM дзвонити на телефони

Компанія, в якій мені довелося працювати, займається продажем інтернет-послуг. Щоранку чергова зміна розбирає загальний стек заявок, що накопичилися, і починається обдзвон клієнтів для уточнення замовлень. Протягом дня оператори ще приймають вхідні дзвінки. До початку моєї витівки вони використовували для дзвінків такий десктопний SIP-клієнт:

нашу

Але найголовнішим траблом була відсутність інтеграції з нашою web-системою та базою даних. Такі, здавалося б прості завдання, як відкриття картки клієнта на вхідний дзвінок, збереження статистики дзвінків для кожного із співробітників та моніторинг їхньої активності з адміністративного web інтерфейсу — все це дуже складно зробити з десктопним софтфоном, навіть у тому випадку він має відповідні можливості інтеграції з браузером, наприклад, за допомогою плагінів.

Виникла ідея об'єднати в одній системі та базі даних всю внутрішню роботу та дзвінки. Я довго допилював нашу CRM з функцією вбудованої дзвонилки із записом розмов. Для реалізації дзвінків розглянув ряд технологій і дійшов висновку, що їх не так вже й багато. Знайшлася пара опенсорсних і комерційних реалізацій, а також кілька SAAS сервісів, які не підходили через внутрішні політики безпеки — обробляти дзвінки через власний сервер.

Спочатку намагався використовувати sipml5:

Так виглядають SIP запити на стороні браузера у консолі налагодження:

webrtc

В результаті почав тестувати Web Call Server. Це не SAAS і дозволяє обробляти дзвінки через свій сервер, що в даному випадку потрібно:

webrtc

За функціями приблизно те саме, що і у sipml5, ті ж WebRTC дзвінки на SIP і назад. Є ще підтримка Flash, але в ній не було необхідності, тому що всі оператори використовують переважно Chrome і Firefoxбраузер, а тим, хто використовує IE, довелося пересісти на більш "правильні" браузери.

У навантаження дається софтфон на JS з відкритим кодом, який можна перемалювати і адаптувати для web-сторінки.

Основна відмінність від sipml5 – це взаємодія з сервером через API, а не через SIP over Websockets. Тобто. SIP стека на стороні браузера немає. Він розташований лише за сервера. Це полегшило завдання front-end розробнику, т.к. SIP стек на стороні браузера кидав його в сум'яття, а при роботі з Javascript API і CSS стало можливим зосередитися на інтерфейсній частині.

Отже, як я це все впроваджував.

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

нашу

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

телефони

нашу

сервер

Виявилося, що в API є для цього спеціальна функція loginByToken:

Для того щоб розібратися, як ця функція працює, довелося добре постаратися. За допомогою документації та прикладів вдалося з'ясувати, що все це працює приблизно так:

сервер

1) При створенні токена на стороні CRM використовується алгоритм шифрування AES, яким зашифровується рядок, що включає SIP логін та пароль користувача, а також іншу необхідну інформацію.

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

В результаті отримав щось на кшталт:

У цьому випадку процедура автоматичної реєстрації по токену розпочнеться відразу після перезавантаження сторінки. 2 і 3) loginByToken і розшифровка.

На стороні сервера в конфізі прописані ключі шифрування для AES:

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

В результаті розшифровки WCS сервер отримує зашифрований раніше рядок:

і з цього рядка XML бере всі дані необхідні для SIP реєстрації.

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

Деякі результати впровадження браузерних дзвінків:

1. Дзвінки робляться з сайту і приймаються на сайті, де всі дії фіксуються в системі.

2. Стало можливим прослуховування записаних розмов, що допомагає вирішувати конфліктні ситуації з клієнтами та розбіжності між співробітниками. Це важливо для нашого розподіленого офісу.

3. Кількість прийнятих дзвінків збільшилася приблизно 20%. Стало зрозуміло, що оператори не завжди піднімали слухавку під час дзвінка клієнта. На даний момент можна сказати, що все працює, як задумано. Проблемні ситуації вдалося вирішити без серйозного занурення у SIP матч.

З недоліків можна назвати неможливість встановлення під Windows. До речі, з установкою під Linux та інтеграцією теж довелося повозитися і, схоже, що подужає її лише просунутий користувач/розробник.

WebRTC аудіо дзвінки працюють стабільно і без будь-яких додаткових браузернихплагінів, типу Flash Player. Тож можна сказати, що мені вдалося реалізувати задуману інтеграцію і два тижні роботи було витрачено недаремно.

Хардкорна конфа за С++. Ми запрошуємо лише профі.