Discord webhooks vs email vs Slack for free automated alerting: setup effort compared
A script needs to tell someone when something happens — a job failed, a threshold was crossed, a scheduled task finished. Three obvious free options exist, and the setup effort between them is not close.
Discord webhooks: lowest effort, genuinely two minutes
Create a webhook in a Discord server's channel settings, copy the URL it gives you, and that's the entire setup — no account creation on your script's side, no API key management beyond keeping that one URL secret. Sending a message is a single unauthenticated POST request with a JSON body:
import json
import urllib.request
def alert(message: str, webhook_url: str):
data = json.dumps({"content": message}).encode()
req = urllib.request.Request(webhook_url, data=data, headers={"Content-Type": "application/json"})
urllib.request.urlopen(req, timeout=10)
No SDK, no OAuth flow, no rate-limit tier to think about at low volume. The tradeoff: whoever needs the alert has to be in that Discord server and checking it, which is a real constraint if the audience is "future me checking a phone while traveling" rather than "a team already living in Discord."
Email: no new account, but real setup on the sending side
Nobody needs to create anything to receive an email alert — that's the appeal. But sending one programmatically needs either SMTP credentials for an existing account (which often means enabling "less secure app" access or generating an app-specific password, both extra steps) or a transactional email service (SendGrid, Mailgun, etc.), which means a new account, API key, and usually a sender-domain verification step before it'll reliably land in an inbox rather than spam. This is meaningfully more setup than a webhook URL, in exchange for reaching an inbox almost everyone already checks.
Slack: similar shape to Discord, slightly more ceremony
Slack incoming webhooks work the same way as Discord's — a URL, a POST request, done — but getting that URL requires creating a Slack "app" for the workspace first (even for personal use), which is a few more clicks through Slack's app-configuration UI than Discord's "channel settings → integrations → webhook" path. Functionally equivalent once set up; Discord's path to that same end state is just shorter.
What this project actually uses
The paper-trading bot's circuit-breaker alerts use a Discord webhook — exactly the pattern above, optional via an environment variable, with the alert function falling back to a local console message if no webhook URL is configured. Given the audience is one person checking in periodically while traveling rather than a team, Discord's zero-account-needed setup made it the obvious choice over building out email delivery for a single-recipient use case.
Sources: Discord and Slack's respective incoming-webhook documentation (setup steps
compared directly); this project's own trading/src/paper_trader.py alert implementation.