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