I have to integrate Amazon lex with Amazon lambda. I came across one problem. I am new at this so please help me. I want to request for a product using Lex. "Where can i find meat" and Meat will be stored to slot 'SearchProduct' Then it will search in the database and reply via lex. Like "i have found Meat in Aisle no 4"
Here i am able to get the value of Aisle no 4 by scanning in the dynamodb but i am not able to send the response.
'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.log(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.log(`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.log(JSON.stringify(event));
try {
console.log(`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);
}
};
I am getting the reply from the search but i am not able to send the reply to Lex. The content part is always empty.
Response:
{
"sessionAttributes": {},
"dialogAction": {
"type": "Close",
"fulfillmentState": "Fulfilled",
"message": {
"contentType": "PlainText",
"content": " "
}
}
}
Lex will send the slot named 'SearchProduct' == 'meat'.
I am not sure at which part i am doing it wrong. Appreciate it if anyone can help me improve the code. Thank you