How I created a Food Recommendation Bot

Shem Leong
4 min readDec 14, 2016

--

The last encounter I had with a chatbot, I was in a Warcraft 3 Battle.net channel answering movie trivia questions. For a while, chatbots languished in obscurity as most could only hold simple conversations. Now, chatbots are back with a vengeance — you can order pizza through them or even talk to the dead.

Food has always been my passion and an obsession. A perennial problem I face is deciding what to eat for lunch. So one day after having a rather one-sided conversation with @atwherebot, which did look rather promising, I decided to try my hand at making my own food recommendation bot. The dream was to aggregate data on good eats from the credible local food review sites/blogs — sorry Google Places, you’re not one of them. Hence, @e8tbot (formerly Coconut, still pending that Facebook name change…) was born!

Shameless advertising

Without much prior programming experience, my stack consisted of tools that were simple enough for me to pick up. I ended up with Node.js for my app server, MongoDB for my database, LUIS for Natural Language Processing and the Microsoft Bot Framework SDK to glue them all together. Although Bot Framework allows easy integration with various messaging apps, I only published on Facebook Messenger because I liked the look and feel best. For app hosting, I used Heroku.

In this article, I won’t go through the steps of building a bot, there’s a ton of useful articles out there that go into the details. I assume you have some experience with Bot Framework so I’ll just go through the key concepts.

Local Development

After you have registered your bot on the Bot Framework, Facebook Pages/Developer, you can set up a secure tunnel to your local server with ngrok. This way, you can immediately test changes to your app via the Facebook Messenger Client without having to deploy to Heroku.

Install ngrok then run this in your command prompt: ngrok http 3978 . Copy the ngrok url and access your bot’s page to fill in the messaging endpoint with:

https://<your-ngrok-url>/api/messages

Next, hit the blue Test button! If all goes well, you should see this:

Ping your server

ngrok also provides a cool web interface, accessible via localhost:4040, which allows you to inspect the requests/responses going through the tunnel.

Even better still is to pair this with nodemon, which is a nifty tool that watches for changes in your code and automatically restarts the server. To make development a breeze, I have also set up a gulp pipeline that transpiles ES6, triggers a nodemon reset and then supplies development environmental variables to my app.

Obtaining User’s Location

Send Location Prompt

One of the key features of my bot is that it can make food recommendations based on the user’s location. The challenge is that you can’t retrieve a user’s location directly. Instead, the user has to send you his/her location before you can extract it from the message body. What you can do is to set up Quick Replies:

https://gist.github.com/lyzs90/b780166c8710ebaf5cbbcd7cd3f3a52e

Carousel to Display Recommendations

Carousel of Cards

After parsing the location, I do MongoDB’s nearSphere geospatial query and order the results based on proximity (there’s no fancy shenanigans like collaborative filtering going on, yet).

Because Facebook has a limit on the number of items that can be displayed in a carousel, I perform two MongoDB queries. The first is a count query to get the total number of records and we store that in the session.userData object. The latter is a find query which does the actual document retrieving, but I limit the retrieval to a maximum of 5 elements. You can maintain a cursor which keeps track of how many elements the user has seen so far. This was when I realized how useful promises (I used bluebird) were in ensuring that the queries were fired in the right order.

To create the carousel, you’ll need to instantiate multiple HeroCard objects and then chuck them into an array.

https://gist.github.com/lyzs90/998584993395fbb23dd43c061caa0b22

Next Steps

I’m still figuring out the NLP bit, especially how to train the AI more efficiently. It’s feeling a bit manual for me now. Most utterances I suspect are going to be single/double words such as laksa chicken rice korean food. They probably wouldn’t type long sentences which the AI needs to recognize the entities/sub-entities. I’m also thinking of shifting to something like Wit.ai because it seems more user friendly (the Azure Portal is pretty hellish to navigate).

I’ll leave you here for now, if you have any suggestions/tips, feel free to leave a comment below (:

--

--

Shem Leong
Shem Leong

Written by Shem Leong

Software engineer and indieparent • Building a applimiter.com in public

Responses (6)