Texts, Not DMs — Restart Alerts Over SMS
Today's notification overhaul in one line: everything that used to announce "the box is restarting / it's back" via Slack now arrives as an actual text message, using nothing but a Gmail account and a carrier email-to-SMS gateway — no Twilio, no paid service, no new vendor.
The stack
Both senders funnel into the same free pipe: Gmail's SMTP (app password auth) delivering mail to <PHONE>@vtext.com, Verizon's email-to-text gateway. Outbound reachability from the container was verified up front (api.twilio.com and ntfy.sh reachable, but both were rejected as unnecessary — SMS via the gateway costs nothing).
Sender 1: the container herder
The herder (catherder.py) supervises every persistent daemon in the container. Its restart events used to land in a log file nobody watches; they now go out as SMS. Key wiring details worth remembering:
line 1, app password on line 2), parsed tolerantly — spaces in Google's grouped xxxx xxxx xxxx xxxx display form are stripped automatically.
send is logged and skipped, never fatal to supervision.
before calling it done — the acceptance test was a real text on a real phone.
Sender 2: reboot-notify v2 on the Windows box
The Windows-side watcher already had the right shape: SYSTEM scheduled tasks for Event 1074 (a restart was initiated, with who/why), Event 6008 (the box came back up dirty after a crash or power loss), and a boot task for the "back up" notice, with 15-minute dedupe so staged update reboots don't spam. v2 keeps all of that and swaps only the delivery leg: the Slack incoming webhook is replaced by Gmail SMTP → gateway, with bodies trimmed to the 160-character SMS cap. An uninstall script removes the tasks and — importantly — the sms.txt file holding the app password.
The one thing that bit
Gmail SMTP rejects everything except real app passwords with the same opaque 5.7.9 Application-specific password required error. Two attempts failed on exactly that: a 15-character paste (truncated) and a regular account password (mixed case, digits — never works). The tell is simple: a valid app password is always 16 lowercase letters. Once the file held one, the end-to-end test passed on the first send.
Status: both senders tested end-to-end; texts confirmed received.