feat: fix capacity error

pull/144/head
Travis Fischer 2022-12-14 21:24:19 -06:00
rodzic 61e9148805
commit 0385b8d7df
5 zmienionych plików z 4 dodań i 164 usunięć

Wyświetl plik

@ -40,7 +40,6 @@
"expiry-map": "^2.0.0",
"p-timeout": "^6.0.0",
"puppeteer-extra": "^3.3.4",
"puppeteer-extra-plugin-recaptcha": "^3.6.6",
"puppeteer-extra-plugin-stealth": "^2.11.1",
"remark": "^14.0.2",
"strip-markdown": "^5.0.0",

Wyświetl plik

@ -18,7 +18,6 @@ specifiers:
prettier: ^2.8.0
puppeteer: ^19.4.0
puppeteer-extra: ^3.3.4
puppeteer-extra-plugin-recaptcha: ^3.6.6
puppeteer-extra-plugin-stealth: ^2.11.1
remark: ^14.0.2
strip-markdown: ^5.0.0
@ -35,7 +34,6 @@ dependencies:
expiry-map: 2.0.0
p-timeout: 6.0.0
puppeteer-extra: 3.3.4_puppeteer@19.4.0
puppeteer-extra-plugin-recaptcha: 3.6.6_puppeteer-extra@3.3.4
puppeteer-extra-plugin-stealth: 2.11.1_puppeteer-extra@3.3.4
remark: 14.0.2
strip-markdown: 5.0.0
@ -3067,26 +3065,6 @@ packages:
- supports-color
- utf-8-validate
/puppeteer-extra-plugin-recaptcha/3.6.6_puppeteer-extra@3.3.4:
resolution: {integrity: sha512-SVbmL+igGX8m0Qg9dn85trWDghbfUCTG/QUHYscYx5XgMZVVb0/v0a6MqbPdHoKmBx5BS2kLd6rorMlncMcXdw==}
engines: {node: '>=9.11.2'}
peerDependencies:
playwright-extra: '*'
puppeteer-extra: '*'
peerDependenciesMeta:
playwright-extra:
optional: true
puppeteer-extra:
optional: true
dependencies:
debug: 4.3.4
merge-deep: 3.0.3
puppeteer-extra: 3.3.4_puppeteer@19.4.0
puppeteer-extra-plugin: 3.2.2_puppeteer-extra@3.3.4
transitivePeerDependencies:
- supports-color
dev: false
/puppeteer-extra-plugin-stealth/2.11.1_puppeteer-extra@3.3.4:
resolution: {integrity: sha512-n0wdC0Ilc9tk5L6FWLyd0P2gT8b2fp+2NuB+KB0oTSw3wXaZ0D6WNakjJsayJ4waGzIJFCUHkmK9zgx5NKMoFw==}
engines: {node: '>=8'}

Wyświetl plik

@ -3,5 +3,3 @@ export * from './chatgpt-conversation'
export * from './types'
export * from './utils'
export * from './openai-auth'
export * from './openai-auth-2captcha'

Wyświetl plik

@ -1,130 +0,0 @@
import delay from 'delay'
import {
type Browser,
type Page,
type Protocol,
type PuppeteerLaunchOptions
} from 'puppeteer'
import puppeteer from 'puppeteer-extra'
import RecaptchaPlugin from 'puppeteer-extra-plugin-recaptcha'
import StealthPlugin from 'puppeteer-extra-plugin-stealth'
import { OpenAIAuth, getBrowser } from './openai-auth'
puppeteer.use(StealthPlugin())
/**
* Bypasses OpenAI's use of Cloudflare to get the cookies required to use
* ChatGPT. Uses Puppeteer with a stealth plugin under the hood.
*
* If you pass `email` and `password`, then it will log into the account and
* include a `sessionToken` in the response.
*
* If you don't pass `email` and `password`, then it will just return a valid
* `clearanceToken`.
*
* This can be useful because `clearanceToken` expires after ~2 hours, whereas
* `sessionToken` generally lasts much longer. We recommend renewing your
* `clearanceToken` every hour or so and creating a new instance of `ChatGPTAPI`
* with your updated credentials.
*/
export async function getOpenAIAuth2Captcha({
email,
password,
timeoutMs = 2 * 60 * 1000,
browser,
captchaToken
}: {
email?: string
password?: string
timeoutMs?: number
browser?: Browser
captchaToken?: string
}): Promise<OpenAIAuth> {
let page: Page
let origBrowser = browser
puppeteer.use(
RecaptchaPlugin({
provider: {
id: '2captcha',
token: captchaToken
},
visualFeedback: true // colorize reCAPTCHAs (violet = detected, green = solved)
})
)
try {
if (!browser) {
browser = await getBrowser()
}
const userAgent = await browser.userAgent()
page = (await browser.pages())[0] || (await browser.newPage())
page.setDefaultTimeout(timeoutMs)
await page.goto('https://chat.openai.com/auth/login')
// NOTE: this is where you may encounter a CAPTCHA
await page.solveRecaptchas()
var capacityLimit = await page.$('[role="alert"]')
if (capacityLimit) {
throw `ChatGPT is at capacity right now`
}
await page.waitForSelector('#__next .btn-primary', { timeout: timeoutMs })
// once we get to this point, the Cloudflare cookies are available
await delay(1000)
// login as well (optional)
if (email && password) {
await Promise.all([
page.click('#__next .btn-primary'),
page.waitForNavigation({
waitUntil: 'networkidle0'
})
])
await page.type('#username', email, { delay: 10 })
await page.solveRecaptchas()
await page.click('button[type="submit"]')
await page.waitForSelector('#password')
await page.type('#password', password, { delay: 10 })
await Promise.all([
page.click('button[type="submit"]'),
page.waitForNavigation({
waitUntil: 'networkidle0'
})
])
}
const pageCookies = await page.cookies()
const cookies = pageCookies.reduce(
(map, cookie) => ({ ...map, [cookie.name]: cookie }),
{}
)
const authInfo: OpenAIAuth = {
userAgent,
clearanceToken: cookies['cf_clearance']?.value,
sessionToken: cookies['__Secure-next-auth.session-token']?.value,
cookies
}
return authInfo
} catch (err) {
console.error(err)
throw err
} finally {
if (origBrowser) {
if (page) {
await page.close()
}
} else if (browser) {
await browser.close()
}
page = null
browser = null
}
}

Wyświetl plik

@ -69,13 +69,8 @@ export async function getOpenAIAuth({
await page.goto('https://chat.openai.com/auth/login')
await checkForChatGPTAtCapacity(page)
// NOTE: this is where you may encounter a CAPTCHA
var capacityLimit = await page.$('[role="alert"]')
if (capacityLimit) {
throw `ChatGPT is at capacity right now`
}
await checkForChatGPTAtCapacity(page)
await page.waitForSelector('#__next .btn-primary', { timeout: timeoutMs })
@ -231,15 +226,15 @@ export const defaultChromeExecutablePath = (): string => {
}
async function checkForChatGPTAtCapacity(page: Page) {
let res: ElementHandle<Element> | null
let res: ElementHandle<Node>[]
try {
res = await page.$('[role="alert"]')
res = await page.$x("//div[contains(., 'ChatGPT is at capacity')]")
} catch (err) {
// ignore errors likely due to navigation
}
if (res) {
if (res?.length) {
const error = new types.ChatGPTError(`ChatGPT is at capacity: ${res}`)
error.statusCode = 503
throw error