Portable Discord webhook transport — Python package + multi-language reference.
All examples implement the same essentials:
DISCORD_WEBHOOK env varRun any of them after exporting the env var:
export DISCORD_WEBHOOK="https://discord.com/api/webhooks/<id>/<token>"
| Language | Runtime needed | Sample |
|---|---|---|
| Python | 3.10+, pip install discord-alert-transport |
full package — severity routing + audit mirror + backoff |
| JavaScript (Node) | Node 18+, stdlib fetch |
raw send + backoff |
| TypeScript | Node 18+, tsx |
typed embed + backoff |
| Go | Go 1.21+, stdlib net/http |
embed + 429/5xx retry |
| Rust | Rust + reqwest + tokio + serde_json |
async send + backoff |
| Bash | bash + curl (+ optional jq) | works anywhere curl is installed |
| PHP | PHP 8+, stdlib curl |
embed + backoff |
| Ruby | Ruby 3+, stdlib net/http |
embed + backoff |
| Java | Java 11+, stdlib java.net.http |
single-file, no Maven |
| C# (.NET) | .NET 6+, stdlib HttpClient |
typed payload + backoff |
The simplest possible send — no embed, no backoff, no error handling. Use this to verify wiring before going production.
curl -X POST -H "Content-Type: application/json" \
-d '{"content":"hello"}' "$DISCORD_WEBHOOK"
import urllib.request, json
urllib.request.urlopen(urllib.request.Request(
URL, data=json.dumps({"content": "hello"}).encode(),
headers={"Content-Type": "application/json"}, method="POST"))
await fetch(URL, {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({content:'hello'})});
http.Post(URL, "application/json", strings.NewReader(`{"content":"hello"}`))
echo '{"content":"hello"}' | curl -d @- -H "Content-Type: application/json" "$URL"
| Need | Use |
|---|---|
| Just send a one-off | Any language, raw HTTP |
| Build a long-lived service | Either — port the package’s ~150 LOC or pip install discord-alert-transport |
| Severity-routed channels + audit mirror | Python package (or port sender.py) |
| Embed length limits enforced | Python build_embed helper |
Secret-safe __repr__ / logging |
Python package |
| Async/threaded fan-out | Wrap any of these in your own queue |
The protocol is universal. Any HTTP client + JSON serializer works.
PR welcome — add a sample
under examples/<language>/.
Next: severity routing.