We never know where to get lunch.
Oh, we know where we can go. But the moment our team steps outside, no one can answer “Where should we go?”
So for my second #MakeEveryWeek project, I made a bot to pick a place.
At work, we use Slack to message each other. A feature of Slack allows other programs to post messages in our chat windows using “incoming webhooks” — web addresses that accept data and then pass it into a Slack window.
Any computer on the internet can use the incoming webhook, you just need to know your team's secret webhook URL. Which I do. :-)
If you use Slack, you can get your URL by clicking on your team name and "Configure integrations." The incoming webhooks section is toward the bottom of the next list.
The bot code
My plan was:
- Start with a list of restaurants and their location.
- Pick a random number from 1 to the number of restaurants on the list.
- Grab the name and location of the restaurant in the random-numberth spot on the list.
- Send a message with that info into a Slack team channel.
- Do this at 12:30 pm every weekday.
The program I wrote is here. It's written in JavaScript and uses node and the node request module, both of which have to be installed for it to work.
In the code, I first manually entered a list of restaurant names, paired with a location link for each I copied from Google Maps.
Next, the random-number picker actually picks a number from zero to the number of restaurants minus one, because JavaScript lists are zero-based and the first restaurant is No. 0.
The "payload" includes the message, set up like Mad Libs, the turkey-leg emoji I want to use, the name of the user (Lunch Bot) and the channel to use.
And then there's some “request” business, which basically makes the program act like a web browser. Mimicking an online form of sorts, it sends the payload to the secret webhook address.
To fire it off, I just type:
node lunchbot.js
But it's a bot, and shouldn't count on me to run it on my laptop before lunch every day.
The weekday timer
Better to have bots living on their own in a computer that's running all day, ever day. So my bot code sits on a virtual computer I have in the cloud — specifically an Amazon EC2 instance.
(Sound daunting? You, too, can spin up a computer in the cloud! Really. Here's how I teach journalism students how to set one up.)
These kinds of computers have a built-in program called “cron” that lets you schedule things to run at specific times by editing a document called "crontab." To run my bot every weekday at 12:30 pm, the crontab line looks like this:
30 12 * * 1-5 /home/ubuntu/bothouse/lunchbot/cron.sh
Translation: On the 30th minute, of the 12th hour, of every day, of every month, on Mondays through Fridays, look in the /home/ubuntu/bothouse/lunchbot directory and run the cron.sh file — which runs the bot.
This actually didn’t work at first, and I learned a lot Googling around to fix it. Geeky details of how I got it going, by tweaking the permissions and the time zone, are here.
Improvements
Once that was ironed out, it worked!
This debut post (which I inadvertently fired early while testing) inspired three colleagues to go get burgers.
There are some improvements and potential features I hope to tinker with, including:
- Don’t repeat restaurants too soon. Random numbers can get randomly repetitive, and we don’t want the same suggestion two days in a row.
- If it’s cold, suggest somewhere nearby.
- If it’s warm and sunny, suggest someplace near a park that’s a little farther afield.
- Notice on Twitter when our favorite food trucks are near and suggest one of them.
- Use outgoing web hooks to allow someone to add a restaurant from within Slack.
- "Not interested in that today, Lunch Bot. Hit us with another."
- Pick brand-new restaurants based on the ones we like. (Requested by @veltman.)
But for a quick #MakeEveryWeek project, I learned a bunch and I’m happy with it.
Image: Greenwich Village streetscape, by Adam Fagen on Flickr