{"id":18907189,"url":"https://github.com/42atomys/webhooked","last_synced_at":"2025-04-15T04:31:55.710Z","repository":{"id":37010495,"uuid":"457914620","full_name":"42atomys/webhooked","owner":"42atomys","description":"A webhook receiver on steroids.","archived":false,"fork":false,"pushed_at":"2024-11-24T12:34:04.000Z","size":855,"stargazers_count":39,"open_issues_count":7,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-28T16:22:08.762Z","etag":null,"topics":["apps","golang","hacktoberfest","webhooks"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/42atomys.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["42Atomys"]}},"created_at":"2022-02-10T19:14:31.000Z","updated_at":"2025-03-21T03:19:43.000Z","dependencies_parsed_at":"2023-02-12T18:15:16.267Z","dependency_job_id":"b0e51048-8cbf-4c0e-873e-ce957599976d","html_url":"https://github.com/42atomys/webhooked","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/42atomys%2Fwebhooked","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/42atomys%2Fwebhooked/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/42atomys%2Fwebhooked/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/42atomys%2Fwebhooked/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/42atomys","download_url":"https://codeload.github.com/42atomys/webhooked/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249006491,"owners_count":21197283,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["apps","golang","hacktoberfest","webhooks"],"created_at":"2024-11-08T09:20:01.821Z","updated_at":"2025-04-15T04:31:54.959Z","avatar_url":"https://github.com/42atomys.png","language":"Go","funding_links":["https://github.com/sponsors/42Atomys"],"categories":["Webhooks Server"],"sub_categories":["Utility/Miscellaneous"],"readme":"\u003ch1 align=\"center\"\u003eWebhooked\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\u003ca href=\"https://github.com/42Atomys/webhooked/actions/workflows/release.yaml\"\u003e\u003cimg src=\"https://github.com/42Atomys/webhooked/actions/workflows/release.yaml/badge.svg\" alt=\"Release 🎉\"\u003e\u003c/a\u003e\n\u003ca href=\"https://goreportcard.com/report/atomys.codes/webhooked\"\u003e\u003cimg src=\"https://goreportcard.com/badge/atomys.codes/webhooked\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://codeclimate.com/github/42Atomys/webhooked\"\u003e\u003cimg alt=\"Code Climate maintainability\" src=\"https://img.shields.io/codeclimate/maintainability/42Atomys/webhooked\"\u003e\u003c/a\u003e\n\u003ca href=\"https://codecov.io/gh/42Atomys/webhooked\"\u003e\u003cimg alt=\"Codecov\" src=\"https://img.shields.io/codecov/c/gh/42Atomys/webhooked?token=NSUZMDT9M9\"\u003e\u003c/a\u003e\n\u003cimg src=\"https://img.shields.io/github/v/release/42atomys/webhooked?label=last%20release\" alt=\"GitHub release (latest by date)\"\u003e\n\u003cimg src=\"https://img.shields.io/github/contributors/42Atomys/webhooked?color=blueviolet\" alt=\"GitHub contributors\"\u003e\n\u003cimg src=\"https://img.shields.io/github/stars/42atomys/webhooked?color=blueviolet\" alt=\"GitHub Repo stars\"\u003e\n\u003ca href=\"https://hub.docker.com/r/atomys/webhooked\"\u003e\u003cimg src=\"https://img.shields.io/docker/pulls/atomys/webhooked\" alt=\"Docker Pull\"\u003e\u003c/a\u003e\n\u003ca href=\"https://hub.docker.com/r/atomys/webhooked\"\u003e\u003cimg src=\"https://img.shields.io/docker/image-size/atomys/webhooked\" alt=\"Docker Pull\"\u003e\u003c/a\u003e\n\u003ca href=\"https://pkg.go.dev/atomys.codes/webhooked\"\u003e\u003cimg src=\"https://pkg.go.dev/badge/atomys.codes/webhooked.svg\" alt=\"Go Reference\"\u003e\u003c/a\u003e\u003c/p\u003e\n  \n\u003cp align=\"center\"\u003eA webhook receiver on steroids. The process is simple, receive webhook from all over the world, and send it to your favorite pub/sub to process it immediately or later without losing any received data\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"/.github/profile/webhooked.png\" alt=\"Webhooked explained\"\u003e\u003c/p\u003e\n\n## Motivation\n\nWhen you start working with webhooks, it's often quite random, and sometimes what shouldn't happen, does. **One or more data sent by a webhook is lost because our service did not respond, or worse to crash**. That's why very often it's better to make a small HTTP server that only receives and conveys the information to another service that will process the information.\n\nThis is exactly what `Webhooked` does !\n\n## Roadmap\n\nI am actively working on this project in order to release a stable version for **2025**\n\n![Roadmap](/.github/profile/roadmap.png)\n\n## Usage\n\n### Step 1 : Configuration file\n```yaml\napiVersion: v1alpha1\n# List of specifications of your webhooks listerners.\nspecs:\n- # Name of your listener. Used to store relative datas and printed on log\n  name: exampleHook\n  # The Entrypoint used to receive this Webhook\n  # In this example the final url will be: example.com/v1alpha1/webhooks/example\n  entrypointUrl: /webhooks/example\n  # Security factories used to verify the payload \n  # Factories is powerful and very modular. This is executed in order of declaration\n  # and need to be ended by a `compare` Factory.\n  #\n  # In this example we get the header `X-Hook-Secret` and compare it to a static\n  # value. If the header value is equals to `test`, `foo` or `bar`, or the value\n  # contained in SECRET_TOKEN env variable, the webhook is process. \n  # Else no process is handled and http server return a 401 error\n  #\n  # If you want to use insecure (not recommended), just remove security property\n  security:\n  - header:\n      inputs:\n      - name: headerName\n        value: X-Hook-Secret\n  - compare:\n      inputs:\n      - name: first\n        value: '{{ Outputs.header.value }}'\n      - name: second\n        values: ['foo', 'bar']\n        valueFrom:\n          envRef: SECRET_TOKEN\n  \n  # Formatting allows you to apply a custom format to the payload received\n  # before send it to the storage. You can use built-in helper function to\n  # format it as you want. (Optional)\n  #\n  # Per default the format applied is: \"{{ .Payload }}\"\n  # \n  # THIS IS AN ADVANCED FEATURE :\n  # Be careful when using this feature, the slightest error in format can\n  # result in DEFFINITIVE loss of the collected data. Make sure your template is\n  # correct before applying it in production.\n  formatting:\n    templateString: |\n      {\n        \"config\": \"{{ toJson .Config }}\",\n        \"metadata\": {\n          \"specName\": \"{{ .Spec.Name }}\",\n          \"deliveryID\": \"{{ .Request.Header | getHeader \"X-Delivery\" | default \"unknown\" }}\"\n        },\n        \"payload\": {{ .Payload }}\n      }\n\n  # Storage allows you to list where you want to store the raw payloads\n  # received by webhooked. You can add an unlimited number of storages, webhooked\n  # will store in **ALL** the listed storages\n  # \n  # In this example we use the redis pub/sub storage and store the JSON payload\n  # on the `example-webhook` Redis Key on the Database 0\n  storage:\n  - type: redis\n    # You can apply a specific formatting per storage (Optional)\n    formatting: {}\n    # Storage specification\n    specs:\n      host: redis.default.svc.cluster.local\n      port: 6379\n      database: 0\n      key: example-webhook\n\n\n  # Response is the final step of the pipeline. It allows you to send a response\n  # to the webhook sender. You can use the built-in helper function to format it\n  # as you want. (Optional)\n  #\n  # In this example we send a JSON response with a 200 HTTP code and a custom\n  # content type header `application/json`. The response contains the deliveryID\n  # header value or `unknown` if not present in the request.\n  response:\n    formatting:\n      templateString: |\n        {\n          \"deliveryID\": \"{{ .Request.Header | getHeader \"X-Delivery\" | default \"unknown\" }}\"\n        }\n    httpCode: 200\n    contentType: application/json\n```\n\nMore informations about security pipeline available on wiki : [Configuration/Security](https://github.com/42Atomys/webhooked/wiki/Security)\n\nMore informations about storages available on wiki : [Configuration/Storages](https://github.com/42Atomys/webhooked/wiki/Storages)\n\nMore informations about formatting available on wiki : [Configuration/Formatting](https://github.com/42Atomys/webhooked/wiki/Formatting)\n\n### Step 2 : Launch it 🚀\n### With Kubernetes\n\nIf you want to use kubernetes, for production or personnal use, refere to example/kubernetes:\n\nhttps://github.com/42Atomys/webhooked/tree/main/examples/kubernetes\n\n\n### With Docker image\n\nYou can use the docker image [atomys/webhooked](https://hub.docker.com/r/atomys/webhooked) in a very simplistic way\n\n```sh\n# Basic launch instruction using the default configuration path\ndocker run -it --rm -p 8080:8080 -v ${PWD}/myconfig.yaml:/config/webhooked.yaml atomys/webhooked:latest\n# Use custom configuration file\ndocker run -it --rm -p 8080:8080 -v ${PWD}/myconfig.yaml:/myconfig.yaml atomys/webhooked:latest serve --config /myconfig.yaml\n```\n\n### With pre-builded binary\n\n```sh\n./webhooked serve --config config.yaml -p 8080\n```\n\n## To-Do\n\nTO-Do is moving on Project Section: https://github.com/42Atomys/webhooked/projects?type=beta\n\n# Contribution\n\nAll pull requests and issues on GitHub will welcome.\n\nAll contributions are welcome :)\n\n## Thanks\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F42atomys%2Fwebhooked","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F42atomys%2Fwebhooked","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F42atomys%2Fwebhooked/lists"}