Выполнение AWS-Lex с AWS-Lambda

Мне нужно интегрировать Amazon lex с Amazon lambda. Я столкнулся с одной проблемой. Я новичок в этом, поэтому, пожалуйста, помогите мне. Я хочу запросить продукт с помощью Lex. «Где я могу найти мясо» и мясо будет храниться в слоте "SearchProduct" Затем он выполнит поиск в базе данных и ответит через lex. Как "я нашел мясо в проходе № 4"

Здесь я могу получить значение Прохода № 4 путем сканирования в Dynamodb, но я не могу отправить ответ.

 'use strict';

const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({ region: "us-east-1" });
var reply = ' ';


// --------------- Helpers to build responses which match the structure of the necessary dialog actions -----------------------

function elicitSlot(sessionAttributes, intentName, slots, slotToElicit, message, responseCard) {
    return {
        sessionAttributes,
        dialogAction: {
            type: 'ElicitSlot',
            intentName,
            slots,
            slotToElicit,
            message,
            responseCard,
        },
    };
}

function close(sessionAttributes, fulfillmentState, message, responseCard) {
    return {
        sessionAttributes,
        dialogAction: {
            type: 'Close',
            fulfillmentState,
            message,
            responseCard,
        },
    };
}

function delegate(sessionAttributes, slots) {
    return {
        sessionAttributes,
        dialogAction: {
            type: 'Delegate',
            slots,
        },
    };
}



// ---------------- Helper Functions --------------------------------------------------

// build a message for Lex responses
function buildMessage(messageContent) {
    return {
        contentType: 'PlainText',
        content: messageContent,
    };
}



// --------------- Functions that control the skill's behavior -----------------------

/**
 * Performs dialog management and fulfillment for ordering a beverage.
 * (we only support ordering a mocha for now)
 */
function ItemSearch(intentRequest, callback) {

    const outputSessionAttributes = intentRequest.sessionAttributes;
    const source = intentRequest.invocationSource;

    if (source === 'FulfillmentCodeHook') {
        const slots = intentRequest.currentIntent.slots;
        const requestProductName = (slots.SearchProduct ? slots.SearchProduct : null);

        var scanningParameters = {
            TableName: "my table name",
            ProjectionExpression: "#pro, Aisle",
            FilterExpression: "contains (#pro, :productname)",
            ExpressionAttributeNames: {
                "#pro": "ProductName",
            },
            ExpressionAttributeValues: {
                ":productname": requestProductName
            }
        };

        docClient.scan(scanningParameters, function(err, data) {
            if (err) {

                callback(close(outputSessionAttributes, 'Fulfilled', { contentType: 'PlainText', content: 'not found' }));
            }
            else {
                console.info(data);
                if (data.Count == 0) {
                    reply = 'not found';
                    callback(close(outputSessionAttributes, 'Fulfilled', { contentType: 'PlainText', content: 'not found' }));
                }
                else {
                    reply = requestProductName + ' can be found in Aisle No: ' + data.Items[0].Aisle;
                    callback(close(outputSessionAttributes, 'Fulfilled', { contentType: 'PlainText', content: requestProductName + ' can be found in Aisle No: ' + data.Items[0].Aisle }));

                }
            }
        });
    }

    callback(close(outputSessionAttributes, 'Fulfilled', {
        contentType: 'PlainText',
        content: `Thanks for using CoffeeBot! `  // i want the reply from the search here but i always end up with null
    }));
}

// --------------- Intents -----------------------

/**
 * Called when the user specifies an intent for this skill.
 */
function dispatch(intentRequest, callback) {

    console.info(`dispatch userId=${intentRequest.userId}, intent=${intentRequest.currentIntent.name}`);

    const name = intentRequest.currentIntent.name;

    // dispatch to the intent handlers
    if (name.startsWith('Product')) {
        return ItemSearch(intentRequest, callback);
    }
    throw new Error(`Intent with name ${name} not supported`);
}

// --------------- Main handler -----------------------

// Route the incoming request based on intent.
// The JSON body of the request is provided in the event slot.
exports.handler = (event, context, callback) => {

    console.info(JSON.stringify(event));

    try {
        console.info(`event.bot.name=${event.bot.name}`);

        // fail if this function is for a different bot
        if (!event.bot.name.startsWith('Aowi')) {
            callback('Invalid Bot Name');
        }
        dispatch(event, (response) => callback(null, response));
    }
    catch (err) {
        callback(err);
    }
};

Я получаю ответ от поиска, но не могу отправить ответ Лексу. Содержательная часть всегда пуста.

Response:
{
  "sessionAttributes": {},
  "dialogAction": {
    "type": "Close",
    "fulfillmentState": "Fulfilled",
    "message": {
      "contentType": "PlainText",
      "content": " "
    }
  }
}

Лекс отправит слот с именем «SearchProduct» == «мясо».

Выполнение AWS-Lex с AWS-Lambda

Я не уверен, в какой части я делаю это неправильно. Благодарю, если кто-нибудь может помочь мне улучшить код. Спасибо

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
1 230
2

Ответы 2

Эта ошибка возникает из-за того, что Amazon Lex ожидает ответов в определенном формате JSON. Судя по всему, вы написали код на Node.js. Я не эксперт по узлам, но могу предоставить вам рабочий пример того, как я отправляю ответ обратно в lex.

Последовательность кода выглядит примерно так:

Intent called -> Lambda function invoked -> (Your lamba code runs and process the data given by lex) -> You generate a response to send back to Lex -> Lex reads the Response json and interprets it based on what you have returned.

def close(fulfillment_state, message):
response = {
    'dialogAction': {
        'type': 'Close',
        'fulfillmentState': fulfillment_state,
        'message': message
    }
}
return response
response_to_lex =  close('Fulfilled',{'contentType': 'PlainText','content': 'Message i want to send to lex'})

Функция close создает событие завершения типа «Close» для lex и генерирует соответствующее ответное сообщение. Примечание: type, fulfullmentState и сообщение - обязательные параметры, которые необходимо передать обратно в lex.

Эта ссылка может быть полезна, чтобы понять это глубже: Lex Docs

Также просматривая документацию для LEX и Node Lambda на здесь, я вижу, что метод вызова функции диспетчеризации отличается. Но здесь я могу ошибаться.

Вы должны отправить ответ в определенном формате. Для Node.js ниже приведен пример

 const response = {
          dialogAction: {
                        type: "Close",
                        fulfillmentState: "Fulfilled",
                        message: {
                            contentType: "PlainText",
                            content: "i have found Meat in Aisle no 4"
                        }
                    }
                };
                callback(null, response);

Можете ли вы принять ответ, если он вам поможет?

Другие вопросы по теме