Ingen beskrivning

ArtyomV2X 5554a3cdd8 Bug fixes 1 månad sedan
README.md 5554a3cdd8 Bug fixes 1 månad sedan
app.py 79fa917e95 Initial Commit 1 månad sedan
dis2hook.initd 79fa917e95 Initial Commit 1 månad sedan
index.html 79fa917e95 Initial Commit 1 månad sedan
install.sh 5554a3cdd8 Bug fixes 1 månad sedan
update.sh 5554a3cdd8 Bug fixes 1 månad sedan

README.md

Dis2Hook — Webhook Relay to Discord Bot

Dis2Hook receives webhooks from anything that can send an HTTP POST — Gitea, Gogs, Proxmox notifications, Uptime Kuma, home-automation scripts — formats them as Markdown, and relays them into Discord channels through the Discord Bot API (not Discord's incoming webhooks, so one bot identity serves every channel).

It is built to live in a small Alpine Linux LXC on Proxmox and is configured entirely from a built-in web UI.

  source A ──▶ POST /hook/gitea-ci ──┐
  source B ──▶ POST /hook/kuma ──────┼──▶  Dis2Hook  ──▶  Discord Bot API ──▶ #channels
  source C ──▶ POST /hook/backup ────┘

Features

  • Web UI configurator — patch in any number of webhook sources, each routed to its own Discord server/channel, from a single console page.
  • Markdown templates — shape each source's message with Discord Markdown and {dotted.path[0]} placeholders resolved from the incoming JSON payload; leave the template empty to relay the raw payload as a pretty-printed JSON block.
  • Event filters — per-source rules (equals / contains / exists on any payload path) so only the events you care about reach Discord.
  • Heartbeat — optional periodic pulse to a channel with uptime and relay counts.
  • Status updates — optional online/offline announcements when the service starts or stops.
  • Secrets stay local — bot token and admin key live in a token.json generated at install time; it is never pulled from, nor pushed to, this repo.
  • One-file updater — pulls fresh app.py / index.html straight from the repo, validates them, backs up the old ones, and restarts the service.

Install

Run this inside an existing Alpine LXC — never on the Proxmox host. The installer refuses to run if it detects Proxmox VE.

  1. On the Proxmox host, enter your Alpine container: pct enter <ctid>
  2. Run the one-liner:

    wget -qO- https://gogs.av2x.dev/av2x/Dis2Hook/raw/master/install.sh | ash
    

The installer will:

  • verify it is running inside Alpine (and not on a Proxmox host),
  • install python3, py3-flask, py3-requests via apk,
  • pull app.py, index.html, update.sh, and the OpenRC service script directly from this repo,
  • prompt for your Discord bot token (Developer Portal → your app → Bot),
  • generate /opt/dis2hook/token.json (mode 600) with the token and a fresh random admin key, printed once at the end — save it,
  • register and start the dis2hook OpenRC service.

Non-interactive install:

DISCORD_BOT_TOKEN=xxxxx wget -qO- https://gogs.av2x.dev/av2x/Dis2Hook/raw/master/install.sh | ash

Optional environment overrides: D2H_BRANCH (defaults to master, auto-falls back to main), D2H_DIR (default /opt/dis2hook), D2H_PORT (default 8823).

First-time setup

  1. Create a bot at the Discord Developer Portal and copy its token.
  2. Invite it to your server with the Send Messages and View Channel permissions (OAuth2 URL generator → scope bot).
  3. In Discord, enable Developer Mode, right-click a channel → Copy Channel ID.
  4. Open http://<container-ip>:8823/, unlock with the admin key, add a source, paste the channel ID, save, and hit Send test message.
  5. Point your service at the source's webhook URL, sending the source secret in the X-Hook-Secret header (or ?secret= query, or a Bearer token).

Sending a webhook by hand

curl -X POST "http://<container-ip>:8823/hook/gitea-ci" \
  -H "Content-Type: application/json" \
  -H "X-Hook-Secret: <source secret>" \
  -d '{"action":"opened","repository":{"full_name":"av2x/Dis2Hook"}}'

Template example

🔔 **{repository.full_name}** — {pusher.name} pushed to `{ref}`
> {commits[0].message}
{commits[0].url}

Unresolved placeholders render as empty strings; objects/lists render as compact JSON. Messages are truncated to Discord's 2000-character limit.

Updating

Pull the latest app.py and index.html directly from the repo and restart:

/opt/dis2hook/update.sh          # app.py + index.html
/opt/dis2hook/update.sh --all    # also refresh update.sh and the service script

Downloads are validated (version marker + compile check) before they replace anything, previous files are kept as *.bak, and token.json and config.json are never touched.

Files

Path Purpose In repo?
/opt/dis2hook/app.py relay service (Flask) yes
/opt/dis2hook/index.html web UI yes
/opt/dis2hook/update.sh updater yes
/etc/init.d/dis2hook OpenRC service (dis2hook.initd) yes
/opt/dis2hook/token.json bot token + admin key — generated at install, mode 600 never
/opt/dis2hook/config.json sources & settings, managed by the web UI never
/var/log/dis2hook.log service log

Service management

rc-service dis2hook status|start|stop|restart
tail -f /var/log/dis2hook.log

Security notes

  • token.json is generated locally, chmod 600, and listed in .gitignore; treat the admin key like a password — it is the only credential for the UI/API.
  • Every source has its own shared secret, compared in constant time; requests with a wrong or missing secret are rejected with 401.
  • Dis2Hook serves plain HTTP. Keep it on a trusted LAN/VLAN, or front it with a reverse proxy (Caddy, nginx, Nginx Proxy Manager) for TLS if sources send webhooks across the internet.
  • Relayed messages are sent with all mentions disabled, so a hostile payload cannot ping @everyone.
  • The UI cannot change the listen host/port — edit config.json and restart if you need to, so a bad save can never lock you out.

How it compares to Discohook

Discohook is a superb editor for Discord's incoming webhooks — you compose a message and Discord hosts the endpoint. Dis2Hook is the opposite direction: it hosts the endpoint, accepts webhooks from your own services, filters and reformats them, and delivers via a bot token — so one self-hosted relay fans out many sources to many servers and channels, with heartbeat and uptime status built in.

Uninstall

rc-service dis2hook stop; rc-update del dis2hook default
rm -rf /opt/dis2hook /etc/init.d/dis2hook /var/log/dis2hook.log