Files
Microsoft-Rewards-Bot/.github/copilot-instructions.md
LightZirconite e981a69095 Refactor bot startup process to auto-create configuration files, enhance update system, and add historical stats endpoints
- Updated README.md to reflect new bot setup and configuration process.
- Removed outdated installer README and integrated update logic directly into the bot.
- Implemented smart update for example configuration files, ensuring user files are not overwritten.
- Added FileBootstrap class to handle automatic creation of configuration files on first run.
- Enhanced BotController to manage stop requests and ensure graceful shutdown.
- Introduced new stats management features, including historical stats and activity breakdown endpoints.
- Updated API routes to include new statistics retrieval functionalities.
2026-01-02 18:38:56 +01:00

11 KiB

Copilot Instructions - Microsoft Rewards Bot

Project Architecture

Core Structure

src/
├── index.ts                 # Main entry point, bot orchestration
├── constants.ts             # Global constants and configurations
├── account-creation/        # Automated account creation system
├── browser/                 # Browser automation (Playwright)
├── dashboard/               # Web dashboard (Express + WebSockets)
├── flows/                   # Desktop/Mobile automation flows
├── functions/               # Core features (Login, Activities, Workers)
├── interface/               # TypeScript interfaces and types
├── scheduler/               # Task scheduling system
└── util/                    # Utility modules
    ├── browser/             # Browser utilities (UA, Humanizer)
    ├── core/                # Core utilities (Utils, MemoryMonitor)
    ├── network/             # HTTP clients, query engines
    ├── notifications/       # Discord, NTFY notifications
    ├── security/            # Anti-detection, ban detection
    ├── state/               # State management (JobState, Load)
    └── validation/          # Input validation, startup checks

Key Design Patterns

1. Bot Class Pattern (index.ts)

  • Main orchestrator with dependency injection
  • Manages lifecycle: initialize → run → cleanup
  • Supports cluster mode (multi-account parallel processing)
  • Implements crash recovery and graceful shutdown

2. Flow Pattern (flows/)

  • DesktopFlow: Desktop browser automation
  • MobileFlow: Mobile browser automation
  • SummaryReporter: Centralized reporting system
  • Each flow is self-contained with error handling

3. Activity Handler Pattern (functions/activities/)

  • Each activity (Quiz, Poll, Search, etc.) is a separate class
  • Implements error recovery and retry logic
  • Uses human-like delays and behaviors

4. State Management (util/state/)

  • JobState: Persistent task completion tracking
  • AccountHistory: Historical data storage
  • Load: Configuration and account loading
  • Files use .jsonc format (JSON with comments)

5. Dashboard Architecture (dashboard/)

  • Server: Express server with WebSockets
  • BotController: Bot lifecycle management for dashboard
  • StatsManager: Persistent statistics tracking
  • State: In-memory state management
  • Real-time updates via WebSocket broadcast

Critical Implementation Rules

1. Configuration Files

IMPORTANT: Files use .example.jsonc templates:

  • src/config.example.jsoncsrc/config.jsonc
  • src/accounts.example.jsoncsrc/accounts.jsonc
  • Auto-copied on first run by FileBootstrap.ts

Loading Order:

// 1. Check multiple locations
const candidates = [
  'src/config.jsonc',
  'config.jsonc',
  'src/config.json'  // Legacy support
]

// 2. Strip JSON comments
const text = stripJsonComments(rawContent)

// 3. Normalize schema (flat + nested support)
const config = normalizeConfig(JSON.parse(text))

2. Browser Automation

Always use these utilities:

// Humanized typing
await this.browser.utils.humanType(page, selector, text)

// Smart waits (handles stale elements)
await this.browser.utils.smartWait(page, selector, { timeout: 30000 })

// Random gestures (anti-detection)
await this.humanizer.randomGesture(page)

NEVER:

  • Direct page.type() or page.fill()
  • Fixed delays (await page.waitForTimeout(5000))
  • Hardcoded selectors without fallback

3. Error Handling

Pattern to follow:

try {
  // Attempt operation
  await riskyOperation()
} catch (error) {
  // 1. Detect ban/security
  const ban = detectBanReason(error)
  if (ban.status) {
    await this.engageGlobalStandby(ban.reason, email)
    throw error
  }
  
  // 2. Log with context
  log(this.isMobile, 'MODULE', `Failed: ${getErrorMessage(error)}`, 'error')
  
  // 3. Retry or fail gracefully
  if (retryCount < MAX_RETRIES) {
    await this.utils.wait(BACKOFF_MS)
    return await retryOperation()
  }
  
  throw error
}

4. Logging System

Use centralized logger:

import { log } from '../util/notifications/Logger'

// Format: log(isMobile, source, message, level, color)
log(false, 'SEARCH', 'Starting desktop searches', 'log', 'cyan')
log(true, 'QUIZ', 'Quiz failed: timeout', 'error', 'red')

Levels: 'log' | 'warn' | 'error'
Colors: 'cyan' | 'yellow' | 'red' | 'green'

5. State Persistence

Always use JobState for idempotency:

// Check if already done
if (this.accountJobState.isCompleted(email, activityKey)) {
  log(mobile, 'ACTIVITY', `${activityKey} already completed`, 'warn')
  return
}

// Mark as completed after success
this.accountJobState.markCompleted(email, activityKey)

Activity Keys:

  • desktop-search, mobile-search
  • daily-set, more-promotions, punch-cards
  • read-to-earn, daily-check-in

