--- title: Electron SDK --- # Electron SDK Electron SDK は完全に **メインプロセス** で動作し、OS ネイティブのウィンドウで CAPTCHA UI を表示します。レンダラープロセスは検証フローに関与しません — セキュリティのためこの分離を維持してください。 ## GitHub のデモ ::: tip 📦 [Captcha-La/electron-demo](https://github.com/Captcha-La/electron-demo) — すべての統合手順を含む実行可能なサンプル。 ::: ## インストール ```bash npm install @captchala/electron ``` The package targets **Electron 28+** (the demo pins `^33.0.0`) and **Node 18+**. Run the demo end-to-end with: ```bash npm install npm start ``` ## クイックスタート ```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)), }); ``` ## 主な API | シンボル | 用途 | | --- | --- | | `new CaptchalaClient({...})` | 使い捨てクライアントを作成。`appKey` / `serverToken` / `action` / `lang` / `theme` / `timeoutMs` / `retryCount` とイベントハンドラを渡します。 | | `await client.verify()` | ネイティブの CAPTCHA ウィンドウを開きます。成功時は結果で resolve、致命的エラー時は reject。 | | `onReady` / `onFail` | コンストラクタに渡す任意ハンドラ。`onFail` は *リカバリ可能な* 失敗です(SDK が再試行します)。 | | `result.passToken` | バックエンドで検証するトークン。クライアントから見れば常に不透明な値です。 | | `client.destroy()` | ウィンドウを閉じてリソースを解放します。クライアント使用後は必ず呼び出してください。 | | `CaptchalaClient.version()` | SDK のバージョン文字列を返す静的ヘルパー。サポート/デバッグ表示に便利。 | ## サーバー側検証 `result.passToken`(または `result.token`)はバックエンドに転送し、CaptchaLa API で検証します。**`X-App-Secret` をクライアント側コードに含めないでください**。 ```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": "" } ``` 完全な検証エンドポイントと `X-App-Key` / `X-App-Secret` のフローは [API リファレンス](../api-reference) を参照してください。 ## トラブルシューティング - **レンダラーで SDK を import しない** `@captchala/electron` は **メインプロセス専用** です。デモの `preload.js` のように `contextBridge` + `ipcRenderer.invoke()` 経由で結果を公開してください。`nodeIntegration: false` と `contextIsolation: true` を維持しましょう。 - **実行時にモジュールが見つからない** `@captchala/electron` は `dependencies` に置きます(`devDependencies` ではありません)。最終アプリにバンドルされる必要があり、electron-builder などは自動で含めます。 - **CAPTCHA ウィンドウがメインウィンドウの背後に出る** これは Linux/X11 特有の挙動です。独自に `BrowserWindow` をラップしているなら `parent` を渡すか、`verify()` 返却後に `mainWindow.focus()` を呼び出してください。 - **Electron 28+ が必要** デモは `electron: ^33.0.0` を宣言しています。古い Electron では SDK が依存する API が欠けることがあるため、`28+` と Node 18+ に固定してください。 ## 動作環境 - Electron 28+ (the demo uses 33.x) - Node 18+ - Cross-platform: macOS, Windows 10 1809+, Linux (X11 / Wayland)