--- title: SDK Electron --- # SDK Electron El SDK de Electron se ejecuta íntegramente en el **proceso principal**, abriendo una ventana CAPTCHA nativa gestionada por el sistema operativo. El renderer nunca toca la verificación — mantenlo así por seguridad. ## Demo en GitHub ::: tip 📦 [Captcha-La/electron-demo](https://github.com/Captcha-La/electron-demo) — ejemplo completo y ejecutable con cada paso de integración. ::: ## Instalación ```bash npm install @captchala/electron ``` El paquete está dirigido a **Electron 28+** (la demo fija `^33.0.0`) y **Node 18+**. Ejecuta la demo de principio a fin con: ```bash npm install npm start ``` ## Inicio rápido ```js // main.js (Electron main process — never the renderer) const { app, BrowserWindow, ipcMain } = require('electron'); const path = require('path'); const { CaptchalaClient } = require('@captchala/electron'); let currentClient = null; ipcMain.handle('verify', async (event, opts) => { // 1. Fetch a one-shot server_token from YOUR backend. const serverToken = await fetchServerTokenFromYourBackend(opts.action); // 2. Tear down any prior client, then build a fresh one. if (currentClient) { currentClient.destroy(); currentClient = null; } currentClient = new CaptchalaClient({ appKey: 'YOUR_APP_KEY', serverToken, action: opts.action, // 'login' | 'register' | 'pay' | … lang: opts.lang, // 'en' | 'zh-CN' | 'ja' | … theme: opts.theme, // 'light' | 'dark' timeoutMs: 15000, retryCount: 3, onReady: () => event.sender.send('captcha-status', 'ready'), onFail: (e) => event.sender.send('captcha-status', `recoverable: ${e.code}`), }); try { const result = await currentClient.verify(); // Send result.passToken to YOUR backend for validation. return { success: true, passToken: result.passToken }; } catch (err) { return { success: false, error: err.message }; } finally { if (currentClient) { currentClient.destroy(); currentClient = null; } } }); function createWindow() { const win = new BrowserWindow({ width: 520, height: 640, resizable: false, webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, nodeIntegration: false, }, }); win.loadFile('index.html'); } app.whenReady().then(createWindow); app.on('window-all-closed', () => app.quit()); ``` ```js // preload.js — bridge the renderer to the main-process verify(). const { contextBridge, ipcRenderer } = require('electron'); contextBridge.exposeInMainWorld('captchala', { verify: (opts) => ipcRenderer.invoke('verify', opts), onStatus: (callback) => ipcRenderer.on('captcha-status', (_, msg) => callback(msg)), }); ``` ## Superficie de la API | Símbolo | Propósito | | --- | --- | | `new CaptchalaClient({...})` | Construye un cliente de un solo uso. Pasa `appKey`, `serverToken`, `action`, `lang`, `theme`, `timeoutMs`, `retryCount`, más los manejadores de eventos. | | `await client.verify()` | Abre la ventana CAPTCHA nativa. Resuelve con un resultado en caso de éxito y rechaza ante un error grave. | | `onReady` / `onFail` | Manejadores opcionales pasados en el constructor. `onFail` es para fallos *recuperables* (el SDK reintentará). | | `result.passToken` | El token a validar en tu backend. Siempre opaco para el cliente. | | `client.destroy()` | Cierra la ventana y libera recursos. Llámalo siempre al terminar con una instancia del cliente. | | `CaptchalaClient.version()` | Helper estático que devuelve la cadena de versión del SDK. Útil en overlays de soporte / depuración. | ## Validación en el servidor Reenvía `result.passToken` (o `result.token`) a tu backend y valídalo contra la API de CaptchaLa. Nunca expongas `X-App-Secret` en el código del cliente. ```bash POST https://apiv1.captcha.la/v1/validate X-App-Key: YOUR_APP_KEY X-App-Secret: YOUR_APP_SECRET Content-Type: application/json { "pass_token": "" } ``` Consulta la [Referencia de la API](/es/api-reference) para el endpoint de validación completo y el flujo de `X-App-Key` / `X-App-Secret`. ## Solución de problemas - **No importes el SDK en el renderer** `@captchala/electron` es **solo para el proceso principal**. Expón su resultado mediante `contextBridge` + `ipcRenderer.invoke()` como hace el `preload.js` de la demo. Mantén `nodeIntegration: false` y `contextIsolation: true`. - **Módulo no encontrado en runtime** `@captchala/electron` es una dependencia normal, no una devDependency — debe empaquetarse con tu aplicación final. Bundlers como electron-builder la incluyen automáticamente. - **La ventana se abre detrás de tu ventana principal** Es una peculiaridad de Linux/X11. Pasa `parent` en tu propio `BrowserWindow` si envuelves la ventana del CAPTCHA, o llama a `mainWindow.focus()` después de que `verify()` retorne. - **Requiere `Electron 28+`** La demo declara `electron: ^33.0.0`. Versiones más antiguas de Electron pueden carecer de APIs en las que el SDK confía; fija `28+` y Node 18+. ## Requisitos - Electron 28+ (la demo usa 33.x) - Node 18+ - Multiplataforma: macOS, Windows 10 1809+, Linux (X11 / Wayland)