You built a comments system. Users are submitting feedback. But you only find out when you remember to check the D1 console. By then, someone has been waiting days for a response.
This post covers three approaches to getting notified when form submissions arrive: instant emails, daily digests, and webhook-based notifications. Each has trade-offs in complexity, cost, and flexibility.
The Problem
The comments system from my previous post stores submissions in Cloudflare D1. Moderation happens manually via SQL queries in the D1 console. This works, but it requires actively checking for new submissions.
For a low-traffic personal blog, checking once a day might be fine. For a business site or active community, you need to know immediately when someone reaches out.
Option 1: Instant Email via MailChannels
Cloudflare Workers can send emails through MailChannels without any SMTP configuration. MailChannels has a special integration with Cloudflare that allows free email sending from Workers.
How It Works
When a comment is submitted, the Pages Function:
- Validates the Turnstile token
- Stores the comment in D1
- Sends an email notification via MailChannels
Implementation
Add this function to your Pages Function:
| |
Then call it after storing the comment:
| |
DNS Configuration Required
MailChannels requires SPF records to prevent your emails from landing in spam. Add this TXT record to your domain’s DNS:
| |
And update your SPF record to include MailChannels:
| |
Pros and Cons
Pros:
- Instant notification
- No external services required
- Free with Cloudflare Workers
- Simple implementation
Cons:
- Requires DNS configuration
- One email per submission (could flood inbox on high-traffic sites)
- MailChannels rate limits apply
- Email deliverability varies
Option 2: Daily Digest via Cron Trigger
Instead of instant emails, send a daily summary of pending submissions. This requires a separate Cloudflare Worker with a Cron Trigger.
How It Works
A scheduled Worker runs at a specified time each day:
- Queries D1 for unapproved comments from the last 24 hours
- Compiles them into a digest email
- Sends a single email with all pending items
Implementation
Create a new Worker file at functions/_scheduled.ts:
| |
Configuring the Cron Schedule
Add to your wrangler.toml:
| |
For Pages Functions, cron triggers work differently. You may need to create a separate Worker and bind it to the same D1 database, or use Cloudflare Queues to trigger the digest.
Alternative: Separate Worker
Create a standalone Worker for the digest:
- Create a new Worker in Cloudflare Dashboard
- Add the D1 binding pointing to your database
- Add environment variables for email addresses
- Set the cron trigger schedule
This keeps your Pages Function simple and handles scheduling separately.
Pros and Cons
Pros:
- Single email per day (no inbox flooding)
- Batch moderation workflow
- Includes SQL to approve all at once
- Runs even if no traffic to site
Cons:
- More complex setup
- Delayed notification (up to 24 hours)
- Requires separate Worker or queue
- Cron triggers have some limitations on Pages
Option 3: Webhook to External Services
The simplest approach: send a webhook to an external service that handles notifications. No email configuration required.
Using ntfy.sh (Free Push Notifications)
ntfy.sh is a free, open-source push notification service. No account required.
| |
Subscribe to notifications:
- Mobile: Install ntfy app, subscribe to your topic
- Desktop: Open
https://ntfy.sh/your-secret-topic-namein browser - CLI:
curl -s ntfy.sh/your-secret-topic-name/json
Using Telegram Bot
Create a Telegram bot and send messages to yourself:
| |
To set up:
- Message @BotFather on Telegram to create a bot
- Get your chat ID by messaging @userinfobot
- Add
TELEGRAM_BOT_TOKENandTELEGRAM_CHAT_IDto Pages environment variables
Using Discord Webhook
Send notifications to a Discord channel:
| |
To set up:
- In Discord, go to channel settings > Integrations > Webhooks
- Create a webhook and copy the URL
- Add
DISCORD_WEBHOOK_URLto Pages environment variables
Using Zapier or Make
For more complex workflows, use Zapier or Make:
- Create a webhook trigger in Zapier/Make
- Send POST request from your Pages Function to the webhook URL
- Configure Zapier/Make to send email, Slack message, or any other action
| |
Pros and Cons
Pros:
- Simplest implementation
- No DNS configuration
- Multiple notification channels
- Mobile push notifications
- Free options available
Cons:
- Depends on external services
- ntfy.sh topics are public (use random strings)
- Rate limits vary by service
- Telegram/Discord require account setup
Which Should You Choose?
Choose Option 1 (Instant Email) if:
- You want email specifically
- You control your domain’s DNS
- Submission volume is low
- You need to respond quickly
Choose Option 2 (Daily Digest) if:
- You prefer batch processing
- Submission volume is moderate to high
- Instant notification is not critical
- You want a cleaner inbox
Choose Option 3 (Webhooks) if:
- You want the simplest setup
- You prefer push notifications over email
- You already use Telegram/Discord/Slack
- You do not control DNS or want to avoid email configuration
Combining Approaches
Nothing stops you from using multiple methods:
| |
Or use instant push for comments and daily digest for likes/analytics.
Security Considerations
Whichever approach you choose:
- Keep webhook URLs secret - Add them as encrypted environment variables, not in code
- Rate limit notifications - Consider batching if traffic spikes
- Sanitize content - Do not include raw user input in notification subjects
- Use unique topic names - For ntfy.sh, use random strings like UUIDs
Conclusion
Getting notified about form submissions does not require complex infrastructure. MailChannels provides free email sending from Workers. External services like ntfy.sh offer instant push notifications with zero configuration.
For my site, I use ntfy.sh for instant mobile notifications. It took five minutes to set up and requires no DNS changes. When I want more detail, I check the D1 console.
The best solution is the one you will actually use. Pick the simplest option that fits your workflow.

Comments
Loading comments...