Integrasi

Airtable + CaptchaAI: Pemecahan CAPTCHA yang Dipicu Basis Data

Airtable adalah platform database fleksibel yang digunakan untuk manajemen proyek, pengumpulan data, dan otomatisasi alur kerja. Saat alur kerja Airtable Anda perlu berinteraksi dengan layanan yang dilindungi CAPTCHA – mengirimkan formulir, memproses URL, atau mengotomatiskan entri data –CaptchaAIdapat menyelesaikan CAPTCHA langsung dari Airtable menggunakan ekstensi Otomatisasi dan Skrip.

Panduan ini menunjukkan cara menyiapkan Airtable Automations yang memicu penyelesaian CAPTCHA melalui CaptchaAI saat catatan baru dibuat atau diperbarui.

Skenario Dunia Nyata

Anda melacak URL target di tabel Airtable. Setiap URL memiliki CAPTCHA yang perlu dipecahkan sebelum data dapat diekstraksi. Saat URL baru ditambahkan:

  1. Otomatisasi Airtable mendeteksi rekor baru
  2. Sebuah skrip mengirimkan parameter CAPTCHA ke CaptchaAI
  3. CaptchaAI mengembalikan token yang diselesaikan
  4. Token disimpan kembali ke catatan Airtable

Struktur Tabel

Buat tabel Airtable yang disebut Tugas CAPTCHA dengan kolom berikut:

Nama Bidang Ketik Tujuan
URL URL URL halaman target
Kunci Situs Teks satu baris kunci situs reCAPTCHA
Status Pilihan tunggal tertunda, menyelesaikan, menyelesaikan, gagal
Tanda Teks panjang Token CAPTCHA terpecahkan
Dipecahkan Pada Tanggal/time Stempel waktu penyelesaian
Kesalahan Teks satu baris Pesan kesalahan jika gagal

Langkah 1: Buat Otomatisasi

Di Airtable:

  1. Buka tab Otomasi
  2. Klik Buat otomatisasi
  3. Beri nama: "Selesaikan CAPTCHA pada Rekor Baru"

Pemicu

Pilih Saat data cocok dengan kondisi:

  • Tabel: Tugas CAPTCHA
  • Kondisi: Status "pending"

Ini terpicu setiap kali rekaman disetel ke "menunggu keputusan" - mencakup rekaman baru dan penyelesaian ulang.

Langkah 2: Tambahkan Tindakan Skrip

Tambahkan tindakan -> Jalankan skrip:

// Airtable Automation Script — Solve CAPTCHA via CaptchaAI

// Input configuration (set in the left panel):
// - recordId: Record ID from trigger
// - sitekey: Sitekey field from trigger
// - pageurl: URL field from trigger
const config = input.config();
const recordId = config.recordId;
const sitekey = config.sitekey;
const pageurl = config.pageurl;

const API_KEY = 'YOUR_API_KEY'; // Use input.config() for security

// Update status to "solving"
const table = base.getTable('CAPTCHA Tasks');
await table.updateRecordAsync(recordId, {
  'Status': { name: 'solving' },
});

try {
  // Step 1: Submit task to CaptchaAI
  const submitUrl = `https://ocr.captchaai.com/in.php?key=${API_KEY}&method=userrecaptcha&googlekey=${encodeURIComponent(sitekey)}&pageurl=${encodeURIComponent(pageurl)}&json=1`;

  const submitResponse = await fetch(submitUrl);
  const submitResult = await submitResponse.json();

  if (submitResult.status !== 1) {
    throw new Error(`Submit failed: ${submitResult.request}`);
  }

  const taskId = submitResult.request;
  console.log(`Task submitted: ${taskId}`);

  // Step 2: Poll for result (wait 15 seconds first)
  await new Promise(resolve => setTimeout(resolve, 15000));

  let token = null;
  for (let i = 0; i < 20; i++) {
    const pollUrl = `https://ocr.captchaai.com/res.php?key=${API_KEY}&action=get&id=${taskId}&json=1`;
    const pollResponse = await fetch(pollUrl);
    const pollResult = await pollResponse.json();

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

    if (pollResult.request !== 'CAPCHA_NOT_READY') {
      throw new Error(`Solve failed: ${pollResult.request}`);
    }

    await new Promise(resolve => setTimeout(resolve, 5000));
  }

  if (!token) {
    throw new Error('Polling timeout — CAPTCHA not solved in time');
  }

  // Step 3: Update record with solved token
  await table.updateRecordAsync(recordId, {
    'Status': { name: 'solved' },
    'Token': token,
    'Solved At': new Date().toISOString(),
    'Error': '',
  });

  console.log(`CAPTCHA solved for record ${recordId}`);

} catch (error) {
  // Update record with error
  await table.updateRecordAsync(recordId, {
    'Status': { name: 'failed' },
    'Error': error.message,
  });
  console.error(`Failed: ${error.message}`);
}

Konfigurasikan Input Skrip

Di panel kiri tindakan skrip, petakan variabel input:

  • recordId -> Rekam ID dari langkah pemicu
  • sitekey -> Bidang kunci situs dari langkah pemicu
  • pageurl -> kolom URL dari langkah pemicu

Langkah 3: Pemrosesan Batch dengan Ekstensi Scripting

