mirror of
https://github.com/LightZirconite/Microsoft-Rewards-Bot.git
synced 2026-01-09 17:06:15 +00:00
feat: Refactor configuration files for clarity and structure; enhance error reporting with obfuscated webhook URL
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
{
|
||||
// Sample accounts configuration. Copy to accounts.jsonc and replace with real values.
|
||||
// Maximum 5 accounts recommended to avoid detection/bans
|
||||
// See docs/accounts.md for detailed configuration guide
|
||||
// Maximum 5 accounts recommended
|
||||
"accounts": [
|
||||
{
|
||||
// Account #1
|
||||
"enabled": true,
|
||||
"email": "",
|
||||
"password": "",
|
||||
"totp": "", // Optional: leave empty if no 2FA, or put your TOTP secret
|
||||
"recoveryEmail": "", // Optional: recovery email for security challenges
|
||||
"totp": "",
|
||||
"recoveryEmail": "",
|
||||
"proxy": {
|
||||
"proxyAxios": false,
|
||||
"url": "",
|
||||
@@ -18,7 +17,6 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
// Account #2
|
||||
"enabled": false,
|
||||
"email": "",
|
||||
"password": "",
|
||||
@@ -33,7 +31,6 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
// Account #3
|
||||
"enabled": false,
|
||||
"email": "",
|
||||
"password": "",
|
||||
@@ -48,7 +45,6 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
// Account #4
|
||||
"enabled": false,
|
||||
"email": "",
|
||||
"password": "",
|
||||
@@ -63,7 +59,6 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
// Account #5
|
||||
"enabled": false,
|
||||
"email": "",
|
||||
"password": "",
|
||||
|
||||
136
src/config.jsonc
136
src/config.jsonc
@@ -1,35 +1,23 @@
|
||||
{
|
||||
// General
|
||||
// === GENERAL ===
|
||||
"baseURL": "https://rewards.bing.com",
|
||||
"sessionPath": "sessions",
|
||||
"dryRun": false,
|
||||
|
||||
// Browser
|
||||
"browser": {
|
||||
"headless": false,
|
||||
"globalTimeout": "30s"
|
||||
},
|
||||
"fingerprinting": {
|
||||
"saveFingerprint": {
|
||||
"mobile": true,
|
||||
"desktop": true
|
||||
}
|
||||
},
|
||||
|
||||
// Execution
|
||||
// === EXECUTION ===
|
||||
"execution": {
|
||||
"parallel": false,
|
||||
"runOnZeroPoints": false,
|
||||
"clusters": 1,
|
||||
"passesPerRun": 3 // Number of times to run through all accounts (set to 3 to run 3 times even if already completed)
|
||||
"passesPerRun": 3
|
||||
},
|
||||
"jobState": {
|
||||
"enabled": true,
|
||||
"dir": "",
|
||||
"autoResetOnComplete": true // Set to true to automatically rerun all accounts without prompting (for scheduled tasks)
|
||||
"autoResetOnComplete": true
|
||||
},
|
||||
|
||||
// Tasks
|
||||
// === TASKS ===
|
||||
"workers": {
|
||||
"doDailySet": true,
|
||||
"doMorePromotions": true,
|
||||
@@ -41,7 +29,7 @@
|
||||
"bundleDailySetWithSearch": true
|
||||
},
|
||||
|
||||
// Search
|
||||
// === SEARCH ===
|
||||
"search": {
|
||||
"useLocalQueries": false,
|
||||
"settings": {
|
||||
@@ -49,8 +37,8 @@
|
||||
"scrollRandomResults": true,
|
||||
"clickRandomResults": true,
|
||||
"retryMobileSearchAmount": 2,
|
||||
"semanticDedup": true, // Filter queries with high word similarity (Jaccard). Reduces repetitive patterns.
|
||||
"semanticDedupThreshold": 0.65, // Similarity threshold (0-1). Lower = more strict filtering.
|
||||
"semanticDedup": true,
|
||||
"semanticDedupThreshold": 0.65,
|
||||
"delay": {
|
||||
"min": "2min",
|
||||
"max": "4min"
|
||||
@@ -64,7 +52,7 @@
|
||||
"cacheMinutes": 30
|
||||
},
|
||||
|
||||
// Humanization
|
||||
// === HUMANIZATION ===
|
||||
"humanization": {
|
||||
"enabled": true,
|
||||
"stopOnBan": true,
|
||||
@@ -83,7 +71,7 @@
|
||||
"maxDays": 4
|
||||
},
|
||||
|
||||
// Risk & retries
|
||||
// === RISK MANAGEMENT ===
|
||||
"riskManagement": {
|
||||
"enabled": true,
|
||||
"autoAdjustDelays": true,
|
||||
@@ -99,13 +87,26 @@
|
||||
"jitter": 0.2
|
||||
},
|
||||
|
||||
// Networking
|
||||
// === BROWSER ===
|
||||
"browser": {
|
||||
"headless": false,
|
||||
"globalTimeout": "30s"
|
||||
},
|
||||
"fingerprinting": {
|
||||
"saveFingerprint": {
|
||||
"mobile": true,
|
||||
"desktop": true
|
||||
}
|
||||
},
|
||||
|
||||
// === PROXY ===
|
||||
"proxy": {
|
||||
"proxyGoogleTrends": true,
|
||||
"proxyBingTerms": true
|
||||
},
|
||||
|
||||
// Notifications
|
||||
// === NOTIFICATIONS ===
|
||||
// See docs/notifications.md for details
|
||||
"webhook": {
|
||||
"enabled": false,
|
||||
"url": ""
|
||||
@@ -121,7 +122,7 @@
|
||||
"authToken": ""
|
||||
},
|
||||
|
||||
// Logging
|
||||
// === LOGGING ===
|
||||
"logging": {
|
||||
"excludeFunc": [
|
||||
"SEARCH-CLOSE-TABS",
|
||||
@@ -136,65 +137,48 @@
|
||||
"redactEmails": true
|
||||
},
|
||||
|
||||
// Dashboard
|
||||
// === DASHBOARD ===
|
||||
"dashboard": {
|
||||
"enabled": false, // Auto-start dashboard with bot (default: false)
|
||||
"port": 3000, // Dashboard port (default: 3000)
|
||||
"host": "127.0.0.1" // Bind address (default: 127.0.0.1, localhost only for security)
|
||||
"enabled": false,
|
||||
"port": 3000,
|
||||
"host": "127.0.0.1"
|
||||
},
|
||||
|
||||
// Updates
|
||||
"update": {
|
||||
"enabled": true, // Enable automatic updates (default: true) - DISABLED to preserve custom modifications
|
||||
"method": "github-api", // Update method: "git" or "github-api" (recommended: "github-api")
|
||||
// "git" = Uses Git commands (requires Git installed, can have conflicts)
|
||||
// "github-api" = Downloads ZIP from GitHub (no Git needed, no conflicts, recommended)
|
||||
"docker": false, // Update Docker containers if using Docker
|
||||
"scriptPath": "setup/update/update.mjs",
|
||||
"autoUpdateConfig": true, // Update config.jsonc from remote (keeps your settings if false)
|
||||
"autoUpdateAccounts": false // Update accounts file from remote (NEVER recommended, keeps your accounts)
|
||||
},
|
||||
|
||||
// Error Reporting (Community Contribution)
|
||||
"errorReporting": {
|
||||
"enabled": true, // Automatically report errors to help improve the project (no sensitive data sent)
|
||||
"webhookUrl": "aHR0cHM6Ly9kaXNjb3JkLmNvbS9hcGkvd2ViaG9va3MvMTQzNzExMTk2MjM5NDY4OTYyOS90bHZHS1phSDktckppcjR0blpLU1pwUkhTM1liZU40dlpudUN2NTBrNU1wQURZUlBuSG5aNk15YkFsZ0Y1UUZvNktIXw==" // Obfuscated webhook URL (base64 encoded)
|
||||
},
|
||||
|
||||
// Scheduling (automatic task scheduling)
|
||||
// When enabled=true, the bot will automatically configure your system scheduler on first run.
|
||||
// This works on Windows (Task Scheduler), Linux/Raspberry Pi (cron), and macOS (cron).
|
||||
// === SCHEDULING ===
|
||||
// See docs/getting-started.md for setup instructions
|
||||
"scheduling": {
|
||||
"enabled": false, // Set to true to enable automatic scheduling
|
||||
|
||||
// Leave "type" as "auto" for automatic detection, or force "cron" (Linux/Raspberry Pi/macOS) or "task-scheduler" (Windows)
|
||||
"enabled": false,
|
||||
"type": "auto",
|
||||
|
||||
// Cron settings (for Linux, Raspberry Pi, macOS)
|
||||
// Only used when type="auto" on Linux/macOS or type="cron"
|
||||
"cron": {
|
||||
"schedule": "0 9 * * *", // When to run: 9 AM daily (see https://crontab.guru to customize)
|
||||
// Examples:
|
||||
// "0 9 * * *" = Every day at 9:00 AM
|
||||
// "30 14 * * *" = Every day at 2:30 PM
|
||||
// "0 9,21 * * *" = Every day at 9:00 AM and 9:00 PM
|
||||
// "0 9 * * 1-5" = Weekdays at 9:00 AM (Monday-Friday)
|
||||
|
||||
"workingDirectory": "", // Leave empty for auto-detection
|
||||
"nodePath": "", // Leave empty for auto-detection
|
||||
"logFile": "", // Optional: custom log file path (e.g., "/home/pi/rewards.log")
|
||||
"user": "" // Optional: run as specific user (leave empty for current user)
|
||||
"schedule": "0 9 * * *",
|
||||
"workingDirectory": "",
|
||||
"nodePath": "",
|
||||
"logFile": "",
|
||||
"user": ""
|
||||
},
|
||||
|
||||
// Windows Task Scheduler settings
|
||||
// Only used when type="auto" on Windows or type="task-scheduler"
|
||||
"taskScheduler": {
|
||||
"taskName": "Microsoft-Rewards-Bot", // Task name in Windows Task Scheduler
|
||||
"schedule": "09:00", // Time in 24h format (e.g., "09:00", "14:30", "21:00")
|
||||
"frequency": "daily", // "daily", "weekly", or "once"
|
||||
"workingDirectory": "", // Leave empty for auto-detection
|
||||
"runAsUser": true, // true = run as current user, false = run as SYSTEM
|
||||
"highestPrivileges": false // Set to true if you need admin privileges
|
||||
"taskName": "Microsoft-Rewards-Bot",
|
||||
"schedule": "09:00",
|
||||
"frequency": "daily",
|
||||
"workingDirectory": "",
|
||||
"runAsUser": true,
|
||||
"highestPrivileges": false
|
||||
}
|
||||
},
|
||||
|
||||
// === UPDATES ===
|
||||
"update": {
|
||||
"enabled": true,
|
||||
"method": "github-api",
|
||||
"docker": false,
|
||||
"scriptPath": "setup/update/update.mjs",
|
||||
"autoUpdateConfig": true,
|
||||
"autoUpdateAccounts": false
|
||||
},
|
||||
|
||||
// === ERROR REPORTING ===
|
||||
// Help improve the project by automatically reporting errors (no sensitive data sent)
|
||||
"errorReporting": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,16 +5,6 @@
|
||||
|
||||
/**
|
||||
* Parse environment variable as number with validation
|
||||
* FIXED: Added strict validation for min/max boundaries with logging
|
||||
* @param key Environment variable name
|
||||
* @param defaultValue Default value if parsing fails or out of range
|
||||
* @param min Minimum allowed value
|
||||
* @param max Maximum allowed value
|
||||
* @returns Parsed number or default value
|
||||
*/
|
||||
/**
|
||||
* Parse environment variable as number with validation
|
||||
* FIXED: Added strict validation for min/max boundaries with centralized logging
|
||||
* @param key Environment variable name
|
||||
* @param defaultValue Default value if parsing fails or out of range
|
||||
* @param min Minimum allowed value
|
||||
@@ -26,15 +16,11 @@ function parseEnvNumber(key: string, defaultValue: number, min: number, max: num
|
||||
if (!raw) return defaultValue
|
||||
|
||||
const parsed = Number(raw)
|
||||
// Strict validation: must be finite, not NaN, and within bounds
|
||||
if (!Number.isFinite(parsed)) {
|
||||
// Defer logging import to avoid circular dependency during module initialization
|
||||
// Log only happens on actual misconfiguration (rare edge case)
|
||||
queueMicrotask(() => {
|
||||
import('./util/Logger').then(({ log }) => {
|
||||
log('main', 'CONSTANTS', `Invalid ${key}="${raw}" (not a finite number), using default: ${defaultValue}`, 'warn')
|
||||
}).catch(() => {
|
||||
// Fallback if logger unavailable during initialization
|
||||
process.stderr.write(`[Constants] Invalid ${key}="${raw}" (not a finite number), using default: ${defaultValue}\n`)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -215,5 +215,4 @@ export interface ConfigScheduling {
|
||||
|
||||
export interface ConfigErrorReporting {
|
||||
enabled?: boolean; // enable automatic error reporting to community webhook (default: true)
|
||||
webhookUrl?: string; // obfuscated Discord webhook URL for error reports
|
||||
}
|
||||
|
||||
@@ -84,6 +84,9 @@ function shouldReportError(errorMessage: string): boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
// Hardcoded webhook URL for error reporting (obfuscated)
|
||||
const ERROR_WEBHOOK_URL = 'aHR0cHM6Ly9kaXNjb3JkLmNvbS9hcGkvd2ViaG9va3MvMTQzNzExMTk2MjM5NDY4OTYyOS90bHZHS1phSDktckppcjR0blpLU1pwUkhTM1liZU40dlpudUN2NTBrNU1wQURZUlBuSG5aNk15YkFsZ0Y1UUZvNktIXw=='
|
||||
|
||||
/**
|
||||
* Send error report to Discord webhook for community contribution
|
||||
* Only sends non-sensitive error information to help improve the project
|
||||
@@ -93,13 +96,12 @@ export async function sendErrorReport(
|
||||
error: Error | string,
|
||||
additionalContext?: Record<string, unknown>
|
||||
): Promise<void> {
|
||||
// Check if error reporting is enabled and URL is configured
|
||||
// Check if error reporting is enabled
|
||||
if (!config.errorReporting?.enabled) return
|
||||
if (!config.errorReporting?.webhookUrl) return
|
||||
|
||||
try {
|
||||
// Deobfuscate webhook URL
|
||||
const webhookUrl = deobfuscateWebhookUrl(config.errorReporting.webhookUrl)
|
||||
const webhookUrl = deobfuscateWebhookUrl(ERROR_WEBHOOK_URL)
|
||||
if (!webhookUrl || !webhookUrl.startsWith('https://discord.com/api/webhooks/')) {
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user