Bulk Messaging System

An Electron Desktop app for marketing campaign & broadcast management, using either whatsapp, gmail or a SMTP server

Main process architecture

Introduction#

Electron main process layout: window creation, IPC registration, WhatsApp client ownership, and cleanup on exit.

Project structure#

The Electron application is organized with the main process, preload bridge, and renderer React components, and supporting utilities. The main process initializes the BrowserWindow, registers IPC handlers, manages the WhatsApp client lifecycle, and performs cleanup. The renderer communicates via a secure contextBridge exposed API.

Core components#

  • Main process entry and window creation: Initializes the BrowserWindow with security hardening and loads either the dev server or production bundle.
  • IPC handler registration: Exposes handlers for Gmail, SMTP, WhatsApp client lifecycle, contact import, email list import, and file reading.
  • WhatsApp client lifecycle: Creates a LocalAuth-based client with Puppeteer headless browser configuration and emits status events.
  • Renderer bridge: Provides a secure API surface via contextBridge for the renderer to invoke main-process functionality.
  • Utilities: Development mode detection and shared helpers.

Architecture overview#

The main process orchestrates the entire application lifecycle. It creates a secure BrowserWindow, registers IPC handlers, manages the WhatsApp client, and exposes a controlled API to the renderer. The renderer invokes these handlers to perform actions like starting the WhatsApp client, importing contacts, sending messages, and managing email lists.

Detailed component analysis#

Main process responsibilities#

  • Window management: Creates a BrowserWindow with security settings and loads the dev server or production bundle. Handles window-all-closed and before-quit events for graceful shutdown.
  • Application lifecycle: Cleans up WhatsApp cache and auth directories on startup and during shutdown. Attempts logout before closing.
  • IPC handler registration: Registers handlers for Gmail, SMTP, WhatsApp client, contact import, email list import, and file reading.

Security configurations enforced in the BrowserWindow:

  • nodeIntegration: false
  • contextIsolation: true
  • enableRemoteModule: false
  • webSecurity: true
  • preload script path configured

WhatsApp client initialization pattern#

  • Authentication strategy: LocalAuth is used to persist authentication state locally.
  • Puppeteer setup: Headless browser with sandbox and GPU-related arguments for stability.
  • Event-driven architecture: Emits qr, ready, authenticated, auth_failure, and disconnected events. The main process forwards these to the renderer via IPC channels.
  • Error handling: Catches initialization errors and notifies the renderer.

WhatsApp client event handling#

  • qr: Converts QR string to a data URL and sends it to the renderer. Also sends status updates.
  • ready: Clears QR and signals readiness.
  • authenticated: Clears QR and confirms authentication.
  • auth_failure: Sends failure message to the renderer.
  • disconnected: Sends disconnection reason, resets client reference.

WhatsApp message sending pipeline#

  • Validates client readiness.
  • Iterates through contacts, constructs chat IDs, checks registration, sends messages with a delay, and reports progress and results.

Contact import and email list processing#

  • Contact import: Opens a file dialog, supports CSV and TXT formats, parses rows, trims whitespace, and returns structured contacts.
  • Email list import: Opens a file dialog for CSV or TXT files and returns the selected file paths.
  • Email list reading: Reads CSV files and extracts email addresses by common column names or first column fallback; reads TXT files and filters lines containing ‘@’.

Cleanup procedures for WhatsApp cache and authentication files#

  • On startup: Deletes .wwebjs_cache and .wwebjs_auth directories.
  • On logout: Calls client.logout() and deletes cache/auth directories, including a forced path if logout throws.
  • On app quit/window-all-closed: Attempts logout and deletes cache/auth directories.

Security configurations#

  • BrowserWindow webPreferences:
  • nodeIntegration: false
  • contextIsolation: true
  • enableRemoteModule: false
  • webSecurity: true
  • preload: path to preload script
  • Preload bridge: Exposes a minimal API surface via contextBridge to the renderer.
  • Gmail OAuth2: Uses offline access and a redirect URI; stores tokens securely using electron-store.
  • SMTP: Supports TLS with rejectUnauthorized disabled for self-signed certs; credentials saved encrypted.

Error handling strategies#

  • WhatsApp client initialization errors: Caught and reported to the renderer.
  • QR code generation failures: Error is caught and a status message is sent.
  • Logout failures: Attempt cleanup and notify renderer with forced disconnect status.
  • File operations: Try/catch around file reading and parsing; returns empty arrays or null on failure.
  • Gmail OAuth2: Timeout handling, error parameter checks, and window closure on completion or failure.
  • SMTP verification and per-message errors: Verified before sending; per-recipient errors are captured and reported.

Graceful shutdown procedures#

  • before-quit: Attempts logout, clears client reference, deletes cache/auth directories.
  • window-all-closed: Same as before-quit plus app.quit() on non-darwin platforms.

Renderer integration patterns#

  • BulkMailer.jsx: Subscribes to WhatsApp status and QR events, manages UI state, validates forms, and triggers IPC calls.
  • WhatsAppForm.jsx: Renders connection controls, QR display, contact management, and message composer; integrates with Pyodide for manual number parsing.
  • Pyodide integration: Loads Pyodide runtime and Python script dynamically, then executes Python functions safely.

Dependency analysis#

The main process depends on external libraries for WhatsApp integration, QR generation, file parsing, and email sending. The preload bridge mediates all IPC calls from the renderer to the main process.

Performance considerations#

  • Puppeteer headless configuration includes sandbox and GPU-related flags to improve stability and reduce resource contention.
  • Delays between message sends help avoid rate limits and detection.
  • File parsing uses streaming for CSV to handle large files efficiently.
  • QR code generation is asynchronous and guarded against errors.

Troubleshooting guide#

Common issues and resolutions:

  • WhatsApp QR code not loading: Retry connection, check console logs, ensure network connectivity.
  • Authentication failures: Verify LocalAuth persistence and browser environment; clear cache/auth directories if stuck.
  • Logout failures: Forced cleanup is performed; verify client state and restart.
  • File import errors: Confirm file format (CSV/TXT), encoding, and column headers; handle empty or malformed entries gracefully.
  • Gmail OAuth2 timeouts: Increase timeout window or retry; ensure redirect URI matches configuration.
  • SMTP connection issues: Verify host/port/security settings; test with a simple connection before bulk sending.

Conclusion#

If the main process owns a resource, it also owns teardown. That rule keeps WhatsApp browsers and temp files from leaking across restarts.