From a1782a70455f9fd44652d5333ecc9802d72d5586 Mon Sep 17 00:00:00 2001 From: Mihai Balint Date: Mon, 26 Jun 2017 01:45:19 +0300 Subject: [PATCH 1/2] Add one more intent, refactor duplicate defs. --- functions/upbot/index.js | 175 +++++++++++++++++++++++++++++---------- 1 file changed, 130 insertions(+), 45 deletions(-) diff --git a/functions/upbot/index.js b/functions/upbot/index.js index e89f032..184d090 100644 --- a/functions/upbot/index.js +++ b/functions/upbot/index.js @@ -1,7 +1,11 @@ console.log('starting function') const AWS = require('aws-sdk'); const lexmodelbuildingservice = new AWS.LexModelBuildingService({apiVersion: '2017-04-19'}); +const dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'}); +/* + Intent slot types +*/ const projectName = { name: 'ProjectName', description: 'The names of all our projects', @@ -15,8 +19,119 @@ const projectName = { {value: 'Manager'} ] }; +const projectRepository = { + name: 'ProjectRepository', + description: 'The url of the project source code repository', + priority: 4 +}; + + +function readSlotType(tableName, tableAttr, slotType) { + return Promise.all([ + lexmodelbuildingservice + .getSlotType({name: slotType.name, version: "$LATEST"}) + .promise(), + dynamodb + .scan({TableName: tablename}) + .promise() + ]).then((data) => { + slotType.checksum = data[0].checksum; + + const values = new Array(); + for(item in data[1]['Items']) { + values.push({value: item[tableAttr]['S']}); + } + slotType['enumerationValues'] = values; + + return lexmodelbuildingservice.putSlotType(slotType).promise(); + }).catch(() => {}); +}; + + +/** + * Intent slots + */ +const projectNameSlot = { + name: "project", + description: "The name of the project.", + priority: 3, + valueElicitationPrompt: { + maxAttempts: 2, + messages: [ + {contentType: "PlainText", content: "What is the name of the project?"}, + {contentType: "PlainText", content: "Project name please?"}, + {contentType: "PlainText", content: "Project name?"}, + {contentType: "PlainText", content: "What project?"} + ] + }, + sampleUtterances: [ + "Project {project} ", + "App {project} ", + "Webapp {project} ", + "For {project} " + ], + slotConstraint: "Required", + slotType: "ProjectName", + slotTypeVersion: "$LATEST" +}; +const projectRepositorySlot = { + name: 'repository', + description: 'The url of the project source code repository.', + priority: 4, + valueElicitationPrompt: { + maxAttempts: 2, + messages: [ + {contentType: "PlainText", content: "What is the repository for {project}?"}, + {contentType: "PlainText", content: "What is bitbucket url for {project}?"} + ] + }, + sampleUtterances: [ + "In bitbucket {repository} ", + "At {repository} ", + "Webapp {repository} ", + "For {repository} " + ], + slotConstraint: "Required", + slotType: "ProjectRepository", + slotTypeVersion: "$LATEST" +}; + +const rejections = { + messages: [ + {contentType: "PlainText", content: "k thnx bye"}, + {contentType: "PlainText", content: "I have so many stories"}, + {contentType: "PlainText", content: "I'm just a bot and I don't understand everything"}, + {contentType: "PlainText", content: "I didn't understand that. How about a pug?"} + ] +}; + -const intent = { +/** + * The Intents + */ +const addProject = { + name: 'AddCodeRepositories', + sampleUtterances: [ + 'I have created a new project', + 'We have a new project', + 'A new project has been created', + 'Project {project} is new and its repository is {repository} ' + ], + slots: [projectNameSlot, projectRepositorySlot], + confirmationPrompt: { + maxAttempts: 1, + messages: [ + {contentType: "PlainText", content: "Please confirm that {project} is here {repository}"}, + {contentType: "PlainText", content: "Should I learn that {project} is here {repository}?"} + ] + }, + rejectionStatement: rejections, + fulfillmentActivity: { + type: "ReturnIntent" + } +}; + +const getRepository = { name: 'CodeRepositories', sampleUtterances: [ "Where is the source code", @@ -25,45 +140,21 @@ const intent = { "Where is the code for {project} ", "What is the repository for {project} source code " ], - slots: [{ - name: "project", - description: "The name of a project.", - priority: 3, - valueElicitationPrompt: { - maxAttempts: 1, - messages: [ - {contentType: "PlainText", content: "For what project?"}, - {contentType: "PlainText", content: "What project?"} - ] - }, - sampleUtterances: [ - "Project {project} ", - "App {project} ", - "Webapp {project} ", - "For {project} " - ], - slotConstraint: "Required", - slotType: "ProjectName", - slotTypeVersion: "$LATEST" - }], + slots: [projectNameSlot], confirmationPrompt: { maxAttempts: 1, messages: [ {contentType: "PlainText", content: "pls cnfrm"} ] }, - rejectionStatement: { - messages: [ - {contentType: "PlainText", content: "k thnx bye"} - ] - }, + rejectionStatement: rejections, /* - For some reason lex does not like this - conclusionStatement: { - messages: [ - {contentType: "PlainText", content: "Anything else?"}, - {contentType: "PlainText", content: "Can I help with anything else?"} - ], + For some reason lex does not like this + conclusionStatement: { + messages: [ + {contentType: "PlainText", content: "Anything else?"}, + {contentType: "PlainText", content: "Can I help with anything else?"} + ], responseCard: "string" }, */ @@ -72,23 +163,17 @@ const intent = { } }; + exports.handle = function(e, ctx, cb) { console.log('processing event: %j', e); - const c1 = lexmodelbuildingservice - .getSlotType({name: projectName.name, version: "$LATEST"}) - .promise() - .then((data) => { - projectName.checksum = data.checksum; - console.log('XXX', data.name, data.checksum); - return lexmodelbuildingservice.putSlotType(projectName).promise(); - }) - .catch(() => {}); + const c1 = readSlotType('projects', 'name', projectName); + const c2 = lexmodelbuildingservice - .getIntent({name: intent.name, version: "$LATEST"}) + .getIntent({name: getRepository.name, version: "$LATEST"}) .promise() .then((data) => { - intent.checksum = data.checksum; + getRepository.checksum = data.checksum; console.log('YYY', data.name, data.checksum); }) .catch(() => {}); @@ -96,7 +181,7 @@ exports.handle = function(e, ctx, cb) { Promise .all([c1, c2]) .then(() => { - return lexmodelbuildingservice.putIntent(intent).promise(); + return lexmodelbuildingservice.putIntent(getRepository).promise(); }) .then((data) => { cb(null, data); From b3d78fa0e067ed88403a8e68dc8d6091a94b4827 Mon Sep 17 00:00:00 2001 From: Mihai Balint Date: Tue, 27 Jun 2017 01:18:23 +0300 Subject: [PATCH 2/2] Fixups --- functions/gracedata/index.js | 10 +++++---- functions/upbot/index.js | 39 +++++++++++++++++++++++------------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/functions/gracedata/index.js b/functions/gracedata/index.js index e0a1cde..ac17133 100644 --- a/functions/gracedata/index.js +++ b/functions/gracedata/index.js @@ -29,12 +29,11 @@ const projectMap = { }; function createTable(tableDef) { - const ensureCreate = dynamodb.createTable(tableDef).promise(); return dynamodb.deleteTable( {'TableName': tableDef['TableName']}) .promise() - .then(ensureCreate) - .catch(ensureCreate); + .then(() => { return dynamodb.createTable(tableDef).promise(); }) + .catch(() => { return dynamodb.createTable(tableDef).promise(); }); }; function populateTable(tableDef, content) { @@ -44,7 +43,7 @@ function populateTable(tableDef, content) { for(item in content) { const kvItem = {}; kvItem[keyField] = {S: item}; - kvItem[valueField] = {S: content[item]} + kvItem[valueField] = {S: content[item]}; items.push({PutRequest: {Item: kvItem}}); }; const requests = {}; @@ -54,6 +53,9 @@ function populateTable(tableDef, content) { exports.handle = function(e, ctx, cb) { createTable(projectsTable) + .catch((err) => { + console.log(err, err.stack); + }) .then(populateTable(projectsTable, projectMap)) .then((data) => { cb(null, {status: 'OK'}); diff --git a/functions/upbot/index.js b/functions/upbot/index.js index 184d090..70e9214 100644 --- a/functions/upbot/index.js +++ b/functions/upbot/index.js @@ -26,15 +26,16 @@ const projectRepository = { }; -function readSlotType(tableName, tableAttr, slotType) { +function updateSlotType(tableName, tableAttr, slotType) { return Promise.all([ lexmodelbuildingservice .getSlotType({name: slotType.name, version: "$LATEST"}) .promise(), dynamodb - .scan({TableName: tablename}) + .scan({TableName: tableName}) .promise() ]).then((data) => { + console.log('Updating slot type ', slotType.name); slotType.checksum = data[0].checksum; const values = new Array(); @@ -44,7 +45,9 @@ function readSlotType(tableName, tableAttr, slotType) { slotType['enumerationValues'] = values; return lexmodelbuildingservice.putSlotType(slotType).promise(); - }).catch(() => {}); + }).catch((err) => { + console.log( err, err.stack); + }); }; @@ -163,25 +166,33 @@ const getRepository = { } }; +function updateIntent(intent) { + return lexmodelbuildingservice + .getIntent({name: intent.name, version: "$LATEST"}) + .promise() + .then((data) => { + intent.checksum = data.checksum; + }) + .catch(() => {}) + .then(() => { + console.log('Updating intent: ', intent.name); + return lexmodelbuildingservice.putIntent(intent).promise(); + }); +}; exports.handle = function(e, ctx, cb) { console.log('processing event: %j', e); - const c1 = readSlotType('projects', 'name', projectName); + const st1 = updateSlotType('projects', 'name', projectName); + const st2 = updateSlotType('projects', 'url', projectRepository); - const c2 = lexmodelbuildingservice - .getIntent({name: getRepository.name, version: "$LATEST"}) - .promise() - .then((data) => { - getRepository.checksum = data.checksum; - console.log('YYY', data.name, data.checksum); - }) - .catch(() => {}); + const i1 = updateIntent(getRepository); + const i2 = updateIntent(addProject); Promise - .all([c1, c2]) + .all([st1, st2]) .then(() => { - return lexmodelbuildingservice.putIntent(getRepository).promise(); + return Promise.all([i1, i2]) }) .then((data) => { cb(null, data);