UNPKG

wailey-whatsapp-lib

Version:

A robust WhatsApp library for Node.js with support for QR code and pairing code authentication

158 lines (135 loc) 4.72 kB
/** * Browser utilities for headless browser emulation */ const puppeteer = require('puppeteer'); /** * Browser session manager */ class Browser { /** * Create a new browser session * @param {Object} options - Puppeteer options */ constructor(options = {}) { this.options = options; this.browser = null; this.page = null; } /** * Initialize the browser * @returns {Promise<void>} */ async initialize() { try { // Enhanced browser options for better compatibility in various environments const defaultOptions = { headless: 'new', args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-accelerated-2d-canvas', '--disable-gpu', '--disable-features=site-per-process', '--disable-web-security', '--disable-extensions' ], ignoreHTTPSErrors: true, defaultViewport: { width: 1280, height: 800 } }; // Merge default options with user-provided options const mergedOptions = { ...defaultOptions, ...this.options }; this.browser = await puppeteer.launch(mergedOptions); this.page = await this.browser.newPage(); // Set user agent to simulate Chrome on Windows await this.page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); // Enable necessary browser features await this.page.setBypassCSP(true); // Optimize for performance await this.page.setCacheEnabled(true); // Handle dialog events (alerts, confirms, etc.) this.page.on('dialog', async (dialog) => { await dialog.dismiss(); }); // Add error handlers this.page.on('error', (err) => { console.error('Page error:', err); }); this.page.on('pageerror', (err) => { console.error('Page error in browser context:', err); }); } catch (error) { console.error('Browser initialization error details:', error); throw new Error(`Failed to initialize browser: ${error.message}`); } } /** * Get the current page * @returns {Page} The current page */ getPage() { if (!this.page) { throw new Error('Browser not initialized'); } return this.page; } /** * Execute JavaScript in the browser context * @param {string|Function} script - Script to execute * @param {...*} args - Arguments to pass to the script * @returns {Promise<*>} Result of the script execution */ async evaluate(script, ...args) { if (!this.page) { throw new Error('Browser not initialized'); } return await this.page.evaluate(script, ...args); } /** * Navigate to a URL * @param {string} url - URL to navigate to * @param {Object} options - Navigation options * @returns {Promise<Response>} Navigation response */ async goto(url, options = {}) { if (!this.page) { throw new Error('Browser not initialized'); } const defaultOptions = { waitUntil: 'networkidle2', timeout: 60000 }; return await this.page.goto(url, { ...defaultOptions, ...options }); } /** * Wait for a selector to appear * @param {string} selector - CSS selector * @param {Object} options - Wait options * @returns {Promise<ElementHandle>} Element handle */ async waitForSelector(selector, options = {}) { if (!this.page) { throw new Error('Browser not initialized'); } const defaultOptions = { visible: true, timeout: 30000 }; return await this.page.waitForSelector(selector, { ...defaultOptions, ...options }); } /** * Close the browser * @returns {Promise<void>} */ async close() { if (this.browser) { await this.browser.close(); this.browser = null; this.page = null; } } } module.exports = Browser;