Detect LinkedIn Easy Apply daily limit and stop run
When LinkedIn shows "Easy Apply limit" message, detect it in the modal-open check, return rate_limited status, put job back in queue, send Telegram alert, and stop the entire run. Prevents burning retries and wasting browser sessions when rate limited. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -201,6 +201,7 @@ async function main() {
|
|||||||
]);
|
]);
|
||||||
result.applyStartedAt = applyStartedAt;
|
result.applyStartedAt = applyStartedAt;
|
||||||
await handleResult(job, result, results, settings, profile, apiKey);
|
await handleResult(job, result, results, settings, profile, apiKey);
|
||||||
|
if (results.rate_limited) break;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(` ❌ Error: ${e.message}`);
|
console.error(` ❌ Error: ${e.message}`);
|
||||||
if (e.stack) console.error(` Stack: ${e.stack.split('\n').slice(1, 3).join(' | ').trim()}`);
|
if (e.stack) console.error(` Stack: ${e.stack.split('\n').slice(1, 3).join(' | ').trim()}`);
|
||||||
@@ -241,6 +242,10 @@ async function main() {
|
|||||||
} finally {
|
} finally {
|
||||||
await browser?.browser?.close().catch(() => {});
|
await browser?.browser?.close().catch(() => {});
|
||||||
}
|
}
|
||||||
|
if (results.rate_limited) {
|
||||||
|
await sendTelegram(settings, `⚠️ *LinkedIn Easy Apply daily limit reached* — stopping all applications until tomorrow.`).catch(() => {});
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final summary + Telegram
|
// Final summary + Telegram
|
||||||
@@ -325,6 +330,12 @@ async function handleResult(job, result, results, settings, profile, apiKey) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'rate_limited':
|
||||||
|
console.log(` ⚠️ LinkedIn Easy Apply daily limit reached — stopping run`);
|
||||||
|
updateJobStatus(job.id, 'new', { title, company, retry_reason: 'rate_limited' });
|
||||||
|
results.rate_limited = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'closed':
|
case 'closed':
|
||||||
console.log(` 🚫 Closed — no longer accepting applications`);
|
console.log(` 🚫 Closed — no longer accepting applications`);
|
||||||
updateJobStatus(job.id, 'closed', { title, company });
|
updateJobStatus(job.id, 'closed', { title, company });
|
||||||
|
|||||||
@@ -143,13 +143,19 @@ export async function apply(page, job, formFiller) {
|
|||||||
let modal = await page.waitForSelector(LINKEDIN_EASY_APPLY_MODAL_SELECTOR, { timeout: 10000 }).catch(() => null);
|
let modal = await page.waitForSelector(LINKEDIN_EASY_APPLY_MODAL_SELECTOR, { timeout: 10000 }).catch(() => null);
|
||||||
|
|
||||||
if (!modal) {
|
if (!modal) {
|
||||||
// Check if the listing is closed
|
// Check if the listing is closed or rate limited
|
||||||
const closed = await page.evaluate(() => {
|
const pageCheck = await page.evaluate(() => {
|
||||||
const text = (document.body.innerText || '').toLowerCase();
|
const text = (document.body.innerText || '').toLowerCase();
|
||||||
return text.includes('no longer accepting') || text.includes('no longer available') ||
|
const closed = text.includes('no longer accepting') || text.includes('no longer available') ||
|
||||||
text.includes('this job has expired') || text.includes('job is closed');
|
text.includes('this job has expired') || text.includes('job is closed');
|
||||||
}).catch(() => false);
|
const rateLimited = text.includes('easy apply limit') || text.includes('limit easy apply');
|
||||||
if (closed) {
|
return { closed, rateLimited };
|
||||||
|
}).catch(() => ({ closed: false, rateLimited: false }));
|
||||||
|
if (pageCheck.rateLimited) {
|
||||||
|
console.log(` ⚠️ LinkedIn Easy Apply daily limit reached`);
|
||||||
|
return { status: 'rate_limited', meta };
|
||||||
|
}
|
||||||
|
if (pageCheck.closed) {
|
||||||
console.log(` ℹ️ Job closed — no longer accepting applications`);
|
console.log(` ℹ️ Job closed — no longer accepting applications`);
|
||||||
return { status: 'closed', meta };
|
return { status: 'closed', meta };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user