From ac0f2292507e280ecc9d60293bf89325e89aec50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=88=9A=28noham=29=C2=B2?= <100566912+NohamR@users.noreply.github.com> Date: Fri, 19 Jun 2026 16:17:04 +0200 Subject: [PATCH] Add local HTML fallback for bot protection --- src/index.js | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index f3e081f..b1e46c5 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,7 @@ +import fs from 'node:fs' import process from 'node:process' import path from 'node:path' +import readline from 'node:readline/promises' import { parseArgs, VALID_THEMES } from './cli.js' import { loadPreferences, readCustomCss } from './config.js' import logger from './logger.js' @@ -26,6 +28,16 @@ import { const EXTENSION_BASE = 'chrome-extension://' +async function promptForInput () { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout + }) + const answer = await rl.question('> ') + rl.close() + return answer.trim().replace(/^['"]|['"]$/g, '') +} + async function main () { const { url, opts } = parseArgs() @@ -63,7 +75,26 @@ async function main () { logger.info(`Fetching article: ${url}`) const articlePage = await browser.newPage() await articlePage.goto(url, { waitUntil: 'networkidle0', timeout: 30000 }) - const article = await extractArticle(articlePage, getReadabilityPath()) + let article = await extractArticle(articlePage, getReadabilityPath()) + + if (article.title === 'Just a moment...' || article.length < 500) { + logger.warn('Cloudflare or bot protection detected..') + logger.warn('Open the URL in your browser, save the page as complete HTML (File > Save Page As),') + logger.warn('then paste the saved file path below and press Enter:') + + const htmlPath = await promptForInput() + const resolvedPath = path.resolve(htmlPath) + + if (!fs.existsSync(resolvedPath)) { + logger.error(`File not found: ${resolvedPath}`) + process.exit(1) + } + + logger.info(`Loading article from local file: ${resolvedPath}`) + await articlePage.goto(`file://${resolvedPath}`, { waitUntil: 'networkidle0', timeout: 30000 }) + article = await extractArticle(articlePage, getReadabilityPath()) + } + await articlePage.close() const extPage = await browser.newPage()