Интегрируем Яндекс.Алису и интим магазины через Spring boot.
Тема голосовых ассистентов набирает обороты, и я решили присоединиться к этому тренду, интегрировав самого крупного оптового поставщика интим-товаров и Яндекс.Алису.
Идея: у поставщика заведены личные кабинеты владельцев интернет-магазинов, и необходимо отдавать аналитические данные от поставщика через голосовой канал Алисы.
Интеграция состояла из двух частей:
Сервис должен понять, что именно попросил пользователь, и запросить эти данные с сервера поставщика. Решили писать сервис на Spring Boot.
Создаем репозиторий в Git и с помощью spring initializr развёртываем проект на spring boot(в dependencies указываем web).
Запрос в сервис приходит в формате JSON. У него хорошо задокументированная структура, поэтому генерировать классы достаточно просто:
![image](https://habr.com/images/px.gif#%3D%22https%3A%2F%2Fimageshack.com%2Fi%2Fplcr0ysAp%22)
Удобно, что в запросе выделяются ключевые слова вроде распознанного адреса. Они расположены в блоке
![image](https://habr.com/images/px.gif#%3D%22https%3A%2F%2Fimageshack.com%2Fi%2Fpm0Cso3Sp%22)
Но в нашем случае было удобнее использовать поле
Интеграцию с поставщиком реализовали через библиотеку Apache httpclients, а десериализацию XML-ответа — через jaxb.
Итак, мы разобрали запрос и запросили у поставщика данные. Но Алиса девушка строгая, и поэтому не примет наш ответ позже, чем через три секунды. А пользователь может захотеть получить сравнительную характеристику по своему магазину за последние два года, что займет больше времени. Для решения этой проблемы мы подключили кэширование через библиотеку ehCache и настроили загрузку данных пользователя. Столкнулись с новым нюансом: Алиса не отдает практически никаких персонифицированных данных пользователя. То есть вы не видите даже email во входящем запросе. Есть лишь userId, который отображает уникальный идентификатор устройства. Его и сделали ключом для идентификации пользователей.
Ключ есть, кэш есть, осталось понять когда в него загружать информацию. Пользователь не запрашивает сразу данные, а сначала запускает навык (это термин, используемый в Алисе, подробнее о нём я расскажу ниже). Для сервера это выглядит как запрос с пустым тегом
Для полноценного тестирования и дальнейшей работы в проде мы решили развернуть приложение в облаке на Heroku. Для этого идем на сайт Heroku, регистрируемся, скачиваем heroku cli и устанавливаем его. Затем открываем консоль и вводим
Когда вы создаете приложение, Git создаёт удаленный репозиторий с именем heroku, который ассоциируется с вашим локальным Git-репозиторием. По умолчанию, Heroku генерирует на сервере случайное имя для вашего проекта. Вы можете заменить его, передав имя приложения с помощью
Для проверки запуска приложения выполняем команду.
И если нужно обратиться по пути “/“, то выполняем
Первая точка интеграции готова.
Мы реализуем интеграцию через создание так называемого навыка на платформе Яндекса. Сначала регистрируемся в Яндексе, а затем переходим на страницу разработчика. Нажимаем «создать диалог» и выбираем тип диалога:
![image](https://habr.com/images/px.gif#%3D%22https%3A%2F%2Fimageshack.com%2Fi%2FpldC2gG5p%22)
На вкладке «Настройки» и нужно заполнить поля:
![image](https://habr.com/images/px.gif#%3D%22https%3A%2F%2Fimageshack.com%2Fi%2FpoWuOxHUp%22)
Сохраняем диалог. Все изменения в настройке навыка вступают в силу только после нажатия кнопки «сохранить».
Интеграцию настроили, сервис написали, теперь можно тестировать.
Переходим на вкладку «Тестирование».
![image](https://habr.com/images/px.gif#%3D%22https%3A%2F%2Fimageshack.com%2Fi%2FplnhhATFp%22)
Здесь можно проверить работоспособность навыка. Ради удобства мы добавили в навык кнопки быстрого доступа к функциям.
Есть ограничения: нельзя проверять навык на корректность запускающей фразы и нельзя проверять голосовой ввод/вывод. И если с фразой никаких проблем возникнуть не должно, то правильность произношения ответов получится проверить только после публикации навыка.
После всех тестов навык можно отправить на модерацию. Для этого переходим на вкладку «Общие сведения» и нажимаем «На модерацию».
![image](https://habr.com/images/px.gif#%3D%22https%3A%2F%2Fimageshack.com%2Fi%2FpmBBZRvtp%22)
После прохождения модерации вместо этой кнопки появится кнопка «Опубликовать». После публикации навык появится в официальном каталоге Яндекса.
На текущий момент навыки несколько отделены от самой Алисы (приходится говорить «запусти навык»), что мешает воспринимать Алису как полноценный голосовой ассистент. Было бы здорово формировать свой контекст навыков и задавать вопросы напрямую Алисе. Нет возможности получать какую-нибудь информацию о пользователе кроме userId, который является идентификатором устройства. Поэтому на каждом устройстве нужно заново проходить авторизацию, что затрудняет хранение единой сессии пользователя. Также навык не может отправлять push-сообщения, поэтому сделать навык-напоминалку не получится.
С другой стороны, навыки могут стать хорошей площадкой для реализации голосового управления, например, домашней техникой. Также навык может быть полезен в обучении или проведении опытов, в уточнении информации по заказам, ценам и т.д. В общем, там, где пользователи могут задать короткий точный вопрос или отдать короткую команду.
Тема голосовых ассистентов набирает обороты, и я решили присоединиться к этому тренду, интегрировав самого крупного оптового поставщика интим-товаров и Яндекс.Алису.
Идея: у поставщика заведены личные кабинеты владельцев интернет-магазинов, и необходимо отдавать аналитические данные от поставщика через голосовой канал Алисы.
Интеграция состояла из двух частей:
- Интеграция веб-сервиса и REST API поставщика товаров.
- Интеграция Яндекс.Алисы и веб-сервиса обработки пользовательских запросов.
Интеграция веб-сервиса и REST API поставщика товаров
Сервис должен понять, что именно попросил пользователь, и запросить эти данные с сервера поставщика. Решили писать сервис на Spring Boot.
Настройка проекта
Создаем репозиторий в Git и с помощью spring initializr развёртываем проект на spring boot(в dependencies указываем web).
Запрос в сервис приходит в формате JSON. У него хорошо задокументированная структура, поэтому генерировать классы достаточно просто:
![image](https://habr.com/images/px.gif#%3D%22https%3A%2F%2Fimageshack.com%2Fi%2Fplcr0ysAp%22)
Удобно, что в запросе выделяются ключевые слова вроде распознанного адреса. Они расположены в блоке
“entities”
:![image](https://habr.com/images/px.gif#%3D%22https%3A%2F%2Fimageshack.com%2Fi%2Fpm0Cso3Sp%22)
Но в нашем случае было удобнее использовать поле
Command
. В нем содержится текст, который продиктовал пользователь. Поскольку распознаванием смысла занимается интеграционный сервис, нам необходимо парсить запросы. Они хорошо отделимы друг от друга (запросы на размещенные заказы, запросы на заказы в обработке), поэтому для их разбора мы решили использовать регулярные выражения. Интеграцию с поставщиком реализовали через библиотеку Apache httpclients, а десериализацию XML-ответа — через jaxb.
Итак, мы разобрали запрос и запросили у поставщика данные. Но Алиса девушка строгая, и поэтому не примет наш ответ позже, чем через три секунды. А пользователь может захотеть получить сравнительную характеристику по своему магазину за последние два года, что займет больше времени. Для решения этой проблемы мы подключили кэширование через библиотеку ehCache и настроили загрузку данных пользователя. Столкнулись с новым нюансом: Алиса не отдает практически никаких персонифицированных данных пользователя. То есть вы не видите даже email во входящем запросе. Есть лишь userId, который отображает уникальный идентификатор устройства. Его и сделали ключом для идентификации пользователей.
Ключ есть, кэш есть, осталось понять когда в него загружать информацию. Пользователь не запрашивает сразу данные, а сначала запускает навык (это термин, используемый в Алисе, подробнее о нём я расскажу ниже). Для сервера это выглядит как запрос с пустым тегом
Command
. В этот момент можно начать загрузку клиентских данных, и тогда к моменту отправки первого пользовательского запроса все данные уже загружены в наш сервис. Для полноценного тестирования и дальнейшей работы в проде мы решили развернуть приложение в облаке на Heroku. Для этого идем на сайт Heroku, регистрируемся, скачиваем heroku cli и устанавливаем его. Затем открываем консоль и вводим
heroku login
. Переходим в директорию с проектом cd ~/myapp и выполняем heroku create
.Когда вы создаете приложение, Git создаёт удаленный репозиторий с именем heroku, который ассоциируется с вашим локальным Git-репозиторием. По умолчанию, Heroku генерирует на сервере случайное имя для вашего проекта. Вы можете заменить его, передав имя приложения с помощью
heroku create myapp
.Для проверки запуска приложения выполняем команду.
heroku ps:scale web=1
И если нужно обратиться по пути “/“, то выполняем
heroku open
.Первая точка интеграции готова.
Интеграция Яндекс.Алисы и сервиса обработки запросов
Мы реализуем интеграцию через создание так называемого навыка на платформе Яндекса. Сначала регистрируемся в Яндексе, а затем переходим на страницу разработчика. Нажимаем «создать диалог» и выбираем тип диалога:
![image](https://habr.com/images/px.gif#%3D%22https%3A%2F%2Fimageshack.com%2Fi%2FpldC2gG5p%22)
На вкладке «Настройки» и нужно заполнить поля:
![image](https://habr.com/images/px.gif#%3D%22https%3A%2F%2Fimageshack.com%2Fi%2FpoWuOxHUp%22)
- Имя навыка — название, которое будет отображаться в каталоге Алисы. С его помощью пользователь сможет активировать навык, например, «Запусти навык [Имя навыка]».
- Активационное имя — здесь можно указать различные варианты обращения к навыку. По умолчанию одним из вариантов активационного имени является имя навыка.
- Пример запроса — фраза, по которой Алиса активирует этот навык. Запросы будут представлены в виде кнопок в каталоге после публикации.
- Webhook URL — необходимо указать URL нашего веб-сервиса, который будет обрабатывать запросы пользователей.
- Яндекс.Облако — Яндекс может дать грант на свое облако, но мы развернем сервис на heroku, поэтому галочку не ставим.
- Голос — здесь можно выбрать голос, которым будет говорить ваш навык. Есть разные вариации мужского и женского. Но стоит учитывать, что пользователь, скорее всего, скажет: «Алиса, запусти навык», и если Алиса ответит мужским баритоном, то это может несколько смутить.
- Ограничения на используемые платформы — обязателен ли экран при работе с навыком. В нашем случае нет, поэтому галочку не ставим.
- Приватность — поставьте галочку, если не хотите, чтобы навык отражался в каталоге.
- Сайт для верификации прав использования бренда — адрес сайта для навыка. Навык, для которого вы заполнили это поле, пройдет модерацию только в том случае, если вы подтвердили права на указанный сайт в Яндекс.Вебмастере.
- Категория — в нашем случае это «бизнес и финансы».
- Описание — зачем нужен ваш навык. Описание навыка будет отображаться в каталоге навыков и будет доступно пользователям.
- Заметки для модератора — пожалуй самое интересное поле. Чтобы попасть в каталог, навык должен пройти модерацию, а значит, должен соответствовать определенным правилам, которые описаны тут. В этом поле можно описать процесс тестирования. Например, как пройти авторизацию и один типовой пользовательский сценарий.
- Возрастные ограничения — несмотря на тематику навыка, передавать мы будем данные, подходящие для любой возрастной группы. Поэтому галочку не ставим.
- Иконка — это обязательно :)
Сохраняем диалог. Все изменения в настройке навыка вступают в силу только после нажатия кнопки «сохранить».
Интеграцию настроили, сервис написали, теперь можно тестировать.
Переходим на вкладку «Тестирование».
![image](https://habr.com/images/px.gif#%3D%22https%3A%2F%2Fimageshack.com%2Fi%2FplnhhATFp%22)
Здесь можно проверить работоспособность навыка. Ради удобства мы добавили в навык кнопки быстрого доступа к функциям.
Есть ограничения: нельзя проверять навык на корректность запускающей фразы и нельзя проверять голосовой ввод/вывод. И если с фразой никаких проблем возникнуть не должно, то правильность произношения ответов получится проверить только после публикации навыка.
После всех тестов навык можно отправить на модерацию. Для этого переходим на вкладку «Общие сведения» и нажимаем «На модерацию».
![image](https://habr.com/images/px.gif#%3D%22https%3A%2F%2Fimageshack.com%2Fi%2FpmBBZRvtp%22)
После прохождения модерации вместо этой кнопки появится кнопка «Опубликовать». После публикации навык появится в официальном каталоге Яндекса.
Возможности и ограничения
На текущий момент навыки несколько отделены от самой Алисы (приходится говорить «запусти навык»), что мешает воспринимать Алису как полноценный голосовой ассистент. Было бы здорово формировать свой контекст навыков и задавать вопросы напрямую Алисе. Нет возможности получать какую-нибудь информацию о пользователе кроме userId, который является идентификатором устройства. Поэтому на каждом устройстве нужно заново проходить авторизацию, что затрудняет хранение единой сессии пользователя. Также навык не может отправлять push-сообщения, поэтому сделать навык-напоминалку не получится.
С другой стороны, навыки могут стать хорошей площадкой для реализации голосового управления, например, домашней техникой. Также навык может быть полезен в обучении или проведении опытов, в уточнении информации по заказам, ценам и т.д. В общем, там, где пользователи могут задать короткий точный вопрос или отдать короткую команду.