Tutorials / Extend Amazon Lex with Location Intelligence
Last Updated: July 31, 2020

Introduction

Location intelligence that sparks compelling opportunities

Voice-enabled devices and chatbots are on the rise due to the increasing need for fast, relevant, 24/7 service. With the explosion of mobile devices and assets with connected sensors, location intelligence has become a key component of digital transformation for organizations around the world.

What’s a chatbot

  • Artificial Intelligence program that delivers conversational experiences - conducts real-time conversations with customers via voice or text
  • Efficiency through Automation - chatbots streamline and automate common and repetitive tasks through simple voice or text requests

Benefits of integrating HERE location awareness technology with Lex

  • Increases business insights with deeper visualization of all aspects of business
  • Enables real-time tracking of assets, devices, products and people in the field
  • Creates visibility of entire shipments down to individual SKUs
  • Facilitates ad-hoc queries for any neighborhood, city, territory and region
  • Delivers Intelligent location data for better decision-making
  • Provides unmatched flexibility with cloud-based services
  • Adds valuable context through geospatial data
  • Drives business value through differentiated services like route optimization, sequencing of waypoints and more
  • Provides map visualization, geocoding, optimized routing and more

Start the tutorial

This tutorial walks you through the steps required to extend an Amazon Lex chatbot with HERE Location Services, within a Slack workspace.

What you’ll learn

  • How to make an Amazon Lex chatbot location-aware with HERE Location Services
  • How to use Geofencing to track whether or not mobile assets are located within specified geographic areas
  • How to build AWS Lambda functions to call HERE Location Services APIs

What you’ll build

  • Amazon Lex chatbot delivered within a Slack workspace
  • Lambda function integrating location awareness for Amazon Lex chatbot

Assumptions & Prerequisites

  • A familiarity with cloud computing and AWS products
  • Working knowledge of AWS Lambda
  • Working knowledge of Node.js and https://npmjs.com

AWS Resources

Architecture overview

img

The HERE Fleet Telematics Geofencing is a REST API that allows you to track whether or not mobile assets are located within specified geographic areas. An asset is any type of trackable object, such as a person, car, smartphone, or package out for delivery.

You can define the geographic areas as geometries in the form of geographic polygons, polylines, or points that are relevant for these assets.

How to upload geo-fencing polygons

You can also choose to check an asset position against map layers, for example country boundaries, postal code boundaries or census boundary layers.

Here is a Region polygon for West Seattle

ID        NAME        ABBR        WKT
1        West Seattle        WS        POLYGON((-122.40289383056643 47.58058419829345,-122.40814907934572 47.57831025614857,-122.4152926032715 47.575688800033156,-122.40406835986329 47.56339608034136,-122.39596714819334 47.55203529886245,-122.38305941796875 47.55225906078617,-122.36245026434324 47.55278836886218,-122.37308348132325 47.57752575602553,-122.38611016918946 47.59363556877512,-122.40289383056643 47.58058419829345))

For more information about HERE Fleet Telematics Geofencing API check out this link: Why Use the Fleet Telematics Geofencing?

Get set up

Adding HERE is easy. You just need:

An Amazon AWS Account

  • Set up an account with Amazon Web Services (AWS)

A HERE Location Services Account

A Slack Account

Node.js and NPM setup on your local machine

Terms

  • Asset - GPS-enabled device
  • Asset Type - metadata describing the category of asset
  • Region - Geofence polygon boundary, area that has a defined perimeter

Create an Amazon Lex chatbot

Duration is 15 min

Amazon Lex is a service for building conversational interfaces into any application using voice and text—it’s the technology powering Alexa. It’s easy to integrate HERE services into your Amazon AWS applications and solutions. This powerful pairing delivers the leading innovation to your products, services and operations, adding robust insights, and functionality.

For this exercise, create a chatbot within the Amazon Lex console.

How to create the chatbot

Sign in to the AWS Management Console: https://console.aws.amazon.com/

img
  1. Click on Services, then select Amazon Lex

  2. If this is your first time creating a bot, click on Get Started; otherwise, click on ‘Custom bot’

Please use defaults value when directions do not explicitly give values

  1. On the ‘Create your Lex bot’ page, provide the following information:
  • Click on ** Custom Bot **
  • Fill out the simple form with your bot name
  • On the ‘Output Voice’ dropdown menu, select ‘This is a text-based application’
  • In the ‘Session timeout’ box enter the number ‘1’
  • For the question about COPPA, select ‘No’
  • Choose ‘Create’

The console will then make the necessary requests to Amazon Lex to save the configuration and will automatically navigate to the "Getting started with your bot’ page.

  1. Click on ‘Create intent’. An ‘Add intent’ window will appear.

  2. Click on ‘Create intent’ in the new window

  3. In the box ‘ Give a unique name for your intent, type in ‘ assetlocation’ then click ‘Add’

