Anda bisa membuat Airtable menyelesaikan reCAPTCHA v2 sendiri: begitu record baru masuk ke tabel, sebuah skrip mengirim sitekey dan URL ke CaptchaAI, menunggu token, lalu menuliskannya kembali ke record itu — tanpa server terpisah, tanpa antrean manual, semua di dalam Airtable Automations dan Scripting Extension.
Banyak tim data di Indonesia memakai Airtable sebagai basis data ringan untuk price monitoring dan scraping skala kecil — sampai halaman target dilindungi CAPTCHA. Panduan ini memasang alur "record masuk → CAPTCHA selesai → token tersimpan" di Airtable, dengan reCAPTCHA v2 sebagai contoh.
Cara kerja alur yang dipicu record
Bayangkan satu tabel berisi daftar URL target, masing-masing dengan CAPTCHA yang harus diselesaikan sebelum datanya diambil. Alurnya mengikuti pola standar CaptchaAI dalam empat langkah.
Automation mendeteksi record baru, skrip mengirim parameter CAPTCHA ke CaptchaAI, menyimpan task ID, polling sampai token siap, lalu menuliskannya kembali ke record. Karena pemicunya adalah kondisi field, alur yang sama menangani record baru maupun percobaan ulang tanpa kode tambahan.
Berapa thread yang perlu Anda bayar
Pahami modelnya: CaptchaAI menagih per thread konkuren, bukan per solve, dan tiap thread mencakup solve tak terbatas sebulan penuh — tabel yang membengkak tidak menaikkan tagihan.
- BASIC ($15/bulan, 5 thread) — cukup untuk operasi khas, beberapa puluh record per hari.
- STANDARD ($30/bulan, 15 thread) — untuk batch besar dengan beberapa record paralel.
- ADVANCE ($90/bulan, 50 thread) — untuk volume tinggi dan paralelisme agresif.
Harga dalam USD, per thread, bukan per CAPTCHA.
Struktur tabel yang perlu disiapkan
Buat tabel bernama CAPTCHA Tasks. Pertahankan nama field dalam bahasa Inggris persis seperti di bawah — skrip merujuknya secara literal, dan salah huruf membuat updateRecordAsync gagal.
| Field | Tipe | Fungsi |
|---|---|---|
| URL | URL | URL halaman target |
| Sitekey | Single line text | sitekey reCAPTCHA |
| Status | Single select | pending, solving, solved, failed |
| Token | Long text | token CAPTCHA terselesaikan |
| Solved At | Date/time | stempel waktu penyelesaian |
| Error | Single line text | pesan kesalahan bila gagal |
Nilai field Status wajib teks Inggris (
pending,solving,solved,failed) agar cocok dengan kondisi pemicu dan skrip.
Langkah 1: buat automation-nya
Di tab Automations, klik Create automation dan beri nama "Solve CAPTCHA on New Record". Untuk pemicunya, pilih When record matches conditions, arahkan ke table CAPTCHA Tasks, lalu set kondisi Status is pending. Pemicu ini aktif setiap kali record disetel ke pending — mencakup record baru maupun yang di-solve ulang.
Langkah 2: tambahkan aksi skrip
Tambahkan aksi -> Run a script:
// 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}`);
}
Di panel kiri, petakan variabel input: recordId ke Record ID, sitekey ke field Sitekey, pageurl ke field URL.
Langkah 3: pemrosesan batch dengan Scripting Extension
Automation memproses satu record per pemicu. Untuk banyak record sekaligus — misalnya setelah impor CSV ratusan URL — pakai Scripting Extension di panel Apps:
// 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');
Jalankan manual atau jadwalkan dari komputer Anda. Karena reCAPTCHA v2 biasanya selesai dalam belasan detik, batch besar lebih hemat sebagai antrean thread, bukan sekaligus.
Pemecahan Masalah
| Masalah | Penyebab | Solusi |
|---|---|---|
| Automation tidak terpicu | Status belum pending |
Pastikan nilai field Status sama persis, termasuk huruf kecil |
fetch is not defined |
Sebagian konteks Airtable memakai remoteFetchAsync |
Ganti fetch dengan remoteFetchAsync |
| Skrip kena batas waktu | Automation dibatasi 30 detik | Kurangi iterasi polling; naikkan jeda awal ke 20 detik |
| Update record gagal | Nama field tidak cocok | Samakan persis nama field di updateRecordAsync dengan tabel |
| API key bocor di skrip | API key ditulis langsung di kode | Pakai input.config() dengan variabel input rahasia |
Pertanyaan Umum
Apakah pola ini bisa untuk Cloudflare Turnstile, bukan hanya reCAPTCHA v2?
Bisa. Polanya sama — hanya method dan parameternya yang berbeda. CaptchaAI mendukung reCAPTCHA v2/v3, Cloudflare Turnstile, dan GeeTest v3, jadi cukup ganti panggilan API-nya. hCaptcha belum didukung saat ini.
Berapa thread yang saya butuhkan untuk batch Airtable?
Untuk record yang diproses berurutan, satu thread cukup. Untuk beberapa record paralel lewat Scripting Extension, jumlah thread menentukan berapa solve berjalan bersamaan. BASIC ($15/bulan) memberi 5 thread — memadai untuk operasi skala tim.
Apakah automation ikut terpicu saat record lama diperbarui?
Ya. Karena pemicunya kondisi Status pending, record mana pun yang dikembalikan ke pending akan memicu ulang alur — bukan hanya record baru. Untuk mengulang CAPTCHA yang gagal, setel saja Status-nya ke pending; tambahkan field penghitung percobaan agar tidak tanpa batas.
Artikel Terkait
- Cara menyelesaikan callback reCAPTCHA v2 via API
- Menangani reCAPTCHA v2 dan Turnstile di satu situs
- Mekanisme callback reCAPTCHA v2
Langkah Selanjutnya
Biarkan tabel Airtable menyelesaikan CAPTCHA sendiri — ambil kunci API CaptchaAI dan rangkai automation pertama Anda.
Panduan terkait: