Commit 091914a0 authored by Travis Fischer's avatar Travis Fischer

feat: minor cleanups

parent 101c31ee
...@@ -112,7 +112,8 @@ export class ChatGPTAPIBrowser extends AChatGPTAPI { ...@@ -112,7 +112,8 @@ export class ChatGPTAPIBrowser extends AChatGPTAPI {
this._browser = await getBrowser({ this._browser = await getBrowser({
captchaToken: this._captchaToken, captchaToken: this._captchaToken,
executablePath: this._executablePath, executablePath: this._executablePath,
proxyServer: this._proxyServer proxyServer: this._proxyServer,
minimize: this._minimize
}) })
this._page = this._page =
(await this._browser.pages())[0] || (await this._browser.newPage()) (await this._browser.pages())[0] || (await this._browser.newPage())
...@@ -474,28 +475,34 @@ export class ChatGPTAPIBrowser extends AChatGPTAPI { ...@@ -474,28 +475,34 @@ export class ChatGPTAPIBrowser extends AChatGPTAPI {
console.warn('chatgpt sendMessage error; retrying...', err.toString()) console.warn('chatgpt sendMessage error; retrying...', err.toString())
await delay(5000) await delay(5000)
continue
} }
} while (!result)
// console.log('<<< EVALUATE', result)
if ('error' in result) { if ('error' in result) {
const error = new types.ChatGPTError(result.error.message) const error = new types.ChatGPTError(result.error.message)
error.statusCode = result.error.statusCode error.statusCode = result.error.statusCode
error.statusText = result.error.statusText error.statusText = result.error.statusText
if (error.statusCode === 403) { if (error.statusCode !== 403) {
await this.refreshSession() throw error
} } else if (++numTries >= 2) {
await this.refreshSession()
throw error
} else {
await this.refreshSession()
await delay(1000)
continue
}
} else {
if (!this._markdown) {
result.response = markdownToText(result.response)
}
throw error return result
} else {
if (!this._markdown) {
result.response = markdownToText(result.response)
} }
} while (!result)
return result // console.log('<<< EVALUATE', result)
}
// const lastMessage = await this.getLastMessage() // const lastMessage = await this.getLastMessage()
...@@ -549,7 +556,17 @@ export class ChatGPTAPIBrowser extends AChatGPTAPI { ...@@ -549,7 +556,17 @@ export class ChatGPTAPIBrowser extends AChatGPTAPI {
} }
override async closeSession() { override async closeSession() {
await this._browser.close() try {
if (this._page) {
this._page.off('request', this._onRequest.bind(this))
this._page.off('response', this._onResponse.bind(this))
}
} catch (_) {}
if (this._browser) {
await this._browser.close()
}
this._page = null this._page = null
this._browser = null this._browser = null
this._accessToken = null this._accessToken = null
......
...@@ -5,13 +5,14 @@ import * as url from 'node:url' ...@@ -5,13 +5,14 @@ import * as url from 'node:url'
import delay from 'delay' import delay from 'delay'
import { TimeoutError } from 'p-timeout' import { TimeoutError } from 'p-timeout'
import type { Browser, Page, Protocol, PuppeteerLaunchOptions } from 'puppeteer' import { Browser, 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'
import random from 'random' import random from 'random'
import * as types from './types' import * as types from './types'
import { minimizePage } from './utils'
puppeteer.use(StealthPlugin()) puppeteer.use(StealthPlugin())
...@@ -57,7 +58,8 @@ export async function getOpenAIAuth({ ...@@ -57,7 +58,8 @@ export async function getOpenAIAuth({
captchaToken = process.env.CAPTCHA_TOKEN, captchaToken = process.env.CAPTCHA_TOKEN,
nopechaKey = process.env.NOPECHA_KEY, nopechaKey = process.env.NOPECHA_KEY,
executablePath, executablePath,
proxyServer = process.env.PROXY_SERVER proxyServer = process.env.PROXY_SERVER,
minimize = false
}: { }: {
email?: string email?: string
password?: string password?: string
...@@ -66,6 +68,7 @@ export async function getOpenAIAuth({ ...@@ -66,6 +68,7 @@ export async function getOpenAIAuth({
timeoutMs?: number timeoutMs?: number
isGoogleLogin?: boolean isGoogleLogin?: boolean
isMicrosoftLogin?: boolean isMicrosoftLogin?: boolean
minimize?: boolean
captchaToken?: string captchaToken?: string
nopechaKey?: string nopechaKey?: string
executablePath?: string executablePath?: string
...@@ -88,6 +91,10 @@ export async function getOpenAIAuth({ ...@@ -88,6 +91,10 @@ export async function getOpenAIAuth({
if (!page) { if (!page) {
page = (await browser.pages())[0] || (await browser.newPage()) page = (await browser.pages())[0] || (await browser.newPage())
page.setDefaultTimeout(timeoutMs) page.setDefaultTimeout(timeoutMs)
if (minimize) {
await minimizePage(page)
}
} }
await page.goto('https://chat.openai.com/auth/login', { await page.goto('https://chat.openai.com/auth/login', {
...@@ -243,6 +250,7 @@ export async function getBrowser( ...@@ -243,6 +250,7 @@ export async function getBrowser(
captchaToken?: string captchaToken?: string
nopechaKey?: string nopechaKey?: string
proxyServer?: string proxyServer?: string
minimize?: boolean
} = {} } = {}
) { ) {
const { const {
...@@ -250,6 +258,7 @@ export async function getBrowser( ...@@ -250,6 +258,7 @@ export async function getBrowser(
nopechaKey = process.env.NOPECHA_KEY, nopechaKey = process.env.NOPECHA_KEY,
executablePath = defaultChromeExecutablePath(), executablePath = defaultChromeExecutablePath(),
proxyServer = process.env.PROXY_SERVER, proxyServer = process.env.PROXY_SERVER,
minimize = false,
...launchOptions ...launchOptions
} = opts } = opts
...@@ -268,6 +277,7 @@ export async function getBrowser( ...@@ -268,6 +277,7 @@ export async function getBrowser(
) )
} }
// https://peter.sh/experiments/chromium-command-line-switches/
const puppeteerArgs = [ const puppeteerArgs = [
'--no-sandbox', '--no-sandbox',
'--disable-setuid-sandbox', '--disable-setuid-sandbox',
...@@ -285,8 +295,8 @@ export async function getBrowser( ...@@ -285,8 +295,8 @@ export async function getBrowser(
'--disable-default-apps', '--disable-default-apps',
'--no-zygote', '--no-zygote',
'--disable-accelerated-2d-canvas', '--disable-accelerated-2d-canvas',
'--disable-web-security', '--disable-web-security'
'--disable-gpu' // '--disable-gpu'
// '--js-flags="--max-old-space-size=1024"' // '--js-flags="--max-old-space-size=1024"'
] ]
...@@ -308,7 +318,6 @@ export async function getBrowser( ...@@ -308,7 +318,6 @@ export async function getBrowser(
const browser = await puppeteer.launch({ const browser = await puppeteer.launch({
headless: false, headless: false,
// https://peter.sh/experiments/chromium-command-line-switches/
args: puppeteerArgs, args: puppeteerArgs,
ignoreDefaultArgs: [ ignoreDefaultArgs: [
'--disable-extensions', '--disable-extensions',
...@@ -322,40 +331,74 @@ export async function getBrowser( ...@@ -322,40 +331,74 @@ export async function getBrowser(
if (process.env.PROXY_VALIDATE_IP) { if (process.env.PROXY_VALIDATE_IP) {
const page = (await browser.pages())[0] || (await browser.newPage()) const page = (await browser.pages())[0] || (await browser.newPage())
// send a fetch request to https://ifconfig.co using page.evaluate() and verify the IP matches if (minimize) {
let ip await minimizePage(page)
}
// Send a fetch request to https://ifconfig.co using page.evaluate() and
// verify that the IP matches
let ip: string
try { try {
;({ ip } = await page.evaluate(() => { const res = await page.evaluate(() => {
return fetch('https://ifconfig.co', { return fetch('https://ifconfig.co', {
headers: { headers: {
Accept: 'application/json' Accept: 'application/json'
} }
}).then((res) => res.json()) }).then((res) => res.json())
})) })
ip = res?.ip
} catch (err) { } catch (err) {
throw new Error(`Proxy IP validation failed: ${err.message}`) throw new Error(`Proxy IP validation failed: ${err.toString()}`)
} }
if (ip !== process.env.PROXY_VALIDATE_IP) {
if (!ip || ip !== process.env.PROXY_VALIDATE_IP) {
throw new Error( throw new Error(
`Proxy IP mismatch: ${ip} !== ${process.env.PROXY_VALIDATE_IP}` `Proxy IP mismatch: ${ip} !== ${process.env.PROXY_VALIDATE_IP}`
) )
} }
} }
// TOdO: this is a really hackity hack way of setting the API key... await initializeNopechaExtension(browser, {
minimize,
nopechaKey
})
return browser
}
export async function initializeNopechaExtension(
browser: Browser,
opts: {
minimize?: boolean
nopechaKey?: string
}
) {
const { minimize = false, nopechaKey } = opts
// TODO: this is a really hackity hack way of setting the API key...
if (hasNopechaExtension) { if (hasNopechaExtension) {
const page = (await browser.pages())[0] || (await browser.newPage()) const page = (await browser.pages())[0] || (await browser.newPage())
if (minimize) {
await minimizePage(page)
}
await page.goto(`https://nopecha.com/setup#${nopechaKey}`) await page.goto(`https://nopecha.com/setup#${nopechaKey}`)
await delay(1000) await delay(1000)
try { try {
const page3 = await browser.newPage() const page3 = await browser.newPage()
await page.close() if (minimize) {
await minimizePage(page3)
}
await page.close()
// find the nopecha extension ID // find the nopecha extension ID
const targets = browser.targets() const targets = browser.targets()
const extensionIds = ( const extensionIds = (
await Promise.all( await Promise.all(
targets.map(async (target) => { targets.map(async (target) => {
// console.log(target.type(), target.url())
if (target.type() !== 'service_worker') { if (target.type() !== 'service_worker') {
return return
} }
...@@ -378,23 +421,27 @@ export async function getBrowser( ...@@ -378,23 +421,27 @@ export async function getBrowser(
await editKey.click() await editKey.click()
const settingsInput = await page3.waitForSelector('input.settings_text') const settingsInput = await page3.waitForSelector('input.settings_text')
// console.log('value1', await settingsInput.evaluate((el) => el.value)) // console.log('value1', )
await settingsInput.evaluate((el) => {
el.value = ''
})
await settingsInput.type(nopechaKey)
// console.log('value2', await settingsInput.evaluate((el) => el.value)) const value = await settingsInput.evaluate((el) => el.value)
await settingsInput.evaluate((el, value) => { if (value !== nopechaKey) {
el.value = value await settingsInput.evaluate((el) => {
}, nopechaKey) el.value = ''
})
await settingsInput.type(nopechaKey)
// console.log('value2', await settingsInput.evaluate((el) => el.value))
await settingsInput.evaluate((el, value) => {
el.value = value
}, nopechaKey)
// console.log('value3', await settingsInput.evaluate((el) => el.value))
await settingsInput.press('Enter')
await delay(500)
await editKey.click()
await delay(2000)
}
// console.log('value3', await settingsInput.evaluate((el) => el.value))
await settingsInput.press('Enter')
await delay(500)
await editKey.click()
await delay(2000)
console.log('initialized nopecha extension with key', nopechaKey) console.log('initialized nopecha extension with key', nopechaKey)
} else { } else {
console.error( console.error(
...@@ -405,14 +452,14 @@ export async function getBrowser( ...@@ -405,14 +452,14 @@ export async function getBrowser(
console.error('error initializing nopecha extension', err) console.error('error initializing nopecha extension', err)
} }
} }
return browser
} }
/** /**
* Gets the default path to chrome's executable for the current platform. * Gets the default path to chrome's executable for the current platform.
*/ */
export const defaultChromeExecutablePath = (): string => { export const defaultChromeExecutablePath = (): string => {
// return executablePath()
if (process.env.PUPPETEER_EXECUTABLE_PATH) { if (process.env.PUPPETEER_EXECUTABLE_PATH) {
return process.env.PUPPETEER_EXECUTABLE_PATH return process.env.PUPPETEER_EXECUTABLE_PATH
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment