Referensi

VS Code Extension untuk Pengembangan API CaptchaAI

Ekstensi VS Code yang disesuaikan untuk pengembangan CaptchaAI dapat mempercepat alur kerja Anda — mendeteksi sitekey dalam kode, menguji penyelesaian dari editor, menampilkan saldo Anda di bilah status, dan menyisipkan cuplikan kode untuk pola API umum.

Fitur Ekstensi

Fitur Apa Fungsinya
Bilah status saldo Menampilkan sekilas saldo CaptchaAI saat ini
Selesaikan perintah Kirimkan penyelesaian CAPTCHA langsung dari VS Code
Deteksi sitekey Sorot dan ekstrak sitekey dari file yang terbuka
Cuplikan kode Masukkan boilerplate untuk panggilan API reCAPTCHA, Turnstile, dan hCaptcha
Pencarian kesalahan Arahkan kursor ke kode kesalahan untuk melihat deskripsi

Struktur Ekstensi

captchaai-vscode/
├── package.json
├── src/
│   └── extension.js
├── snippets/
│   ├── python.json
│   └── javascript.json
└── README.md

paket.json

{
  "name": "captchaai-dev-tools",
  "displayName": "CaptchaAI Dev Tools",
  "description": "CaptchaAI API development tools for VS Code",
  "version": "1.0.0",
  "engines": { "vscode": "^1.80.0" },
  "categories": ["Snippets", "Other"],
  "activationEvents": ["onStartupFinished"],
  "main": "./src/extension.js",
  "contributes": {
    "commands": [
      {
        "command": "captchaai.checkBalance",
        "title": "CaptchaAI: Check Balance"
      },
      {
        "command": "captchaai.solveRecaptcha",
        "title": "CaptchaAI: Solve reCAPTCHA v2"
      },
      {
        "command": "captchaai.solveTurnstile",
        "title": "CaptchaAI: Solve Turnstile"
      },
      {
        "command": "captchaai.detectSitekey",
        "title": "CaptchaAI: Detect Sitekey in File"
      }
    ],
    "configuration": {
      "title": "CaptchaAI",
      "properties": {
        "captchaai.apiKey": {
          "type": "string",
          "default": "",
          "description": "Your CaptchaAI API key"
        },
        "captchaai.showBalance": {
          "type": "boolean",
          "default": true,
          "description": "Show balance in status bar"
        },
        "captchaai.pollInterval": {
          "type": "number",
          "default": 5,
          "description": "Poll interval in seconds"
        }
      }
    },
    "snippets": [
      {
        "language": "python",
        "path": "./snippets/python.json"
      },
      {
        "language": "javascript",
        "path": "./snippets/javascript.json"
      }
    ]
  }
}

Implementasi Penyuluhan

// src/extension.js
const vscode = require("vscode");

const API_BASE = "https://ocr.captchaai.com";

function getApiKey() {
  const config = vscode.workspace.getConfiguration("captchaai");
  const key = config.get("apiKey");
  if (!key) {
    vscode.window.showErrorMessage(
      "CaptchaAI: Set your API key in Settings → CaptchaAI"
    );
    return null;
  }
  return key;
}

// --- Balance Status Bar ---

let balanceStatusBar;
let balanceInterval;

async function updateBalance() {
  const key = getApiKey();
  if (!key) return;

  try {
    const url = new URL(`${API_BASE}/res.php`);
    url.searchParams.set("key", key);
    url.searchParams.set("action", "getbalance");
    url.searchParams.set("json", "1");

    const response = await fetch(url);
    const result = await response.json();

    if (result.status === 1) {
      const balance = parseFloat(result.request).toFixed(2);
      balanceStatusBar.text = `$(credit-card) CaptchaAI: $${balance}`;
      balanceStatusBar.tooltip = `CaptchaAI Balance: $${balance}`;
    } else {
      balanceStatusBar.text = "$(warning) CaptchaAI: Error";
    }
  } catch {
    balanceStatusBar.text = "$(warning) CaptchaAI: Offline";
  }
}

// --- Solve Command ---

async function solveCaptcha(method, extraFields) {
  const key = getApiKey();
  if (!key) return;

  const sitekey = await vscode.window.showInputBox({
    prompt: "Enter the CAPTCHA sitekey",
    placeHolder: "6LeIxAcTAAAAAJcZ...",
  });
  if (!sitekey) return;

  const pageurl = await vscode.window.showInputBox({
    prompt: "Enter the page URL",
    placeHolder: "https://example.com",
  });
  if (!pageurl) return;

  const params = {
    key,
    method,
    pageurl,
    json: 1,
    ...extraFields,
  };

  if (method === "userrecaptcha") {
    params.googlekey = sitekey;
  } else {
    params.sitekey = sitekey;
  }

  // Submit
  vscode.window.withProgress(
    {
      location: vscode.ProgressLocation.Notification,
      title: "CaptchaAI: Solving...",
      cancellable: true,
    },
    async (progress, cancellation) => {
      try {
        const submitResponse = await fetch(`${API_BASE}/in.php`, {
          method: "POST",
          body: new URLSearchParams(params),
        });
        const submitResult = await submitResponse.json();

        if (submitResult.status !== 1) {
          vscode.window.showErrorMessage(
            `CaptchaAI: ${submitResult.request || "Submit failed"}`
          );
          return;
        }

        const taskId = submitResult.request;
        progress.report({ message: `Task ${taskId} submitted` });

        // Poll
        const config = vscode.workspace.getConfiguration("captchaai");
        const interval = config.get("pollInterval") * 1000;

        for (let i = 0; i < 60; i++) {
          if (cancellation.isCancellationRequested) return;

          await new Promise((r) => setTimeout(r, interval));

          const pollUrl = new URL(`${API_BASE}/res.php`);
          pollUrl.searchParams.set("key", key);
          pollUrl.searchParams.set("action", "get");
          pollUrl.searchParams.set("id", taskId);
          pollUrl.searchParams.set("json", "1");

          const pollResponse = await fetch(pollUrl);
          const pollResult = await pollResponse.json();

          if (pollResult.request === "CAPCHA_NOT_READY") {
            progress.report({ message: `Waiting... (${(i + 1) * (interval / 1000)}s)` });
            continue;
          }

          if (pollResult.status === 1) {
            const token = pollResult.request;

            // Copy to clipboard
            await vscode.env.clipboard.writeText(token);
            vscode.window.showInformationMessage(
              `CaptchaAI: Solved! Token copied to clipboard (${token.length} chars)`
            );

            // Also insert at cursor if editor is active
            const editor = vscode.window.activeTextEditor;
            if (editor) {
              const action = await vscode.window.showQuickPick(
                ["Copy only", "Insert at cursor"],
                { placeHolder: "Token copied. Insert into editor?" }
              );
              if (action === "Insert at cursor") {
                editor.edit((editBuilder) => {
                  editBuilder.insert(editor.selection.active, token);
                });
              }
            }
            return;
          }

          vscode.window.showErrorMessage(
            `CaptchaAI: ${pollResult.request || "Solve failed"}`
          );
          return;
        }

        vscode.window.showErrorMessage("CaptchaAI: Solve timed out");
      } catch (err) {
        vscode.window.showErrorMessage(`CaptchaAI: ${err.message}`);
      }
    }
  );
}

// --- Sitekey Detection ---