Untuk memproses banyak catatan sekaligus, gunakan ekstensi skrip Airtable (tersedia di panel Aplikasi):

// Batch CAPTCHA Solver — Airtable Scripting Extension
const API_KEY = 'YOUR_API_KEY';
const table = base.getTable('CAPTCHA Tasks');

// Get all pending records
const query = await table.selectRecordsAsync({
  fields: ['URL', 'Sitekey', 'Status'],
});

const pendingRecords = query.records.filter(
  r => r.getCellValueAsString('Status') === 'pending'
);

output.text(`Found ${pendingRecords.length} pending CAPTCHAs`);

for (const record of pendingRecords) {
  const sitekey = record.getCellValueAsString('Sitekey');
  const pageurl = record.getCellValueAsString('URL');

  if (!sitekey || !pageurl) {
    output.text(`Skipping ${record.id} — missing sitekey or URL`);
    continue;
  }

  output.text(`Solving for: ${pageurl}`);

  await table.updateRecordAsync(record.id, {
    'Status': { name: 'solving' },
  });

  try {
    // Submit
    const submitResp = await fetch(
      `https://ocr.captchaai.com/in.php?key=${API_KEY}&method=userrecaptcha&googlekey=${encodeURIComponent(sitekey)}&pageurl=${encodeURIComponent(pageurl)}&json=1`
    );
    const submitData = await submitResp.json();

    if (submitData.status !== 1) throw new Error(submitData.request);

    // Poll
    await new Promise(r => setTimeout(r, 15000));
    let token = null;

    for (let i = 0; i < 20; i++) {
      const pollResp = await fetch(
        `https://ocr.captchaai.com/res.php?key=${API_KEY}&action=get&id=${submitData.request}&json=1`
      );
      const pollData = await pollResp.json();

      if (pollData.status === 1) { token = pollData.request; break; }
      if (pollData.request !== 'CAPCHA_NOT_READY') throw new Error(pollData.request);
      await new Promise(r => setTimeout(r, 5000));
    }

    if (!token) throw new Error('Timeout');

    await table.updateRecordAsync(record.id, {
      'Status': { name: 'solved' },
      'Token': token,
      'Solved At': new Date().toISOString(),
    });
    output.text(`✓ Solved: ${pageurl}`);

  } catch (e) {
    await table.updateRecordAsync(record.id, {
      'Status': { name: 'failed' },
      'Error': e.message,
    });
    output.text(`✗ Failed: ${e.message}`);
  }
}

output.text('Batch processing complete');

Pemecahan Masalah

Masalah Penyebab Solusi
Otomatisasi tidak terpicu Catatan tidak cocok dengan kondisi "menunggu keputusan". Verifikasi nilai bidang Status sama persis
fetch is not defined Airtable Scripting menggunakan remoteFetchAsync dalam beberapa konteks Coba remoteFetchAsync, bukan fetch
Batas waktu skrip habis Skrip airtable memiliki batas 30 detik untuk otomatisasi Gunakan lebih sedikit iterasi polling; tingkatkan waktu tunggu awal menjadi 20 detik
Pembaruan rekaman gagal Nama bidang tidak cocok Pastikan nama field di tabel updateRecordAsync sama persis
Kunci API diekspos dalam skrip Kunci API yang dikodekan secara keras Gunakan input.config() dengan variabel input rahasia

Pertanyaan Umum

Berapa batas waktu eksekusi skrip di Airtable?

Skrip otomatisasi: 30 detik. Ekstensi skrip: 30 detik (tetapi dapat diperpanjang dengan paket Pro). Untuk polling yang panjang, tingkatkan waktu tunggu awal dan kurangi iterasi.

Bisakah saya menggunakan ini untuk CAPTCHA Gambar juga?

Ya. Ubah method menjadi base64 dan kirimkan data gambarnya. Anda dapat menyimpan gambar CAPTCHA yang dikodekan base64 di bidang Lampiran Airtable dan mengekstraknya dalam skrip.

Bagaimana cara menangani kunci API dengan aman?

Di Otomatisasi, gunakan variabel input yang dikonfigurasi di panel pengaturan skrip. Di ekstensi Scripting, Anda dapat meminta kunci saat runtime dengan input.textAsync().

Bisakah saya menyelesaikan kembali CAPTCHA yang gagal?

Ya. Atur Status kembali ke "menunggu keputusan" dan otomatisasi akan terpicu kembali. Tambahkan bidang penghitung percobaan ulang untuk membatasi percobaan ulang.

Artikel Terkait

  • Cara Mengatasi Callback Recaptcha V2 Menggunakan Api
  • Penanganan reCAPTCHA v2 dan Turnstile di Situs yang Sama
  • Mekanisme Callback reCAPTCHA v2

Langkah Selanjutnya

Otomatiskan penyelesaian CAPTCHA dari database Airtable Anda – dapatkan kunci API CaptchaAI Anda dan mulai atur otomatisasi.

Panduan terkait:

  • Skrip Google Apps + CaptchaAI
  • n8n + CaptchaAI: Otomatisasi CAPTCHA Tanpa Kode
  • Buat (Integromat) + CaptchaAI
Komentar dinonaktifkan untuk artikel ini.