AWS Lex:发生错误:Lambda响应无效

时间:2019-01-30 11:22:39

标签: amazon-web-services amazon-dynamodb amazon-lex

我正在尝试将Amazon Lex收集的值保存到DynamoDB中。 我制作(或复制和修改)了Lambda函数,该函数显然不起作用,但是我真的不明白为什么。 这是我从Amazon Lex收到的错误:“发生了错误:无效的Lambda响应:从Lambda收到了错误响应:已处理”

其他所有方法都正常,我解决了权限问题以及其他错误。

出现错误时,对话框处于状态:

{
   "dialogState": "ElicitSlot",
   "intentName": "MCQ_A",
   "message": "What is a black and white horse",
   "messageFormat": "PlainText",
   "responseCard": null,
   "sessionAttributes": {},
   "slotToElicit": "QB",
   "slots": {
       "QA": "4",
       "QB": null,
       "Session": "444"
   }
}

//这是我的Lambda函数。它是用javascript编写的,我刚刚发现了它,我绝对不满意^^'

console.log('Loading event');
var AWS = require('aws-sdk');
var dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var tableName = "MCQ";

// Close dialog with the customer, reporting fulfillmentState of Failed or Fulfilled
function close(session_attributes, m) {
    let callback_obj = {
        sessionAttributes: session_attributes,
        dialogAction: {
            type: 'Close',
            fulfillmentState: "Fulfilled",
            message: m,
        }
    }
    return callback_obj;
}

function storeRegistration(intent, callback) {

    let userInfo = {};

    // store every slot we received as part of registration
    Object.keys(intent.slots).forEach((item) => {
        console.log(item)
        userInfo[item] = {"S": intent.slots[item]};
    });

    dynamodb.putItem({
        "TableName": tableName,
        "Item" : userInfo
    }, function(err, data) {
        if (err) {
            console.log('Failure storing user info');
            console.log(err);
            callback(close(intent.sessionAttributes, {contentType: 'PlainText', content: "I am sorry, but something went wrong. Please try again."}));
        } else {
            console.log("Successfully Stored UserInfo");
            callback(close(intent.sessionAttributes, {contentType: 'PlainText', content: "Thank you for attending the MCQ."}));
        }
    });
}

// --------------- 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.log(event);
    try {
        storeRegistration(event, (response) => {callback(null, response)});
    } catch (err) {
        callback(err);
    }
};

您知道发生了什么吗? :) 提前非常感谢您!

3 个答案:

答案 0 :(得分:0)

  1. 插槽 QB 可以在插槽定义区域中按必需进行检查。即使您通过实现意图来关闭对话框,但lex仍会遵循其优先级以引出广告位。
  2. 从代码端而不是从lex控制台处理elicitSLot条件。

答案 1 :(得分:0)

非常感谢您的回答。 QB确实设置为“必需”。 所以我在主要部分添加了一些行来处理这种情况:

if (event.dialogState == "ElicitSlot")
        callback(null, {
            "dialogAction": {
                "type": "ElicitSlot",
                "intentName": event.intentName,
                "slots": event.slots,
                "slotToElicit" : event.slotToElicit
        }})

但是我得到了同样的错误。在绝望中,我也尝试了“委托”响应,但同样的错误。 我有doc,所以我想我的回答写得正确。 仍然,我不明白为什么我的聊天机器人会返回带有空插槽的输出,因为我实际上是在对话框中填充了插槽...

编辑:在使用AWS的蓝图“ order flowers”和相应的lambda函数进行了几次测试之后,一切工作顺利,直到我添加了要存储到Dynamodb中的行。所以我的错误一定在那里。

答案 2 :(得分:0)

我找到了一个解决方案:

我放弃了我的职能,并采用了AWS的lex-order-flowers-python蓝图。它与Lex蓝图OrderFlowers开箱即用。我只需要适应我的工作,然后添加DynamoDB部分。

确保您的商品格式正确,并指定了值类型(字符串为'S')

put_item(
    TableName = 'myTableName',
    Item = {
        'key1': {'S': 'value1'}
        'key2': {'S': 'value2'}
    })

所以我做到了:

userInfo = {}
for key, value in intent_request['currentIntent']["slots"].items() :
    userInfo[key] = {'S': value}

logger.debug(userInfo)

dynamodb = boto3.client('dynamodb')
dynamodb.put_item(TableName='MCQ', Item=userInfo)