Сегодня мы будем делать навык (приложение) для Алисы — своеобразную записную книжку (или стикер на холодильник): если во фразе пользователя (он же на профессиональном сленге юзер) есть слово "Запомни" — вся фраза сохраняется, и при следующем запуске навыка — будет любезно зачитана пользователю. Код приложения мы пишем на Node.js, для выполнения кода будем использовать Yandex Cloud Functions, а хранить данные — в Firebase Cloud Firestore. В результате у нас должен получиться точно такой же навык как "Запомни и Забудь", опубликованный в каталоге навыков Алисы.
Код навыка выложен на GitHub. Он испещрён комментариями, словно египетские пирамиды иероглифами, и является неотъемлемой частью данной статьи.
Итак, клонируем этот код в выбранный каталог, переходим в каталог проекта, и устанавливаем необходимые зависимости:
git clone https://github.com/stmike/alice-tutorial-remember.git
cd alice-tutorial-remember
npm install
О том как загрузить (deploy) код в Yandex Cloud Functions, подробно описано в предыдущей моей статье: "Алиса в стране Битрикс", и здесь всё это повторяться не будет. Это же касается и создания и публикации навыков Алисы в консоли для разработчиков Яндекс.Диалогов: кто не знает и этого — отсылаю к статье: "Алиса приобретает навык".
Сегодня же у нас следующая повестка дня:
- Создание проекта в Firebase.
- Использование сервисного аккаунта Firebase для интеграции с навыком.
- Активация базы данных Cloud Firestore.
- Конфигурация навыка.
- Рассуждения об интентах, и контексте.
- Планы будущих статей.
- Донаты (лучший раздел).
1. Создание проекта в Firebase
a) Переходим в консоль Firebase и нажимаем плитку Add project:
b) Присваиваем проекту любое разумное имя:
c) Отключаем для проекта Google Analytics (здесь он нам не поможет):
d) Ждём несколько секунд… готово:
2. Использование сервисного аккаунта
Сервисный аккаунт позволяет связать Firebase-проект с другим веб-сервисом (в нашем случае это будет Yandex Cloud Functions) с помощью Firebase Admin SDK. Эта информация для общего понимания того что мы делаем.
a) Сейчас в левом меню нажимаем значок шестерни, и выбираем Project settings:
b) Затем в верхнем меню выбираем пункт Service accounts:
c) Здесь нам нужно скопировать и сохранить значение свойства databaseURL для последующей вставки в код (впрочем, это можно будет сделать в любой момент позже). Теперь нажимаем кнопку Generate new private key:
d) В результате всплывёт модальное окно с предупреждением хранить этот файл в надёжном месте и нигде не публиковать (поэтому в моём проекте на GitHab вы его не найдёте), нажимаем кнопку Generate key, и на ваш компьютер загрузится json-файл с длинным названием.
e) Давайте сразу его переименуем (это не обязательно, но лучше сделать, чтобы в проекте не менять на него ссылку) в serviceAccountKey.json. С Firebase почти всё, осталось только активировать базу данный Cloud Firestore.
3. Активация базы данных
a) В левом меню выбираем пункт Database и нажимаем кнопку Create database:
b) На следующем шаге конфигурируем правила безопасности. Оставляем Start in production mode, и жмём кнопку Next:
c) И наконец, выбираем регион физического расположения базы данных. Здесь небольшой ахтунг: однажды выбрав — это изменить будет невозможно! Поэтому, сразу выбираем eur3 (europe-west) — чем ближе база данных к потребителям, тем лучше. В конце нажимаем кнопку Done:
4. Конфигурация навыка
a) В файле index.js поменять на актуальный (как это описано выше) URL базы данных:
b) В каталог secret загрузить актуальный файл ключа serviceAccountKey.js (полученный и переименованный как описано выше):
c) В файле src/settings.js поменять название навыка и опционально — значения других полей:
d) Из каталога images загрузить три изображения (конечно, для уникальности лучше сделать свои картинки, но с сохранением названий, чтобы не менять свойства в коде; формат JPEG или PNG, размер рекомендую 512x230 px) в консоль для разработчиков Яндекс.Диалоги, как показано на двух последующих скриншотах:
e) В файл src/images.js вставить идентификаторы изображений, полученные после их загрузки в консоль:
Это всё! Осталось создать zip-архив проекта (все файлы и каталоги проекта в него включать не надо, а только корневой файл index.js и каталоги с файлами src, secret, node_modules), как изображено на скриншоте:
Теперь публикуем наш код в Яндекс.Облаке, как это подробно описано в статье "Алиса в стране Битрикс".
5. Интенты и контекст
a) Если открыть файл src/nlu.js (кстати, NLU — аббревиатура от Natural Language Understanding) мы увидим определения констант CONTEXT, INTENT и функции getIntent:
b) Функция getIntent в качестве параметров принимает фразу юзера и контекст диалога. Если с фразой юзера всё понятно, то вот пара слов о контексте. Контекст — это о чём мы говорим. Если навык только-что сообщил справку о том как этим навыком пользоваться, контекст будет help (название мы придумываем сами), и в этом случае если юзер скажет "Повтори" — навык будет знать что именно повторять (т.е. в данном случае справку, а не что-то другое). Поэтому каждый раз обновлённый контекст мы сохраняем в базе данных. Далее функция с учётом фразы и контекста определяет намерения пользователя — т.н. интент, методом поиска ключевых слов, соответствующих тому или иному намерению. Для этого в данном навыке используется функция includes из библиотеки Lodash. Вот фрагмент кода из функции getIntent, определяющий намерение юзера выйти из навыка (закрыть навык):
с) В файле index.js мы вызываем функцию getIntent и реагируем, в зависимости от того, какой интент (намерение юзера) функция нам вернула:
Это была лишь зацепка для ума — самостоятельно сделайте навык, отследите все взаимосвязи в коде — тогда всё поймёте!
6. Планы будущих статей
Моей целью в этом году было написать небольшую серию статей, позволяющую научить создавать навыки Алисы на Node.js. И я считаю что эта задача выполнена, поскольку в трёх статьях (включая эту) были рассмотрены все основные вопросы: получение данных от сторонних сервисов — "Алиса приобретает навык"; отправка данных сторонним сервисам — "Алиса в стране Битрикс, и наконец, в этой статье — сохранение состояний приложения, интенты пользователей, и контекст беседы.
Но, естественно, рассказать по-прежнему всё ещё есть о чём. Итак, вот примерный план тем статей на 2020 год (не окончательный и не в хронологическом порядке):
a) Создание простого квиза (викторины) с использованием Firebase Functions и Cloud Firestore.
b) Связка аккаунтов: например начав квиз на смартфоне, пользователь должен иметь возможность продолжить его на Яндекс.Станции с того же самого места, где остановился на смартфоне.
c) Если в Яндекс.Облаке будет сделана внутренняя интеграция баз данных с Cloud Functions, а также для навыков Алисы будет предложен льготный или бесплатный тарифный план на использование баз данных — тогда будет статья и об этом. Кстати, на эту тему я открыл в Яндекс.Облаке специальный топик — приглашаю проголосовать "ЗА" — сначала кликните на скриншот внизу, а затем на кнопку «Голосовать» (я уже проголосовал, поэтому на скриншоте другая надпись):
d) Сейчас в закрытом тестировании находится сервис приёма платежей через Алису Яндекс.Оплата. Если этот сервис будет жить, и станет публичным — будет статья и о нём.
Ну и конечно, жизнь внесёт свои коррективы, и добавит новые темы. В общем, кому интересно — подписывайтесь, чтобы не пропустить.
7. Донаты
Автор: Михаил Захаров