img
  1. Add an utterance with the text “Find assets in location”

  2. Click on the ‘+’ symbol next to ‘‘* Create a new Slot type’ on the left side of the page.

  3. A popup window appears called “Add slot type” Click on ‘Create slot type’

  4. The ‘Add slot type’ pop-up window reappears

  • Under ‘Slot type name’ type in ‘Regions’. You don’t need to fill in the ‘Description’ box
  • Under ‘Value’ type in the first location: ‘Ballard’ then click on the ‘+’ symbol.
  • An additional text box appears. Type in the second location: ‘West Seattle’, click on the ‘+’ symbol again
  • A third text box appears - type in the final location: ‘Downtown’ then click on the button called ‘Add slot to intent’
img
  1. *Click on the ‘+’ symbol next to ‘‘* Create a new Slot type" on the left side of the page. The popup will window appear called “Add slot type” Click on ‘Create slot type’. Follow the directions in step 11, but this time, use “Assets” for the slot type name and plug in these 5 asset type values: helicopter, bulldozer, delivery vehicle, and boat.

img/1e9c836860a05eb0.png

  1. Click on the ‘Build’ button on the upper left side of the page. A popup window will appear asking if you want to build your bot. Click on ‘Build’ again to begin.

  2. You’ll be guided through steps to build your bot. When completed, a confirmation notification will appear on the page, stating that your bot was built.

Test the bot

  1. To test the bot, type text into the test window, or choose the microphone button in the test window and start speaking.

Use the following example text to engage in typed conversation with your assetlocation bot. Type the words in the grey text bubble. The bot answers are in blue.

img

For the complete tutorial on creating an Amazon Lex chatbot click here

Integrate chatbot with Slack

Duration is 30 min

To integrate and run your Amazon Lex chatbot with the Slack collaboration hub, follow the complete tutorial steps here.

Test it

Once you’ve completed the steps provided in the link above, you can test the integration with Slack by engaging in conversation with your Amazon Lex bot. Type the same questions from the test section of creating your Lex bot, but this time type them into the Slack channel.

img

Integration location services

Duration is 20 min

Upload Geofence Polygon Layer

Save this as layer file ‘layers_seattle.wkt’. Note, the columns must be tab delimited (this may not come through if copied from this code block).

ID        NAME        ABBR        WKT
1        West Seattle        WS        POLYGON((-122.40289383056643 47.58058419829345,-122.40814907934572 47.57831025614857,-122.4152926032715 47.575688800033156,-122.40406835986329 47.56339608034136,-122.39596714819334 47.55203529886245,-122.38305941796875 47.55225906078617,-122.36245026434324 47.55278836886218,-122.37308348132325 47.57752575602553,-122.38611016918946 47.59363556877512,-122.40289383056643 47.58058419829345))
2        Ballard        Ball        POLYGON((-122.39466504345182 47.684774048296326,-122.39466504345182 47.669170576436436,-122.37561063061003 47.66928617486375,-122.37595395336393 47.68558298996103,-122.39466504345182 47.684774048296326))
3        Downtown Dwntn        DowntownSea        POLYGON((-122.33445571727111 47.59849206326816,-122.3253576642926 47.601501607033775,-122.34012054271057 47.61955523417492,-122.34887527293517 47.61388521492726,-122.33445571727111 47.59849206326816))

Create a zip file that includes the wkt file. Save the zip file as ‘layers_seattle.zip’.

Now run a curl command to upload the layer file.

curl --request -i -X POST -H "Content-Type: multipart/form-data" -F "zipfile=@layers_seattle.zip" "https://fleet.ls.hereapi.com/2/layers/upload.json?layer_id=1001&apiKey={YOUR_API_KEY}"

The result from the curl command should look like this

{"storedTilesCount":9,"response_code":"201 Created"}

Create the Node.js Package

Create the Node.js package that will be uploaded to the Lambda function you will create in the next step. package.json

{
      "name": "demo",
      "version": "1.0.0",
      "dependencies": {
              "request": "^2.0.0"
      }
}

The Lambda function will create a request to the HERE Rest services API Search Proximity with a geo-location point. This will determine if the asset is inside or outside of the Region polygon specified.

