§ Ember — habit & ritual tracker · Telegram — nudges & check-ins
The rituals plugin
A ~90-line Python plugin at /root/apps/telegram-bot/plugins/rituals/. Because the bot runs network_mode: host, it reaches Ember's app at http://127.0.0.1:3300 directly; because ./plugins is bind-mounted, dropping the folder in hot-loads it (no rebuild — only the framework upgrade itself needed a rebuild).
What it exposes
@watcher("due", interval=300, cooldown=7200)— every 5 min it GETs/api/agenda(the app's list of scheduled + not done + reminder-time-passed + not-snoozed items). If something's due it returns anAlert(stylenotify) for the first item, with Done/Skip/+1h buttons. The key is{date}:{kind}:{id}so each item nudges once per cooldown — no spam.@on_callback— parses"{action}:{kind}:{id}", POSTs to/api/checkin, and returnsReply(edit=True, answer=…)so the nudge becomes a confirmation in place./today— the day's checklist with a one-tap ✅ button per pending item./done <name>— a typed fallback that fuzzy-matches a title and checks it in.
Why the agenda lives in the app, not the plugin
"What's due right now" depends on cadence + reminder times + completions + snoozes — all of which the app already computes. So the app exposes /api/agenda and the plugin stays dumb: it just renders and forwards. If the scheduling rules change, only the app changes.
Quieting demo nudges
Seeded demo habits had reminder times, so the watcher fired a (correct) nudge on first boot — proof the chain works. Their reminders were then cleared so the watcher stays silent until you set real ones. Set a reminder time that's just passed and within 5 minutes you'll get your first real nudge.