6. Dashboard Integration

Update dashboard state:

import { dashboardState } from '../dashboard/state'

// Update account status
dashboardState.updateAccount(email, {
  status: 'running', // 'idle' | 'running' | 'completed' | 'error'
  errors: []
})

// Add logs
dashboardState.addLog({
  timestamp: new Date().toISOString(),
  level: 'log',
  platform: 'DESKTOP',
  title: 'SEARCH',
  message: 'Completed 30 searches'
})

7. Anti-Detection

Mandatory humanization:

// Random delays between actions
await this.humanizer.randomDelay('search') // 2-5 seconds

// Mouse movements
await this.humanizer.randomGesture(page)

// Scroll simulation
await this.browser.utils.scrollRandomAmount(page)

// Click with human-like coordinates
await this.browser.utils.humanClick(page, selector)

CRITICAL: Never disable humanization in production!


Common Tasks

Adding a New Activity

  1. Create activity class:
// src/functions/activities/NewActivity.ts
import { ActivityHandler } from '../../interface/ActivityHandler'

export class NewActivity extends ActivityHandler {
  async execute(): Promise<void> {
    const activityKey = 'new-activity'
    
    // Check if already done
    if (this.bot.accountJobState.isCompleted(this.bot.currentAccountEmail!, activityKey)) {
      return
    }
    
    // Execute activity
    await this.performActivity()
    
    // Mark complete
    this.bot.accountJobState.markCompleted(this.bot.currentAccountEmail!, activityKey)
  }
  
  private async performActivity(): Promise<void> {
    // Implementation
  }
}
  1. Register in Workers.ts:
if (this.bot.config.workers.doNewActivity) {
  await this.runActivity('NewActivity', async () => {
    const activity = new NewActivity(this.bot)
    await activity.execute()
  })
}
  1. Add config option:
// interface/Config.ts
export interface ConfigWorkers {
  doNewActivity: boolean
  // ... other activities
}

Adding a Dashboard API Endpoint

// src/dashboard/routes.ts
apiRouter.get('/api/new-endpoint', async (req: Request, res: Response) => {
  try {
    // Validate input
    const param = req.query.param as string
    if (!param) {
      return sendError(res, 400, 'Missing param')
    }
    
    // Process
    const result = await processData(param)
    
    // Respond
    res.json({ success: true, data: result })
  } catch (error) {
    sendError(res, 500, getErr(error))
  }
})

Debugging

Enable verbose logging:

# Full debug output
DEBUG_REWARDS_VERBOSE=1 npm start

# Specific module debug
DEBUG=playwright:* npm start

Common debug points:

  • Browser: this.browser.func.makeDebugScreenshot(page, 'issue-name')
  • State: console.log(this.accountJobState.getState(email))
  • Network: await this.axios.request(config) (auto-logged)

Testing Checklist

Before committing changes:

  • npm run build succeeds
  • npm run lint passes (or npm run lint:fix)
  • Test with npm start (single account)
  • Test dashboard with npm run dashboard
  • Check JobState resume works (stop mid-run, restart)
  • Verify humanization delays are active
  • Test error handling (disconnect network mid-run)
  • Check logs are informative and properly formatted

File Naming Conventions

  • Interfaces: PascalCase (Account.ts, Config.ts)
  • Classes: PascalCase (BrowserFunc.ts, StatsManager.ts)
  • Utilities: PascalCase (Utils.ts, Logger.ts)
  • Constants: SCREAMING_SNAKE_CASE in constants.ts
  • Config files: kebab-case + .jsonc extension

Prohibited Patterns

DO NOT:

  • Hardcode credentials or sensitive data
  • Use any type (use unknown + type guards)
  • Directly manipulate dist/ (auto-generated from src/)
  • Create .json configs (use .jsonc with comments)
  • Ignore TypeScript errors (fix properly)
  • Use console.log() directly (use log() function)
  • Block main thread with while(true) loops
  • Store passwords in plaintext outside accounts.jsonc

DO:

  • Use strict TypeScript checks
  • Add JSDoc comments for public APIs
  • Handle all promise rejections
  • Use try/finally for cleanup
  • Validate external input
  • Use environment variables for secrets when possible
  • Test on Windows + Linux (cross-platform compatible)

Key Dependencies

Package Purpose Notes
rebrowser-playwright Browser automation Patched for detection evasion
fingerprint-generator Browser fingerprinting Generates realistic fingerprints
express Dashboard server RESTful API + WebSockets
axios HTTP client Used for Rewards API calls
cheerio HTML parsing Extracting activity data
chalk Terminal colors Pretty console output

Update Process

  1. GitHub releases: Bot auto-updates from GitHub
  2. Config updates: Use autoUpdateConfig: false to preserve customizations
  3. Accounts updates: Use autoUpdateAccounts: false to preserve credentials
  4. Smart merge: Compares local vs remote, only updates if unchanged

See: scripts/installer/update.mjs for implementation


Performance Guidelines

  • Memory: Target < 500MB per account (monitor with MemoryMonitor.ts)
  • Execution time: ~5-10 minutes per account (desktop + mobile)
  • Concurrent accounts: Default 1 cluster, max 4 recommended
  • Rate limiting: Respect Bing search delays (3-5 min default)

Support & Community

  • GitHub Issues: Bug reports and feature requests
  • Discord: Real-time community support
  • Docs: docs/ folder contains detailed guides

Last Updated: January 2026
Maintainer: LightZirconite