The Dirt Free CRM includes an automated SMS reminder system that runs via Vercel cron jobs. This system safely processes due reminders while respecting quiet hours and handling concurrent execution.
Add these to your Vercel project environment variables:
CRON_SECRET=your-secure-random-string-here
TWILIO_PHONE_NUMBER=+1234567890 # Your Twilio phone numberImportant: Use a strong, random string for CRON_SECRET. This authenticates cron requests.
The cron job is automatically configured via vercel.json to run every 15 minutes:
{
"crons": [
{
"path": "/api/cron/send-reminders",
"schedule": "*/15 * * * *"
}
]
}Check the Vercel dashboard under "Functions" > "Crons" to confirm the job is scheduled.
- Authentication: Requires
Bearer ${CRON_SECRET}header - Quiet Hours: Respects 9PM-8AM Central Time (no messages sent)
- Concurrent Safety: Uses row-level locking (
FOR UPDATE SKIP LOCKED) - Batch Processing: Processes 50 reminders per run
- Retry Logic: Max 3 attempts with exponential backoff
- Idempotent Logging: Prevents duplicate messages via deterministic IDs
- Authentication Check - Validates cron secret
- Quiet Hours Check - Skips during 9PM-8AM CT
- Select & Lock - Finds due reminders with database locking
- Batch Process - Sends SMS messages in batches
- Audit & Cleanup - Logs all attempts and unlocks records
The system adds these fields for safe concurrent processing:
-- Added to reminders table
locked_at timestamptz -- Processing lock timestamp
last_attempt_at timestamptz -- Last send attempt
attempt_count int default 0 -- Number of send attemptsCheck these locations for monitoring:
- Vercel Functions Tab: Cron execution logs
- Database
audit_logs: All send attempts with metadata - Database
communication_logs: SMS delivery status
Test the cron endpoint locally:
curl -X POST http://localhost:3000/api/cron/send-reminders \
-H "Authorization: Bearer your-cron-secret"You can adjust these constants in /src/app/api/cron/send-reminders/route.ts:
BATCH_SIZE: Number of reminders per run (default: 50)MAX_ATTEMPTS: Max retry attempts (default: 3)- Quiet hours range in
/src/lib/time/ct.ts
- 401 Unauthorized: Check
CRON_SECRETenvironment variable - No reminders processed: Verify reminder data in database
- SMS not sending: Check Twilio credentials and phone number format
The cron response includes debug info:
{
"ok": true,
"processed": 25,
"sent": 20,
"skipped": 3,
"failures": 2,
"debug": {
"quietHours": {
"currentTimeCT": "Mar 15, 2024, 2:30 PM",
"isQuietHours": false
},
"batchSize": 50,
"timeInfo": {
"durationMs": 1250
}
}
}This provides visibility into processing results and timing information.