![](https://habrastorage.org/webt/j3/wn/6n/j3wn6nuiz_dkqh3tibf-sr4aote.jpeg)
Сегодня мы будем делать навык (приложение) для Алисы — своеобразную записную книжку (или стикер на холодильник): если во фразе пользователя (он же на профессиональном сленге юзер) есть слово "Запомни" — вся фраза сохраняется, и при следующем запуске навыка — будет любезно зачитана пользователю. Код приложения мы пишем на Node.js, для выполнения кода будем использовать Yandex Cloud Functions, а хранить данные — в Firebase Cloud Firestore. В результате у нас должен получиться точно такой же навык как "Запомни и Забудь", опубликованный в каталоге навыков Алисы.
![Навык Запомни и Забудь](https://habrastorage.org/webt/em/r-/-a/emr--axvzbdgxv06ahmacdnziow.png)
Код навыка выложен на GitHub. Он испещрён комментариями, словно египетские пирамиды иероглифами, и является неотъемлемой частью данной статьи.
![Проект на GitHub](https://habrastorage.org/webt/if/y2/k1/ify2k1_cvzde4cr72bifojqazr8.png)
Итак, клонируем этот код в выбранный каталог, переходим в каталог проекта, и устанавливаем необходимые зависимости:
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:
![Консоль Firebase](https://habrastorage.org/webt/yx/cb/0t/yxcb0tsahvt_g8tu7vwmomis3aw.png)
b) Присваиваем проекту любое разумное имя:
![Название проекта](https://habrastorage.org/webt/m_/dw/fz/m_dwfzzi23en-embhjda0ugixhi.png)
c) Отключаем для проекта Google Analytics (здесь он нам не поможет):
![Отключение Google Analytics](https://habrastorage.org/webt/ru/3i/mr/ru3imrah4akn5rvbwgbumzpalui.png)
d) Ждём несколько секунд… готово:
![Firebase проект создан](https://habrastorage.org/webt/qu/vo/ey/quvoeyb3x_ednmwm6ug51ssffr4.png)
2. Использование сервисного аккаунта
Сервисный аккаунт позволяет связать Firebase-проект с другим веб-сервисом (в нашем случае это будет Yandex Cloud Functions) с помощью Firebase Admin SDK. Эта информация для общего понимания того что мы делаем.
a) Сейчас в левом меню нажимаем значок шестерни, и выбираем Project settings:
![Настройки проекта](https://habrastorage.org/webt/1z/9e/m7/1z9em75bpe4-ekxeatx9wqdl7l0.png)
b) Затем в верхнем меню выбираем пункт Service accounts:
![Сервисные аккаунты](https://habrastorage.org/webt/5n/wl/ad/5nwladk01p096hn5n7udh7c8xcy.png)
c) Здесь нам нужно скопировать и сохранить значение свойства databaseURL для последующей вставки в код (впрочем, это можно будет сделать в любой момент позже). Теперь нажимаем кнопку Generate new private key:
![Создание приватного ключа](https://habrastorage.org/webt/5k/rh/pz/5krhpz2nogf3jjoliwb0ch6pyxw.png)
d) В результате всплывёт модальное окно с предупреждением хранить этот файл в надёжном месте и нигде не публиковать (поэтому в моём проекте на GitHab вы его не найдёте), нажимаем кнопку Generate key, и на ваш компьютер загрузится json-файл с длинным названием.
![Скачивание ключа сервисного аккаунта](https://habrastorage.org/webt/d3/cw/wr/d3cwwrwb0-lx7rqa3srjuakrgdg.png)
e) Давайте сразу его переименуем (это не обязательно, но лучше сделать, чтобы в проекте не менять на него ссылку) в serviceAccountKey.json. С Firebase почти всё, осталось только активировать базу данный Cloud Firestore.
3. Активация базы данных
a) В левом меню выбираем пункт Database и нажимаем кнопку Create database:
![Создание базы данных](https://habrastorage.org/webt/td/id/qp/tdidqps-m2dobnz6hzlssiv5m_c.png)
b) На следующем шаге конфигурируем правила безопасности. Оставляем Start in production mode, и жмём кнопку Next:
![Правила безопасности](https://habrastorage.org/webt/ck/tx/q-/cktxq-hlgbkjvsykn3hby3wcjgq.png)
c) И наконец, выбираем регион физического расположения базы данных. Здесь небольшой ахтунг: однажды выбрав — это изменить будет невозможно! Поэтому, сразу выбираем eur3 (europe-west) — чем ближе база данных к потребителям, тем лучше. В конце нажимаем кнопку Done:
![Регион базы данных](https://habrastorage.org/webt/x9/m2/gc/x9m2gcedwdcmfdszrz5x5cpffce.png)
4. Конфигурация навыка
a) В файле index.js поменять на актуальный (как это описано выше) URL базы данных:
![URL адрес базы данных](https://habrastorage.org/webt/tq/jo/df/tqjodfh2jgmnxk8bl5_hsz6o2n0.png)
b) В каталог secret загрузить актуальный файл ключа serviceAccountKey.js (полученный и переименованный как описано выше):
![Загрузка файла-ключа](https://habrastorage.org/webt/nu/-z/t_/nu-zt_q8norj6whmckf4bf_eley.png)
c) В файле src/settings.js поменять название навыка и опционально — значения других полей:
![Настройки навыка](https://habrastorage.org/webt/mg/k1/pt/mgk1ptezw_x6eloiw1oiqq1cqxu.png)
d) Из каталога images загрузить три изображения (конечно, для уникальности лучше сделать свои картинки, но с сохранением названий, чтобы не менять свойства в коде; формат JPEG или PNG, размер рекомендую 512x230 px) в консоль для разработчиков Яндекс.Диалоги, как показано на двух последующих скриншотах:
![Картинки в каталоге проекта](https://habrastorage.org/webt/bu/lm/5t/bulm5tmi-oxlij3og8fm_9-ityq.png)
![Картинки в консоли разработчика](https://habrastorage.org/webt/ib/fq/2b/ibfq2bm72cnjxq_4sscqyehrrz8.png)
e) В файл src/images.js вставить идентификаторы изображений, полученные после их загрузки в консоль:
![Идентификаторы изображений](https://habrastorage.org/webt/p5/bw/ff/p5bwffdhowvzym8kgyxqa4m2__q.png)
Это всё! Осталось создать zip-архив проекта (все файлы и каталоги проекта в него включать не надо, а только корневой файл index.js и каталоги с файлами src, secret, node_modules), как изображено на скриншоте:
![zip-архив проекта](https://habrastorage.org/webt/jt/ut/ru/jtutrukgqc08xknympxwbmva3ug.png)
Теперь публикуем наш код в Яндекс.Облаке, как это подробно описано в статье "Алиса в стране Битрикс".
5. Интенты и контекст
a) Если открыть файл src/nlu.js (кстати, NLU — аббревиатура от Natural Language Understanding) мы увидим определения констант CONTEXT, INTENT и функции getIntent:
![NLU](https://habrastorage.org/webt/wu/ug/g0/wuugg0mbds7a03ll-lmnfde_yyq.png)
b) Функция getIntent в качестве параметров принимает фразу юзера и контекст диалога. Если с фразой юзера всё понятно, то вот пара слов о контексте. Контекст — это о чём мы говорим. Если навык только-что сообщил справку о том как этим навыком пользоваться, контекст будет help (название мы придумываем сами), и в этом случае если юзер скажет "Повтори" — навык будет знать что именно повторять (т.е. в данном случае справку, а не что-то другое). Поэтому каждый раз обновлённый контекст мы сохраняем в базе данных. Далее функция с учётом фразы и контекста определяет намерения пользователя — т.н. интент, методом поиска ключевых слов, соответствующих тому или иному намерению. Для этого в данном навыке используется функция includes из библиотеки Lodash. Вот фрагмент кода из функции getIntent, определяющий намерение юзера выйти из навыка (закрыть навык):
![Интенты](https://habrastorage.org/webt/vs/km/nv/vskmnv7xnlhniwf1k5xp1lykgmg.png)
с) В файле index.js мы вызываем функцию getIntent и реагируем, в зависимости от того, какой интент (намерение юзера) функция нам вернула:
![Вызов функции](https://habrastorage.org/webt/z7/49/8s/z7498svlvwmtzfgfd3mvsdvqspi.png)
Это была лишь зацепка для ума — самостоятельно сделайте навык, отследите все взаимосвязи в коде — тогда всё поймёте!
6. Планы будущих статей
Моей целью в этом году было написать небольшую серию статей, позволяющую научить создавать навыки Алисы на Node.js. И я считаю что эта задача выполнена, поскольку в трёх статьях (включая эту) были рассмотрены все основные вопросы: получение данных от сторонних сервисов — "Алиса приобретает навык"; отправка данных сторонним сервисам — "Алиса в стране Битрикс, и наконец, в этой статье — сохранение состояний приложения, интенты пользователей, и контекст беседы.
Но, естественно, рассказать по-прежнему всё ещё есть о чём. Итак, вот примерный план тем статей на 2020 год (не окончательный и не в хронологическом порядке):
a) Создание простого квиза (викторины) с использованием Firebase Functions и Cloud Firestore.
b) Связка аккаунтов: например начав квиз на смартфоне, пользователь должен иметь возможность продолжить его на Яндекс.Станции с того же самого места, где остановился на смартфоне.
c) Если в Яндекс.Облаке будет сделана внутренняя интеграция баз данных с Cloud Functions, а также для навыков Алисы будет предложен льготный или бесплатный тарифный план на использование баз данных — тогда будет статья и об этом. Кстати, на эту тему я открыл в Яндекс.Облаке специальный топик — приглашаю проголосовать "ЗА" — сначала кликните на скриншот внизу, а затем на кнопку «Голосовать» (я уже проголосовал, поэтому на скриншоте другая надпись):
![Голосование](https://habrastorage.org/webt/go/iy/d-/goiyd-aggqnzyqcl2hfjjpwlbwq.png)
d) Сейчас в закрытом тестировании находится сервис приёма платежей через Алису Яндекс.Оплата. Если этот сервис будет жить, и станет публичным — будет статья и о нём.
Ну и конечно, жизнь внесёт свои коррективы, и добавит новые темы. В общем, кому интересно — подписывайтесь, чтобы не пропустить.
7. Донаты
![Донаты](https://habrastorage.org/webt/ql/pf/qk/qlpfqkqkbo3d-ype6hpdtsoih5s.jpeg)
nckma
Что будет если по телевизору покажут клип с песней Ротару?:
mzaharov Автор
А потестируйте сами… Я не знаю. :-)