Tutorials / Create a location-aware chatbot with Twilio and HERE Location Services.
Last Updated: July 28, 2020
Introduction
Duration is 3 min
We recently partnered with the Greater Chicago Food Depository (GCFD) to build a location-aware chatbot that helps those in need find nearby food pantries.
The bot works as such:
A user of the chatbot texts the bot with their current location.
The chatbot returns the 3 closest food pantries to the provided location. The message includes information such as the phone number, address, and operating hours of the pantry.
Although the Greater Chicago Food Depository is geared at a very specific use case of helping food insecure individuals find nearby food pantries, this type of chatbot concept can be applied in many different situations and industries. For example, a gas station brand could build a similar service directing drivers to nearby gas stations in areas with poor data service. In this situation, a SMS-based chatbot would be appropriate.
What you’ll need
Duration is 5 min
This tutorial assumes some familiarity with JavaScript and Node.js.
In this tutorial, we’ll be using a few different services:
HERE Geocoding API: a service to translate coordinates to addresses and vice-versa.
Be sure to swap out your HERE Developer Account app id/code and Twilio sid/token. Leave the HERE token value as empty for now; we’ll be obtaining the HERE token in a later step.
Additionally, run the command npm install express twilio body-parser @turf/turf request in the directory of the server.js file to ensure the correct dependencies are installed.
We’re also going to need to install ngrok to run a tunnel providing an externally available URL to our server.
You can install ngrok globally with the following command:
npm install -g ngrok
Send messages with Twilio
Duration is 8 min
Now that our skeleton is complete, we can start writing some logic to send messages with the Twilio Programmable SMS API.
Once Twilio is configured correctly, the following code will enable our bot to reply with ‘Hello, there!’ anytime you text the Twilio phone number.
We’ll want to configure our server to reply to messages sent to our Twilio phone number. In the server.js file, add the following code:
app.post('/sms', (req, res) => {
const twiml = new MessagingResponse();
twiml.message('Hello, there!');
res.writeHead(200, {'Content-Type': 'text/xml'});
res.end(twiml.toString());
});
http.createServer(app).listen(1337, () => {
console.log('Express server listening on port 1337');
});
To get the server up and running, you’re going to want to run node server.js (alternatively nodemon server.js if you have it installed. This eliminates the need to restart the server) in the command line. In order to make your server publicly accessible, you’ll want to run the command ngrok http 1337. Port 1337 is now exposed to the public internet.
Copy the forwarding URL (highlighted in the below screenshot) provided by the ngrok console.
Take the copied URL and configure it as a webhook for your phone number. Under the Messaging header, paste this URL followed by /sms in the message comes in field.
twilio url
Once you’ve got that configured, try sending a message to your Twilio phone number. You should get a friendly reply saying ‘Hello, there!’
Upload data to a Data Hub space
Duration is 20 min
We’ve set up the infrastructure to send messages via Twilio, now let’s upload our data to a Data Hub space for storage.
Data Hub Spaces are powerful geospatial databases that can store millions of rows. For the simplicity of this tutorial, we will only be uploading a small amount of features into our Data Hub space.
For more information about Data Hub spaces, take a look at the documentation.
There are many ways to upload data to an Data Hub space:
To upload the data to the space, use the following command:
here xyz upload YOUR_SPACE_ID -f food_pantries.geojson
Be sure to replace YOUR_SPACE_ID with the space id that was outputted when you created the space with the here xyz create command.
Now is also a good time to grab your HERE Developer token. To see your available tokens, run the following command:
here xyz token
Go ahead and copy one of these (one with reading and writing permissions), and paste it into the the server.js code, inside the const here variable.
Congrats! We’ve now created a new Data Hub space and uploaded data. To verify you’ve successfully created the space, you can run the following command:
So far, we’ve configured our SMS infrastructure (Twilio) and our database (Data Hub). Now it’s time to write some code that will handle our search logic.
We’ll want to perform the following tasks:
Transform our user received input (addresses like 425 W. Randolph Street Chicago) into coordinates using the Geocoder API.
Search for the closest food pantries in our Data Hub space by performing a distance request from the starting coordinates to the coordinates of each food pantry. This is by no means a computationally efficient method, but it is adequate for such a small dataset.
Return the top 3 closest food pantries back to the user.
For distance calculations, we will be using the as the crow flies distance. This means we will be calculating distance as the closest path between points A and B on a spherical earth, regardless of road networks. This is also known as the haversine formula.
Geocoder API
Duration is 8 min
The first task we’d like to accomplish is geocoding the user’s address input. Using the HERE Geocoding API, we can do this. Modify the app.post('/sms') to do perform the geocoding:
What we’ve done here is query all the food banks inside of the Data Hub space. So far, we’re just confirming we can access the data. In the next step, we’ll be doing some calculations with the data.
Calculate distance from origin to destination
Duration is 8 min
Since we’ll be doing a haversine formula distance calculation, we’ll employ the help of the handy turf module. turf is an open source geospatial engine for JavaScript. We’ll be using the distance function.
Inside of our second request.get() block, the xyz one, let’s insert the following code:
let features = xyzJson.features;
for (let i = 0; i < features.length; i++) {
const pantryCoordinates = features[i].geometry.coordinates;
features[i].properties.distanceFromOrigin = turf.distance(turf.point([coordinates.long,coordinates.lat]), turf.point(pantryCoordinates), {units: 'miles'});
}
features = features.sort((a,b) => a.properties.distanceFromOrigin - b.properties.distanceFromOrigin).slice(0, 3);
In the above code block, we:
loop through all the food pantries (the Data Hub space features) and calculate the distance from the origin (the coordinates of the user’s query) to the destination (the coordinates of each food pantry). The distance is outputted in miles.
sort the features based on the shortest distance.
and keep only the first 3 elements of the array (the 3 pantries with the shortest distance from origin to destination).
Construct and send the SMS message
Duration is 5 min
Now for the fun part! Sending the message back to the user. We’ve successfully calculated distances and sorted the three shortest distances to the user, but we still need to construct a nice message to send back to the user.
const output = `Here are the 3 closest food pantries near ${query}: \n\n ${features.map(x =>
`${x.properties.Name}\n${x.properties.distanceFromOrigin.toFixed(2)} miles away\n${x.properties['Phone number']}\n\n`
).join('')}`
twiml.message(output);
res.writeHead(200, {
'Content-Type': 'text/xml'
});
res.end(twiml.toString());
output is the message we’ve constructed. When rendered properly, it will look something like:
Here are the 3 closest food pantries near 425 w randolph street chicago:
Pine Avenue United Church
6.50 miles away
(773) 287-4777
Project Care
7.23 miles away
(773) 881-8296
Sanad Organization
8.06 miles away
(773) 436-7989
Finally, we send the message to the user using the Twilio code.
Review
Duration is 1 min
Congratulations! You’ve completed this tutorial!
The end result should look something like:
result
In this tutorial, you’ve learned how to:
create Data Hub spaces and upload data with the HERE command line interface.
transform addresses to coordinates with the HERE Geocoding API.
send and receive messages with Twilio.
This is just a basic example of what can be done with HERE Location Services and the Data Hub API, take a look at the HERE Developer blog to see more examples of creative and useful applications of HERE Location Services and the Data Hub API.