Cloudflare Worker Comment System
A serverless comment backend built with Cloudflare Workers, Hono, D1 (Database), and KV (Caching).
Features
- Store Comments: Persist comments in Cloudflare D1 (SQLite).
- Avatar Caching: Caches Gravatar/QQ avatars in KV to reduce external requests.
- Spam Protection: Turnstile integration.
- Email Notifications:
- Sends emails via an external REST API (e.g., Vercel-based mailer gateway).
- Smart routing: Replies notify the parent author; new threads notify the admin.
- Multi-site Support: Configure different admin notification emails for different websites using the same worker.
- Admin API: View and delete comments.
Deployment
Prerequisites
- Cloudflare Account: You need a Cloudflare account.
- Wrangler: Install the Cloudflare CLI.
npm install -g wrangler - External Mailer API: An external REST API to handle email sending (e.g., vercel-email-routing).
Setup Steps
-
Clone & Install
git clone <your-repo-url> cd worker-comment npm install -
Create Resources
-
D1 Database:
wrangler d1 create comments-dbCopy the
database_idand updatewrangler.toml(under[[d1_databases]]). -
KV Namespace:
wrangler kv:namespace create AVATAR_KVCopy the
idand updatewrangler.toml(under[[kv_namespaces]]).
-
-
Initialize Database
wrangler d1 execute comments-db --file=./schema.sql -
Configure Secrets You need to set the following secrets in Cloudflare:
# JWT Signing Secret (Secure string for signing tokens) wrangler secret put ADMIN_SECRET # Turnstile Secret Key wrangler secret put TURNSTILE_SECRET # External Mailer API URL wrangler secret put EMAIL_API_URL # External Mailer API Key wrangler secret put EMAIL_API_KEY # Admin Email (Comma-separated list of allowed admin emails) # REQUIRED: Only emails in this list can log in. wrangler secret put ADMIN_EMAIL -
Deploy
wrangler deploy
Multi-site Configuration
You can use a single Worker instance for multiple websites (site_id). You can configure different Admin notification emails for each site.
Admin Email (ADMIN_EMAIL)
This variable determines who receives notifications for new threads (or fallbacks when a parent author has no email).
Option A: Single Admin (Simple) Comma-separated list of emails:
[email protected], [email protected]
Option B: Multi-site (JSON)
Set the secret to a JSON string mapping site_id to emails.
{
"siteA": "[email protected]",
"siteB": "[email protected], [email protected]",
"default": "[email protected]"
}
- When a request comes in with
?site_id=siteA(or in the POST body), the worker looks up the matching key in your JSON configuration. - If the key
siteAisn’t found, it looks fordefault. - If
defaultisn’t found, it picks the first available value or falls back to a hardcoded default.
Authentication & Admin Panel
The Admin Panel is protected by an Email OTP (One-Time Password) system with Turnstile spam protection.
- Access: Navigate to your site and click the “Admin” button (or append
?view=adminto the URL). - Login:
- Enter any email address and complete the Turnstile challenge.
- Click “Send Code”. The system will email you a 6-digit code regardless of whether you are an admin or not (to prevent email enumeration).
- Enter the code to verify.
- Only if your email is in the
ADMIN_EMAILlist will login succeed.
- Session:
- Upon verification, a JWT is issued and stored in your browser.
- You will remain logged in for 7 days.
Environment Variables for Admin Frontend
Ensure your admin-frontend/.env file has the following:
VITE_TURNSTILE_SITE_KEY=your_site_key_here