fix: minor cleanups

pull/142/head
Travis Fischer 2022-12-15 16:59:28 -06:00
rodzic 1f1fc66429
commit fdb60f633a
1 zmienionych plików z 77 dodań i 66 usunięć

Wyświetl plik

@ -2,13 +2,7 @@ import * as fs from 'node:fs'
import * as os from 'node:os' import * as os from 'node:os'
import delay from 'delay' import delay from 'delay'
import type { import type { Browser, Page, Protocol, PuppeteerLaunchOptions } from 'puppeteer'
Browser,
ElementHandle,
Page,
Protocol,
PuppeteerLaunchOptions
} from 'puppeteer'
import puppeteer from 'puppeteer-extra' import puppeteer from 'puppeteer-extra'
import RecaptchaPlugin from 'puppeteer-extra-plugin-recaptcha' import RecaptchaPlugin from 'puppeteer-extra-plugin-recaptcha'
import StealthPlugin from 'puppeteer-extra-plugin-stealth' import StealthPlugin from 'puppeteer-extra-plugin-stealth'
@ -51,8 +45,6 @@ export async function getOpenAIAuth({
browser, browser,
page, page,
timeoutMs = 2 * 60 * 1000, timeoutMs = 2 * 60 * 1000,
// TODO: temporary for testing...
// timeoutMs = 60 * 60 * 1000,
isGoogleLogin = false, isGoogleLogin = false,
captchaToken = process.env.CAPTCHA_TOKEN captchaToken = process.env.CAPTCHA_TOKEN
}: { }: {
@ -93,15 +85,18 @@ export async function getOpenAIAuth({
// login as well (optional) // login as well (optional)
if (email && password) { if (email && password) {
await page.waitForSelector('#__next .btn-primary', { timeout: timeoutMs }) await waitForConditionOrAtCapacity(page, () =>
page.waitForSelector('#__next .btn-primary', { timeout: timeoutMs })
)
await delay(500) await delay(500)
// click login button and wait for navigation to finish
await Promise.all([ await Promise.all([
// click login button
page.click('#__next .btn-primary'),
page.waitForNavigation({ page.waitForNavigation({
waitUntil: 'networkidle0' waitUntil: 'networkidle0'
}) }),
page.click('#__next .btn-primary')
]) ])
await checkForChatGPTAtCapacity(page) await checkForChatGPTAtCapacity(page)
@ -125,9 +120,9 @@ export async function getOpenAIAuth({
await delay(100) await delay(100)
if (hasRecaptchaPlugin) { if (hasRecaptchaPlugin) {
console.log('solveRecaptchas()') // console.log('solveRecaptchas()')
const res = await page.solveRecaptchas() const res = await page.solveRecaptchas()
console.log('solveRecaptchas result', res) // console.log('solveRecaptchas result', res)
} }
await page.click('button[type="submit"]') await page.click('button[type="submit"]')
@ -137,50 +132,16 @@ export async function getOpenAIAuth({
} }
await Promise.all([ await Promise.all([
new Promise<void>((resolve, reject) => { waitForConditionOrAtCapacity(page, () =>
let resolved = false page.waitForNavigation({
async function waitForCapacityText() {
if (resolved) {
return
}
try {
await checkForChatGPTAtCapacity(page)
if (!resolved) {
setTimeout(waitForCapacityText, 500)
}
} catch (err) {
if (!resolved) {
resolved = true
return reject(err)
}
}
}
page
.waitForNavigation({
waitUntil: 'networkidle0' waitUntil: 'networkidle0'
}) })
.then(() => { ),
if (!resolved) {
resolved = true
resolve()
}
})
.catch((err) => {
if (!resolved) {
resolved = true
reject(err)
}
})
setTimeout(waitForCapacityText, 500)
}),
submitP() submitP()
]) ])
} else {
await delay(2000)
await checkForChatGPTAtCapacity(page)
} }
const pageCookies = await page.cookies() const pageCookies = await page.cookies()
@ -227,7 +188,7 @@ export async function getBrowser(
if (captchaToken && !hasRecaptchaPlugin) { if (captchaToken && !hasRecaptchaPlugin) {
hasRecaptchaPlugin = true hasRecaptchaPlugin = true
console.log('use captcha', captchaToken) // console.log('use captcha', captchaToken)
puppeteer.use( puppeteer.use(
RecaptchaPlugin({ RecaptchaPlugin({
@ -275,17 +236,18 @@ export const defaultChromeExecutablePath = (): string => {
} }
async function checkForChatGPTAtCapacity(page: Page) { async function checkForChatGPTAtCapacity(page: Page) {
let res: ElementHandle<Node>[] // console.log('checkForChatGPTAtCapacity', page.url())
let res: any[]
try { try {
// res = await page.$('[role="alert"]')
res = await page.$x("//div[contains(., 'ChatGPT is at capacity')]") res = await page.$x("//div[contains(., 'ChatGPT is at capacity')]")
console.log('capacity', res) // console.log('capacity1', els)
// if (els?.length) {
if (!res?.length) { // res = await Promise.all(
res = await page.$x("//div[contains(., 'at capacity right now')]") // els.map((a) => a.evaluate((el) => el.textContent))
console.log('capacity2', res) // )
} // console.log('capacity2', res)
// }
} catch (err) { } catch (err) {
// ignore errors likely due to navigation // ignore errors likely due to navigation
} }
@ -296,3 +258,52 @@ async function checkForChatGPTAtCapacity(page: Page) {
throw error throw error
} }
} }
async function waitForConditionOrAtCapacity(
page: Page,
condition: () => Promise<any>,
opts: {
pollingIntervalMs?: number
} = {}
) {
const { pollingIntervalMs = 500 } = opts
return new Promise<void>((resolve, reject) => {
let resolved = false
async function waitForCapacityText() {
if (resolved) {
return
}
try {
await checkForChatGPTAtCapacity(page)
if (!resolved) {
setTimeout(waitForCapacityText, pollingIntervalMs)
}
} catch (err) {
if (!resolved) {
resolved = true
return reject(err)
}
}
}
condition()
.then(() => {
if (!resolved) {
resolved = true
resolve()
}
})
.catch((err) => {
if (!resolved) {
resolved = true
reject(err)
}
})
setTimeout(waitForCapacityText, pollingIntervalMs)
})
}