JQ Daily Drops Cron Setup
This document explains how to set up the daily cron job that automatically generates personalized encouragement drops from JQ for users who have enabled check-ins.
Overview
The JQ Daily Drops system:
- Automatically generates 1 personalized drop per day for users with
read_notes_enabled: trueandcheck_in_enabled: true - Uses the user's latest note analysis to create personalized messages
- Appears in the user's stream as an encouragement drop
- Prevents duplicate drops on the same day
User Settings
Users can enable this feature in the JQ chatbot settings:
- Open the JQ chatbot
- Go to Settings
- Enable "Let JQ Read Your Notes" (
read_notes_enabled) - Enable "Daily Check-ins" (
check_in_enabled)
Both settings must be enabled for JQ to generate daily drops.
Endpoint
POST /api/encouragement-drops/cron/generate-daily-drops
This endpoint is protected by a secret token and should be called by your cron service.
Headers:
x-cron-secret: Secret token (usesDROPS_CRON_SECRET,WORKOUT_WINDOW_CRON_SECRET, orCHAT_CRON_SECRET)
Response:
{
"success": true,
"message": "Generated 15 daily drops",
"results": {
"total": 20,
"generated": 15,
"skipped": 3,
"failed": 2,
"errors": ["User abc123: Failed to generate drop content"]
}
}
Environment Variables
The endpoint uses one of these environment variables (in order of preference):
DROPS_CRON_SECRETWORKOUT_WINDOW_CRON_SECRETCHAT_CRON_SECRET
Add to your backend .env file:
DROPS_CRON_SECRET=your-secret-token-here
Cron Service Setup
Recommended Schedule
Daily at 9 AM UTC (or your preferred time):
- Gives users time to complete their morning journaling
- Ensures drops appear during active hours
- Avoids late-night notifications
Vercel Cron
If using Vercel, add to vercel.json:
{
"crons": [
{
"path": "/api/encouragement-drops/cron/generate-daily-drops",
"schedule": "0 9 * * *"
}
]
}
Railway Cron
If using Railway, you can:
- Use Railway's cron job feature
- Set up an external cron service
External Cron Service
You can use services like:
Configure them to make a POST request to:
https://your-backend-url.com/api/encouragement-drops/cron/generate-daily-drops
With header:
x-cron-secret: your-secret-token-here
How It Works
- Find Eligible Users: Queries all users with both
read_notes_enabled: trueandcheck_in_enabled: true - Check for Existing Drop: Skips users who already received a JQ drop today
- Get Note Analysis: Fetches the user's latest note analysis (from
note_analysestable) - Generate Drop: Uses OpenAI to create a personalized message based on:
- Recent journaling summary
- Mood trends
- Key topics
- Patterns noticed
- Recommendations
- Insights (gratitude, challenges, goals, achievements)
- Send Drop: Creates a system drop (bypasses normal drop limits) from JQ to the user
- Track Usage: Records token usage for cost tracking
Drop Content
Drops are personalized based on:
- Mood trends: References how the user has been feeling
- Topics: Mentions what they've been writing about
- Patterns: Acknowledges behavioral patterns noticed
- Challenges: Offers support for difficulties mentioned
- Achievements: Celebrates progress and wins
- Goals: Encourages continued progress toward goals
Example drops:
- "I noticed you've been writing about work stress lately. Remember to take breaks and breathe. You've got this! 💪"
- "Your gratitude entries have been really inspiring. Keep focusing on the positive - it's making a difference! ✨"
- "I see you're working toward your fitness goals. Every small step counts. Keep going! 🎯"
System User Setup
JQ drops are sent from a special system user ID: e06ebb7d-c31b-4b95-8677-3e5ac2d78be5
Important: You need to create this system user in Supabase before the cron job will work:
Step 1: Create System User in Supabase Auth
- Go to Supabase Dashboard → Authentication → Users
- Click "Add User" → "Create new user"
- Set:
- Email:
jq@hivejournal.com - Password: Generate a secure random password (you won't need it)
- User ID:
e06ebb7d-c31b-4b95-8677-3e5ac2d78be5(must match exactly)
- Email:
- Click "Create user"
Note: The system user has already been created with ID e06ebb7d-c31b-4b95-8677-3e5ac2d78be5. If you need to recreate it, use this exact ID.
Step 2: Run Migration
The migration 042_allow_jq_system_drops.sql will:
- Create a profile entry for JQ
- Document the system user ID
Run the migration:
# If using Supabase CLI
supabase migration up
# Or apply via Supabase Dashboard → SQL Editor
Step 3: Verify
After setup, JQ drops will:
- Display "JQ" as the sender name
- Bypass normal drop limits
- Be easily identifiable as system-generated
- Have no impact on user drop allowances
Testing
You can test the cron endpoint manually:
curl -X POST https://your-backend-url.com/api/encouragement-drops/cron/generate-daily-drops \
-H "x-cron-secret: your-secret-token-here" \
-H "Content-Type: application/json"
Monitoring
Monitor the cron job to ensure:
- Drops are generated daily
- No errors occur during processing
- All eligible users receive drops
Check your backend logs for:
[JQ Daily Drops] Starting generation for X users[JQ Daily Drops] Generated drop for user...[JQ Daily Drops] Completed: X generated, Y skipped, Z failed- Any error messages
Performance Considerations
- Processes users in batches of 5 to avoid overwhelming the API
- 1-second delay between batches to avoid rate limits
- Only users with both settings enabled are processed
- Skips users who already received a drop today
- Falls back to generic message if analysis unavailable
Database Schema
Drops are stored in the drops_sent table:
sender_id: System user ID (00000000-0000-0000-0000-000000000000)recipient_id: User who receives the dropdrop_type: Always'encouragement'content: Personalized message from JQdate_sent: Date the drop was sent
Troubleshooting
No Drops Generated
Check:
- Users have both
read_notes_enabled: trueANDcheck_in_enabled: true - Users have note analyses available (run note analysis cron first)
- Users haven't already received a drop today
- OpenAI API key is set correctly
Generic Drops Only
If all drops are generic:
- Users may not have note analyses yet
- Run the note analysis cron first:
/api/chat/cron/analyze-notes - Check that users have recent journal entries
Drops Not Appearing in Stream
Check:
- Drops are being created in
drops_senttable - Stream is fetching from
/api/encouragement-drops/received - Drops have
read_at: nullto appear as unread
Related Systems
- Note Analysis: Requires note analysis to be run first (
/api/chat/cron/analyze-notes) - Stream Display: Drops appear in stream when fetched from
/api/encouragement-drops/received - Token Tracking: All AI-generated drops track token usage for cost monitoring
Recommended Setup:
- Run note analysis cron at 2 AM UTC:
/api/chat/cron/analyze-notes - Run daily drops cron at 9 AM UTC:
/api/encouragement-drops/cron/generate-daily-drops
This ensures users have fresh analysis before drops are generated.