0.3.1 • Published 4 years ago

yandex-dialoger v0.3.1

Weekly downloads
2
License
MIT
Repository
github
Last release
4 years ago

Yandex Dialoger (не окончательное название)

/npm/:interval/:scope?/:packageName

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

Плюсы:

  • Написан для запуска в функциях в Яндекс.Облаке (но можно запустить и на сервере и локально)
  • Написан на TypeScript с акцентом на нормальную типизацию
  • Поддерживает новые возможности протокола Диалогов
  • Не требует сборки, можно писать сразу в web-редакторе функций
  • Готов к покрытию навыка юнит-тестами

Чат поддержки в Телеграм https://t.me/yandex_dialoger

npm version

Содержание

Простейший пример

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 зависимость
{
    "dependencies": {
        "yandex-dialoger": "latest"
    }
}

Тестирование диалога

TestClosure будет сохранять state и заполнять поля запроса к навыку.

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('Привет.');
});

Запуск на сервере и локально

В библиотеку входит самый простой сервер – запускалка диалога. С его помошью можно потестировать навык локально, через тунелер или запустить на своём сервере.

const { createDialog, startServer } = require('yandex-dialoger');

const dialog = createDialog(...);
startServer(dialog, 3000);

Сервер можно остановить сигналом Ctrl + C, как обычно.

Change log

0.2.0

  • Для завершения сессии теперь используется переход на сцену без onInput и onTransition. Метод ReplyBuinder.withEndSession удалён.
0.3.1

4 years ago

0.3.0

4 years ago

0.2.0

4 years ago

0.1.3

4 years ago

0.1.2

4 years ago

0.1.1

4 years ago

0.1.0

4 years ago