Skip to content

Publish webhook callbacks to 3rd party subscribers using Lambda, SQS and the Serverless Framework

Notifications You must be signed in to change notification settings

shotstack/serverless-webhook-publisher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Serverless Webhook Publisher

A simple service for publishing and retrying webhook POSTs to a 3rd party callback URL.

Uses AWS Lambda, SQS and the Serverless Framework. A Consumer receives messages from SQS with a payload which it POST's to a callback URL. If the callback POST fails then the message is requeued with an exponential back-off delay.


Setup

Prerequisites

  • Node.js 16
  • AWS Account

Serverless Framework

The Serverless Framework is used to deploy the application to AWS Lambda. A local version is installed as a dev dependency using NPM. Follow the Serverless AWS credentials setup guide to ensure access to AWS is configured correctly.

Add AWS Account ID

The serverless.yaml file needs to know your 12 digit [AWS Account ID] (https://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html#FindingYourAWSId).

Copy the .env.dist file and rename it to .env

cp .env.dist .env

Edit the .env file and insert your AWS ID next to AWS_ACCOUNT_ID=

Modify header name

The POST callback uses a custom headers which can be prefixed with your project or service name. Just edit the .env file and change HEADER_NAME

Add deployment bucket prefix

A deployment bucket centralizes all your Serverless deployments in to a single bucket in S3 rather than creating a new bucket for each Serverless project and each environment. Make sure the bucket exists, create it if it does not. The deployment will append the region to the bucket prefix. Edit the .env file and change DEPLOY_BUCKET_PREFIX.

Install dependencies

Install project dependencies including a local installation of the Serverless Framework

npm install

Deploy

Deploys to the dev environment by default.

npm run deploy

To deploy to a particular staging environment:

npm run deploy -- --stage [dev|stage|v1]

Note: the deployment uses the serverless-stage-manager to restrict the environments that can be created. Also the serverless-prune-plugin is used to prune old versions of Lambda functions. Edit or remove these in the serverless.yaml file to suit your deployment and environment requirements.


How it works

Worker/Consumer (src/worker.js)

The worker is a Lambda function that listens for messages in an SQS queue.

When a message is received it will try to post the message payload to the provided callback URL. If it fails, it attempts to requeue the message with a delay until the maximum amount of retries is exceeded.

Subscriber (src/subscriber.js)

The subscriber is provided as an example only. The subscriber receives the POSTed callback data and does something with it (i.e. update a database based on a value in the payload). The subscriber should be an external system somewhere on the internet.

A MOCK_SUBSCRIBER_RESPONSE_CODE environment variable is available that can be edited in the Lambda console to test requeueing or success (i.e. set to 200 for success or 500 to requeue).

Publishing Messages

Your application would usually publish a message to SQS after it has completed a long running process, process or status change (i.e. after completing a video render task). For testing you can follow the AWS SQS message sending guide to send a message via the AWS Console.

The message should be JSON formatted with the following schema:

payload: The main body/data that you want your application to POST to the subscriber.

url: The subscriber callback URL that data will be POSTed to.

eventType: An optional event type that will be sent as an X-Shotstack-Event-Type to the subscriber.

attempt: Allows the retry mechanism to keep track of the number of retries it has processed. Defaults to 1 if omitted.

Example:

{
    "payload": {
        "id": "a6d44d83-a065-4154-b421-4759acd6d4df",
        "status": "complete"
    },
    "url": "https://apigid.execute-api.ap-southeast-2.amazonaws.com/dev/mock-subscriber",
    "eventType": "render",
    "attempt": 1
}

Requeueing

If the worker receives a response error code outside the 200-399 range the message will be requeued.

An exponential back-off is used to avoid placing a burden on the server receiving the webhook callback. By default the worker will try to requeue the message 10 times with a back-off exponent of 3.

The retries will be as follows:

Attempt Back-off (sec) Back-off (min) Cumulative (sec) Cumulative (min)
1 - - 0 0
2 8 0:08 8 0:08
3 27 0:27 35 0:35
4 64 1:04 99 1:39
5 125 2:05 224 3:44
6 216 3:36 440 7:20
7 343 5:43 783 13:03
8 512 8:32 1295 21:35
9 729 12:09 2024 33:44
10 900 15:00 2924 48:44

The number of retries and exponent can be adjusted in the worker file. Note that SQS has a maximum delivery delay of 900 seconds (15 minutes).

About

Publish webhook callbacks to 3rd party subscribers using Lambda, SQS and the Serverless Framework

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published