Merge branch 'feature/improve-robustness' into feature/improve-robustness

pull/143/head
Joel 2022-12-14 22:27:41 -08:00 zatwierdzone przez GitHub
commit b8a3fe0d2a
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
4 zmienionych plików z 141 dodań i 24 usunięć

Wyświetl plik

@ -16,7 +16,7 @@ async function main() {
const email = process.env.OPENAI_EMAIL
const password = process.env.OPENAI_PASSWORD
const api = new ChatGPTAPIBrowser({ email, password })
const api = new ChatGPTAPIBrowser({ email, password, debug: true })
const res = await api.init()
console.log('init result', res)

Wyświetl plik

@ -1,9 +1,10 @@
import delay from 'delay'
import html2md from 'html-to-md'
import { type Browser, type HTTPResponse, type Page } from 'puppeteer'
import type { Browser, HTTPRequest, HTTPResponse, Page } from 'puppeteer'
import * as types from './types'
import { getBrowser, getOpenAIAuth } from './openai-auth'
import { isRelevantRequest, minimizePage } from './utils'
export class ChatGPTAPIBrowser {
protected _markdown: boolean
@ -102,25 +103,93 @@ export class ChatGPTAPIBrowser {
return false
}
// this._page.on('response', this._onResponse.bind(this))
// await minimizePage(this._page)
this._page.on('request', this._onRequest.bind(this))
this._page.on('response', this._onResponse.bind(this))
return true
}
// _onResponse = (response: HTTPResponse) => {
// const request = response.request()
_onRequest = (request: HTTPRequest) => {
if (!this._debug) return
// console.log('response', {
// url: response.url(),
// ok: response.ok(),
// status: response.status(),
// statusText: response.statusText(),
// headers: response.headers(),
// request: {
// method: request.method(),
// headers: request.headers()
// }
// })
// }
const url = request.url()
if (!isRelevantRequest(url)) {
return
}
const method = request.method()
let body: any
if (method === 'POST') {
body = request.postData()
try {
body = JSON.parse(body)
} catch (_) {}
// if (url.endsWith('/conversation') && typeof body === 'object') {
// const conversationBody: types.ConversationJSONBody = body
// const conversationId = conversationBody.conversation_id
// const parentMessageId = conversationBody.parent_message_id
// const messageId = conversationBody.messages?.[0]?.id
// const prompt = conversationBody.messages?.[0]?.content?.parts?.[0]
// // TODO: store this info for the current sendMessage request
// }
}
console.log('\nrequest', {
url,
method,
headers: request.headers(),
body
})
}
_onResponse = async (response: HTTPResponse) => {
if (!this._debug) return
const request = response.request()
const url = response.url()
if (!isRelevantRequest(url)) {
return
}
let body: any
try {
body = await response.json()
} catch (_) {}
if (url.endsWith('/conversation')) {
// const parser = createParser((event) => {
// if (event.type === 'event') {
// onMessage(event.data)
// }
// })
// await response.buffer()
// for await (const chunk of streamAsyncIterable(response.body)) {
// const str = new TextDecoder().decode(chunk)
// parser.feed(str)
// }
}
console.log('\nresponse', {
url,
ok: response.ok(),
status: response.status(),
statusText: response.statusText(),
headers: response.headers(),
body,
request: {
method: request.method(),
headers: request.headers(),
body: request.postData()
}
})
}
async getIsAuthenticated() {
try {
@ -198,7 +267,7 @@ export class ChatGPTAPIBrowser {
const lastMessage = await this.getLastMessage()
await inputBox.click()
await inputBox.focus()
const paragraphs = message.split('\n')
for (let i = 0; i < paragraphs.length; i++) {
await inputBox.type(paragraphs[i], { delay: 0 })
@ -220,6 +289,7 @@ export class ChatGPTAPIBrowser {
newLastMessage &&
lastMessage?.toLowerCase() !== newLastMessage?.toLowerCase()
) {
await delay(5000)
return newLastMessage
}
} while (true)

Wyświetl plik

@ -2,12 +2,12 @@ import * as fs from 'node:fs'
import * as os from 'node:os'
import delay from 'delay'
import {
type Browser,
type ElementHandle,
type Page,
type Protocol,
type PuppeteerLaunchOptions
import type {
Browser,
ElementHandle,
Page,
Protocol,
PuppeteerLaunchOptions
} from 'puppeteer'
import puppeteer from 'puppeteer-extra'
import RecaptchaPlugin from 'puppeteer-extra-plugin-recaptcha'

Wyświetl plik

@ -1,3 +1,4 @@
import type { Page } from 'puppeteer'
import { remark } from 'remark'
import stripMarkdown from 'strip-markdown'
@ -7,3 +8,49 @@ export function markdownToText(markdown?: string): string {
.processSync(markdown ?? '')
.toString()
}
export async function minimizePage(page: Page) {
const session = await page.target().createCDPSession()
const goods = await session.send('Browser.getWindowForTarget')
const { windowId } = goods
await session.send('Browser.setWindowBounds', {
windowId,
bounds: { windowState: 'minimized' }
})
}
export async function maximizePage(page: Page) {
const session = await page.target().createCDPSession()
const goods = await session.send('Browser.getWindowForTarget')
const { windowId } = goods
await session.send('Browser.setWindowBounds', {
windowId,
bounds: { windowState: 'normal' }
})
}
export function isRelevantRequest(url: string): boolean {
let pathname
try {
const parsedUrl = new URL(url)
pathname = parsedUrl.pathname
url = parsedUrl.toString()
} catch (_) {
return false
}
if (!url.startsWith('https://chat.openai.com')) {
return false
}
if (pathname.startsWith('/_next')) {
return false
}
if (pathname.endsWith('backend-api/moderations')) {
return false
}
return true
}