Trigger a Custom Webhook with a Serverless Function

Lukas Ruebbelke
InstructorLukas Ruebbelke

Share this video with your friends

Send Tweet
Published 6 months ago
Updated 5 months ago

Using serverless functions with webhooks is a commonly used modern frontend pattern. It makes integrating with services flexible and straightforward.

In this lesson we will set up a webhook in Zapier that sends a task in the request body over to Google Sheets and creates a row in a spreadsheet.

Then we will create a Lambda function that you can make a POST request to with a task in the body of the request. Once the request is made the task is parsed out of the body and posted to our Zapier URL, triggering the webhook.

Instructor: [0:01] I am really excited about this lesson. Not only because it is incredibly useful, but also because it's incredibly fun. We're going to learn about Serverless Functions in the context of webhooks and how we can use them to integrate with the real world.

[0:16] This is going to set the foundation for learning Internet of Things or Internet of awesome things. Our example is going to start in Zapier, where we're going to use a trigger webhook to kick off an action inside of a Google spreadsheet.

[0:31] Webhooks up until recently were a premium feature, but they've actually made that part of the free plan now, which is really handy. To kick this off, we are going to use a Catch Hook, which will generate a custom webhook URL, which we will use later.

[0:50] You can also make some additional adjustments to the trigger. One of which is the ability to respond with an empty body. We'll leave this unchecked and move on to testing the trigger.

[1:01] I like this a little bit more than if'd, if this then that, because you can send a test request to this endpoint here and it will pick it up. Then you can use that for a template in the rest of your integration. In this case, we're using a spreadsheet in Google Sheets.

[1:18] We're going to create a spreadsheet row, use my Gmail account. Then we're going to determine the spreadsheet, and then the worksheet within that. Then it's going to have two columns, a timestamp, and a task column where we're going to use the task off of the payload.

[1:40] From here, you can go ahead and test the action which I've already done. Doing this is a good way to ensure that your integration is up and running. We are now ready to create and deploy our Serverless Function. From our command line, let's do sls create.

[1:56] We're going to use the AWS Node.js template. We're going to call this project, Egghead Zap Webhook. We'll hit Enter. Now that this is created, we'll go ahead and step into the project and open it with VS code. Let's start with the handler.

[2:17] The first thing to do is clean up these lines here and we'll clean up this call to JSON.stringify(). We'll need to install our dependencies. We will npm i axios, which is what we're going to use to call the webhook. Then from here, we are going to import our axios dependency. Let's close this left panel to open up some space and then import our dependency.

[2:46] Next, we can create an asynchronous function called Zap, which accepts a task parameter. We are going to make a post request to our endpoint. We'll deconstruct the data property off of that response.

[3:02] Inside of this call, we'll take the task parameter and assign that to the payload object that we're sending over the wire. This first parameter, which I've intentionally left blank, is here so we can take a moment and talk about a specific technique that I like using with serverless.

[3:18] We typically do not want to allow sensitive information like keys or URLs to leak into our source code. To avoid this, we can embed these inside of the Lambda, and then access them via environment variables. In this case, process.env.zapURL, which we will set up a bit later.

[3:43] We will return this response and then parse out this event object. To do that, we'll turn it into JSON using json.parse, and then pull the task off of the object. If it doesn't exist yet, we'll just use pending for now.

[3:59] Next, we'll call Zap, take this result, pass it into this JSON.stringify() call, and format it using null and to. We will also change the name of this handler to Log. We are ready to define the serverless portion of this project. Let's open up the serverless YAML.

[4:23] As usual, get rid of all of the craft. That means we'll delete this here and we'll go ahead and delete this here as well. I feel like there should be a minimal template we can use to build our projects from because this definitely becomes a little tedious.

[4:41] Let's go ahead and change the name of the function to Log, as well as the handler reference to Log. Next, we'll add in our gateway, so events HTTP API. We'll set up our route and our method. Great. We are ready to deploy this project.

[5:01] We'll go sls deploy from the command line. We'll let the serverless framework do it's magic. It's going to generate a bunch of Cloud formation items, zip them up, put them into S3, then create the stack and validate it. Once this is complete, we are ready to test it out.

[5:20] Let's go back to the AWS Console and verify that our Lambda was created. To do that, we will Refresh the page. With a little bit of luck, we will see that our Zap hook Lambda function is in fact, in place.

[5:38] We can see here that we also have our API gateway along with our Lambda function. This is the code that we wrote in our local environment, but you'll notice here we still have this process.env.zapURL, which we still need to set up.

[5:58] Let's scroll up a bit and click on Configuration, click Edit, and click Add. Then type in the key and paste in the URL as the value. Once we click Save, we should see that we have our environment variable in place, so that when we call the Zap function, everything is in order.

[6:21] We can test this from the command line using Curl. Curl-X post, and then we'll add in a header of content type application JSON. Then on the next line, we're going to add in the data that we're going to pass in.

[6:43] This is the JSON object that we want to pass in, which will include the task and some value. In this case, we'll go with hello from the command line. Then last but not least, we'll go ahead and paste in the URL for our endpoint.

[7:04] Make sure that we have the full route and hit Enter. Hopefully, we have a successful event. Indeed we do. If we jump into our spreadsheet, we should see this event properly logged. That's awesome. We can do better.

[7:23] You probably noticed how tedious it was to write that entire Curl command from the command line. That's not something I really want to do every single time. Instead of doing that, let's wrap this in a convenience function within our terminal such as Bash, or dun, dun, da, da, Z shell.

[7:44] What we're going to do is open up our shell config file and create a function called C log for Cloud Log to reconstruct this Curl command. Most of this is the same.

[7:57] The main difference is that we have that $1 inside of our data structure, which is capturing the first argument from our command line when we call the function, so it gets passed in as the task. Let's go ahead and source our configuration file.

[8:16] Once it has been reloaded, we'll call C log and go, "Hello Demo." It looks like we have a successful event, which is very promising. Let's check inside of our Google Sheet where we can see that this event has indeed been logged.

[8:38] I think you'll find this to be a pretty convenient integration. Let's do a quick review. We are calling a webhook that we defined using axios, putting that URL inside of an environment variable that we store inside of our Lambda, and then simply parsing in our event.

[8:59] Once we get the return from Zap, we're, stringifying it, and sending it back as a response. All in all, this is a fairly quick integration. The ability to log results from a command line, and then have it go out to a Lambda, then to Zapier, then into a Google spreadsheet is pretty awesome.

[9:22] If I must say so myself, that is all there is to it.