Super Chemex Bot: IoT and love of coffee combined

Published
September 27, 2017
Category

Product

At Contentful, we drink a lot of coffee. And while there are many ways to brew coffee, Chemex is one of our favorites. It’s fun, simple, and you can make enough for the whole team.

Chemex container with pourer

Back when everyone sat in one small office, we had an actual doorbell in the kitchen. Whenever someone made a fresh batch of Chemex, they’d ring the bell, and regardless of where you were in the office, you could hear it. But over the past two years, the company has grown, and that solution didn’t scale.

Our Berlin office spans multiple floors and adjacent buildings, with each floor featuring its own kitchen and a dedicated Slack channel for communication. We wanted a button in every kitchen to post a notification to that area’s Slack channel when there's coffee available.

We got our hands on some AWS IoT buttons—the programmable version of Amazon Dash buttons—and decided to hack a solution. The basic idea was to have the button trigger an AWS Lambda function that would then emit a message to the right channel using the Slack API. We stored our configurations, such as mappings between buttons and Slack channels, along with the content of the messages in Contentful. This allows anyone to change these around without pushing code each time.

The first step was to register each Dash button with the AWS IoT platform. This process involved connecting a computer to the button’s wifi network and following the wizard to generate a certificate and private key. Then we copied those onto the button.

Next, we switched over to the Lambda dashboard in AWS and created a new function. We selected Node.js as the runtime so we could use the Slack and Contentful JavaScript SDKs. Under Triggers, we added each configured button as a trigger to this function. Now our Lambda function will receive the button press event as an argument. CloudWatch shows us that when the button is pressed, our function is called. Awesome!

After that, we set up the data in Contentful. We created two content types—Configuration and Message. Each configuration entry contains the button’s serial number and its respective Slack channel's name. Each message contains the text—and our bot will pick one at random to post on the Slack channel. The entries look like so:

We created our Slack application, gave it a name, description, and permissions. Then we copied the generated client ID and secret into Lambda environment variables.

The final step was to finish writing the Lambda function. It goes something like this:

javascript
exports.handler = (event) => {
  // Fetch data from Contentful containing all configs and messages
  contentfulClient.getEntries()
  .then(prepareContentfulData)
  .then(({ configs, messages }) => {
    const { channel } = configs[event.serialNumber]

    // Select a message at random from the list
    const { message } = messages[Math.floor(Math.random() * messages.length)]

    // Post it to slack
    slackWebClient.chat.postMessage(channel, message)
  })
}

We pushed the code to Lambda with the AWS CLI tool, and glued the first button to the table in the kitchen of the engineering floor and went home. The next morning we announced it on Slack.

Allowing everyone to come up with new messages sparked some creativity.

Since we deployed this to the engineering floor in April, our team pressed that one button 275 times. The average Chemex is around 900mL. That’s almost 250 liters of coffee in 4.5 months on just one floor. Not bad!

If you want your own Chemex Button, you can check out the code on GitHub. Or if you’re in Berlin, swing by our office and have a coffee with us.

About the authors
Don't miss the latest
Get updates in your inbox
A monthly newsletter to help you build better digital experiences with Contentful.
add-circle remove style-two-pin-marker subtract-circle