MailSignals

Alerts and digest

An alert that fires on a scanner teaches you to ignore alerts.

An email tracker that pings on everything gets muted within a day. The filtering is as much the feature as the notification, and the bias throughout is against noise.

Seven kinds, each with a rule

Alert types, triggers and wording
AlertFires whenSays
openedThe first confirmed open of a message (every one, if you ask for that)Ada opened your email.
clickedA counted click on a tracked linkAda clicked a link in your email.
repliedA reply arrives on the threadAda replied.
hotSeveral counted opens inside a short window (3 in 10 minutes by default), at most once per windowAda is reading your email right now.
revivedActivity after a genuine earlier event and at least 7 days of silenceAda came back to an old email.
follow_upNo reply after 3 days, evaluated hourly, indifferent to opensNo reply from Ada yet.
bouncedGmail's delivery-failure notice, once per message, even on a closed threadYour email to Ada bounced — the address could not be reached.

The rules that keep it quiet

  • Only counted events can alert. An open must pass your sensitivity; a click must be a person's. A gateway's fetch never raises anything.
  • Your own views are withdrawn before alerts are evaluated, so you are never notified about yourself.
  • "Opened" fires on the first confirmed open only, unless you ask for every one. A message someone keeps re-reading would otherwise fire all afternoon.
  • "Hot" fires at most once per window; "revived" requires a genuine earlier event, because a first open a fortnight after sending is simply a late open.
  • A muted message raises nothing, ever, and still records every event.
  • On a thread you archived or trashed, only a reply alerts. Opens on it are no longer news; a reply is the one thing that should pull it back.
  • The alert is stamped on the message before it is delivered. A notification delivered twice is noise; a stamp written twice is harmless, and the stamp is what stops the next event raising the same alert again.
  • The alert document is written even during quiet hours, so it is in your timeline and badge count. Only the notification is suppressed.
  • Quiet hours may wrap midnight (22 to 07), which is the common case, and are computed in your timezone rather than the machine's.
  • Follow-up reminders are indifferent to opens: the reminder is about the reply you are waiting for, and an opened-but-unanswered message is exactly the case worth chasing. Replied, bounced, muted and closed messages are skipped.

How an alert reaches you

Where alerts appear
SurfaceWhat it shows
Desktop notificationRaised by the extension's service worker after each sync, filtered by your preferences and quiet hours; one "opened" per message per sync; the last 200 ids remembered so a re-sync never repeats one. Clicking it opens the message in the dashboard.
In-Gmail toastGmail's own butter bar, for messages already on screen only, at most two per sync, for five seconds, when a status became opened, clicked or replied.
Extension popupThe last alerts the worker saw, with a glyph per type: ✓✓ ↗ ↩ ★ ↺ ⏰ ✕
DashboardUnread, All and Snoozed views, mark all read, snooze for an hour or a day, a red tone for bounces, and a badge counting unread, unsnoozed alerts.

The extension learns about alerts by polling every minute while a Gmail tab is open and every five minutes otherwise. Web Push is wired server-side, but no client registers a subscription today, so nothing is pushed; the polling is what delivers.

The digest

Daily or weekly, at an hour you choose, in your timezone. One hourly schedule serves every timezone by selecting the users for whom it is now their hour; weekly digests go out on Monday, when the week's plan is still open. A missed run is skipped, never replayed: a digest about yesterday morning helps nobody.

A period with nothing sent produces no email at all, because a digest that arrives every morning saying "0 sent" trains people to filter it. "Opened" counts messages, not opens: five opens of one email is one person reading it twice.

Delivery is handed to the Firestore Trigger Email extension, which you install and point at the SMTP provider of your choice, so no mail credentials ever live in the codebase.

Where it lives

functions/src/lib/alerts.ts
The rules, pure and covered by 33 tests.
functions/src/triggers.ts
Evaluation after each event, after the self-open backstop.
functions/src/schedules.ts
The hourly follow-up scan and the digest.
extension/src/background/notify.ts
Desktop notifications, quiet hours in your timezone.
functions/src/lib/digest.ts
Who gets a digest this hour, and what it says.

Related: replies and bounces · the Alerts page.

Run it in your own project.

One Firebase project, two subdomains, one deploy script. About an hour the first time, and no subscription afterwards.