01-05-2021



In my last blog post, I have written about how to turn a Raspberry Pi into a serverless platform with the lightweight OpenFaaS implementation faasd. If you haven't checked it out already, you can find the link to the post below:

Spunky, It's all you need. Using Slack with your team? Learn how to use Slack more efficiently with these tips, shortcuts, and Slack apps. Get more done in less time!

Please note that a Raspberry Pi is not required here.
faasd can be installed without issues on any other machine or cloud instance as well.
This blog post from Alex Ellis describes how to build a faasd serverless appliance on DigitalOcan:
https://blog.alexellis.io/deploy-serverless-faasd-with-cloud-init/

I did that only as a small hobby project. But then, I wanted to use this setup for a real-world use case, and also use the opportunity to try another useful open-source project which is inlets.

Inlets is a cloud native tunnel that allows you to expose private endpoints to the Internet. In this case, it will be used to expose the OpenFaaS gateway running on my Raspberry Pi board to receive incoming Stripe Webhook events and dispatch them to the relevant function.

For more details about inlets, check the official docs and resources available at https://docs.inlets.dev/

So in this post, I will describe how I built a local OpenFaaS function that serves as a Stripe webhook. This function simply sends a Slack notification for every new charge.succeeded event.

The architecture

Inlets is an open source HTTP tunnel which we can use to get a public IP address to receive webhooks. The inlets client will be running on the Raspberry Pi and connects to the inlets server using a websocket connection to listen for any incoming requests.

In our setup, every Stripe webhook event that is received by the inlets client will be forwarded to the OpenFaaS gateway on the Raspberry Pi, which will in turn trigger the stripe-slack-notifier function to send a new Slack notification.

Stripe Slack

Preparing the Setup

Obtain an exit node with inlets

First, make sure you have created an inlets exit server following this nice guide by Alex Ellis:

Wide Striped Slacks

This would allow you to have an exit node with a public domain that can be used for receiving webhook events. In the setup described earlier, the inlets client is running on the Raspberry Pi, so I have chosen the upstream to be http://127.0.0.1:8080, which is the OpenFaaS Gateway URL.

Using the token provided by the inlets server, the command below exposes the OpenFaaS Gateway to the Internet:

Our function will then be available from the Internet using the https://${REMOTE_EXIT_NODE}/function/stripe-slack-notifier

Add a Stripe Webhook

We need to add a new Stripe webhook using the

Create a Slack App

To receive incoming webhooks we need to create an App in the Slack dashboard.

Create a function to receive webhooks from Stripe

The function stripe-slack-notifier was built using the python3-http template that is available in the OpenFaaS template store. Ux50v driver.

Creating a new function using faas-cli new

The final source code for the function can be found in this Github repository:

Pinstripe slacks

The function is written in python. It will verify the received payload using the Stripe API key and the webhook singing secret, and then send a slack notification:

OpenFaaS secrets are used to pass the following data to the function:

  • Stripe API key
  • Webhook signing secret
  • Slack Webhook URL

So they need to be created manually with faas-cli before deploying the function:

Building & deploying the function

Since the function will be running on Raspberry Pi, we need to build the Docker image for armv7.
Fortunately, this has become easier with the multi platform builds feature by buildx available in docker v19.03.

But since we have already exposed our OpenFaaS gateway using inlets, we can use Github Actions to build and deploy the latest version of our function to the Raspberry Pi with every git push. The workflow file used to automate this can be found here.

Manually, this can be achieved with the following steps:

  1. Generate the Docker build context for the function

2. This step is not needed if using Docker for desktop as this would be done automatically for you. On Linux, we need to register other platforms like armv7 with the kernel using the docker/binfmt image:

3. Create a new builder for buildx

4. Finally build and push the image for both armv7 and amd64 platforms:

A new Docker image is now available on the Docker registry for both amd64 and armv7 architectures:

Stripe Slack

To deploy the function to the Raspberry Pi, we can finally run the command below from our laptop:

Test the function

Check the status of the function with faas-cli describe

We can test that it's now by triggering some test events from the Stripe dashboard:

Slack

After a few moments, we can see a similar message in Slack:

The function only supports charge.succeeded Stripe events for now, so any other type of event will receive Unsupported event type error from the function, and no Slack messages will be sent.

Conclusion

In this blog post, I have described how we can create a serverless webhook handler for Stripe API events using faasd and inlets.

As we have seen in this post, faasd can be a great alternative to running OpenFaaS without the need for managing a Kubernetes or Docker Swarm cluster. Combined with inlets, they can be used together for running and exposing functions for real-world use cases.

Stripe Slack Webhook

Things that you might want to do next:

Side Stripe Slacks

Stripe slacks

Baseball Stripe Slacks

  • Join the OpenFaaS community on slack
  • Extend the mehyedes/stripe-slack-notifier function to support other webhook event types
  • Build a faasd serverless appliance on a cloud instance using cloud-init (see deploy-serverless-faasd-with-cloud-init)
  • Try out the inlets-operator for getting public IP addresses for your local kubernetes cluster