The problem
Sending a text at a fixed time is a five-minute job. Sending one reliably, every week, for a year, on a phone that Android is actively trying to put to sleep, is not.
That gap is where the App Store category lives. The commercial SMS schedulers all want the same three things before they'll do the five-minute job: an account, a subscription, and permission to route your messages through somebody's server. And most of them still quietly stop working — not with an error, but with silence, the week after an OEM battery optimiser decides the app has been idle long enough to kill.
Silence is the worst possible failure mode for this. A message that doesn't arrive doesn't announce itself; you find out when the person on the other end asks why you never wrote. So the brief was narrow and awkward: an app that keeps firing for months without ever checking in, that tells you honestly when a send failed, and that never has to hand a message's content to anyone to decide what to do with it.
The decisions
Reliability came from distrusting the scheduler. Android's exact alarms are precise but revocable — Doze, a reboot, an app update, an aggressive OEM ROM. So Automatiq runs two engines side by side: AlarmManager for the exact fire time, and an hourly WorkManager job that sweeps every enabled macro and sends anything the alarm missed. Two engines introduce a new failure mode — double-sending — so the fire path is gated by an atomic claim keyed to local midnight: whichever engine gets there first wins, and the other one finds the slot already taken. Alarms and geofences are re-armed on boot, on app update, and again on every launch as a self-heal.
Privacy came from the same instinct, applied to the network. There is no account and no backend, because there is nothing for a backend to do. Exactly two calls ever leave the device: geofencing, through Play Services, and — only if you switch it on and supply your own free API key — a request to Gemini for an AI-written reply. If that request fails, the macro falls back to its fixed message rather than sending nothing. The key is stored on-device only, kept out of logs, and excluded from Android's cloud backups.
And honesty came from refusing to trust the radio. "Handed to SmsManager" is not "sent" — the network can drop a message after dispatch, and the naive implementation logs a cheerful success anyway. Every message carries a sent receipt, so a late failure flips the log entry, the macro status, and the widget to failed with the radio's actual reason. Where the carrier reports back, delivery is confirmed too.
What was built
Six triggers, one send path:
- Scheduled — a set time, any combination of weekdays, every N weeks, with an optional expiry date or a single one-off date
- Manual — tap the macro in the list, or a home-screen widget that shows its own last send
- Auto-reply — an incoming SMS matching an optional sender and/or keyword, with a loop guard
- Location — arriving at or leaving a geofenced place, re-armed after reboots and updates
- Missed call — a call that rings out or gets declined, with an optional caller filter
- Device state — the charger, a specific Bluetooth device, or a named Wi-- Fi network connecting or dropping
Every one of them ends in the same function, which is the point: one place where a message is composed, dispatched, logged and verified, rather than six subtly different implementations drifting apart.
On top of that: messages carry variables — date, weekday, recipient name — so a macro with a list of recipients personalises every copy instead of blasting the same text at everyone. Auto-replies answer with a fixed text or a Gemini-generated one, either held for your approval or sent automatically and reported afterwards. A scheduled macro can run the same trick in reverse, rewriting its own message on every fire so a weekly reminder never reads identically twice, and falling back to the original text the moment the API is unreachable. Quiet hours don't discard the replies that arrive overnight — they hold them and answer each person's latest message once the window closes. Folders group macros with a master switch, a health screen surfaces exact-alarm and battery status with one-tap fixes, and everything exports to JSON and back.
Result
In daily use on my own phone, sideloaded rather than published — a personal tool that had no reason to become a product. The interesting part isn't the feature list, it's what the feature list demanded underneath: a send path that can't double-fire, a scheduler that survives the operating system trying to stop it, an AI integration that degrades to plain text instead of failing, and a log that reports what actually happened rather than what was attempted.
The whole thing is on GitHub — architecture, migrations, permission rationale and all.
View source on GitHub
Or contact me to get the latest version ready to install on your Android phone.