index.js

 'use strict';

 const request = require('request');

 function formatResponse(sessionAttributes, fulfillmentState, assetType, region, regionFound) {

     var messageText;

     if(region != regionFound){
         messageText = `We did not find a ${assetType} in ${region} but we did find one in ${regionFound}`;
     }else if (region == regionFound)
     {
         messageText = `We have found 1 ${assetType} in ${region}`;
     }

     var message = {'contentType': 'PlainText', 'content': messageText};

     return {
         sessionAttributes,
         dialogAction: {
             type: 'Close',
             fulfillmentState,
             message,
         },
     };
 }

 // replace with internal system call that gets realtime GPS coordinates for a given assetType
 function findAssetLocationByAssetType(assetType) {
     var assetLatLong;

     switch(assetType) {
       case 'helicopter':
         assetLatLong = '47.679506, -122.387584';  // ballard
         break;
       case 'bulldozer':
         assetLatLong = '47.570186, -122.386759';  // west seattle
         break;
       case 'delivery vehicle':
         assetLatLong = '47.603980, -122.335579';  // downtown
         break;
       case 'boat':
         assetLatLong = '47.608291, -122.338056';  // downtown
         break;
       default:
         assetLatLong = null;  // for demo purposes we only, no error handling
     }

     return assetLatLong;
 }

 // --------------- Events -----------------------

 function dispatch(intentRequest, callback) {

     const sessionAttributes = intentRequest.sessionAttributes;

     console.log(`dispatch userId=${intentRequest.userId}, intentName=${intentRequest.currentIntent.name}`);

     const intentName = intentRequest.currentIntent.name;
     const slots = intentRequest.currentIntent.slots;
     const region = slots.slotOne.toLowerCase();
     const assetType = slots.slotTwo.toLowerCase();

     var proximity = findAssetLocationByAssetType(assetType);
     var layerIds = '1001';

     const url = 'https:https://fleet.ls.hereapi.com/2/search/proximity.json' +
                 '?apiKey=<YOUR_API_KEY>' +
                 '&proximity=' + proximity +
                 '&layer_ids=' + layerIds +
                 '&key_attribute=NAME';

     request(url, { json: true }, (err, res, body) => {

                     if (err) { return console.log('err: ', err); }

                     console.log('statusCode:', res && res.statusCode);
                     console.log('body: ', JSON.stringify(body));

                     // process response
                     var regionFound = body.geometries[0].attributes.NAME.toLowerCase();
                     var distance = body.geometries[0].distance;

                     var formattedResponse = formatResponse(sessionAttributes, 'Fulfilled', assetType, region, regionFound);

                     callback(formattedResponse);
                 });
 }

 // --------------- Main handler -----------------------

 exports.handler = (event, context, callback) => {
     try {
         dispatch(event,
             (response) => {
                 callback(null, response);
             });
     } catch (err) {
         callback(err);
     }
 };

Execute an npm install command

npm install

Create a zip file with contents of the folder (index.js, package.json and node_modules folder).

Create the Lambda Function

To create the Lambda function that will be used for your Lex bot follow these steps:

  1. Go to the AWS console and select ‘Lambda’
  2. Click ‘ Create Function’ , then click ‘ Author from scratch’
img
  1. Upload the zip file of the Node.js contents you created in the previous step. Click ‘Save’ within the Lambda console after you have selected your zip file.
img

Test it in the Lambda console

When you click ‘Test’ within the Lambda function, you will be prompted with configuring a test event. You can use the following json to setup your first test event. This test will mimic searching for a ‘bulldozer’ in ‘west seattle’.

 {
   "messageVersion": "1.0",
   "invocationSource": "FulfillmentCodeHook",
   "userId": "user-1",
   "sessionAttributes": {},
   "bot": {
     "name": "here_demo",
     "alias": "$LATEST",
     "version": "$LATEST"
   },
   "outputDialogMode": "Text",
   "currentIntent": {
     "name": "assetlocaion",
     "slots": {
       "slotOne": "west seattle",
       "slotTwo": "bulldozer"
     },
     "confirmationStatus": "None"
   }
}

Click ‘Create’ for your test event, then click ‘Test’. The Lambda response should include the following.

Response: json { "sessionAttributes": {}, "dialogAction": { "type": "Close", "fulfillmentState": "Fulfilled", "message": { "contentType": "PlainText", "content": "We have found 1 bulldozer in west seattle" } } }

For more information on creating Lambda Functions

Update the Fulfillment of the Lex chatbox to call the Lambda function

img

Build and Publish the Lambda function.

Test it in Lex console

Test the Lambda integration within the Lex console.

img

Test it in Slack

Log into your Slack workspace, type the same commands used to test the chatbot in Lex. You should get the same responses in Slack.

img

Review

In this tutorial we extended the capabilities of an Amazon Lex chatbot with HERE Location Services.

Key takeaways

  • How to make a Lex bot location aware by leveraging HERE Location Services
  • How to use Geofencing to track whether or not mobile assets are located within the specified geographic areas
  • How to use Custom Locations to find assets in a geographic polygon