All articles on Amazon Lex
Amazon Lex can't communicate directly with Cognigy.AI, therefore it needs a Lambda function to forward the payload to Cognigy.AI and then return the response in a special format to Amazon Lex.
When using the Amazon Lex bot for NLU, we forward the entire NLU response 1:1 to Cognigy.AI, and then the built-in Amazon Lex NLU in Cognigy.AI will transform the transcript, Intents and Slots into a format that can be understood by Cognigy.AI.
Setup
- Log on to the AWS console as a privileged user.
- Open AWS Lambda and create a new Lambda function with a Node.js 16.x runtime.
- Copy the following code into your index.js file
const COGNIGY_ENDPOINT_HOSTNAME = "endpoint-trial.cognigy.ai"; const COGNIGY_ENDPOINT_PATH = "/your-urltoken";
// Change these attributes to the session attributes that contain your userId and sessionId const USERID_ATTRIBUTE = "CustomerNumber"; const SESSIONID_ATTRIBUTE = "ContactId";
// Pagination doesn't work at this API so we need to specify the maximum number of slots that are used for a single intent as page size const PAGESIZE = 20;
const AWS = require("aws-sdk");
const lexmodelsv2 = new AWS.LexModelsV2({ apiVersion: "2020-08-07" });
exports.handler = async (event, context, callback) => { const slotMap = await retrieveSlots(event); const postObject = { userId: event["sessionState"]["sessionAttributes"][USERID_ATTRIBUTE] || AWS.util.uuid.v4(), sessionId: event["sessionState"]["sessionAttributes"][SESSIONID_ATTRIBUTE] || AWS.util.uuid.v4(), text: event["transcriptions"][0]["transcription"], data: { request: event, slotMap }, }; const resultMap = await sendMessageToCognigy(postObject); const defaultSessionAtrributes = { action: "NONE", action_data: "", }; if (resultMap["data"] && resultMap["data"]["connect_action"]) { defaultSessionAtrributes["action"] = resultMap["data"]["connect_action"]; } if (resultMap["data"] && resultMap["data"]["connect_action_data"]) { defaultSessionAtrributes["action_data"] = JSON.stringify(resultMap["data"]["connect_action_data"]); } const response = { sessionState: { sessionAttributes: { action: defaultSessionAtrributes.action, action_data: JSON.stringify(defaultSessionAtrributes.action_data), }, dialogAction: { type: "Close", fulfillmentState: "Fulfilled", message: resultMap["text"], }, intent: { confirmationState: "Confirmed", name: event["sessionState"]["intent"]["name"], slots: {}, state: "Fulfilled", }, }, messages: [{ contentType: "PlainText", content: resultMap["text"], }, ], }; callback(null, response); }; const https = require("https"); async function sendMessageToCognigy(postObject) { return new Promise((resolve, reject) => { const postData = JSON.stringify(postObject); const options = { hostname: COGNIGY_ENDPOINT_HOSTNAME, path: COGNIGY_ENDPOINT_PATH, method: "POST", headers: { "Content-Type": "application/json", }, }; const request = https.request(options, handleResponse); request.on("error", error => { reject(error); }); request.write(postData); request.end(); function handleResponse(response) { let data = ""; response.on("data", d => { data += d.toString(); }); response.on("end", () => { resolve(JSON.parse(data)); }); } }); } async function retrieveSlots(event) { const params = { botId: event.bot.id, botVersion: event.bot.version, localeId: event.bot.localeId, filters: [{ name: "IntentName", operator: "EQ", values: [event.sessionState.intent.name], }, ], }; const intents = await lexmodelsv2.listIntents(params).promise(); const slotParams = { botId: event.bot.id, botVersion: event.bot.version, localeId: event.bot.localeId, intentId: intents.intentSummaries[0].intentId, maxResults: PAGESIZE, }; const slotList = await lexmodelsv2.listSlots(slotParams).promise(); const slots = slotList.slotSummaries.reduce((obj, item) => Object.assign(obj, { [item.slotName]: item.slotTypeId }), {}, ); return slots; } - Replace the two variables in the top rows with your Endpoint hostname and the URL token of your Endpoint.
- Modify the service that was created for the Lambda function. You will need to add the rights lex:ListIntents and lex:ListSlots. Instead you may also use a predefined role such as AmazonLexReadOnly.
- Save the Lambda function.
Comments
0 comments