# ⏰ Scheduler & Automation
**🚀 Built-in scheduler for automated daily execution** *Set it and forget it*
--- ## 🎯 What is the Scheduler? The built-in scheduler provides **automated script execution** at specified times without requiring external cron jobs or task schedulers. ### **Key Features** - 📅 **Daily automation** — Run at the same time every day - 🌍 **Timezone aware** — Handles DST automatically - 🔄 **Multiple passes** — Execute script multiple times per run - 🏖️ **Vacation mode** — Skip random days monthly - 🎲 **Jitter support** — Randomize execution times - 📅 **Humanization off-days** — Weekly random skips (disable via `humanization.randomOffDaysPerWeek`) - ⚡ **Immediate start** — Option to run on startup --- ## ⚙️ Configuration ### **Basic Setup** ```json { "schedule": { "enabled": true, "time": "09:00", "timeZone": "America/New_York", "runImmediatelyOnStart": true }, "passesPerRun": 2 } ``` ### **Advanced Setup with Vacation Mode** ```json { "schedule": { "enabled": true, "time": "10:00", "timeZone": "Europe/Paris", "runImmediatelyOnStart": false }, "passesPerRun": 3, "vacation": { "enabled": true, "minDays": 3, "maxDays": 5 } } ``` ### **Configuration Options** | Setting | Default | Description | |---------|---------|-------------| | `enabled` | `false` | Enable built-in scheduler | | `time` | `"09:00"` | Daily execution time (24-hour format) | | `timeZone` | `"UTC"` | IANA timezone identifier | | `runImmediatelyOnStart` | `true` | Execute once on process startup | | `passesPerRun` | `1` | Number of complete runs per execution | | `vacation.enabled` | `false` | Skip random monthly off-block | | `vacation.minDays` | `3` | Minimum vacation days | | `vacation.maxDays` | `5` | Maximum vacation days | | `cron` | `undefined` | Optional cron expression (string or array) for advanced scheduling | ### **Cron Expressions (Advanced)** You can now drive the scheduler with classic cron syntax instead of a single daily time. Provide either a string or an array in `schedule.cron`. ```json { "schedule": { "enabled": true, "cron": [ "0 7 * * *", // every day at 07:00 "30 19 * * 1-5" // weekdays at 19:30 ], "timeZone": "Europe/Paris" } } ``` - Supports 5-field and 6-field cron expressions (`second minute hour day month weekday`). - When `cron` is set, the legacy `time`, `time12`, `time24`, and daily jitter env vars are ignored. - The scheduler still honors vacation mode, weekly random off-days, run-on-start, and watchdog features. --- ## 🚀 How It Works ### **Daily Scheduling** 1. **Calculate next run** — Timezone-aware scheduling 2. **Wait until time** — Minimal resource usage 3. **Execute passes** — Run script specified number of times 4. **Schedule next day** — Automatic DST adjustment ### **Startup Behavior** #### **Immediate Start Enabled (`true`)** - **Before scheduled time** → Run immediately + wait for next scheduled time - **After scheduled time** → Run immediately + wait for tomorrow's time #### **Immediate Start Disabled (`false`)** - **Any time** → Always wait for next scheduled time ### **Multiple Passes** - Each pass processes **all accounts** through **all tasks** - Useful for **maximum point collection** - Higher passes = **more points** but **increased detection risk** --- ## 🏖️ Vacation Mode ### **Monthly Off-Blocks** Vacation mode randomly selects a **contiguous block of days** each month to skip execution. ### **Configuration** ```json { "vacation": { "enabled": true, "minDays": 3, "maxDays": 5 } } ``` ### **How It Works** - **Random selection** — Different days each month - **Contiguous block** — Skip consecutive days, not scattered - **Independent** — Works with weekly random off-days - **Logged** — Shows selected vacation period ### **Example Output** ``` [SCHEDULE] Selected vacation block this month: 2025-01-15 → 2025-01-18 [SCHEDULE] Skipping run - vacation mode (3 days remaining) ``` --- ## 🌍 Supported Timezones ### **North America** - `America/New_York` — Eastern Time - `America/Chicago` — Central Time - `America/Denver` — Mountain Time - `America/Los_Angeles` — Pacific Time - `America/Phoenix` — Arizona (no DST) ### **Europe** - `Europe/London` — GMT/BST - `Europe/Paris` — CET/CEST - `Europe/Berlin` — CET/CEST - `Europe/Rome` — CET/CEST - `Europe/Moscow` — MSK ### **Asia Pacific** - `Asia/Tokyo` — JST - `Asia/Shanghai` — CST - `Asia/Kolkata` — IST - `Australia/Sydney` — AEST/AEDT - `Pacific/Auckland` — NZST/NZDT --- ## 🎲 Randomization & Watchdog ### **Environment Variables** ```powershell # Add random delay before first run (5-20 minutes) $env:SCHEDULER_INITIAL_JITTER_MINUTES_MIN=5 $env:SCHEDULER_INITIAL_JITTER_MINUTES_MAX=20 # Add daily jitter to scheduled time (2-10 minutes) $env:SCHEDULER_DAILY_JITTER_MINUTES_MIN=2 $env:SCHEDULER_DAILY_JITTER_MINUTES_MAX=10 # Kill stuck passes after N minutes $env:SCHEDULER_PASS_TIMEOUT_MINUTES=180 # Run each pass in separate process (recommended) $env:SCHEDULER_FORK_PER_PASS=true ``` ### **Benefits** - **Avoid patterns** — Prevents exact-time repetition - **Protection** — Kills stuck processes - **Isolation** — Process separation for stability --- ## 🖥️ Running the Scheduler ### **Development Mode** ```powershell npm run ts-schedule ``` ### **Production Mode** ```powershell npm run build npm run start:schedule ``` ### **Background Execution** ```powershell # Windows Background (PowerShell) Start-Process -NoNewWindow -FilePath "npm" -ArgumentList "run", "start:schedule" # Alternative: Windows Task Scheduler (recommended) # Create scheduled task via GUI or schtasks command ``` --- ## 📊 Usage Examples ### **Basic Daily Automation** ```json { "schedule": { "enabled": true, "time": "08:00", "timeZone": "America/New_York" } } ``` ⏰ **Perfect for morning routine** — Catch daily resets ### **Multiple Daily Passes** ```json { "schedule": { "enabled": true, "time": "10:00", "timeZone": "Europe/London", "runImmediatelyOnStart": false }, "passesPerRun": 3 } ``` 🔄 **Maximum points** with higher detection risk ### **Conservative with Vacation** ```json { "schedule": { "enabled": true, "time": "20:00", "timeZone": "America/Los_Angeles" }, "passesPerRun": 1, "vacation": { "enabled": true, "minDays": 4, "maxDays": 6 } } ``` 🏖️ **Natural patterns** with monthly breaks --- ## 🐳 Docker Integration ### **Built-in Scheduler (Recommended)** ```yaml services: microsoft-rewards-script: build: . environment: TZ: Europe/Paris command: ["npm", "run", "start:schedule"] ``` - Uses `passesPerRun` from config - Single long-running process - No external cron needed ### **External Cron (Project Default)** ```yaml services: microsoft-rewards-script: build: . environment: CRON_SCHEDULE: "0 7,16,20 * * *" RUN_ON_START: "true" ``` - Uses `run_daily.sh` with random delays - Multiple cron executions - Lockfile prevents overlaps --- ## 📋 Logging Output ### **Scheduler Initialization** ``` [SCHEDULE] Scheduler initialized for daily 09:00 America/New_York [SCHEDULE] Next run scheduled for 2025-01-21 09:00:00 EST ``` ### **Daily Execution** ``` [SCHEDULE] Starting scheduled run (pass 1 of 2) [SCHEDULE] Completed scheduled run in 12m 34s [SCHEDULE] Next run scheduled for 2025-01-22 09:00:00 EST ``` ### **Time Calculations** ``` [SCHEDULE] Current time: 2025-01-20 15:30:00 EDT [SCHEDULE] Target time: 2025-01-21 09:00:00 EDT [SCHEDULE] Waiting 17h 30m until next run ``` --- ## 🛠️ Troubleshooting | Problem | Solution | |---------|----------| | **Scheduler not running** | Check `enabled: true`; verify timezone format | | **Wrong execution time** | Verify system clock; check DST effects | | **Memory growth** | Restart process weekly; monitor logs | | **Missed executions** | Check system sleep/hibernation; verify process | ### **Debug Commands** ```powershell # Test timezone calculation node -e "console.log(new Date().toLocaleString('en-US', {timeZone: 'America/New_York'}))" # Verify config syntax node -e "const fs=require('fs');const strip=input=>{let out='',inString=false,stringChar='',inLine=false,inBlock=false;for(let i=0;i schedule.log 2>&1 & # Windows (background service - requires additional setup) # Recommend using Task Scheduler or Windows Service wrapper ``` ## Process Management ### Long-Running Process - Scheduler runs continuously - Automatically handles timezone changes - Graceful handling of system clock adjustments ### Memory Management - Minimal memory footprint between runs - Garbage collection after each execution - No memory leaks in long-running processes ### Error Recovery - Failed runs don't affect future scheduling - Automatic retry on next scheduled time - Error logging for troubleshooting ## Logging Output ### Scheduler Events ``` [SCHEDULE] Scheduler initialized for daily 09:00 America/New_York [SCHEDULE] Next run scheduled for 2025-09-21 09:00:00 EST [SCHEDULE] Starting scheduled run (pass 1 of 2) [SCHEDULE] Completed scheduled run in 12m 34s [SCHEDULE] Next run scheduled for 2025-09-22 09:00:00 EST ``` ### Time Calculations ``` [SCHEDULE] Current time: 2025-09-20 15:30:00 EDT [SCHEDULE] Target time: 2025-09-21 09:00:00 EDT [SCHEDULE] Waiting 17h 30m until next run ``` ## Integration with Other Features ### Docker Compatibility - Scheduler works in Docker containers - Alternative to external cron jobs - Timezone handling in containerized environments ### Buy Mode Exclusion - Scheduler only runs automation mode - Buy mode (`-buy`) ignores scheduler settings - Manual executions bypass scheduler ### Clustering - Scheduler runs only in single-process mode - Clustering disabled when scheduler is active - Use scheduler OR clustering, not both ## Best Practices ### Optimal Timing - **Morning runs**: Catch daily resets and new activities - **Evening runs**: Complete remaining tasks before midnight - **Avoid peak hours**: Reduce detection risk during high traffic ### Timezone Selection - Use your local timezone for easier monitoring - Consider Microsoft Rewards server timezone - Account for daylight saving time changes ### Multiple Passes - **2-3 passes**: Good balance of points vs. detection risk - **More passes**: Higher detection risk - **Single pass**: Safest but may miss some points ### Monitoring - Check logs regularly for errors - Monitor point collection trends - Verify scheduler is running as expected ## Troubleshooting ### Common Issues **Scheduler not running:** - Check `enabled: true` in config - Verify timezone format is correct - Ensure no syntax errors in config.jsonc (remember it allows comments) **Wrong execution time:** - Verify system clock is accurate - Check timezone identifier spelling - Consider daylight saving time effects **Memory growth over time:** - Restart scheduler process weekly - Monitor system resource usage - Check for memory leaks in logs **Missed executions:** - System was sleeping/hibernating - Process was killed or crashed - Clock was adjusted significantly ### Debug Commands ```bash # Test timezone calculation node -e "console.log(new Date().toLocaleString('en-US', {timeZone: 'America/New_York'}))" # Verify config syntax node -e "const fs=require('fs');const strip=input=>{let out='',inString=false,stringChar='',inLine=false,inBlock=false;for(let i=0;i