UNPKG

yandex-dialoger

Version:

Ещё одна библиотека/фреймворк для разработки навыков Алисы.

240 lines (206 loc) 10.4 kB
# Yandex Dialoger (не окончательное название) /npm/:interval/:scope?/:packageName Ещё одна библиотека/фреймворк для разработки навыков Алисы. Плюсы: - Написан для запуска в функциях в Яндекс.Облаке (но можно запустить и на сервере и локально) - Написан на TypeScript с акцентом на нормальную типизацию - Поддерживает новые возможности протокола Диалогов - Не требует сборки, можно писать сразу в web-редакторе функций - Готов к покрытию навыка юнит-тестами Чат поддержки в Телеграм https://t.me/yandex_dialoger [![npm version](https://img.shields.io/npm/v/yandex-dialoger)](https://www.npmjs.com/package/yandex-dialoger) ## Содержание - [Простейший пример](#простейший-пример) - [Запуск в Яндекс.Облаке](#запуск-в-яндексоблаке) - [Тестирование диалога](#тестирование-диалога) - [Запуск на сервере и локально](#запуск-на-сервере-и-локально) - [Change log](#change-log) ## Простейший пример ```javascript const { createDialog } = require('yandex-dialoger'); exports.handler = createDialog({ /** * Функция state вызывается для каждой новой сессии * и создаёт объект-состояние для неё. * Не забудьте включить состояния в настройках навыка. * * Можно не передавать. Тогда состояние будет пустым объектом. */ state() { return { count: 0, }; }, /** * Диалог состоит из сцен и переходов. Каждая сцена определяет, * что будет выведено пользователю и как будет обработан ввод. * - Сцена всегда ожидает ответа от пользователя. * - Переход не ожидает ответа, но перемещает диалог к следующему переходу, * пока не будет достигнута сцена. Когда диалог достигнет сцены, * пользователю будет выведет ответ всех пройденных переходов * и текущей сцены. * * Сцены и переходы отличаются наличием обработчиков: * - onInput у сцены * - onTransition у перехода */ scenes: { /** * Диалог всегда начинается со сцены (или перехода) Start. Это соглашение. */ Start: { /** * Ответ пользователю описывается в функции reply, * которая первым параметром принимает ReplyBuilder. */ reply(reply) { reply.withText('Начнём считать.'); }, /** * Сцены и переходы возвращают название следующей сцены или перехода. */ onTransition() { return 'ChangeCount'; }, }, ChangeCount: { reply(reply) { /** * В ReplyBuilder есть ещё несколько методов. */ reply.withText('Скажите «Плюс» или «Минус».'); reply.withButton('Плюс'); reply.withButton('Минус'); }, /** * onInput первым параметром принимает объект Input, * который содержит данные ввода пользователя в удобной форме * (также есть request в неизменном виде). * * Вторым и третьим параметрами onInput принимает состояние * и метод для его изменения. */ onInput({ command }, state, setState) { if (command === 'плюс') { setState({ count: state.count + 1 }); return 'SayCount'; } if (command === 'минус') { setState({ count: state.count - 1 }); return 'SayCount'; } }, /** * В сцене можно указать обработчик unrecognized. * Он отработает, если onInput вернёт undefined. * При этом диалог останется на той же сцене. * * Если обработчик unrecognized не указан, будет выполнен * обработчик help текущей сцены или reply последней сцены. */ unrecognized(reply) { reply.withText('Повторите, пожалуйста. Вы сказали «Плюс» или «Минус»?'); }, /** * В сцене можно указать обработчик help. * Он отработает, если будет получен интент YANDEX.HELP или команда «Помощь». * При этом диалог останется на той же сцене. * * Если обработчик help не указан, будет выполнен * обработчик unrecognized текущей сцены или reply последней сцены. * * Каждая сцена содержит свой собственный обработчик help, * т.к. подсказки в диалоге должны быть привязаны к контексту. * Для рассказа о навыке вцелом служит обработчик whatCanYouDo (см. ниже). */ help(reply) { reply.withText( 'Сейчас вы можете изменить счётчик.', 'Для этого скажите «Плюс» или «Минус».' ); }, }, SayCount: { /** * Вторым параметром reply принимает состояние. * Изменение состояния в reply не предусмотрено. */ reply(reply, state) { reply.withText(`Теперь у вас ${state.count}.`); }, /** * onTransition, как и onInput, принимает состояние * и метод для его изменения. Менять состояние можно * только в onInput и onTransition. */ onTransition(state) { if (state.count < 3 && state.count > -3) { return 'ChangeCount'; } return 'Quit'; }, }, /** * Сцена без onInput или onTransition завершит сессию. */ Quit: { reply(reply) { reply.withText('Этого достаточно. Пока!'); }, }, }, /** * Отрабатывает на интент YANDEX.WHAT_CAN_YOU_DO или комаду * «Что ты умеешь». К этому ответу добавляется help текущей * сцены чтобы пользователь не потерял контекст. */ whatCanYouDo(reply) { reply.withText(`Этот навык помогает считать.`); }, }); ``` ## Запуск в Яндекс.Облаке 1. Нужно выбрать Среду выполнения функции nodejs12-preview. В ней поддерживается установка зависимостей из package.json. 2. Добавить в package.json зависимость ```json { "dependencies": { "yandex-dialoger": "latest" } } ``` ## Тестирование диалога TestClosure будет сохранять state и заполнять поля запроса к навыку. ```javascript const { createDialog, createTestClosure } = require('yandex-dialoger'); /** * Наш навык */ const dialog = createDialog({ scenes: { Start: { reply: (reply) => reply.withText('Привет.'), onInput: () => 'Start', }, }, }); /** * Тесты */ test('Hello world', async () => { const closure = createTestClosure(dialog); const { text } = await closure.handleCommand(''); expect(text).toBe('Привет.'); }); ``` ## Запуск на сервере и локально В библиотеку входит самый простой сервер – запускалка диалога. С его помошью можно потестировать навык локально, через тунелер или запустить на своём сервере. ```js const { createDialog, startServer } = require('yandex-dialoger'); const dialog = createDialog(...); startServer(dialog, 3000); ``` Сервер можно остановить сигналом `Ctrl + C`, как обычно. ## Change log 0.2.0 - Для завершения сессии теперь используется переход на сцену без `onInput` и `onTransition`. Метод `ReplyBuinder.withEndSession` удалён.