Features:
Attack of the Helpful Chatbots
Small, Powerful, and Adorable—the Chatbot at Work
For this year’s #botweek, Ryan Pitts and I asked colleagues to pull together their favorite Slackbots, chatbots, and other small, friendly automations—and I made Ryan promise to write about BMO, our adorable yet deadly site-building Slackbot. Many thanks to Ian Dees, Jason Bartz, Chris Hagan, our own Ryan Pitts, David Yee—and to all the splendidly personable wee bots they’ve released into our world.
Issueboy, from Ian Dees
I work at Modest, where at least half of my coworkers are remote. This means we spend a huge portion of our day collaborating in Slack, keeping each other up to date on our current work progress. As a team lead, I found myself switching between a browser window with GitHub issues and Slack, helping to capture tasks and bugs as the day went on. To remove this constant context switch I got started writing a tool that connects GitHub Issues directly with Slack.
The result was Issueboy, a small Node.js app that gives you the power to create GitHub Issues directly from Slack with a simple slash-command. Now that I can quickly and easily add issues to our repos, I don’t have to lose the thread of an important conversation with a coworker to take note of a bug they reminded me about or to start tracking a new feature that my team is starting to work on. The readme located in the root of the repository can get you started quickly and easily, and once it’s installed you can interact with all of your repos that are visible to your GitBub user, not just the ones that are associated with your organization.
Chat Ops, from Jason Bartz
The Washington Post platform team is building an internal tool to deploy individual code projects inside of a cluster, to abstract away some of the ops and maintenance issues that come with code deployment.
To build and deploy code we have embraced the concept of “chat ops,” commonly popularized by GitHub. Chat ops essentially moves all of your deployment communication through a single interface, in this case a chat window. We use a bot, currently GitHub’s hubot project connected through Slack, in order to build and deploy projects.
This gets away from a command line tool, which only one person can see the output of on his or her machine, and brings the history of the project into a public timeline. This pattern achieves a lot of the same goals as an interface like a website, but allows an engineer to get notifications and respond to those notifications in real time.
So an engineer might ask hubot (whom we have expertly named “hal”):
bartz [5:49 PM] @hal list apps on wpit
And Hal will output to the chat window the apps currently running:
hal BOT [5:49 PM]
NAME | DEPLOYMENT | STAGES | IMAGE |
---|---|---|---|
hello-hal | automatic | test -> prod | hello-hal |
kafka-elasticsearch | manual | wpit | kafka-elasticsearch |
platform-tools-jenkins | automatic | jenkins | platform-tools-jenkins |
To deploy, someone would type “deploy app my_app”, and Hal will do the work to figure out which cluster “my_app” needs to be deployed to and go ahead and deploy it.
Hal also listens to things happening in chat and takes actions from those messages. For example, Hal is listening for a post commit hook from GitHub. We have hooked up GitHub to post messages into Slack when we have new commits from a project. Hal reads those messages and then, if the project is set to deploy automatically, will trigger a build. When the build finishes it will send a message to the chat window. Hal is listening for that and then will deploy the build.
Using a chatbot interface extends beyond just deployment commands. A chatbot can also be used to retrieve metrics graphs, display production alarms, and automate various other operational tasks. In a way, the chatbot becomes the single user interface for all operational tools from deployments to monitoring.
PermitBot, from Chris Hagan
The Tuesday after I moved to Chicago I went to my first OpenGov Hack Night, the city’s main civic tech meetup.
There I was introduced to Steven Vance, a Chicago transportation reporter who leads the transportation breakout group at the meetups. At the time he was building a website tracking building permits in Chicago, and was looking for another way to get out information on construction activity. Chatting after the meetup I suggested he build a twitter bot, to which he quickly replied, “Good idea. Go do it.”
And so was born PermitBot, who lives to tweet about building and demolition permits in the city of Chicago.
The bones of the bot are pretty simple (all the code is available here). Chicago publishes information on all building permits on its data portal using Socrata, which comes with an API with a JSON endpoint. Every hour we ask for the past day’s permits, check a text list of IDs for previously tweeted permits and see if the value of the permit is more than $500,000 (our cutoff for large projects). If all the conditions check out, PermitBot sends the information out into the world with a link to its page at ChicagoCityscape, the site Vance ended up creating.
Originally we looked just for big projects, but eventually added a check for demolition permits after Vance noticed a trend of teardowns (a demolition permit and building permit in the same location, usually a multi-family home becoming single family). We also ran 30 and 90-day summaries for a while, but stopped after we noticed a problem where projects got double counted when developers used the full value of a project on multiple permits.
Since sending its first tweet last March, PermitBot has tweeted more than 2,000 times. It’s tracked the re-purposing of closed Chicago schools, the renovation of Wrigley Field and LASERS. Every morning it’s another reminder of how fast the city, that can seem so static, is changing around you.
“Hey BMO, can you fetch data, transform it, git commit, and rebuild the site?” from Ryan Pitts
One of the fun things about getting ready for SRCCON is seeing all the great session ideas roll in. We publish proposals on the conference site so everyone can enjoy them (and maybe get inspired to submit their own). Last year, that meant following a tedious process: Export from our submissions database, update the data file in the site repo, pull request, merge, push to production. Every time we updated. Just so some JavaScript on the page could call in session data and display a list.
This year we have a BMO.
We knew there was plenty of room to streamline the publishing process, and we got a head start when our submissions system added an API. It was easy enough to write some Python to pull live data from that API, transforming it into a JSON file with only the fields we wanted to show. And easy enough to write a webhook that triggered that Python script with a POST request to a Heroku app.
But then we got a little more ambitious. The SRCCON website is hosted on GitHub Pages and runs on Jekyll, so if we drop JSON into a _data
directory, page templates can pull it in. We just needed a way to let a bot push proposal data into the repo, and although I’d never seen a great reason to automate git commits, with this use case, it clicked. The github3.py
library let us interact nicely with the GitHub API, and I patched it so we could send files directly into the gh-pages
branch. Which, pleasantly enough, logs a commit and triggers an automatic site rebuild, so the simple act of fetching new proposal data now puts a fresh page into production.
def commit_proposal_json(data):
# authenticate with GitHub
gh = github3.login(token=GITHUB_CONFIG_TOKEN)
# get the right repo
repo = gh.repository(GITHUB_REPO_OWNER, GITHUB_REPO_NAME)
# check to see whether data file exists
contents = repo.file_contents(
path=GITHUB_DATA_PATH,
ref=GITHUB_TARGET_BRANCH
)
if not contents:
# create file if it doesn't exist
repo.create_file(
path=GITHUB_DATA_PATH,
message='adding proposal data',
content=data,
branch=GITHUB_TARGET_BRANCH
)
else:
# update existing file
contents.update(
message='updating proposal data',
content=data,
branch=GITHUB_TARGET_BRANCH
)
The only thing left to do was to give our webhook a name so we could trigger it from Slack, our team chat app. And thus, our BMO was born.
Chatbots for Lighter Hearts, from David Yee
The viability of hilarious robots really hit its zenith with the widespread arrival of chat-based workplaces. In real life, personable, wry, and/or antic bots have proven elusive (see Small Wonder, Short Circuit, and Boston Dynamics), but the history of chat is rife with text-based automatons who leave in their wake frameworks and practices that even relatively inexperienced developers can use to add a certain corny and mechanical charm to their chat rooms. This is something you can do, which I will attempt to demonstrate here.
Let us start atop the shoulders of giants: with Hubot and Heroku. The former, a framework for chatbots brought to you by GitHub; the latter, a dead-simple platform on which to host your robot. There are, of course, many alternatives for both Hubot and Heroku, but the documentation for both these products is excellent and should prove very helpful in launching your own bots. To that end, start with the intro to Hubot, and then learn how to deploy a basic Hubot to Heroku. Even if you write no additional commands, you will be able to have a bot in your Slack, or HipChat, or Campfire, or IRC, in under an hour.
Out of the box, your robot will be able to do many things, like displaying random photos of pugs and procuring YouTube videos, but it will be curiously incapable of mangling the name of the famed British producer and actor Benedict Cumberbatch. Let me walk you through the simple two-step process of how I have corrected this egregious oversight. Feel free to follow along in the GitHub project for the simplest, most inept Benedict Cumberbatch robot ever.
Step one, make up ridiculous first and last names:
benedicts = [
"BENEDICT",
"BAILIWICK",
...
The first two long blocks in this script are just collections of misremembered versions of Cumberbatch’s first and last names-compiling these lists was incredibly fun. The reader will find that adding to these lists is technically easy, yet prosaically complex.
Step two, mix until ready:
module.exports = (robot) ->
robot.hear /benedict cumberbatch/i, (msg) ->
benedict = msg.random benedicts
cumberbatch = msg.random cumberbatches
msg.send "#{benedict} #{cumberbatch}!"
In plain English, this block reads: “HERETOFORE, something a ROBOT does! The ROBOT shall listen for mentions of the word “Benedict Cumberbatch”, and do as follows: Select a random first name and a random last name, then put them together and proclaim them to the world.”
That is pretty much all this bot does, and yet this is what it yields:
At the risk of lionizing rocket scientists, this kind of programming is definitely not rocket science, which is great, because rockets are very dangerous; by contrast, your chatbot mistakes are almost certainly going to be harmless; you will not break anything by writing a chat bot. Bots are a fantastic way to learn to program, precisely because there is so little riding on their success. Using a framework like Hubot means you have a ton of clever examples at your fingertips, and you can steal/honor all that great work in the service of your team’s amusement.
Much better work can be done than we have discussed here today. Bots should say “good morning” when greeted; They should post GIFs from Ethan Marcotte’s legendary bukk.it; They should…
This is basically like ventriloquism, but less creepy. We bring bots to chat as a safety valve for the neurosis potentially induced by living in text, and knowing that there’s always somebody in your chat to rely on. In short, think of your bot as the hilarious chat-room friend you can always rely upon to get you out of the grumps. Then, remember you invented your friend. You are pretty amazing.
Credits
-
Erin Kissane
Editor, Source, 2012-2018.