async function detectSitekey() {
  const editor = vscode.window.activeTextEditor;
  if (!editor) {
    vscode.window.showWarningMessage("No active editor");
    return;
  }

  const text = editor.document.getText();
  const patterns = [
    { regex: /data-sitekey=["']([^"']+)["']/g, type: "HTML data-sitekey" },
    { regex: /googlekey['":\s]+["']([a-zA-Z0-9_-]{40})["']/g, type: "API googlekey" },
    { regex: /sitekey['":\s]+["']([a-zA-Z0-9_-]{20,})["']/g, type: "sitekey parameter" },
    { regex: /render=([a-zA-Z0-9_-]{40})/g, type: "reCAPTCHA render" },
  ];

  const found = [];
  for (const { regex, type } of patterns) {
    let match;
    while ((match = regex.exec(text)) !== null) {
      found.push({ key: match[1], type, position: match.index });
    }
  }

  if (found.length === 0) {
    vscode.window.showInformationMessage("No sitekeys found in current file");
    return;
  }

  const items = found.map((f) => ({
    label: f.key,
    description: f.type,
    detail: `Position: ${f.position}`,
    key: f.key,
  }));

  const selected = await vscode.window.showQuickPick(items, {
    placeHolder: `Found ${found.length} sitekey(s) — select to copy`,
  });

  if (selected) {
    await vscode.env.clipboard.writeText(selected.key);
    vscode.window.showInformationMessage(`Sitekey copied: ${selected.key}`);
  }
}

// --- Activation ---

function activate(context) {
  // Balance status bar
  const config = vscode.workspace.getConfiguration("captchaai");

  if (config.get("showBalance")) {
    balanceStatusBar = vscode.window.createStatusBarItem(
      vscode.StatusBarAlignment.Right,
      100
    );
    balanceStatusBar.command = "captchaai.checkBalance";
    balanceStatusBar.text = "$(credit-card) CaptchaAI";
    balanceStatusBar.show();

    updateBalance();
    balanceInterval = setInterval(updateBalance, 300000); // Every 5 minutes

    context.subscriptions.push(balanceStatusBar);
  }

  // Register commands
  context.subscriptions.push(
    vscode.commands.registerCommand("captchaai.checkBalance", async () => {
      await updateBalance();
      vscode.window.showInformationMessage(balanceStatusBar.tooltip);
    }),

    vscode.commands.registerCommand("captchaai.solveRecaptcha", () => {
      solveCaptcha("userrecaptcha", {});
    }),

    vscode.commands.registerCommand("captchaai.solveTurnstile", () => {
      solveCaptcha("turnstile", {});
    }),

    vscode.commands.registerCommand("captchaai.detectSitekey", detectSitekey)
  );
}

function deactivate() {
  if (balanceInterval) clearInterval(balanceInterval);
}

module.exports = { activate, deactivate };

Cuplikan Kode

Cuplikan Python

{
  "CaptchaAI reCAPTCHA v2": {
    "prefix": "cai-recaptcha-v2",
    "body": [
      "import requests",
      "",
      "# Submit reCAPTCHA v2 task",
      "response = requests.post(",
      "    \"https://ocr.captchaai.com/in.php\",",
      "    data={",
      "        \"key\": \"${1:YOUR_API_KEY}\",",
      "        \"method\": \"userrecaptcha\",",
      "        \"googlekey\": \"${2:SITE_KEY}\",",
      "        \"pageurl\": \"${3:https://example.com}\",",
      "        \"json\": 1,",
      "    },",
      ")",
      "task_id = response.json()[\"request\"]",
      "",
      "# Poll for result",
      "import time",
      "while True:",
      "    time.sleep(5)",
      "    result = requests.get(",
      "        \"https://ocr.captchaai.com/res.php\",",
      "        params={\"key\": \"${1}\", \"action\": \"get\", \"id\": task_id, \"json\": 1},",
      "    ).json()",
      "    if result[\"request\"] != \"CAPCHA_NOT_READY\":",
      "        token = result[\"request\"]",
      "        break"
    ],
    "description": "CaptchaAI reCAPTCHA v2 solve"
  },
  "CaptchaAI Turnstile": {
    "prefix": "cai-turnstile",
    "body": [
      "import requests",
      "",
      "response = requests.post(",
      "    \"https://ocr.captchaai.com/in.php\",",
      "    data={",
      "        \"key\": \"${1:YOUR_API_KEY}\",",
      "        \"method\": \"turnstile\",",
      "        \"sitekey\": \"${2:SITE_KEY}\",",
      "        \"pageurl\": \"${3:https://example.com}\",",
      "        \"json\": 1,",
      "    },",
      ")",
      "task_id = response.json()[\"request\"]"
    ],
    "description": "CaptchaAI Turnstile solve"
  },
  "CaptchaAI Balance Check": {
    "prefix": "cai-balance",
    "body": [
      "import requests",
      "",
      "balance = requests.get(",
      "    \"https://ocr.captchaai.com/res.php\",",
      "    params={\"key\": \"${1:YOUR_API_KEY}\", \"action\": \"getbalance\", \"json\": 1},",
      ").json()",
      "print(f\"Balance: \\${balance['request']}\")"
    ],
    "description": "CaptchaAI balance check"
  }
}

Cuplikan JavaScript

{
  "CaptchaAI reCAPTCHA v2": {
    "prefix": "cai-recaptcha-v2",
    "body": [
      "const response = await fetch('https://ocr.captchaai.com/in.php', {",
      "  method: 'POST',",
      "  body: new URLSearchParams({",
      "    key: '${1:YOUR_API_KEY}',",
      "    method: 'userrecaptcha',",
      "    googlekey: '${2:SITE_KEY}',",
      "    pageurl: '${3:https://example.com}',",
      "    json: 1,",
      "  }),",
      "});",
      "const { request: taskId } = await response.json();",
      "",
      "// Poll for result",
      "let token;",
      "while (true) {",
      "  await new Promise(r => setTimeout(r, 5000));",
      "  const url = new URL('https://ocr.captchaai.com/res.php');",
      "  url.searchParams.set('key', '${1}');",
      "  url.searchParams.set('action', 'get');",
      "  url.searchParams.set('id', taskId);",
      "  url.searchParams.set('json', '1');",
      "  const result = await (await fetch(url)).json();",
      "  if (result.request !== 'CAPCHA_NOT_READY') {",
      "    token = result.request;",
      "    break;",
      "  }",
      "}"
    ],
    "description": "CaptchaAI reCAPTCHA v2 solve"
  }
}

Kontrak manifes minimal

  • Cantumkan peristiwa aktivasi, perintah yang dikontribusikan, dan entri konfigurasi aman yang diperlukan ekstensi sejak hari pertama.
  • Simpan kunci API di luar jalur implementasi perintah sehingga pengemasan dan manajemen rahasia tetap dapat dipisahkan.
  • Dokumentasikan permukaan package.json terkecil yang masih memungkinkan pengujian dan penerbitan lokal yang andal.

Kontrak manifes minimal

  • Cantumkan peristiwa aktivasi, perintah yang dikontribusikan, dan entri konfigurasi aman yang diperlukan ekstensi sejak hari pertama.
  • Simpan kunci API di luar jalur implementasi perintah sehingga pengemasan dan manajemen rahasia tetap dapat dipisahkan.
  • Dokumentasikan permukaan package.json terkecil yang masih memungkinkan pengujian dan penerbitan lokal yang andal.

Pemecahan masalah

Masalah Sebab Perbaiki
Saldo menunjukkan "Offline" Tidak dapat menjangkau API dari VS Code Periksa jaringan/firewall; pastikan ocr.captchaai.com dapat diakses
Kesalahan "Setel kunci API Anda". Kunci tidak dikonfigurasi Pengaturan → cari "CaptchaAI" → masukkan kunci API
Cuplikan tidak muncul Modus bahasa salah Periksa mode bahasa file yang cocok dengan cuplikan (Python/JavaScript)
Selesaikan waktu habis Tugas gagal atau jaringan lambat Tingkatkan interval jajak pendapat dalam pengaturan; verifikasi sitekey dan pageurl
Deteksi sitekey tidak menemukan apa pun Tidak ada pola yang cocok dalam file Pastikan file berisi atribut data-sitekey, googlekey, atau sitekey

Pertanyaan Umum

Apakah ekstensi ini tersedia di VS Code Marketplace?

Panduan ini menunjukkan cara membuat ekstensi. Untuk mempublikasikan, ikutiPanduan Penerbitan Ekstensi Kode VS. Anda juga dapat menggunakan ekstensi secara lokal melalui code --install-extension captchaai-dev-tools-1.0.0.vsix.

Apakah ekstensi menyimpan kunci API saya dengan aman?

Pengaturan VS Code disimpan dalam JSON di disk. Untuk keamanan yang lebih kuat, gunakan API SecretStorage VS Code untuk menyimpan kunci di gantungan kunci OS, bukan di pengaturan teks biasa.

Bisakah saya menambahkan awalan cuplikan khusus?

Ya — edit file cuplikan JSON di folder snippets/. Setiap cuplikan memiliki bidang prefix yang memicu saran pelengkapan otomatis.

Artikel Terkait

Langkah Selanjutnya

Bangun alat CaptchaAI langsung ke editor Anda —dapatkan kunci API Andadan mulai berkembang.

Panduan terkait:

Komentar dinonaktifkan untuk artikel ini.