| const axios = require('axios'); |
| const puppeteer = require('puppeteer'); |
| const crypto = require('crypto'); |
|
|
| class WormGPTScraper { |
| constructor() { |
| this.tempMailAPI = 'https://api.internal.temp-mail.io/api/v3'; |
| this.wormGPTAPI = 'https://chat.wrmgpt.com'; |
| this.headers = { |
| 'Content-Type': 'application/json', |
| 'Application-Name': 'web', |
| 'Application-Version': '4.0.0', |
| 'X-CORS-Header': 'iaWg3pchvFx48fY' |
| }; |
| this.chatAPI = null; |
| this.currentChatId = null; |
| } |
|
|
| |
| async delay(ms) { |
| return new Promise(resolve => setTimeout(resolve, ms)); |
| } |
|
|
| generatePassword(length = 12) { |
| const uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; |
| const lowercase = 'abcdefghijklmnopqrstuvwxyz'; |
| const numbers = '0123456789'; |
| const symbols = '!@#$%^&*'; |
| const allChars = uppercase + lowercase + numbers + symbols; |
| |
| let password = ''; |
| password += uppercase[Math.floor(Math.random() * uppercase.length)]; |
| password += lowercase[Math.floor(Math.random() * lowercase.length)]; |
| password += numbers[Math.floor(Math.random() * numbers.length)]; |
| password += symbols[Math.floor(Math.random() * symbols.length)]; |
| |
| for (let i = password.length; i < length; i++) { |
| password += allChars[Math.floor(Math.random() * allChars.length)]; |
| } |
| |
| return password.split('').sort(() => Math.random() - 0.5).join(''); |
| } |
|
|
| blurString(str, visibleChars = 3) { |
| if (!str || str.length <= visibleChars) return '***'; |
| return str.substring(0, visibleChars) + '*'.repeat(str.length - visibleChars); |
| } |
|
|
| async createTempEmail() { |
| const response = await axios.post(`${this.tempMailAPI}/email/new`, { |
| min_name_length: 10, |
| max_name_length: 10 |
| }, { headers: this.headers }); |
| |
| return { |
| email: response.data.email, |
| token: response.data.token |
| }; |
| } |
|
|
| async registerWithBrowser(email, password) { |
| const browser = await puppeteer.launch({ |
| headless: true, |
| args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'] |
| }); |
| const page = await browser.newPage(); |
| |
| await page.goto('https://chat.wrmgpt.com/register', { waitUntil: 'networkidle2' }); |
| await this.delay(2000); |
| |
| await page.type('input[id="email"]', email); |
| await page.type('input[id="password"]', password); |
| await page.type('input[id="confirmPassword"]', password); |
| |
| await page.click('button[type="submit"]'); |
| await this.delay(3000); |
| |
| await browser.close(); |
| return 'Registration completed'; |
| } |
|
|
| async getVerificationLink(email) { |
| let attempts = 0; |
| const maxAttempts = 10; |
| |
| while (attempts < maxAttempts) { |
| await this.delay(3000); |
| |
| try { |
| const response = await axios.get(`${this.tempMailAPI}/email/${email}/messages`, { |
| headers: this.headers |
| }); |
|
|
| if (response.data && response.data.length > 0) { |
| const bodyText = response.data[0].body_text; |
| const match = bodyText.match(/https:\/\/chat\.wrmgpt\.com\/verify-email\?token=[a-f0-9-]+/); |
| if (match) { |
| return match[0]; |
| } |
| } |
| } catch (error) { |
| console.log(`Attempt ${attempts + 1}: Waiting for email...`); |
| } |
| |
| attempts++; |
| } |
| |
| return null; |
| } |
|
|
| async verifyEmail(verificationUrl) { |
| const browser = await puppeteer.launch({ |
| headless: true, |
| args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'] |
| }); |
| const page = await browser.newPage(); |
| |
| await page.goto(verificationUrl, { waitUntil: 'networkidle2' }); |
| await this.delay(5000); |
| |
| await browser.close(); |
| return 'Email verified'; |
| } |
|
|
| async loginAndGetSession(email, password) { |
| try { |
| const browser = await puppeteer.launch({ |
| headless: true, |
| args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'] |
| }); |
| const page = await browser.newPage(); |
| |
| await page.goto('https://chat.wrmgpt.com/login', { waitUntil: 'networkidle2', timeout: 30000 }); |
| await this.delay(3000); |
| |
| await page.type('input[id="email"]', email); |
| await page.type('input[id="password"]', password); |
| |
| await page.click('button[type="submit"]'); |
| await this.delay(15000); |
| |
| const currentUrl = page.url(); |
| const isLoggedIn = currentUrl.includes('chat.wrmgpt.com') && !currentUrl.includes('login'); |
| |
| const cookies = await page.cookies(); |
| const cookieString = cookies.map(c => `${c.name}=${c.value}`).join('; '); |
| |
| let chatId = null; |
| const chatIdMatch = currentUrl.match(/chat\/([a-f0-9-]+)/); |
| if (chatIdMatch) { |
| chatId = chatIdMatch[1]; |
| } |
| |
| await browser.close(); |
| |
| return { |
| success: isLoggedIn, |
| currentUrl: currentUrl, |
| cookieString: cookieString, |
| chatId: chatId |
| }; |
| } catch (error) { |
| return { |
| success: false, |
| error: error.message |
| }; |
| } |
| } |
|
|
| initializeChatAPI(cookieString, chatId) { |
| this.currentChatId = chatId || crypto.randomUUID(); |
| |
| this.chatAPI = axios.create({ |
| baseURL: this.wormGPTAPI, |
| headers: { |
| 'Content-Type': 'application/json', |
| 'Cookie': cookieString, |
| 'User-Agent': 'Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36', |
| 'Origin': 'https://chat.wrmgpt.com', |
| 'Referer': `https://chat.wrmgpt.com/chat/${this.currentChatId}`, |
| 'Accept': '*/*' |
| }, |
| responseType: 'text' |
| }); |
| } |
|
|
| parseStreamResponse(data) { |
| let fullText = ''; |
| const lines = data.split('\n\n'); |
| |
| for (const line of lines) { |
| if (!line.startsWith('data: ')) continue; |
| const jsonStr = line.slice(6).trim(); |
| if (jsonStr === '[DONE]') break; |
| |
| try { |
| const msg = JSON.parse(jsonStr); |
| if (msg.type === 'text-delta' && msg.delta) { |
| fullText += msg.delta; |
| } |
| } catch (e) { |
| } |
| } |
| |
| return fullText; |
| } |
|
|
| async sendMessage(messageText, model = 'wormgpt-v6') { |
| if (!this.chatAPI) { |
| throw new Error('Chat API not initialized. Please login first.'); |
| } |
|
|
| const messageId = crypto.randomUUID(); |
| const payload = { |
| id: this.currentChatId, |
| message: { |
| role: 'user', |
| parts: [{ type: 'text', text: messageText }], |
| id: messageId |
| }, |
| selectedChatModel: model, |
| selectedVisibilityType: 'private' |
| }; |
|
|
| try { |
| const response = await this.chatAPI.post('/api/chat', payload); |
| const fullResponse = this.parseStreamResponse(response.data); |
| |
| return { |
| success: true, |
| message: fullResponse, |
| messageId: messageId |
| }; |
| } catch (error) { |
| return { |
| success: false, |
| error: error.message, |
| status: error.response?.status |
| }; |
| } |
| } |
|
|
| async chat(messages = []) { |
| if (!Array.isArray(messages) || messages.length === 0) { |
| return { success: false, error: 'No messages provided' }; |
| } |
|
|
| const results = []; |
| |
| for (const msg of messages) { |
| const response = await this.sendMessage(msg); |
| |
| if (response.success) { |
| results.push({ |
| user: msg, |
| assistant: response.message, |
| messageId: response.messageId |
| }); |
| } else { |
| results.push({ |
| user: msg, |
| error: response.error |
| }); |
| } |
| |
| await this.delay(1000); |
| } |
| |
| return { |
| success: true, |
| conversation: results |
| }; |
| } |
|
|
| async main(autoChat = false, chatMessages = []) { |
| try { |
| const { email, token } = await this.createTempEmail(); |
| |
| const password = this.generatePassword(12); |
|
|
| await this.registerWithBrowser(email, password); |
|
|
| const verificationUrl = await this.getVerificationLink(email); |
| if (!verificationUrl) { |
| return { |
| success: false, |
| message: 'Verification email not received', |
| email: email, |
| step: 'verification' |
| }; |
| } |
|
|
| await this.verifyEmail(verificationUrl); |
|
|
| await this.delay(5000); |
|
|
| const loginResult = await this.loginAndGetSession(email, password); |
|
|
| if (!loginResult.success) { |
| return { |
| success: false, |
| message: 'Login failed', |
| email: email, |
| password: password, |
| error: loginResult.error, |
| step: 'login' |
| }; |
| } |
|
|
| this.initializeChatAPI(loginResult.cookieString, loginResult.chatId); |
|
|
| const result = { |
| success: true, |
| email: email, |
| password: password, |
| chatId: this.currentChatId, |
| cookieString: loginResult.cookieString, |
| step: 'completed' |
| }; |
|
|
| if (autoChat && chatMessages.length > 0) { |
| const chatResult = await this.chat(chatMessages); |
| result.chatHistory = chatResult.conversation; |
| } |
|
|
| return result; |
|
|
| } catch (error) { |
| return { |
| success: false, |
| error: error.message, |
| stack: error.stack, |
| step: 'error' |
| }; |
| } |
| } |
| } |
|
|
| module.exports = WormGPTScraper; |