Spaces:
Sleeping
Sleeping
| 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; | |
| } | |
| // Helper function untuk mengganti waitForTimeout | |
| 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; |