Notifications
The app sends push/SMS notifications for every new transaction in real time (and for the monthly summary job). Pick one provider and set its env vars in .env. The recommended default for self-hosters is ntfy.sh — free, no account needed, and works on iOS and Android.
If no provider is configured, the app falls back to a log-only mode and writes notifications to stdout — handy for local testing before wiring up a real provider.
Provider comparison
Section titled “Provider comparison”| Provider | Cost | Best for |
|---|---|---|
| Ntfy (default) | Free | Self-hosters; everyone who doesn’t specifically need SMS |
| Twilio | ~$5–10/mo | You want SMS delivery and don’t use AWS |
| AWS SNS | ~$0.01/SMS US (base $0.007 + carrier fee ~$0.003) + 10DLC fees | You already deploy on AWS |
| Log-only | Free | Local testing; no provider configured |
Ntfy (recommended)
Section titled “Ntfy (recommended)”Ntfy is a free push notification service. It’s anonymous — no signup, no account. Messages are delivered to any device subscribed to your topic.
Security: pick a hard-to-guess topic
Section titled “Security: pick a hard-to-guess topic”Your topic name is the auth. Anyone who knows it can read your notifications, and anyone can publish to it. Do not use something guessable like finance or my-transactions. Use a random slug:
finance-dashboard-x8k2m9p4A shell one-liner to generate one:
echo "finance-dashboard-$(openssl rand -hex 6)"-
Install the ntfy mobile app (iOS / Android) or use the web app.
-
Subscribe to your chosen topic — e.g.
finance-dashboard-x8k2m9p4. -
Set the URL in
.env:Terminal window NOTIFICATION_URL=https://ntfy.sh/finance-dashboard-x8k2m9p4 -
Test-send from your terminal:
Terminal window curl -d "hello from ntfy" https://ntfy.sh/finance-dashboard-x8k2m9p4If the push arrives on your phone, the connection is working.
Self-hosting
Section titled “Self-hosting”If you want full control (no reliance on ntfy.sh), you can run your own ntfy server in a container. Point NOTIFICATION_URL at your instance instead. See docs.ntfy.sh/install.
Twilio (SMS)
Section titled “Twilio (SMS)”Twilio is a paid SMS provider. Pick this if you specifically want text messages rather than push notifications.
-
Sign up at twilio.com, verify your phone, and buy a phone number (minimum ~$1.15/mo for a US local number).
-
From the Twilio console, grab:
- Account SID
- Auth Token
- The From number you just purchased
-
Add to
.env(exactly these env-var names — the service reads them directly):Terminal window NOTIFICATION_PROVIDER=twilioTWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxTWILIO_AUTH_TOKEN=your-auth-tokenTWILIO_FROM_NUMBER=+15551234567TWILIO_TO_NUMBER=+15557654321Note: Twilio is not auto-detected from its env vars — you must set
NOTIFICATION_PROVIDER=twilioexplicitly. (OnlySNS_TOPIC_ARNandNOTIFICATION_URLauto-detect.)Security note: Auth Token works for self-hosting, but Twilio recommends API Keys (or OAuth 2.0) for production — they can be scoped and revoked individually. The current Tidings notifier uses Auth Token; that’s fine for personal self-hosting but rotate regularly.
-
Test-send:
Terminal window uv run python -c "from src.finance.notification_service import send_raw; send_raw('Test', 'hello from twilio')"You should get an SMS within a few seconds.
10DLC (US recipients)
Section titled “10DLC (US recipients)”US carriers require 10-digit long-code registration for application-to-person (A2P) SMS. Twilio will prompt you through brand + campaign registration when you add the number. This takes a few business days for approval.
- Canadian numbers sending only to Canadian numbers may not need 10DLC. As of March 2025, Canadian carriers require Canadian A2P SMS registration for newly purchased numbers. Confirm current Twilio guidance for your region.
- If you skip 10DLC for US traffic, messages may silently fail to US recipients (no bounce, no error — they just don’t arrive). See Troubleshooting below.
Roughly $0.0083 per SMS segment plus US carrier surcharges ($0.004) — about $0.012 per outbound segment in practice. For typical personal use, budget $5–10/month: the SMS volume itself is cents, but the US 10DLC campaign monthly fee ($1.50–10/mo depending on campaign type) dominates the total.
AWS SNS (advanced)
Section titled “AWS SNS (advanced)”Most users should pick Ntfy. Only use SNS if you’re already deploying the Lambda email parser on AWS and want notifications to go through the same account.
-
Create an SNS topic in your preferred AWS region (e.g.
us-west-2). -
Subscribe your phone number to it as an SMS subscription.
-
For US numbers: you’ll hit 10DLC requirements, same as Twilio. Register a brand + campaign through the AWS End User Messaging SMS console — AWS now manages SMS origination IDs and 10DLC registration there rather than in the SNS console. See Mobile text messaging with Amazon SNS for the broader overview.
-
Set in
.env:Terminal window SNS_TOPIC_ARN=arn:aws:sns:us-west-2:YOUR_ACCOUNT_ID:your-topic-nameAWS_REGION=us-west-2Setting
SNS_TOPIC_ARNalone is enough — the provider auto-detects from it.AWS_REGIONdefaults tous-west-2if unset. -
AWS CLI credentials must be available to the running process (or container). Use an IAM role if running on EC2/ECS/Lambda, or mount
~/.aws/credentialsinto the container for local self-hosted use.
Roughly $0.01 per SMS to US destinations (base $0.007 + carrier fee ~$0.003) plus 10DLC registration fees. Canadian SMS is slightly cheaper. No monthly number fee — pay per message.
Log-only fallback
Section titled “Log-only fallback”If none of SNS_TOPIC_ARN, NOTIFICATION_URL, or an explicit NOTIFICATION_PROVIDER are set, the app logs notifications to stdout:
NOTIFY [Transaction]: Transaction | Company: TIM HORTONS | Amount: $4.85 | ...Useful for verifying the parser and categorization pipeline before configuring a real provider. Nothing is sent to your phone in this mode.
Provider auto-selection
Section titled “Provider auto-selection”The service picks a provider at startup in this order:
NOTIFICATION_PROVIDER— if set explicitly tontfy,twilio,sns, orlog, that wins.SNS_TOPIC_ARN— if set, use SNS.NOTIFICATION_URL— if set, use ntfy.- Log-only.
Twilio is only selected via the explicit
NOTIFICATION_PROVIDER=twiliosetting. Its env vars (TWILIO_ACCOUNT_SID, etc.) are not auto-detected.
To force a specific provider regardless of what else is in the environment:
NOTIFICATION_PROVIDER=ntfy # or twilio | sns | logAn unrecognized value logs a warning and falls back to log-only.
Troubleshooting
Section titled “Troubleshooting”“I’m not getting notifications.”
The log-only fallback engages silently whenever required env vars are missing. Check your .env:
- Ntfy: is
NOTIFICATION_URLset? - SNS: is
SNS_TOPIC_ARNset? - Twilio: is
NOTIFICATION_PROVIDER=twilioset (not just theTWILIO_*creds)?
Then tail the daemon log and look for a NOTIFY [Transaction]: ... line — if you see one, you’re in log-only mode.
“SNS 10DLC blocked.” Register a brand and campaign in the AWS SNS console. Until approved, SMS to unregistered US numbers will be dropped.
“Twilio error 30034.” 10DLC registration is incomplete or rejected — finish brand and campaign signup in the Twilio console. (Error 30032 is the related Toll-Free Verification error if you’re using a toll-free number instead.)
“Ntfy says it delivered but no push on my phone.” Your phone’s battery optimizer or notification settings are blocking delivery.
- Android: enable Instant delivery in the ntfy app settings (uses a foreground service for prompt delivery), then whitelist ntfy in Settings → Apps → ntfy → Battery → Unrestricted. Without instant delivery, FCM doze mode can delay pushes by minutes or hours.
- iOS: ensure notifications are enabled for the ntfy app under Settings → Notifications. APNs delivers regardless of Background App Refresh; if pushes still don’t arrive, check Focus modes / Do Not Disturb.
“Unknown NOTIFICATION_PROVIDER=… — falling back to log-only.”
Typo in NOTIFICATION_PROVIDER. Valid values: ntfy, twilio, sns, log.
Next step
Section titled “Next step”Provider configured? Return to Docker setup or AWS deployment to wire it in.