{"id":40531774,"url":"https://github.com/shotstack/serverless-webhook-publisher","last_synced_at":"2026-01-20T22:04:29.415Z","repository":{"id":43964578,"uuid":"239247742","full_name":"shotstack/serverless-webhook-publisher","owner":"shotstack","description":"Publish webhook callbacks to 3rd party subscribers using Lambda, SQS and the Serverless Framework","archived":false,"fork":false,"pushed_at":"2023-11-22T01:36:48.000Z","size":535,"stargazers_count":2,"open_issues_count":4,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2023-11-22T02:26:30.392Z","etag":null,"topics":["lambda","serverless-framework","sqs","webhook-service","webhooks"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shotstack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-02-09T04:41:23.000Z","updated_at":"2023-11-22T02:26:31.368Z","dependencies_parsed_at":"2023-02-15T05:00:59.090Z","dependency_job_id":null,"html_url":"https://github.com/shotstack/serverless-webhook-publisher","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/shotstack/serverless-webhook-publisher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shotstack%2Fserverless-webhook-publisher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shotstack%2Fserverless-webhook-publisher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shotstack%2Fserverless-webhook-publisher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shotstack%2Fserverless-webhook-publisher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shotstack","download_url":"https://codeload.github.com/shotstack/serverless-webhook-publisher/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shotstack%2Fserverless-webhook-publisher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28615581,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T21:52:42.722Z","status":"ssl_error","status_checked_at":"2026-01-20T21:52:20.513Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lambda","serverless-framework","sqs","webhook-service","webhooks"],"created_at":"2026-01-20T22:04:28.642Z","updated_at":"2026-01-20T22:04:29.408Z","avatar_url":"https://github.com/shotstack.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Serverless Webhook Publisher\n\n### A simple service for publishing and retrying webhook POSTs to a 3rd party callback URL.\n\nUses AWS Lambda, SQS and the Serverless Framework. A Consumer receives messages from SQS with a payload which it POST's\nto a callback URL. If the callback POST fails then the message is requeued with an exponential back-off delay.\n\n-----\n\n## Setup\n\n### Prerequisites\n\n- Node.js 16\n- AWS Account\n\n### Serverless Framework\n\nThe Serverless Framework is used to deploy the application to AWS Lambda. A local version is installed as a dev \ndependency using NPM. Follow the Serverless AWS credentials\n[setup guide](https://www.serverless.com/framework/docs/providers/aws/guide/credentials) to ensure access to AWS is\nconfigured correctly.\n\n### Add AWS Account ID\n\nThe [serverless.yaml](serverless.yaml) file needs to know your 12 digit [AWS Account ID]\n(https://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html#FindingYourAWSId).\n\nCopy the `.env.dist` file and rename it to `.env`\n\n```\ncp .env.dist .env\n```\n\nEdit the .env file and insert your AWS ID next to `AWS_ACCOUNT_ID=`\n\n### Modify header name\n\nThe POST callback uses a custom headers which can be prefixed with your project or service name. Just edit the \n.env file and change `HEADER_NAME`\n\n### Add deployment bucket prefix\n\nA deployment bucket centralizes all your Serverless deployments in to a single bucket in S3 rather than creating a new\nbucket for each Serverless project and each environment. Make sure the bucket exists, create it if it does not. The\ndeployment will append the region to the bucket prefix. Edit the .env file and change `DEPLOY_BUCKET_PREFIX`.\n\n### Install dependencies\n\nInstall project dependencies including a local installation of the Serverless Framework\n\n```\nnpm install\n```\n\n### Deploy\n\nDeploys to the `dev` environment by default.\n\n```\nnpm run deploy\n```\n\nTo deploy to a particular staging environment:\n\n```\nnpm run deploy -- --stage [dev|stage|v1]\n```\n\nNote: the deployment uses the \n[serverless-stage-manager](https://www.npmjs.com/package/serverless-stage-manager) \nto restrict the environments that can be created. Also the \n[serverless-prune-plugin](https://www.npmjs.com/package/serverless-prune-plugin) \nis used to prune old versions of Lambda functions. Edit or remove these in the \n**serverless.yaml** file to suit your deployment and environment requirements.\n\n-----\n\n## How it works\n\n### Worker/Consumer ([src/worker.js](src/worker.js))\n\nThe worker is a Lambda function that listens for messages in an SQS queue.\n\nWhen a message is received it will try to post the message payload to the provided \ncallback URL. If it fails, it attempts to requeue the message with a delay \nuntil the maximum amount of retries is exceeded.\n\n### Subscriber ([src/subscriber.js](src/subscriber.js))\n\nThe subscriber is provided as an example only. The subscriber receives the POSTed \ncallback data and does something with it (i.e. update a database based on a value \nin the payload). The subscriber should be an external system somewhere on the \ninternet.\n\nA `MOCK_SUBSCRIBER_RESPONSE_CODE` environment variable is available that can be \nedited in the Lambda console to test requeueing or success (i.e. set to 200 for\nsuccess or 500 to requeue).\n\n### Publishing Messages\n\nYour application would usually publish a message to SQS after it has completed a \nlong running process, process or status change (i.e. after completing a video \nrender task). For testing you can follow the \n[AWS SQS message sending guide](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-send-message.html) \nto send a message via the AWS Console.\n\nThe message should be JSON formatted with the following schema:\n\n**payload:** The main body/data that you want your application to POST to the subscriber.\n\n**url:** The subscriber callback URL that data will be POSTed to.\n\n**eventType:** An optional event type that will be sent as an `X-Shotstack-Event-Type` to the subscriber.\n\n**attempt:** Allows the retry mechanism to keep track of the number of retries it has processed. Defaults to `1` if omitted.\n\n#### Example:\n```\n{\n    \"payload\": {\n        \"id\": \"a6d44d83-a065-4154-b421-4759acd6d4df\",\n        \"status\": \"complete\"\n    },\n    \"url\": \"https://apigid.execute-api.ap-southeast-2.amazonaws.com/dev/mock-subscriber\",\n    \"eventType\": \"render\",\n    \"attempt\": 1\n}\n```\n\n-----\n\n## Requeueing\n\nIf the worker receives a response error code outside the 200-399 range the \nmessage will be requeued.\n\nAn exponential back-off is used to avoid placing a burden on the server \nreceiving the webhook callback. By default the worker will try to requeue \nthe message 10 times with a back-off exponent of 3.\n\nThe retries will be as follows:\n\n| Attempt | Back-off (sec) | Back-off (min) | Cumulative (sec) | Cumulative (min)\n|---|---|---|---|---\n| 1 | - | - | 0 | 0\n| 2 | 8 | 0:08 | 8 | 0:08\n| 3 | 27 | 0:27 | 35 | 0:35\n| 4 | 64 | 1:04 | 99 | 1:39\n| 5 | 125 | 2:05 | 224 | 3:44\n| 6 | 216 | 3:36 | 440 | 7:20\n| 7 | 343 | 5:43 | 783 | 13:03\n| 8 | 512 | 8:32 | 1295 | 21:35\n| 9 | 729 | 12:09 | 2024 | 33:44\n| 10 | 900 | 15:00 | 2924 | 48:44\n\nThe number of retries and exponent can be adjusted in the worker file. Note that \nSQS has a maximum delivery delay of 900 seconds (15 minutes).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshotstack%2Fserverless-webhook-publisher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshotstack%2Fserverless-webhook-publisher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshotstack%2Fserverless-webhook-publisher/lists"}