Как реализовать навык Alexa с помощью Spring Boot

1656586935 kak realizovat navyk alexa s pomoshhyu spring boot

автор Рафаэль Фиол

И зачем тебе такое делать

1*agCi2IBtbBlRZsDfy6KRxA

Существует два способа реализовать свои навыки для Alexa.

Первый является самым распространенным и рекомендованным Amazon. Используйте AWS Lambda, компьютерную службу без сервера. Нет статей и учебных пособий по теме. Это не один из них.

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

1*CBS-TT_JYEOWhYsdyr0OWQ
Конфигурация конечной точки на консоли разработчика Alexa Skills

Но прежде чем прыгнуть в какдавайте поговорим о почему:

  • Почему бы вам не использовать AWS Lambda?
  • Почему игнорировать рекомендацию Amazon?

Эти вопросы важны. Вы найдете множество замечательных примеров и документации по созданию навыков с помощью Lambda, и не так много для альтернативы. Также важно, если вы соглашаетесь, что я делаю, что мир будет без серверов. Это замечательная статья по этой теме Джеймса Бесвика. Переход по маршруту HTTPS приведет вас в одиночку, но иногда это нормально.

Вот несколько причин, почему вы можете захотеть или потребовать пойти по этому одинокому пути.

  • Вы можете написать свои веб-сервисы Alexa с помощью любого языка программирования.
  • Если вы уже развернули существующие сервисы RESTful, и вы хотите использовать эту инфраструктуру/инвестиции.
  • Если ваш CISO не позволяет использовать инфраструктуру вне помещения или облака.
  • Если ты любишь одинокие тропы.

В моем случае я решил исследовать путь без лямбда прежде всего, потому что у меня уже был существующий уровень услуг, который я хотел использовать. Имеются POJO и методы, которые я хотел использовать повторно, не открывая новые конечные точки. Конечно, я мог бы создать Lambdas, которые просто предшествовали эти службы, и это действительный шаблон. Но я не хотел добавлять еще один уровень сценариев развертывания, тестирования и мониторинга.

Наверняка у вас есть свои причины. Если бы я создавал новое программное обеспечение, я, вероятно, пошел бы по пути Лямбда.

Предпосылки

Вы будете использовать консоль разработчика Alexa, чтобы зарегистрировать свои навыки, определить намерения и выражения и проверить их. Я предполагаю, что вы уже создали аккаунт разработчика, и что вы можете настроить новый специальный навык на консоли.

Навык Alexa Spring Boot

Остальная статья покажет вам, как легко добавить Alexa Skill к вашим существующим приложениям Spring Boot. Чтобы продемонстрировать это, мы создадим навык, который будет искать интересные факты об определенном году или случайном году. Вы сможете взаимодействовать с нашими навыками, произнося такие вещи, как:

Alexa, ask my demo app to tell me trivia about a random year.Alexa, ask my demo app, what happened in the year 1984? 

Ладно, да, это довольно бесполезный навык. Но он продемонстрирует все важные аспекты программы Alexa, в частности:

  • специальная обработка намерений
  • использование слотов, управление сессиями
  • встроенная обработка намерений

Чтобы достичь этого, наш пример навыков будет вызывать бесплатный посторонний API для поиска информации о мелочах, используя отличный NumbersAPI. Большое спасибо Дэвиду и Маку за создание этого веселого сервиса.

Начинаем

В первую очередь. Добавьте пакет SDK Alexa Skills Kit в файл «pom.xml». На момент написания статьи последняя версия SDK – 1.8.1.

<dependency>    <groupId>com.amazon.alexa</groupId>    <artifactId>alexa-skills-kit</artifactId>    <version>1.8.1</version></dependency>

Пакет SDK содержит специальный сервлет с ним. SpeechletServlet, который вам нужно будет скачать как часть загрузки приложения. Это действительно очень легко сделать.

Сервлет – это рабочая лошадка. Он обрабатывает все беспорядочные требования для размещения навыков, например проверку запроса Alexa, проверку подписи и проверку отметки времени. К нашему счастью, нам не приходится сталкиваться ни с одной из этих головных болей. Нам просто нужно скачать сервлет. Вот как мы это делаем:

