Когда возникла бизнес-проблема по созданию скоростного механизма уведомления пользователя о эвентах в Контакт-центре (переполнение очередей) и телефонной станции (уведомление о пропущенных вызовах), то пришла в голову мысль про Telegram.
На самом деле в данной ситуации Telegram, это лишь один из возможных вариантов. Можно делать через СМС. Можно делать банально по email, и он потом прийдет пользователю на мобильный и у него вылезет серверный Push. Или делать напрямую на приложение на мобильном, чтобы Push получался прямо от него.
Но у каждого метода есть свои минусы. За СМС надо платить. Email забивает пользователю глаза постоянным приходом и пользователь перестает реагировать. Отдельное приложение на телефон надо сделать под каждую платформу, установить и организовывать регистрацию токенов на внутренних серверах компании. Решение с telegram этих минусов лишено, хотя приложение должно конечно быть установлено на мобильном, десктопе или еще где-то. Впрочем у Telegram тоже есть минус. Это наш уважаемый Роскомнадзор, который очень его не любит. Это вносит некую дополнительную пикантность реализации.
Итак.
Воодушевившись вот этим и этим я приступил к делу.
Для начала я создал бота в BotFather
Далее следует уже работать напрямую с API.
Найдя вот эту достойную публикацию, я обратился на Hetzner и организовал свой http proxy для работы с api всего за 3 евро в месяц на немецкой территории.
Следующий обязательный шаг — надо создать группу, в которую будут входить ваши пользователи и собственно вновь созданный чат-бот. Это является защитой от спама. То, чего так не хватает Viber например.
Далее требуется узнать номера необходимых пользователей.
Для этого надо каждому пользователю бросить в чат некое сообщение. В целом оно произвольно. Но используем например для этой цели фразу register и некий номер. Номер будет являться идентификатором для АТС.
Теперь обратимся к API.
Используя вновь созданный прокси делаем следующий запрос прямо из шела прокси. Если уже переключили свой браузер на работу с ним, то можно прямо из браузера.
Вместо «553ХХХХХХ:AAGrXfKHwхххххххххххххххххххххххххх» указывается то, что вы получили от BotFather.
В ответе мы ищем идентификатор пользователя, оставившего сообщение register.
В тексте выше видим само сообщение: "/register 1000"
И искомый идентификатор пользователя: «id»:3918ххххх"
Вместо ххххх конечно идут реальный цифры.
Теперь можно проверить работу бота и API прямо из шела или из вашего браузера следующим запросом:
api.telegram.org/bot553ХХХХХХ:AAGrXfKHwхххххххххххххххххххххххххх/sendMessage?text=Your_queue_is_overloaded&chat_id=3918ххххх
Где bot553ХХХХХХ:AAGrXfKHwхххххххххххххххххххххххххх — это номер бота и ключ, полученный от BotFather, а 3918ххххх — это номер пользователя, полученный из предыдущего шага.
В тексте можно использовать русский, но пробелы надо заменить на %20.
Как результат этой команды, сообщение было получено в Telegram на десктопе и на мобильный телефон одновременно.
Браузер вернул следующий ответ:
Итак api работает. Теперь следует перейти к интеграции с телефонной станцией Avaya. Для этой цели я буду использовать продукт Avaya Aura Experience Portal 7.1. Он используется для организации IVR в экосистеме Avaya и является полностью софтовой, виртуализированной платформой интеллектуального обслуживания. Важной его чертой является возможность вставки Java кода, что и потребуется нам для интеграции с Telegram. Не буду создавать рекламы, но на мой взгляд это один из лучших продуктов Avaya и на нем можно писать реально удивительные вещи. Например Голосовой контроль чайника или посерьезнее Транскрибирование разговора на лету.
Данная система IVR конечно весьма недешева, однако есть особенности. Она лицензируется по портам. Т.к. мы планируем использовать ее крайне кратковременно, то будет достаточно одного порта. А один порт имеет достаточно низкую стоимость. И при виртуализации система требует всего 2 Core/4GB RAM/60GB HDD. В общем ее можно установить на почти любой ноутбук или десктоп. Ну и как вишенка на торте — у данного продукта есть trial режим, позволяющий бесплатно пользоваться ей 30 дней.
Для реализации задачи нам требуется по событию в телефонной станции организовать звонок на IVR и далее настроить его так, чтобы он отсылал соответствующий эвент по только что созданному API.
Если рассмотреть задачу уведомления супервизора о превышении числа звонков в очереди в Контакт-центр, то в телефонной станции надо будет видоизменить основной вектор и создать дополнительный.
CALL VECTOR
Number: 5 Name: Vector for Skill 5
01 goto step 5 if calls-queued in skill 5 pri m > 5
02 queue-to skill 5 pri m
03 wait-time 30 secs hearing silence
04 goto step 3 if unconditionally
05 route-to number 1214 with cov n if unconditionally
06 goto step 2 if unconditionally
Данный вектор непосредственно перед постановкой вызова в очередь проверяет число вызовов находящихся в данной очереди. Если оно превышает 5, то вызов уходит на шаг 5, где переводится на номер 1214. Это номер маршрутизируется на IVR.
В условии в шаге 1 можно проверять огромное число параметров, являющихся показателем нагрузки в Контакт-центре. Например EWT, число доступных операторов, число вошедших в систему операторов, число вызовов в очереди, уровень сервиса и т.д. и при превышении того или иного показателя переадресовывать вызов в IVR.
Приложении в IVR будет запускать отсылку сообщения в Telegram и тут-же переводить вызов обратно в Контакт-центр на похожий вектор, только без шага 1 и 5.
Время задержки такого вызова по обработку составит около 100 миллисекунд, что для звонящего абонента абсолютно несущественно.
Второй вектор будет выглядеть следующим образом:
CALL VECTOR
Number: 6 Name: Skill 5 Direct
01 queue-to skill 5 pri m
02 wait-time 30 secs hearing silence
03 goto step 2 if unconditionally
Итак вызов по событию перенаправлен в IVR. Перейдем к разработке приложения на нем.
Приложения для Avaya Aura Experience Portal разрабатываются в Eclipse c установленным плагином Orchestration Designer. Это позволяет перенести разработку для неквалифицированных пользователей в режим Drag&Drop перемещения квадратиков и стрелочек без погружения в Java код.
Ну и квалифицированные пользователи могут уже делать вкрапления Java кода. Далее приложение собирается в виде сервлета и разворачивается на Tomcat, куда ссылается IVR при получении вызова.
Приложение выглядит следующим образом:
Вызов попадает в нод AppRoot, далее проводится предварительная обработка переменных и вызов оправляется в Telegram Connector, который уже является чистым Java кодом. После отсылки сообщения, идет обработка перевода вызова обратно в Контакт-центр.
Для упрощения настроек используются Configurable Variables, которые позволяют вывести настройки внутренних переменных приложения на Web портал самого Experience Portal. Нужно это для того, чтобы при смене настроек не пересобирать приложение.
Блок переменных выглядит следующим образом:
Как Configurable Variables используется переменная DNIS c подпеременными. Для передачи переменных в Java код используются переменные, написанные заглавными буквами.
Блок первичной обработки выглядит следующим образом:
Да простят меня любители чистого кода. Блок сбора урла выглядит ужасно. Это особенности Orchestration Designer. Конечно правильнее его было собрать прямо в Java коде одной строкой, но мне важно было проконтролировать какой урл попадает в Java код и пришлось его собирать вот так.
Сам коннектор выглядит крайне минималистично:
Функции mySession.getVariable и mySession.getVariableField нужны для передачи в Java код информации из приложения и возврата ответа обратно.
Т.е. мы сформировали URL по вышеописанному принципу и запустили его, передав то, что вернул сервер, обратно.
Вот собственно и все приложение, да в общем и все решение. Сам web портал IVR с Configurable Variables выглядит следующим образом:
Если кому-то интересно посмотреть на реальную демонстрацию прототипа, то он может ее увидеть здесь.
Ну и не обошлось без вишенки на торте. Точнее даже двух.
Про первую я уже написал. Для работы решения нужно сервер приложений подключать к Telegram через прокси, находящийся не в России. Надеюсь этот бред когда-нибудь закончится.
Ну и вторая вишенка. Конечно соединение с telegram обязано шифроваться и соединение идет через https. И используется для него конечно же не самоподписанный сертификат. И этот сертификат Telegram не отдает. А в отличии от браузера, сервер приложений не может так просто установить соединение без сертификата. Так вот вишенкой на торте является сам процесс нахождения данного сертификата и загрузку его в сервер приложений. После данной процедуры все сразу волшебно заработало.
Верю, что человек, который пройдет успешно мой путь, также успешно найдет данный сертификат. Главное что он знает, что его надо найти.
Спасибо за внимание.
На самом деле в данной ситуации Telegram, это лишь один из возможных вариантов. Можно делать через СМС. Можно делать банально по email, и он потом прийдет пользователю на мобильный и у него вылезет серверный Push. Или делать напрямую на приложение на мобильном, чтобы Push получался прямо от него.
Но у каждого метода есть свои минусы. За СМС надо платить. Email забивает пользователю глаза постоянным приходом и пользователь перестает реагировать. Отдельное приложение на телефон надо сделать под каждую платформу, установить и организовывать регистрацию токенов на внутренних серверах компании. Решение с telegram этих минусов лишено, хотя приложение должно конечно быть установлено на мобильном, десктопе или еще где-то. Впрочем у Telegram тоже есть минус. Это наш уважаемый Роскомнадзор, который очень его не любит. Это вносит некую дополнительную пикантность реализации.
Итак.
Воодушевившись вот этим и этим я приступил к делу.
Для начала я создал бота в BotFather
Далее следует уже работать напрямую с API.
Найдя вот эту достойную публикацию, я обратился на Hetzner и организовал свой http proxy для работы с api всего за 3 евро в месяц на немецкой территории.
Следующий обязательный шаг — надо создать группу, в которую будут входить ваши пользователи и собственно вновь созданный чат-бот. Это является защитой от спама. То, чего так не хватает Viber например.
Далее требуется узнать номера необходимых пользователей.
Для этого надо каждому пользователю бросить в чат некое сообщение. В целом оно произвольно. Но используем например для этой цели фразу register и некий номер. Номер будет являться идентификатором для АТС.
Теперь обратимся к API.
Используя вновь созданный прокси делаем следующий запрос прямо из шела прокси. Если уже переключили свой браузер на работу с ним, то можно прямо из браузера.
root@ubuntu-dsenash ~ # wget https://api.telegram.org/bot553ХХХХХХ:AAGrXfKHwхххххххххххххххххххххххххх/getUpdates
--2018-06-21 11:11:25-- https://api.telegram.org/bot553ХХХХХХ:AAGrXfKHwхххххххххххххххххххххххххх/getUpdates
Resolving api.telegram.org (api.telegram.org)... 149.154.167.220, 2001:67c:4e8:f004::9
Connecting to api.telegram.org (api.telegram.org)|149.154.167.220|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 370 [application/json]
Saving to: ‘getUpdates’
getUpdates 100%[==================================================================================>] 370 --.-KB/s in 0s
2018-06-21 11:11:25 (14.1 MB/s) - ‘getUpdates’ saved [370/370]
root@ubuntu-dsenash ~ # cat getUpdates
{"ok":true,"result":[{"update_id":90770хххх,
"message":{"message_id":43,"from":{"id":3918ххххх,"is_bot":false,"first_name":"Dmitry","last_name":"Senashenko","language_code":"ru"},"chat":{"id":3918ххххх,"first_name":"Dmitry","last_name":"Senashenko","type":"private"},"date":1529572218,"text":"/register 1000","entities":[{"offset":0,"length":9,"type":"bot_command"}]}}]}root@ubuntu-dsenash ~ #
Вместо «553ХХХХХХ:AAGrXfKHwхххххххххххххххххххххххххх» указывается то, что вы получили от BotFather.
В ответе мы ищем идентификатор пользователя, оставившего сообщение register.
В тексте выше видим само сообщение: "/register 1000"
И искомый идентификатор пользователя: «id»:3918ххххх"
Вместо ххххх конечно идут реальный цифры.
Теперь можно проверить работу бота и API прямо из шела или из вашего браузера следующим запросом:
api.telegram.org/bot553ХХХХХХ:AAGrXfKHwхххххххххххххххххххххххххх/sendMessage?text=Your_queue_is_overloaded&chat_id=3918ххххх
Где bot553ХХХХХХ:AAGrXfKHwхххххххххххххххххххххххххх — это номер бота и ключ, полученный от BotFather, а 3918ххххх — это номер пользователя, полученный из предыдущего шага.
В тексте можно использовать русский, но пробелы надо заменить на %20.
Как результат этой команды, сообщение было получено в Telegram на десктопе и на мобильный телефон одновременно.
Браузер вернул следующий ответ:
Итак api работает. Теперь следует перейти к интеграции с телефонной станцией Avaya. Для этой цели я буду использовать продукт Avaya Aura Experience Portal 7.1. Он используется для организации IVR в экосистеме Avaya и является полностью софтовой, виртуализированной платформой интеллектуального обслуживания. Важной его чертой является возможность вставки Java кода, что и потребуется нам для интеграции с Telegram. Не буду создавать рекламы, но на мой взгляд это один из лучших продуктов Avaya и на нем можно писать реально удивительные вещи. Например Голосовой контроль чайника или посерьезнее Транскрибирование разговора на лету.
Данная система IVR конечно весьма недешева, однако есть особенности. Она лицензируется по портам. Т.к. мы планируем использовать ее крайне кратковременно, то будет достаточно одного порта. А один порт имеет достаточно низкую стоимость. И при виртуализации система требует всего 2 Core/4GB RAM/60GB HDD. В общем ее можно установить на почти любой ноутбук или десктоп. Ну и как вишенка на торте — у данного продукта есть trial режим, позволяющий бесплатно пользоваться ей 30 дней.
Для реализации задачи нам требуется по событию в телефонной станции организовать звонок на IVR и далее настроить его так, чтобы он отсылал соответствующий эвент по только что созданному API.
Если рассмотреть задачу уведомления супервизора о превышении числа звонков в очереди в Контакт-центр, то в телефонной станции надо будет видоизменить основной вектор и создать дополнительный.
CALL VECTOR
Number: 5 Name: Vector for Skill 5
01 goto step 5 if calls-queued in skill 5 pri m > 5
02 queue-to skill 5 pri m
03 wait-time 30 secs hearing silence
04 goto step 3 if unconditionally
05 route-to number 1214 with cov n if unconditionally
06 goto step 2 if unconditionally
Данный вектор непосредственно перед постановкой вызова в очередь проверяет число вызовов находящихся в данной очереди. Если оно превышает 5, то вызов уходит на шаг 5, где переводится на номер 1214. Это номер маршрутизируется на IVR.
В условии в шаге 1 можно проверять огромное число параметров, являющихся показателем нагрузки в Контакт-центре. Например EWT, число доступных операторов, число вошедших в систему операторов, число вызовов в очереди, уровень сервиса и т.д. и при превышении того или иного показателя переадресовывать вызов в IVR.
Приложении в IVR будет запускать отсылку сообщения в Telegram и тут-же переводить вызов обратно в Контакт-центр на похожий вектор, только без шага 1 и 5.
Время задержки такого вызова по обработку составит около 100 миллисекунд, что для звонящего абонента абсолютно несущественно.
Второй вектор будет выглядеть следующим образом:
CALL VECTOR
Number: 6 Name: Skill 5 Direct
01 queue-to skill 5 pri m
02 wait-time 30 secs hearing silence
03 goto step 2 if unconditionally
Итак вызов по событию перенаправлен в IVR. Перейдем к разработке приложения на нем.
Приложения для Avaya Aura Experience Portal разрабатываются в Eclipse c установленным плагином Orchestration Designer. Это позволяет перенести разработку для неквалифицированных пользователей в режим Drag&Drop перемещения квадратиков и стрелочек без погружения в Java код.
Ну и квалифицированные пользователи могут уже делать вкрапления Java кода. Далее приложение собирается в виде сервлета и разворачивается на Tomcat, куда ссылается IVR при получении вызова.
Приложение выглядит следующим образом:
Вызов попадает в нод AppRoot, далее проводится предварительная обработка переменных и вызов оправляется в Telegram Connector, который уже является чистым Java кодом. После отсылки сообщения, идет обработка перевода вызова обратно в Контакт-центр.
Для упрощения настроек используются Configurable Variables, которые позволяют вывести настройки внутренних переменных приложения на Web портал самого Experience Portal. Нужно это для того, чтобы при смене настроек не пересобирать приложение.
Блок переменных выглядит следующим образом:
Как Configurable Variables используется переменная DNIS c подпеременными. Для передачи переменных в Java код используются переменные, написанные заглавными буквами.
Блок первичной обработки выглядит следующим образом:
Да простят меня любители чистого кода. Блок сбора урла выглядит ужасно. Это особенности Orchestration Designer. Конечно правильнее его было собрать прямо в Java коде одной строкой, но мне важно было проконтролировать какой урл попадает в Java код и пришлось его собирать вот так.
Сам коннектор выглядит крайне минималистично:
String response = "";
String str = mySession.getVariable(IProjectVariables.URL).getSimpleVariable().getStringValue();
str = str.replaceAll(" ", "%20");
IVariableField variable = mySession.getVariableField(IProjectVariables.RESPONSEINFO);
variable.setValue(str);
URL url;
try {
url = new URL(str);
InputStream is = url.openConnection().getInputStream();
BufferedReader reader = new BufferedReader( new InputStreamReader( is ) );
String line = null;
response = "";
while( ( line = reader.readLine() ) != null ) {
response = response + line;
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
Функции mySession.getVariable и mySession.getVariableField нужны для передачи в Java код информации из приложения и возврата ответа обратно.
Т.е. мы сформировали URL по вышеописанному принципу и запустили его, передав то, что вернул сервер, обратно.
Вот собственно и все приложение, да в общем и все решение. Сам web портал IVR с Configurable Variables выглядит следующим образом:
Если кому-то интересно посмотреть на реальную демонстрацию прототипа, то он может ее увидеть здесь.
Ну и не обошлось без вишенки на торте. Точнее даже двух.
Про первую я уже написал. Для работы решения нужно сервер приложений подключать к Telegram через прокси, находящийся не в России. Надеюсь этот бред когда-нибудь закончится.
Ну и вторая вишенка. Конечно соединение с telegram обязано шифроваться и соединение идет через https. И используется для него конечно же не самоподписанный сертификат. И этот сертификат Telegram не отдает. А в отличии от браузера, сервер приложений не может так просто установить соединение без сертификата. Так вот вишенкой на торте является сам процесс нахождения данного сертификата и загрузку его в сервер приложений. После данной процедуры все сразу волшебно заработало.
Верю, что человек, который пройдет успешно мой путь, также успешно найдет данный сертификат. Главное что он знает, что его надо найти.
Спасибо за внимание.
Комментарии (5)
DmitrySen Автор
22.06.2018 11:55Как общий комментарий. Данное описание еще не покрывает следующую сопутствующую задачу:
Автоматизация просмотра регистрация и апдейт данной информацией некой базы.
Ну чтобы пользователь писал боту /register XXXX. Некое приложение должно извлечь данный номер и положить его в базу, связав с идентификатором пользователя. Далее основное приложение при получении вызова на DNIS XXXX должно просканить базу и всем пользователям, связанным с номером ХХХХ выслать соответствующее сообщение.
dmxrand
А что насчет рейтлимитов?
DmitrySen Автор
Внимательно изучил вот это. Противоречий не нашел. Если есть сомнения — озвучьте pls. Обсудим. Вообще данное решение является прототипом во-первых. А во-вторых данная задача не предусматривает огромной нагрузки и объема. Необходимо лишь быстро уведомить пользователя не заморачиваясь с операционкой его мобильного или десктопного клиента.
dmxrand
Я и спросил. Лично я не уверен что мой сервис не выскочит из них. Поэтому и переживаю.
dmxrand
Не там не более 30 сообщений в секунду вообще это раз. А во вторых там еще в минуту на одного юзера лимит есть. Да и сообщения слать не получается чаще 2-х раз в секунду…