A Go server for processing webhooks from Buy Me a Coffee and forwarding them to clients via websockets. (actually you can process any webhooks with secret and x-signature-sha256)
This project is designed to be installed on a server with a public IP and allows:
- Receiving webhooks from Buy Me a Coffee
- Transmitting webhook content via websockets to authorized clients (e.g., StreamerBot)
- Managing access through IP authorization
- Processing webhooks from Buy Me a Coffee
- Webhook verification via HMAC SHA-256 (take secret from your BMAC webhook page)
- Data transmission through websockets
- Client authorization via IP whitelist
- Simple web page for adding IPs to the whitelist
- TLS encryption support
- Operation behind reverse proxies (Nginx, Caddy) and Cloudflare
Create a .env
file in the project root with the following parameters:
# Server main settings
SERVER_PORT=8080
WEBHOOK_SECRET=your_webhook_secret_from_buy_me_a_coffee
# Define path for your websocket clients
WEBSOCKET_PATH=/ws
# Define path for BMAC webhook
WEBHOOK_PATH=/webhook
# This password is used on /auth page for whitelisting IP
ADMIN_PASSWORD=change_this_password
# TLS settings
TLS_ENABLED=false
TLS_CERT=cert.pem
TLS_KEY=key.pem
# Security settings
BEHIND_PROXY=false
TRUST_CLOUDFLARE=false
IP_WHITELIST=127.0.0.1,::1
# Actually, this is just "token" for websockets.
WHITELIST_PASSWORD=change_this_secret
docker-compose up -d
(don't forget to install go)
# Install dependencies
go mod download
# Build
go build -o webhook-bridge .
# Run
./webhook-bridge
- Log in to your Buy Me a Coffee account
- Go to the Webhooks section: https://www.buymeacoffee.com/webhooks
- Click "Create New Webhook"
- Specify your server URL:
https://yourdomain.com/{WEBHOOK_PATH}
- Select the events you want to track and click "create".
- Select your newly created webhook
- Copy the secret key and add it to the
WEBHOOK_SECRET
env variable
- Open in your browser:
https://yourdomain.com/auth
- Enter the administrator password (from the
ADMIN_PASSWORD
variable) - After successful authorization, your IP will be added to the whitelist
- Use the obtained websocket URL for connection
The websocket is available at: ws://yourdomain.com/ws/your_token/your_ip
(you will obtain this URL in the previous step)
Where your_token
is the value from the WHITELIST_PASSWORD
variable.
If you're hosting the server behind a reverse proxy (e.g., Nginx, Caddy) or/and Cloudflare, you need to properly configure the environment variables:
# Proxy settings
BEHIND_PROXY=true # Enable proxy mode
TRUST_CLOUDFLARE=false # Trust the CF-Connecting-IP header (true if using Cloudflare)
IMPORTANT: Caddy v2 sets own X-Forwarded- headers by default. But Nginx does not. In your nginx config you can do something like:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
P.S. - If you use Cloudflare, just set TRUST_CLOUDFLARE to true and everything will be fine.
-
When
BEHIND_PROXY=true
:- To determine the client's IP, the server checks the
X-Forwarded-For
andX-Real-IP
headers - When forming the websocket URL, the
wss://
protocol is automatically used (assuming the proxy provides HTTPS) - TLS can be disabled on the server itself (
TLS_ENABLED=false
), as encryption is provided by the reverse proxy
- To determine the client's IP, the server checks the
-
If also
TRUST_CLOUDFLARE=true
:- The client's IP is determined by the
CF-Connecting-IP
header provided by Cloudflare - This ensures you get the actual client IP, not the Cloudflare server IP
- The client's IP is determined by the
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ws/ {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
- Use HTTPS. PLEASE
- Change default passwords
- Use strong and random tokens
- Configure proxies properly
I created this project after realizing that the default BMAC OBS notification is completely shit. With this tool, you can get donation events in real-time and create fully custom notifications in OBS with StreamerBot.
-
- Add redis as a message broker (if there are no websocket connections at the moment)
-
- Add something for whitelist remembering