https://github.com/lachee/webhook-publisher
Publishes Webhook events behind the scenes, freeing your frontend.
https://github.com/lachee/webhook-publisher
Last synced: 27 days ago
JSON representation
Publishes Webhook events behind the scenes, freeing your frontend.
- Host: GitHub
- URL: https://github.com/lachee/webhook-publisher
- Owner: Lachee
- License: mit
- Created: 2021-03-10T06:44:32.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-04-26T01:13:45.000Z (about 3 years ago)
- Last Synced: 2025-03-20T07:46:13.588Z (about 1 year ago)
- Language: JavaScript
- Size: 94.7 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Webhook Publisher
Publishes Webhook events behind the scenes, freeing your frontend.
This microservice handles publishing webhook events to numerous clients without slowing down the event emitter. A fire and forget solution that requires minimal setup and no external "subscription" is required for your API consumers, you simply tell it what endpoints to hit.
[Example Video (mp4)](https://i.lu.je/2021/IOxRsiMx01.mp4)
This is particularlly useful if you have a web service written in a language like PHP, and you wish to execute your API consumer's webhooks on a user action. You dont want to wait around for your slow consumer servers before responding to the user.
# Terminology
* `Publisher` is your web service that is emitting the events
* `Hook` is the consumer of your service's webhook feature. They are the individual webhooks
* `Publication`, `Event` these mean the same thing. They are the event you send.
* `WHPUB`, `Service` this application
# Usage
## Signatures
The usage is fairly straight forward, but for security purposes its important you setup 2 seperate RSA keys before hand:
1. Your Publisher (private) -> WHPUB (public)
2. The WHPUB (private) -> Hook (public)
Ensure you have the appropriate WHPUB keys configured in the .env. These are used to verify signatures and then later on, generate signatures.
## Running
Running is straight forward:
`node src/index.mjs`
## Configuration
The configuration is likely to change as this project gets developed. Initially, there can only be one Publisher, but that is a lack of configuration infrastructure.
In the meantime, all the configuration is managed by the .env
| Key | Description |
|-----|-------------|
| PORT | Port of the WHPUB Service (If using the WebService). |
|PUBLISHER_NAME| The name of the first default publisher. Used for authorization. |
|PUBLISHER_KEY| A path to the publisher's public key. Used to verify publications from the publisher. |
|PRIVATE_KEY|A path to the WHPUB private key. Used to generate signatures. |
|USER_AGENT|An optional parameter to customise the user agent that is sent in hooks. Useful for "professionalism". |
## Publishing Events
Publishing a event is straight forward. Simple use `POST /publish` to post the event payload:
```json
{
"hooks": [
],
"event": "name.of.event",
"author": "author-identitifcation",
"payload": {
}
}
```
To authorize yourself to do this, include the following 2 headers:
| Header | Description |
|--------|-------------|
| `X-Credential` | The name of the credential. As defined by the PUBLISHER_NAME |
| `X-Signature` | A SHA256 signature of the entire JSON payload, using the private key pair of the PUBLISHER_KEY. It needs to be compatible with `crypto.verify`|
You will receive a HTTP 200 (OK) if successful, with a simple payload that looks like this:
```json
{
"id": "a time sortable id"
}
```
You can supply the `id` field to the `/publish` payload too if you wish to manually define the IDs. This will be required in the future for some other services such as the RedisPubSubService.
## Receiving Webhooks
Hello! You may have been linked here because your developer didn't want to rewrite this o/
The webhooks are all sent out with the following headers:
| Header | Description |
|--------|-------------|
| `X-Hook-ID` | Unique identifier of the webhook. This in theory should be time sortable and the publisher should have a endpoint to retrieve events after this id. |
| `X-Hook-Time` | Unix Epoch Timestamp ( in ms) that the publication was made. This maybe different than time received as publications can be queued for long periods. |
| `X-Hook-Author` | Copy of the `author` field in the payload. It's the user that trigged the webhook. |
| `X-Hook-Event` | Copy of the `event` field in the payload. It's the event that triggered the webhook. |
| `X-Hook-Signature` | A SHA356 Signature of the entire body. Ensure this is valid with the public key pair of the PRIVATE_KEY. Ask your API host to provide the public key. |
The payload looks like so:
```json
{
"id": "60489484065f8584a4c2b076000025",
"event": "name.of.event",
"author": "unique-identifier",
"payload": {
}
}
```
### Security
It's important that, as a consumer of the webhook, you verify that the signature has come from this service. Use the Public Key and verify the `X-Hook-Signature` of the body before continue processing webhooks.
The verify function must be equivilent of [Node.JS crypto.Sign](https://nodejs.org/api/crypto.html#crypto_class_sign). It uses a `SHA256` algorithm.
# Docker
### Build
`docker build -t lachee/webhook-publisher`
### Run
See the sample `docker-run.sh` file. But basically:
```sh
docker run \
-p 7080:7080 \
--env-file "$(pwd)"/.env \
--mount type=bind,source="$(pwd)"/.keys,target=/usr/src/app/.keys,readonly \
-d lachee/webhook-publisher
```