Integration with NLP engine (Amazon Lex)

  • 3 October 2019
  • 3 replies
  • 251 views

Hi,


I’ve managed to integrate Lookerbot with Amazon Lex, for using free text requests instead of specific commands:



  • Custom command in Lookerbot posts message text to Amazon Lex bot

  • Amazon Lex bot detects intent, and returns that back to Lookerbot

  • Lookerbot uses the intent name to map to the actual Looker dashboard


Here is a code snippet for that custom command in Lookerbot:


 import * as _ from "underscore"
import config from "../config"
import { Looker } from "../looker"
import { DashboardQueryRunner } from "../repliers/dashboard_query_runner"
import { ReplyContext } from "../reply_context"
import { Command } from "./command"
import * as AWS from "aws-sdk"

export class CustomNlpCommand extends Command {

public attempt(context: ReplyContext) {

AWS.config.update({ region: 'eu-west-1' });

var lexruntime = new AWS.LexRuntime();

var params = {
botAlias: '$LATEST', /* required, has to be '$LATEST' */
botName: 'lookerbot', /* required, the name of you bot */
inputText: context.sourceMessage.text.toLowerCase(), /* required, your text */
userId: 'lookerbot' /* required, arbitrary identifier */
};

lexruntime.postText(params, function (err, data) {
if (err) {
console.log(err, err.stack); // an error occurred
return false
}
else {
console.log(data); // successful response

if (!data.intentName) {
console.log("Cannot find intent");
context.replyPrivate("😿 " + data.message);
return false;
}

const normalizedText = data.intentName!.toLowerCase()
const shortCommands = _.sortBy(_.values(Looker.customCommands), (c) => -c.name.length)
const matchedCommand = shortCommands.filter((c) => normalizedText.indexOf(c.name) === 0)[0]
if (matchedCommand) {

if (data.message) context.replyPrivate("😼 " + data.message);

const { dashboard } = matchedCommand
const query = matchedCommand.name
normalizedText.indexOf(matchedCommand.name)
context.looker = matchedCommand.looker

const runner = new DashboardQueryRunner(context, matchedCommand.dashboard, {})
runner.start()

return true
} else {
return false
}
}
});

return false
}
}

3 replies

This is awesome, nice work @Olegas_Murasko!

Userlevel 7
Badge +1

This is so cool! There’s one specific Lookerbot command that I always mess up in some minor way, and this would be really helpful.

I’ve actually never seen a custom Lookerbot command defined before, could you quickly explain how to implement one?

All commands are stored here: https://github.com/looker/lookerbot/tree/master/src/commands


I did the following:



  1. Copied custom_command.ts, renamed that to custom_nlp_command.ts

  2. In custom_nlp_command.ts, changed the class name to CustomNlpCommand

  3. Modified the “attempt” method of CustomNlpCommand to send the message text to Amazon Lex, get back identified intent, and run a Looker query with DashboardQueryRunner with that intent name (assuming there is a dashboard with such name is already created in Looker)

  4. Custom commands return “true”, if the handling attempt is successful (and “false” otherwise) - so, return “true”, if the intent has been detected by Lex, and DashboardQueryRunner gets back the actual dashboard

  5. Modify “commands” list in index.ts (/src/index.ts#L24) to include that new CustomNlpCommand command


In my case, I have removed other non-NLP commands from the command list entirely, as all other commands are handled over NLP with free text.


Thanks.

Reply