Notifications & digests
When something lands in one of your flows, AppMate tells you — by email, in Slack, or both. Alerts are per-submission and near-instant; an optional daily or weekly digest rolls the same data up into one message. Everything is configured in Settings → Profile.
Per-submission alerts
Every new submission fires an alert to the app's owner. Six submission types are covered:
- Waitlist signup — someone joins a waitlist.
- Feedback message
- Report
- Crash report
- Contact message
- Feature request — a new wishlist idea, and also a new comment on an existing idea.
The alert names the app, carries a short preview of what was written, adds context rows where the flow has them (reply-to email, category, rating, device…), and links straight to that submission list in the dashboard.
Channels
Two channels exist today: email (delivered through Resend) and Slack. They're independent — enable either or both. The per-type toggles are a shared gate: if you mute “crash report”, no channel fires for crashes.
Connecting Slack
There are two ways to point AppMate at a Slack channel.
1. Add to Slack (one click)
AppMate ships a single Slack app. Hit Add to Slack, authorise it, and pick the channel you want — Slack hands back an Incoming Webhook scoped to that channel and AppMate stores it for you, along with the channel name for display. The only scope requested is incoming-webhook: no bot token is stored and AppMate never reads your Slack messages.
2. Paste an Incoming Webhook
Or do it by hand: create a Slack app, enable Incoming Webhooks, pick a channel, and paste the resulting URL into the field in Settings → Profile. Save, then use Send test to post a test message to the saved webhook and confirm the connection end-to-end.
https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
Account channel vs. per-app channel
The webhook you set in Settings → Profile is your account default— every app you own posts there. Each app can also have its own webhook, set on the app's Settingspage (the same two routes work there: an “Add to Slack” button, or a pasted URL).
- A per-app webhook winswhen it's set — it's an explicit “route this app here”, and it's active whether or not the account-level Slack toggle is on.
- With no per-app webhook, alerts fall back to the account channel — but only when you've enabled Slack on your profile.
- Your per-type toggles still apply either way, and the message always names the app and links to its dashboard.
So a multi-app owner can send each app's alerts to its own channel, with anything unrouted landing in the account default.
Webhook validation (SSRF guard)
Slack webhook URLs are user-supplied and AppMate POSTs to them server-side, so they're validated before they're ever stored or used. A URL is accepted only if all of the following hold:
- the scheme is
https:; - the host is exactly
hooks.slack.com; - the path starts with
/services/; - the whole URL is at most 300 characters.
Anything else is rejected, so a crafted value can't make the server reach an internal address. The check runs when preferences are saved, when they're read back, and again at send time. A saved config with no usable webhook is also forced “off” rather than left looking enabled while doing nothing.
Daily & weekly digests
A digest is an opt-in roll-up of what came in over the window — for each of your apps, a count per submission type (“3 feedback messages, 1 waitlist signup”), the grand total, and a link to your dashboard. Apps with nothing new are left out, and if nothing came in at all the digest isn't sent — no empty “nothing happened” mail.
- Daily covers the last 24 hours; weekly covers the last 7 days.
- Delivered over the same channels as alerts — email and your account Slack webhook. (Per-app webhooks are for real-time alerts; digests use the account channel.)
- Counts cover the same six types as alerts. Digests are not filtered by the per-type toggles.
- Both are off by default — tick them in Settings → Profile.
Sends are scheduled by an in-process cron. The default schedule is a standard cron expression evaluated in UTC:
DIGEST_DAILY_CRON 0 17 * * * # daily — 17:00 UTC DIGEST_WEEKLY_CRON 0 8 * * 1 # weekly — Mondays, 08:00 UTC
Each window is claimed exactly once, so running several server replicas never produces duplicate digests. Self-hosters can override either expression, set DIGEST_DISABLED=1 to turn the in-process scheduler off, and drive sweeps from an external cron by POSTing to /api/cron/digest?period=daily|weekly with the CRON_SECRET as a bearer token.
Notification preferences
Everything above lives in one card under Settings → Profile:
- Email me — the master switch for the email channel.
- Post to Slack— the account Slack channel, plus the “Add to Slack” button, the webhook field and Send test.
- Which submissions — one toggle per type, applied across every channel.
- Digest — daily and weekly checkboxes.
Alerts go to your sign-in email. Super-admins get one extra field, Send alerts to, which redirects email alerts to a different address — useful when the account email is a shared alias with no real mailbox.
See the wishlist and the API reference for what the individual flows collect.