mirror of
https://github.com/LightZirconite/Microsoft-Rewards-Bot.git
synced 2026-01-10 17:26:17 +00:00
feat: Add Microsoft rate-limit detection and improve marketing opt-in unchecking strategies
This commit is contained in:
@@ -184,6 +184,36 @@ export class AccountCreator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CRITICAL: Check for Microsoft rate-limit block (too many accounts created)
|
||||||
|
try {
|
||||||
|
const blockTitles = [
|
||||||
|
'h1:has-text("We can\'t create your account")',
|
||||||
|
'h1:has-text("We can\'t create your Microsoft account")',
|
||||||
|
'h1:has-text("nous ne pouvons pas créer votre compte")', // French
|
||||||
|
'[data-testid="title"]:has-text("can\'t create")',
|
||||||
|
'[data-testid="title"]:has-text("unusual activity")'
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const selector of blockTitles) {
|
||||||
|
const blockElement = this.page.locator(selector).first()
|
||||||
|
const isVisible = await blockElement.isVisible({ timeout: 1000 }).catch(() => false)
|
||||||
|
|
||||||
|
if (isVisible) {
|
||||||
|
log(false, 'CREATOR', '🚨 MICROSOFT RATE LIMIT DETECTED', 'error')
|
||||||
|
log(false, 'CREATOR', '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', 'error')
|
||||||
|
log(false, 'CREATOR', '❌ "We can\'t create your account" error detected', 'error')
|
||||||
|
log(false, 'CREATOR', '📍 Cause: Too many accounts created from this IP recently', 'warn', 'yellow')
|
||||||
|
log(false, 'CREATOR', '⏰ Solution: Wait 24-48 hours before creating more accounts', 'warn', 'yellow')
|
||||||
|
log(false, 'CREATOR', '🌐 Alternative: Use a different IP address (VPN, proxy, mobile hotspot)', 'log', 'cyan')
|
||||||
|
log(false, 'CREATOR', '🔗 Learn more: https://go.microsoft.com/fwlink/?linkid=2259413', 'log', 'cyan')
|
||||||
|
log(false, 'CREATOR', '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', 'error')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1216,6 +1246,9 @@ export class AccountCreator {
|
|||||||
const hasErrors = !(await this.verifyNoErrors())
|
const hasErrors = !(await this.verifyNoErrors())
|
||||||
if (hasErrors) {
|
if (hasErrors) {
|
||||||
log(false, 'CREATOR', `❌ Errors detected after clicking Next (${step})`, 'error')
|
log(false, 'CREATOR', `❌ Errors detected after clicking Next (${step})`, 'error')
|
||||||
|
log(false, 'CREATOR', '⚠️ Browser left open for inspection. Press Ctrl+C to exit.', 'warn', 'yellow')
|
||||||
|
// Keep browser open for user to see the error
|
||||||
|
await new Promise(() => { })
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1597,6 +1630,10 @@ export class AccountCreator {
|
|||||||
const noErrors = await this.verifyNoErrors()
|
const noErrors = await this.verifyNoErrors()
|
||||||
if (!noErrors) {
|
if (!noErrors) {
|
||||||
log(false, 'CREATOR', '❌ Errors detected after filling names', 'error')
|
log(false, 'CREATOR', '❌ Errors detected after filling names', 'error')
|
||||||
|
log(false, 'CREATOR', '⚠️ This usually means Microsoft rate limit was triggered', 'warn', 'yellow')
|
||||||
|
log(false, 'CREATOR', '⚠️ Browser left open for inspection. Press Ctrl+C to exit.', 'warn', 'yellow')
|
||||||
|
// Keep browser open for user to see the error
|
||||||
|
await new Promise(() => { })
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1678,26 +1715,74 @@ export class AccountCreator {
|
|||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
log(false, 'CREATOR', '⚠️ Marketing checkbox is CHECKED (US locale default) - unchecking now...', 'log', 'yellow')
|
log(false, 'CREATOR', '⚠️ Marketing checkbox is CHECKED (US locale default) - unchecking now...', 'log', 'yellow')
|
||||||
|
|
||||||
// Click to uncheck
|
// IMPROVED: Try multiple click strategies for Fluent UI checkboxes
|
||||||
await checkbox.click()
|
let unchecked = false
|
||||||
await this.humanDelay(400, 800)
|
|
||||||
|
|
||||||
// CRITICAL: Verify it was actually unchecked
|
// Strategy 1: Normal Playwright click
|
||||||
const stillChecked = await checkbox.isChecked().catch(() => true)
|
try {
|
||||||
if (!stillChecked) {
|
await checkbox.click({ force: false })
|
||||||
log(false, 'CREATOR', '✅ Marketing opt-in unchecked successfully', 'log', 'green')
|
await this.humanDelay(500, 800)
|
||||||
} else {
|
const check1 = await checkbox.isChecked().catch(() => true)
|
||||||
log(false, 'CREATOR', '⚠️ Failed to uncheck marketing opt-in (still checked)', 'warn', 'yellow')
|
if (!check1) {
|
||||||
// Retry once
|
unchecked = true
|
||||||
log(false, 'CREATOR', '🔄 Retrying uncheck...', 'log', 'cyan')
|
log(false, 'CREATOR', '✅ Unchecked via normal click', 'log', 'green')
|
||||||
await checkbox.click()
|
|
||||||
await this.humanDelay(400, 800)
|
|
||||||
const finalCheck = await checkbox.isChecked().catch(() => true)
|
|
||||||
if (!finalCheck) {
|
|
||||||
log(false, 'CREATOR', '✅ Marketing opt-in unchecked on retry', 'log', 'green')
|
|
||||||
} else {
|
|
||||||
log(false, 'CREATOR', '❌ Could not uncheck marketing opt-in after retry', 'error')
|
|
||||||
}
|
}
|
||||||
|
} catch {
|
||||||
|
// Continue to next strategy
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategy 2: Force click (bypass visibility checks)
|
||||||
|
if (!unchecked) {
|
||||||
|
try {
|
||||||
|
await checkbox.click({ force: true })
|
||||||
|
await this.humanDelay(500, 800)
|
||||||
|
const check2 = await checkbox.isChecked().catch(() => true)
|
||||||
|
if (!check2) {
|
||||||
|
unchecked = true
|
||||||
|
log(false, 'CREATOR', '✅ Unchecked via force click', 'log', 'green')
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Continue to next strategy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategy 3: Click the label instead (Fluent UI pattern)
|
||||||
|
if (!unchecked) {
|
||||||
|
try {
|
||||||
|
const label = this.page.locator('label[for="marketingOptIn"]').first()
|
||||||
|
const labelVisible = await label.isVisible({ timeout: 1000 }).catch(() => false)
|
||||||
|
if (labelVisible) {
|
||||||
|
await label.click()
|
||||||
|
await this.humanDelay(500, 800)
|
||||||
|
const check3 = await checkbox.isChecked().catch(() => true)
|
||||||
|
if (!check3) {
|
||||||
|
unchecked = true
|
||||||
|
log(false, 'CREATOR', '✅ Unchecked via label click', 'log', 'green')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Continue to next strategy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategy 4: JavaScript click (most reliable for stubborn checkboxes)
|
||||||
|
if (!unchecked) {
|
||||||
|
try {
|
||||||
|
await checkbox.evaluate((el: HTMLInputElement) => el.click())
|
||||||
|
await this.humanDelay(500, 800)
|
||||||
|
const check4 = await checkbox.isChecked().catch(() => true)
|
||||||
|
if (!check4) {
|
||||||
|
unchecked = true
|
||||||
|
log(false, 'CREATOR', '✅ Unchecked via JavaScript click', 'log', 'green')
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unchecked) {
|
||||||
|
log(false, 'CREATOR', '❌ Could not uncheck marketing opt-in after all strategies', 'error')
|
||||||
|
log(false, 'CREATOR', '⚠️ Account will receive Microsoft promotional emails', 'warn', 'yellow')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log(false, 'CREATOR', '✅ Marketing opt-in already unchecked (good!)', 'log', 'green')
|
log(false, 'CREATOR', '✅ Marketing opt-in already unchecked (good!)', 'log', 'green')
|
||||||
|
|||||||
Reference in New Issue
Block a user