Просто. Вы можете видеть выше, что мы создали конфигурационный класс, который загружает наш сервлет. В строке 10 это видно SpeechletServlet создается экземпляр, а затем в строке 13 он регистрируется в Spring.

Это почти все, что вам нужно сделать, чтобы скачать сервлет.

Как я отмечал, сервлет берет на себя все сложные коммуникации рукопожатия из Alexa. И после того, как это сделает, сервлет делегирует реальную бизнес-логику взаимодействия. Speechlet, который вы должны реализовать. Вы можете увидеть в строке 11 этот Speechlet, который я назвал HandlerSpeechlet, назначается сервлетом. Этот Speechlet будет вызываться при каждом взаимодействии с Alexa.

Speechlet – это просто POJO, соответствующий интерфейсу SpeechletV2, определенному в Alexa Skills SDK. Вот как смотрится интерфейс.

Ваша работа – реализовать эти четыре метода.

Все они важны, но большинство работы происходит у них OnIntent(), который вызывается, когда пользователь говорит что-нибудь значимое. Если вы новичок в словарном запасе программирования Alexa, вам следует прочесть Намерения, высказывания и слоты: новый словарь, необходимый для развития голоса.

Определение намерений

Выделите консоль разработчика Alexa. Настройте новый специальный навык в консоли – эта часть очень проста. Я назвал свой навык «MyDemoApp», а в меню «Вызов» установил «Название вызова навыка» на «моя демонстрационная программа».

Напомним, ранее в этой статье я говорил, что вы можете взаимодействовать с нашими навыками, произнося такие вещи, как:

Alexa, ask my demo app to tell me trivia about a random year.Alexa, ask my demo app, what happened in the year 1984?

Вы можете видеть, что каждое из приведенных выше предложений начинается со слова пробуждения (Alexa) и названия вызова навыков (моя демонстрационная программа).

Alexa, ask my demo app ...

Все после имени вызова навыка известно как an высказывания. Ваша работа состоит в том, чтобы перечислить высказывания на консоли разработчика и сопоставить их с намерением. Одно намерение обычно содержит множество высказываний, представляющих варианты, которые может сказать пользователь. Например, все следующие высказывания по существу одинаковы:

tell me trivia about a random year.say something about any year.pick a random year.tell me some trivia.say anything about any year.

Все эти высказывания означают одно и то же, и потому могут отражаться в одном умысле. В своей заявке я назвал это RandomYearIntent. Вот как это смотрится на консоли разработчика.

1*-jAvV7iIAAnBDazM_TGgTA

Вернуться к написанию кода

Когда наше первое намерение определено, пора вернуться в нашу программу Spring и написать некоторый код. Давайте отредактируем наш HandlerSpeechlet. На данный момент давайте пропустим onSessionStarted и onLaunch методов Speechlet, и перейти прямо в onIntent метод.

Поскольку наша программа будет обрабатывать несколько намерений, нам сначала нужно определить, какое намерение вызывается.

В строке 10 мы теперь называем название намерения. В нашем примере пока это должно быть RandomYearIntent. В этот момент у вас может возникнуть соблазн написать кучу if-else высказывания против названия умысла, но давайте попробуем что-нибудь умнее.

Убедившись, что наши намерения соблюдают определенную конвенцию по именам, мы можем использовать некоторую магию Spring для загрузки и вызова специализированных обработчиков для каждого намерения. Дальше не является чем-то специфическим для Alexa Skills SDK. Это просто мой способ обработки нескольких намерений. Есть много способов воплотить эту логику. Вот мой.

Давайте начнем с определения интерфейса, который мы будем использовать для всех наших обработчиков. Давайте творить IntentHandler как:

Далее для каждого намерения мы создадим класс, реализующий этот интерфейс. Мы также будем осторожны называть наши классы так же, как имя умысла, с добавлением слова Handler. Например, для намерения «RandomYearIntent» мы создадим класс с именем RandomYearIntentHandler.

