Search for “ESP32 Telegram notification” and every tutorial hands the board a bot token and an HTTPS client and wishes it luck. It works — until you want the same alert on Discord, or the token leaks with a firmware dump, or you’re reflashing a deployed board because the wording changed.
This guide inverts it. The ESP32 sends one line of telemetry and holds zero secrets. The threshold, the message, the credentials, and the channel — Telegram, Discord, Slack, SMS, WhatsApp, email, or PagerDuty — live in an automation on your own Cloudflare account, where changing any of them is an edit, not a reflash. One sketch, any channel, swappable forever.
The worked example is a freezer monitor — the project where notifications aren’t a novelty but the entire point.
Why the board shouldn’t send the alert
Sending from firmware means, for every channel: its TLS endpoint compiled in, its credential stored in flash (readable by anyone with the board and five minutes), its message format hard-coded, and its failure modes handled at 3 a.m. by a microcontroller. Multiply by every channel you add.
Sending from the cloud means the board’s contract is just temperature every minute. Then:
- Secrets stay out of flash. The bot token and webhook URLs live in your nodrix instance, not in something you might one day post to GitHub.
- The channel is a dropdown. Telegram today, Discord for the household tomorrow, SMS for the cabin with no one watching chat — same firmware, forever.
- The logic is editable. Threshold, wording, hysteresis, recipients: dashboard edits, applied on the next reading.
- Deep sleep stays deep. A battery board reports and sleeps; the alerting happens after it’s already unconscious.
What you’ll need
- An ESP32 dev board and a temperature sensor — a DS18B20 on a long lead is the classic freezer choice.
- The Arduino IDE with the ESP32 board package, the Nodrix library, and the DallasTemperature library, from the Library Manager.
- A nodrix instance with a project and a project token.
- An account on whichever channel should wake you: Telegram, Discord, Slack, or Twilio for SMS and WhatsApp.
The firmware
All of it. Note what’s absent: no bot token, no webhook URL, no threshold, no message text.
#include <Nodrix.h>
#include <OneWire.h>
#include <DallasTemperature.h>
const char* WIFI_SSID = "your-ssid";
const char* WIFI_PASS = "your-password";
const char* HOST = "nodrix.you.workers.dev";
const char* TOKEN = "tok_your_project_token";
OneWire oneWire(4);
DallasTemperature sensors(&oneWire);
void setup() {
sensors.begin();
Nodrix.begin(WIFI_SSID, WIFI_PASS, HOST, TOKEN);
}
void loop() {
Nodrix.run();
static unsigned long lastReading = 0;
if (millis() - lastReading >= 60000) {
lastReading = millis();
sensors.requestTemperatures();
float t = sensors.getTempCByIndex(0);
if (t > -100) Nodrix.send("temperature", t); // -127 = sensor disconnected
}
}
The library keeps the socket alive and reconnects on its own; for a battery build, swap
Nodrix.begin for Nodrix.beginHTTP and report once per wake — the alert side of this guide
doesn’t change at all.
Wire up a channel
Each channel is added once, under your project’s integrations, and then reused by any automation.
Telegram — the best free option for personal alerts: instant, free, works everywhere. Message
@BotFather, create a bot, paste the bot token into the integration; message your bot once,
pull your chat ID from the getUpdates URL, done. Group alerts: add the bot to a group and use
the group’s chat ID.
Discord — the right answer when a household or team already lives there. In your server: channel settings → Integrations → Webhooks → copy the webhook URL. That URL is the entire credential. The integration can send a plain message or a titled embed — embeds read better for alerts with a value in them.
Slack — same shape as Discord for workplaces: create an Incoming Webhook in your Slack app settings, paste the URL. If the freezer is in an office, the alert belongs in the channel people actually have open.
SMS and WhatsApp via Twilio — for alerts that must land when nobody’s watching a chat app. Paste your Account SID, auth token, and sending number. SMS costs real (small) money per message, which the hysteresis below keeps honest; a trial account works for testing but only texts verified numbers.
Email and PagerDuty follow the same pattern — a webhook-shaped credential pasted once — and everything below applies to them identically.
Build the alert
One automation: trigger on a new temperature reading, condition above -10, action: send —
“Freezer at {{value}}°C — check the door.” The {{value}} fills in from the reading that tripped
it. That’s a working alert.
Now make it a good alert:
- Add hysteresis. A freezer cycling around the line would ping you on every crossing. Alarm
above -10, and only rearm after the reading recovers below -15 — the automation’s
set-a-flag pattern: on alarm, also set an
alertedvariable; condition the alert onalertedbeing off; clear it on recovery. Three conditions in the editor, zero firmware. - Alert on silence, too. A dead sensor sends nothing — which no threshold ever catches. Add a
schedule trigger (say, every morning) with an
if-variablecheck that the lasttemperatureis fresh; stale means power, Wi-Fi, or the board itself. A monitor that fails silently is worse than none. - Escalate by severity. Above -10: Telegram. Above -5: Telegram and SMS. Two automations, same variable, different thresholds and channels — the melted-food tier earns the message that costs money.
One sketch, any alert
Nothing in this pattern is about freezers. The same firmware shape — read, Nodrix.send, repeat —
with a different sensor and threshold is a leak detector under the washing machine, a mailbox
switch, a greenhouse heat alarm, or the plant-watering monitor
that messages you when the reservoir runs dry. The channel decision stays where it belongs: in a
dropdown, six months from now, when you’ve moved from Telegram to Discord and the board neither
knows nor cares.
Notes
- Credentials live in one place. Rotating a leaked webhook is one edit in your instance — not a reflash of every deployed board.
- The alert path is yours. Board → your Cloudflare account → channel API. No third-party automation service in the middle, no monthly task quota.
- Every alert has a paper trail. The readings that tripped it are in your dashboard’s chart and behind the read API — the alert tells you now, the chart tells you why.