# ⏰ 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 - ⚡ **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 | --- ## 🚀 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 "console.log(JSON.parse((Get-Content 'src/config.json' | Out-String)))" # Check running processes Get-Process | Where-Object {$_.ProcessName -eq "node"} ``` --- ## ⚡ Performance & Best Practices ### **Optimal Timing** - **🌅 Morning (7-10 AM)** — Catch daily resets - **🌆 Evening (7-10 PM)** — Complete remaining tasks - **❌ Avoid peak hours** — Reduce detection during high traffic ### **Pass Recommendations** - **1 pass** — Safest, good for most users - **2-3 passes** — Balance of points vs. risk - **4+ passes** — Higher risk, development only ### **Monitoring** - ✅ Check logs regularly for errors - ✅ Monitor point collection trends - ✅ Verify scheduler status weekly --- ## 🔗 Alternative Solutions ### **Windows Task Scheduler** ```powershell # Create scheduled task schtasks /create /tn "MS-Rewards" /tr "npm start" /sc daily /st 09:00 /sd 01/01/2025 ``` ### **PowerShell Scheduled Job** ```powershell # Register scheduled job Register-ScheduledJob -Name "MSRewards" -ScriptBlock {cd "C:\path\to\project"; npm start} -Trigger (New-JobTrigger -Daily -At 9am) ``` --- ## 🔗 Related Guides - **[Getting Started](./getting-started.md)** — Initial setup and configuration - **[Humanization](./humanization.md)** — Natural behavior patterns - **[Docker](./docker.md)** — Container deployment - **[Job State](./jobstate.md)** — Execution state management ## Usage Examples ### Basic Daily Run ```json { "schedule": { "enabled": true, "time": "08:00", "timeZone": "America/New_York" } } ``` ### Multiple Daily Passes ```json { "schedule": { "enabled": true, "time": "10:00", "timeZone": "Europe/London", "runImmediatelyOnStart": false }, "passesPerRun": 3 } ``` ### Development Testing ```json { "schedule": { "enabled": true, "time": "00:01", "timeZone": "UTC", "runImmediatelyOnStart": true } } ``` ## Supported Timezones Common IANA timezone identifiers: ### 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) ### UTC Variants - `UTC` (Coordinated Universal Time) - `GMT` (Greenwich Mean Time) ## Running the Scheduler ### Development Mode ```bash npm run ts-schedule ``` ### Production Mode ```bash npm run build npm run start:schedule ``` ### Optional Randomization and Watchdog You can introduce slight randomness to the start times and protect against stuck runs: - `SCHEDULER_INITIAL_JITTER_MINUTES_MIN` / `SCHEDULER_INITIAL_JITTER_MINUTES_MAX` - Adds a one‑time random delay before the very first run after the scheduler starts. - Example: `SCHEDULER_INITIAL_JITTER_MINUTES_MIN=5` and `SCHEDULER_INITIAL_JITTER_MINUTES_MAX=20` delays the first run by 5–20 minutes. - `SCHEDULER_DAILY_JITTER_MINUTES_MIN` / `SCHEDULER_DAILY_JITTER_MINUTES_MAX` - Adds an extra random delay to each daily scheduled execution. - Example: 2–10 minutes of daily jitter to avoid exact same second each day. - `SCHEDULER_PASS_TIMEOUT_MINUTES` - Kills a stuck pass after N minutes (default 180). Useful if the underlying browser gets stuck. - `SCHEDULER_FORK_PER_PASS` - Defaults to `true`. When `true`, each pass runs in a child Node process so a stuck pass can be terminated without killing the scheduler. Set to `false` to run passes in‑process (not recommended). ### Background Execution ```bash # Linux/macOS (background process) nohup npm run start:schedule > 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.json **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 "console.log(JSON.parse(require('fs').readFileSync('src/config.json')))" # Check process status ps aux | grep "start:schedule" ``` ## Alternative Solutions ### External Cron (Linux/macOS) ```bash # Crontab entry for 9 AM daily 0 9 * * * cd /path/to/MSN-V2 && npm start # Multiple times per day 0 9,15,21 * * * cd /path/to/MSN-V2 && npm start ``` ### Windows Task Scheduler - Create scheduled task via Task Scheduler - Set trigger for daily execution - Configure action to run `npm start` in project directory ### Docker Cron ```dockerfile # Add to Dockerfile RUN apt-get update && apt-get install -y cron COPY crontab /etc/cron.d/rewards-cron RUN crontab /etc/cron.d/rewards-cron ``` ### Docker + Built-in Scheduler Au lieu d'utiliser cron, vous pouvez lancer le scheduler intégré dans le conteneur (un seul process long‑vivant) : ```yaml services: microsoft-rewards-script: build: . environment: TZ: Europe/Paris command: ["npm", "run", "start:schedule"] ``` Dans ce mode : - `passesPerRun` fonctionne (exécutera plusieurs passes à chaque horaire interne défini par `src/config.json`). - Vous n'avez plus besoin de `CRON_SCHEDULE` ni de `run_daily.sh`. ### Docker + External Cron (par défaut du projet) Si vous préférez la planification par cron système dans le conteneur (valeur par défaut du projet) : - Utilisez `CRON_SCHEDULE` (ex.: `0 7,16,20 * * *`). - `run_daily.sh` introduit un délai aléatoire (par défaut 5–50 min) et un lockfile pour éviter les chevauchements. - `RUN_ON_START=true` déclenche une exécution immédiate au démarrage du conteneur (sans délai aléatoire). ## Performance Considerations ### System Resources - Minimal CPU usage between runs - Low memory footprint when idle - No network activity during waiting periods ### Startup Time - Fast initialization (< 1 second) - Quick timezone calculations - Immediate scheduling of next run ### Reliability - Robust error handling - Automatic recovery from failures - Consistent execution timing