Ладно, пока оставим это нереализованным. Мы вернемся к нашему «HandlerSpeechlet» чтобы добавить код, который передаст управление нашему новому RandomYearIntentHandler. Основная стратегия состоит в том, чтобы полагаться на наше соглашение об именовании IntentName + Handler.

Я удалил некоторые детали и обработки ошибок из кода ниже, чтобы мы могли сосредоточиться на важных частях. В конце этой статьи вы можете найти ссылку на мой репозиторий GitHub с полным кодом.

Просмотрите строки 12 и 13 ниже, формирующие имя класса, а затем попросите Spring найти зарегистрированный bean с таким названием. Затем, наконец, в строке 17 мы передаем управление этому обработчику.

RandomYearIntentHandler

Теперь у нас есть сантехника, чтобы вызвать наших специализированных менеджеров. Давайте вернемся к реализации нашего RandomYearIntentHandler. Это конкретное намерение просто. Вот полная реализация.

Просто! Вы уловили аннотацию в строке 1? Это @Component annotation – это крутой маленький трюк, который скажет Spring создать экземпляр этого класса как Bean. Вот как мы можем получить доступ к обработчику в нашем Speechlet, используя beanFactory.getBean(handlerBeanName).

В строке 11 мы создаем случайное число между 1900 и текущим годом. Затем мы вызываем Numbers API, чтобы получить информацию о том году.

В строках 14 и 15 создаем a Card и а Speech. The Card это то, что отображается в вашем мобильном приложении Alexa или на экране в Echo Show. Язык – это то, что произносится пользователю.

AlexaUtils это простой класс, который я создал. Я не буду вдаваться в детали здесь, но вы можете просмотреть это на GitHub.

Это было легко — а как насчет слотов?

Слоты в основном переменные в высказываниях. Посмотрите на два намерения в нашей программе. Второе намерение, которое я буду называть SpecificYearIntent, позволяет пользователю сказать любой год. Например:

Alexa, ask my demo app, what happened in the year 1984?

В приведенном выше высказывании год очень изменчив. Мы не хотим определить высказывания для каждого возможного года. Вместо этого мы определим это высказывание, используя слот, как:

Alexa, ask my demo app, what happened in the year {Year}?

{Year} – число. Вернувшись к нашей консоли разработчика, мы настроим новое намерение SpecificYearIntent со связанными с ним высказываниями следующим образом:

1*CDFfMDV8z_cQQeoSeMaisw
Высказывания SpecificYearIntent

Я определил слот под названием Year, который имеет тип AMAZON.NUMBER. Теперь в своем обработчике я могу легко получить значение слота под названием.

В строке 13 мы определяем год Slot. Остальное – это стандартный Java-код, который придерживается того же шаблона, что и первое намерение – позвоните в службу NumbersAPI за год и обработайте ответ.

Сессии и состояние

Я не попал в OnSessionStarted или OnLaunch методы Speechlet в этой статье, но я включил реализацию для OnLaunch в примерном проекте на GitHub.

Вы можете использовать Session объект для хранения переменных, которые сохраняются во время вызовов в режиме разговора. Режим разговора возникает, когда пользователь использует ваш навык, но не говорит распознанного высказывания. Например:

Alex, open my demo app.
>> Hello.  Here are some things you can say: Tell me something about a random year.  Or, what happened in nineteen eighty-nine?
What happened in the year 1984?
>> 1984 is the year that the European Economic Community makes £1.8 million available to help combat the Ethiopian famine on October 25th. 
>> What else can I tell you? Say "Help" for some suggestions.
Cancel.
>> OK.  Goodbye.

В моем исходном коде вы заметите, что у меня есть метод с именем setConversationMode. Он просто устанавливает переменную в сеансе, давая мне знать, что мы в режиме разговора.

Резюме

Написать навыки Alexa с помощью Spring Boot достаточно легко и может являться мощным способом повторного использования существующей инфраструктуры. Загрузите полное приложение с GitHub, чтобы узнать больше.

А если вы находитесь в районе Южной Флориды, вы можете использовать мой Cutler Stew Skill (построен с помощью Spring Boot), чтобы узнать, когда и где моя группа Cutler Stew выступит следующим образом.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *