Интегрируйте Алексу с Voiceflow – CodesCode

Как интегрировать Alexa и Voiceflow, сделав акцент на дизайн разговора вместо кодирования. Это поможет вам улучшить ваши диалоги!

Алекса имеет множество возможностей, но создание сложного разговора не так просто. Voiceflow – это инструмент, который позволяет создавать сложные разговоры с Алексой без написания кода. Эта интеграция позволяет создавать разговор в Voiceflow, а затем развернуть его на Алексе.

Именно поэтому в этом репозитории вы найдете простой пример того, как интегрировать Алексу с Voiceflow, используя набор инструментов Alexa Skills Kit SDK для Node.js и вызывая Dialog Manager API Voiceflow.

Предварительные требования

  1. Вам нужен аккаунт в Voiceflow
  2. Вам нужен аккаунт в Alexa Developer
  3. Node.js и npm/yarn установлены на вашем компьютере

Проект Voiceflow

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

В этом примере мы собираемся создать простой разговор, который будет спрашивать у пользователя информацию о Покемоне. Разговор будет выглядеть так:

NLU

В Voiceflow есть встроенный NLU, так как мы собираемся вызывать Voiceflow, используя Dialog Manager API, мы должны разработать наш NLU на Voiceflow и Alexa.

Следуя примеру, мы создадим интент с именем info_intent и слот с именем pokemon, который будет заполняться именем Покемона, о котором пользователь хочет узнать:

Dialog Manager API

Dialog Manager API – это REST API, позволяющий вам взаимодействовать с Voiceflow. Документацию можно найти здесь.

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

Конечная точка DM API: https://general-runtime.voiceflow.com/state/user/%7BuserID%7D/interact

Можно отправлять разные типы запросов. Чтобы увидеть список всех типов запросов, ознакомьтесь с документацией ниже для поля действия.

Чтобы начать разговор, вы должны отправить запрос на запуск. Затем, чтобы передать ответ пользователя, вы должны отправить текстовый запрос. Если у вас есть своя система сопоставления NLU, тогда можете напрямую отправить запрос интента.

Вот пример запроса:

curl --request POST \     --url 'https://general-runtime.voiceflow.com/state/user/{userID}/interact?logs=off' \     --header 'accept: application/json' \     --header 'content-type: application/json' \     --header 'Authorization: VF.DM.96ds3423ds9423fs87492fds79792gf343' \     --data '{  "action": {    "type": "launch"  },  "config": {    "tts": false,    "stripSSML": true,    "stopAll": true,    "excludeTypes": [      "block",      "debug",      "flow"    ]  }}'

Как видите, вам нужно передать userID и заголовок Authorization. userID – это идентификатор пользователя, с которым вы хотите взаимодействовать. Заголовок Authorization – это ключ API, который можно найти в настройках проекта Voiceflow.

Проект Voiceflow, который я использовал для этого примера, можно найти в voiceflow/project.vf.

Навык Alexa

Чтобы создать навык Alexa, перейдите на сайт Alexa Developer и создайте новый навык. Следуйте инструкции Alexa Developer Console Quick Start, чтобы создать простой навык.

NLU

Нам понадобится воссоздать Voiceflow NLU (намерения и сущности) в нашем навыке для Alexa.

Как вы можете видеть, мы используем тип SearchQuery. Этот тип используется для получения пользовательского ввода и отправки его напрямую в Voiceflow. Более подробную информацию об этом типе можно найти здесь.

Код Lambda

Код навыка для Alexa будет универсальным, что означает, что этот код навыка для Alexa может использоваться с любым проектом Voiceflow. Для этого мы собираемся реализовать функцию Lambda, которая будет вызывать API менеджера диалога Voiceflow. Мы собираемся использовать набор Alexa Skills Kit SDK для Node.js и Axios для вызова API.

Нам потребуется изменить только 2 обработчика: LaunchRequestHandler и ListenerIntentHandler. LaunchRequestHandler будет использоваться для запуска разговора, а ListenerIntentHandler будет использоваться для отправки пользовательского ввода в Voiceflow.

Начнем с обработчика LaunchRequestHandler:

const LaunchRequestHandler = {    canHandle(handlerInput) {        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';    },    async handle(handlerInput) {        let chatID = Alexa.getUserId(handlerInput.requestEnvelope).substring(0, 8);        const messages = await utils.interact(chatID, {type: "launch"});        return handlerInput.responseBuilder            .speak(messages.join(" "))            .reprompt(messages.join(" "))            .getResponse();    }};

Этот обработчик вызывается при запуске навыка. Мы получим идентификатор пользователя и вызовем API менеджера диалога Voiceflow с действием launch. Затем мы вернем ответ.

Следующие взаимодействия будут обработаны обработчиком ListenerIntentHandler:

const ListenerIntentHandler = {    canHandle(handlerInput) {        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'    },    async handle(handlerInput) {        let chatID = Alexa.getUserId(handlerInput.requestEnvelope).substring(0, 8);        const intent = Alexa.getIntentName(handlerInput.requestEnvelope);        const entitiesDetected = utils.alexaDetectedEntities(handlerInput.requestEnvelope);        const request = {             type: "intent",             payload: {                 intent: {                    name: intent                },                entities: entitiesDetected            }        };        const messages = await utils.interact(chatID, request);        return handlerInput.responseBuilder            .speak(messages.join(" "))            .reprompt(messages.join(" "))            .getResponse();    }};

Этот обработчик вызывается, когда пользователь говорит что-то. Мы получим пользовательский ввод и вызовем API менеджера диалога Voiceflow с действием intent. Поскольку NLU-вывод выполняется Alexa, нам нужно получить обнаруженные сущности и намерения и передать их в Voiceflow. Затем мы вернем ответ.

Для получения обнаруженных сущностей мы будем использовать следующую функцию:

module.exports.alexaDetectedEntities = function alexaDetectedEntities(alexaRequest) {    let entities = [];    const entitiesDetected = alexaRequest.request.intent.slots;    for ( const entity of Object.values(entitiesDetected)) {        entities.push({            name: entity.name,            value: entity.value        });    }    return entities;}

Код этой функции можно найти в файле lambda/utils.js.

Наконец, мы должны убедиться, что мы добавляем обработчики в навык:

exports.handler = Alexa.SkillBuilders.custom()    .addRequestHandlers(        LaunchRequestHandler,        ListenerIntentHandler,        HelpIntentHandler,        CancelAndStopIntentHandler,        FallbackIntentHandler,        SessionEndedRequestHandler,        IntentReflectorHandler)    .addErrorHandlers(        ErrorHandler)    .withCustomUserAgent('sample/hello-world/v1.2')

В вышеперечисленных обработчиках вы можете видеть, что мы используем функцию под названием utils.interact. Эта функция будет вызывать API менеджера диалога Voiceflow. Код этой функции можно найти в файле lambda/utils.js:

const axios = require('axios');const VF_API_KEY = "VF.DM.96ds3423ds9423fs87492fds79792gf343";module.exports.interact = async function interact(chatID, request) {    let messages = [];    console.log(`request: `+JSON.stringify(request));    const response = await axios({        method: "POST",        url: `https://general-runtime.voiceflow.com/state/user/${chatID}/interact`,        headers: {            Authorization: VF_API_KEY        },        data: {            request        }    });    for (const trace of response.data) {        switch (trace.type) {            case "text":            case "speak":                {                    // remove break lines                    messages.push(this.filter(trace.payload.message));                    break;                }            case "end":                {                    messages.push("Пока!");                    break;                }        }    }    console.log(`response: `+messages.join(","));    return messages;};

Перевод

Эта функция вернет массив сообщений. Мы будем использовать этот массив для создания ответа. Мы также добавили некоторый код для удаления переносов строк и странных символов:

module.exports.filter = function filter(string) {    string = string.replace(/\u0027/g, '\'')    string = string.replace(/(<([^>]+)>)/ig, "")    string = string.replace(/\&/g, ' и ')    string = string.replace(/[&\\#,+()$~%*?<>{}]/g, '')    string = string.replace(/\s+/g, ' ').trim()    string = string.replace(/ +(?= )/g,'')    return string;};

С этим кодом мы закончили Skill для Alexa. Вы можете найти код функции Lambda в lambda/index.js.

Тестирование

После создания Skill для Alexa и проекта Voiceflow, вы можете его протестировать. Для тестирования вы можете использовать симулятор Alexa или настоящее устройство.

Следуя приведенному ниже примеру, вы можете протестировать Skill для Alexa с помощью следующих предложений, чтобы запросить информацию о Pokémon:

Заключение

Как видите, интеграция Alexa с Voiceflow достаточно проста. Вы можете создавать сложные диалоги с помощью Voiceflow, а затем развертывать их на Alexa. Таким образом, ваше внимание будет сосредоточено на диалоге, а не на коде!

Надеюсь, вам понравился этот учебник.

Вы можете найти код этого учебника здесь.

Счастливого кодинга!


Leave a Reply

Your email address will not be published. Required fields are marked *