3 min read

Quick webhooks using AWS

By leveraging an AWS account or creating a webhook at no cost, you can effortlessly set up a production-ready webhook without any additional expenses
Quick webhooks using AWS

When constructing a webhook integration and needing to test various scenarios and edge cases, it is advantageous to run it outside of your development machine while still being able to access logs remotely. By leveraging an AWS account or creating one at no cost, you can effortlessly set up a production-ready webhook without any additional expenses. To create a webhook on AWS, you will need to follow a few simple steps:

Create a lambda function:

Create a simple Lambda function that will handle incoming webhook requests. You can start with a basic "Hello World" function and expand on it later in the example.

Create an API Gateway:

Start by creating a new API Gateway in your AWS account. This will serve as the endpoint for your webhook. You can configure the API Gateway to handle incoming requests and forward them to a Lambda function.

Choose your API Type.

AWS will provide you with a variety of API types. You can choose between HTTP or REST API. HTTP will be cheaper with fewer features. Please compare the differences before making a decision. If you are unsure, it is recommended to choose HTTP, as it is easier to work with for proof of concept (POC) purposes.

Attach your lambda function

When you select HTTP, the next step would be to add your integration. Choose Lambda, and search for the name of the Lambda function you created in the first step. Give it an API name for future reference.

❕If you can't find your lambda function, try changing the region.
❕The API name is not unique and is just for cosmetic reference. You can change it later on.

Press the button to Review and Create . This will allow to change a few more things. If not you can edit these later on.

  1. Update Routes; by default, it will auto-generate a route. You can click on "edit" to update the route name as well as the method. It's better to select "POST" instead of getting the webhook triggered in all routes.
  2. Stages, while you do not need to update anything here, it's good to understand this. The default stage name is $default and is set to auto deploy. The idea is that you can test changes in a different stage than prod and keep prod free from beta changes. Since this is a quick hack, you might not need it.

Find the URL

The url to your api gateway is not presented outright. You have to build it using the following template.

https://api-id.execute-api.region.amazonaws.com/stage/

  • Api-id: Head over to APIs in api gateway services. You’ll find the ID right there.
  • Region: The AWS region you are working in.
  • Stage: Skip this if you are using the default region otherwise the stage name if deployed.

e.g. it will look like the following url

https://zly82ok4uh.execute-api.us-east-1.amazonaws.com/webhook

4. Update your lambda function.

Head over to the AWS lambda service and update the code then and there

export const handler = async (event, context) => {
  console.log(event);
}

Or update the code to match whatever language you chose when creating the lambda function.


In conclusion, setting up a webhook for testing on AWS is a simple and cost-effective solution that can save you time and effort in the long run. By leveraging the power of AWS services such as API Gateway and Lambda, you can create a robust webhook system that meets your development needs. So, next time you need to test a webhook, consider creating one on AWS for free.

⚠️ For REST API: Update your passthrough.

If you chose the request validator for your API to be "Validate body, query string parameters, and headers," you will need to define a pass-through. Select your created API and go to the POST method you just created.

  1. Add all the headers you want to be checked for by marking them required
  2. Under Integration Request > Mapping Templates add in the following code picked up from the documentation. This will pass through all the body parameters through to your lambda function.
##  See https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
##  This template will pass through all parameters including path, querystring, header, stage variables, and context through to the integration endpoint via the body/payload
#set($allParams = $input.params())
{
"body-json" : $input.json('$'),
"params" : {
#foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
"$type" : {
    #foreach($paramName in $params.keySet())
    "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
        #if($foreach.hasNext),#end
    #end
}
    #if($foreach.hasNext),#end
#end
},
"stage-variables" : {
#foreach($key in $stageVariables.keySet())
"$key" : "$util.escapeJavaScript($stageVariables.get($key))"
    #if($foreach.hasNext),#end
#end
},
"context" : {
    "account-id" : "$context.identity.accountId",
    "api-id" : "$context.apiId",
    "api-key" : "$context.identity.apiKey",
    "authorizer-principal-id" : "$context.authorizer.principalId",
    "caller" : "$context.identity.caller",
    "cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
    "cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
    "cognito-identity-id" : "$context.identity.cognitoIdentityId",
    "cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
    "http-method" : "$context.httpMethod",
    "stage" : "$context.stage",
    "source-ip" : "$context.identity.sourceIp",
    "user" : "$context.identity.user",
    "user-agent" : "$context.identity.userAgent",
    "user-arn" : "$context.identity.userArn",
    "request-id" : "$context.requestId",
    "resource-id" : "$context.resourceId",
    "resource-path" : "$context.resourcePath"
    }
}