Bringing our Comic Relief Values to life with IoT, Amplify and Serverless

Peter Vanhee
Dec 6, 2019 · 4 min read

Seven values, from “Break down Barriers”, to “Have a sense of humour, always”, together with a wish from our director Charlotte to bring our values to life, proved to be enough inspiration to spend a fun afternoon hacking together a live values dashboard.

The idea? Put an Amazon Dash button on each card, make people vote for the value they’ll carry out throughout the day by pushing the button on the card when they enter the office, and display a live dashboard of “most voted values”.

While our dashboard certainly piqued the interest of colleagues, ranging from “this is cool!”, to mild curiosity, to “what the hell is this?”, we really did this as a fun exercise in turning a simple idea into an actual scalable product in a short time frame and using our familiar serverless stack.

Image for post
Image for post
Our seven Comic Relief Values.

Our tools

  • Seven AWS IoT enterprise buttons we purchased and registered to our AWS account, with each button associated to one of our seven values.
  • A DynamoDB table to store all the votes
  • AWS AppSync, so we can use GraphQL to update our DynamoDB table and streams updates to the front-end using subscriptions
  • A Lambda function which connects the IoT button click and runs a GraphQL mutation update DynamoDB
  • A ReactJS front-end bootstrapped using create-react-app and using our Comic Relief component library.

Real-time values dashboard

Image for post
Image for post
The dashboard in action.

It takes approximate 3–4 seconds from button push to dashboard update, and most of that time is spent by the dash button connecting to the WiFi and sending the payload to the Lambda function, with <1sec to update DynamoDB and stream the updates to the front-end.

Image for post
Image for post
In real life.

To get some insight into usage, we hooked it up to Serverless dashboard which will send out alerts to Slack when there is lots of activity.

Image for post
Image for post
Using Serverless dashboard to get a bit of insight into button pushes.

How we built it

Image for post
Image for post
Architecture diagam.

First of all, let’s initialise our app

# Create a new react app
npx create-react-app cr-values
cd cr-values
# Initialize amplify
amplify init

Now, adding a GraphQL API is as simple as

amplify add api

The only input you need to give is the GraphQL schema, which in our case was really simple. We associate a random ID with a buttonType (any of the seven values), a clickType (single click, double click or long click), and a timestamp.

type ButtonPush @model {
id: ID!
buttonType: String!
clickType: String
created: AWSTimestamp
}

Amplify automatically handles the entire API creation, and generates GraphQL queries, mutations and subscriptions you can use in your ReactJs front-end.

Now, we need to connect button pushes to a GraphQL mutation using Lambda. The event contains which button was pushed, and the clickType. We then send this to GraphQL using the aws-appsync SDK.

const push = async (event, context) => {
const { placementInfo, deviceEvent } = event;

const mutation = gql`
mutation createButtonPush {
createButtonPush(input: {
id: "${uuid()}",
buttonType: "${placementInfo.attributes.buttonType}",
clickType: "${deviceEvent.buttonClicked.clickType}",
created: ${new Date().getTime()}
}) {
id
buttonType
clickType
created
}
}
`;

await graphqlClient.mutate({ mutation });
return {
statusCode: 200,
body: 'Button clicked',
}),
};
export default push;

For our front-end, we have a simple React component which uses the useEffect hook to run a subscription operation and store button pushes using useState so we can re-render our component.

const [newPushes, setNewPushes] = useState([]);useEffect(() => {
API.graphql(
graphqlOperation(subscriptions.onCreateButtonPush)
).subscribe({
next: (todoData) => setNewPushes(todoData.value.data.onCreateButtonPush)
});
}, []);

The actual code is a little more complicated, as we use another effect to run GraphQL list operation to populate initial state, and re-render upon changes of the newPushes.

And that’s all — we proved that with the right tooling it’s incredibly quick to build something useable. We’re excited about this tech stack (AWS Amplify is something I’ll personally explore a lot more going forward) and will certainly do a few more iterations with our colleagues.

Image for post
Image for post
Dashboard snapshot.

Massive thanks to Adam Clark and Gustavo Liedke for building this together in an afternoon and learning from each other, and Charlotte Hillenbrand for launching our Comic Relief values and providing us with the inspiration to build this.

Comic Relief Technology

This is where we showcase the ways that we are use…

Peter Vanhee

Written by

Passionate technologist. Founder and director @marzeelabs @weareserverless. ex-head of technology @comicrelief

Comic Relief Technology

This is where we showcase the ways that we are use technology to support the core aims of our organisation and how we do it.

Peter Vanhee

Written by

Passionate technologist. Founder and director @marzeelabs @weareserverless. ex-head of technology @comicrelief

Comic Relief Technology

This is where we showcase the ways that we are use technology to support the core aims of our organisation and how we do it.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store