forked from ddupont808/GPT-4V-Act
-
Notifications
You must be signed in to change notification settings - Fork 0
/
chatgpt.js
100 lines (84 loc) · 3.39 KB
/
chatgpt.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
const puppeteer = require('puppeteer-extra');
const EventEmitter = require('events');
// add stealth plugin and use defaults (all evasion techniques)
const StealthPlugin = require('puppeteer-extra-plugin-stealth')
puppeteer.use(StealthPlugin())
const {executablePath} = require('puppeteer')
class OpenAIChatController extends EventEmitter {
constructor() {
super();
this.browser = null;
this.page = null;
}
async initialize() {
this.browser = await puppeteer.launch({
headless: false, // Launch browser in non-headless mode so you can see what's happening
userDataDir: "./user_data", // Persist user data so you can login
executablePath: executablePath()
});
this.page = await this.browser.newPage();
await this.page.exposeFunction('emitEndTurn', (data) => this.emit('end_turn', data));
await this.page.goto('https://chat.openai.com/?model=gpt-4');
await this.preparePage();
}
async preparePage() {
await this.page.waitForSelector('input[type="file"]');
await this.page.evaluate(() => {
const {fetch: origFetch} = window;
window.fetch = async (...args) => {
const response = await origFetch(...args);
if(args[0] === "https://chat.openai.com/backend-api/conversation") {
console.log("intercepting conversation...");
const { body } = response.clone();
const raw = await new Response(body).text();
const chunks = raw.split('\ndata: ');
for(let chunk of chunks) {
chunk = chunk.trim();
if(chunk.startsWith('{')) {
console.log(chunk);
try {
let msg = JSON.parse(chunk);
if(msg.message && msg.message.end_turn) {
console.log(msg.message.content.parts);
window.emitEndTurn(msg.message.content.parts.join(''));
break;
}
} catch( ex ) { }
}
}
}
return response;
};
});
}
async typeIntoPrompt(text) {
if (!this.page) {
throw new Error('You need to initialize first');
}
await this.page.type('#prompt-textarea', text.split('\n').join(';'));
}
async clickSendButton() {
if (!this.page) {
throw new Error('You need to initialize first');
}
await this.page.waitForSelector('button[data-testid="send-button"]:not([disabled])');
await this.page.click('[data-testid="send-button"]');
}
async uploadImage(filePath) {
if (!this.page) {
throw new Error('You need to initialize first');
}
await this.page.reload();
await this.preparePage();
const input = await this.page.$('input[type="file"]');
await input.uploadFile(filePath);
// wait until upload is complete
await this.page.waitForSelector('button[data-testid="send-button"]:not([disabled])');
}
async close() {
if (this.browser) {
await this.browser.close();
}
}
}
module.exports = OpenAIChatController;