Integrations

Retool + CaptchaAI: Internal Tool dengan Penanganan CAPTCHA

Retool tidak punya komponen penyelesai CAPTCHA, dan Anda memang tidak membutuhkannya: dua query REST API plus satu query JavaScript sudah cukup. Query pertama mengirim tantangan ke CaptchaAI, query kedua polling sampai token siap, lalu token itu ikut dikirim query formulir berikutnya.

Tidak ada backend yang perlu di-hosting sendiri, tidak ada library tambahan, dan API key cukup tinggal di Secrets Store Retool. Tiga query yang akan Anda buat:

  • submitCaptcha — mengirim tantangan ke in.php
  • pollResult — mengambil hasil dari res.php
  • solveCaptcha — query JavaScript yang mengatur jeda dan perulangan

Skenario: satu operator yang seharian mengklik kotak verifikasi

Bayangkan tim operasi agensi data di Jakarta yang tiap pagi mengisi ratusan baris di portal vendor tempat mereka punya akun resmi. Halaman submit-nya memasang reCAPTCHA v2, jadi satu orang praktis mengklik kotak verifikasi seharian. Setelah integrasi terpasang, aplikasi Retool-lah yang:

  1. Menerima sitekey dan URL halaman sebagai input
  2. Mengirim tantangan CAPTCHA ke CaptchaAI
  3. Melakukan polling sampai hasilnya selesai
  4. Menampilkan token siap pakai untuk query pengiriman formulir

Langkah 1: daftarkan CaptchaAI sebagai resource REST API

Di Retool, buka Resources -> Create New -> REST API, lalu isi:

  • Name: CaptchaAI
  • Base URL: https://ocr.captchaai.com
  • Authentication: None — API key dikirim sebagai parameter query

Simpan resource. Nama inilah yang Anda pilih di setiap query berikutnya.

Langkah 2: buat query submit ke in.php

Buat query baru bernama submitCaptcha dengan resource CaptchaAI, Action Type GET, dan URL Path /in.php. Parameter query-nya:

  • key: {{secretsStore.CAPTCHAAI_API_KEY}}
  • method: userrecaptcha
  • googlekey: {{sitekeyInput.value}}
  • pageurl: {{pageurlInput.value}}
  • json: 1

Simpan API key di Secrets Store Retool (Settings -> Secrets), jangan tulis langsung di definisi query — pembuat aplikasi lain hanya melihat referensinya, bukan nilai key-nya. Transformator berikut opsional, tetapi memudahkan membaca hasilnya:

// Parse the response
const data = {{ submitCaptcha.data }};
if (data.status === 1) {
  return { taskId: data.request, status: 'submitted' };
}
return { error: data.request, status: 'failed' };

Langkah 3: buat query polling ke res.php

Buat query bernama pollResult, juga GET, dengan URL Path /res.php dan parameter:

  • key: {{secretsStore.CAPTCHAAI_API_KEY}}
  • action: get
  • id: {{submitCaptcha.data.request}}
  • json: 1

Selama hasil belum siap, endpoint ini membalas CAPCHA_NOT_READY — bukan kesalahan. Transformator di bawah memisahkannya dari error sungguhan:

const data = {{ pollResult.data }};
if (data.status === 1) {
  return { token: data.request, status: 'solved' };
}
if (data.request === 'CAPCHA_NOT_READY') {
  return { status: 'pending' };
}
return { error: data.request, status: 'error' };

Langkah 4: satukan submit dan polling di satu query JavaScript

Buat query JavaScript bernama solveCaptcha sebagai pengatur siklusnya. Jeda 15 detik sebelum polling pertama disengaja: reCAPTCHA v2 jarang selesai lebih cepat.

// solveCaptcha — JavaScript Query
async function solve() {
  // Submit the CAPTCHA task
  await submitCaptcha.trigger();
  const submitResult = submitCaptcha.data;

  if (submitResult.status !== 1) {
    return { error: submitResult.request, status: 'submit_failed' };
  }

  const taskId = submitResult.request;

  // Wait 15 seconds before first poll
  await new Promise(r => setTimeout(r, 15000));

  // Poll up to 20 times (100 seconds max)
  for (let i = 0; i < 20; i++) {
    await pollResult.trigger({
      additionalScope: { taskId: taskId }
    });

    const result = pollResult.data;

    if (result.status === 1) {
      return { token: result.request, status: 'solved' };
    }

    if (result.request !== 'CAPCHA_NOT_READY') {
      return { error: result.request, status: 'error' };
    }

    // Wait 5 seconds before next poll
    await new Promise(r => setTimeout(r, 5000));
  }

  return { error: 'Polling timeout', status: 'timeout' };
}

return solve();

Total tunggu maksimalnya sekitar 115 detik, tepat di bawah batas 120 detik Retool untuk query JavaScript. Jika iterasi dinaikkan, perpendek jeda antar-polling.

Langkah 5: susun UI aplikasi Retool — satu tombol, satu kolom hasil

Komponen Nama Peran
Text Input sitekeyInput Label "reCAPTCHA Sitekey"
Text Input pageurlInput Label "URL Halaman"
Button solveButton Label "Selesaikan CAPTCHA", onClick -> solveCaptcha.trigger()
Text + Loading Indicator Tampil saat {{ solveCaptcha.isFetching }}
Text Area tokenOutput Read-only, isinya {{ solveCaptcha.data?.token }}
Copy Button + Status Badge Menyalin token dan menampilkan {{ solveCaptcha.data?.status }}

Langkah 6: pakai token di query pengiriman formulir

Token baru berguna jika langsung ikut terkirim. Buat query submitForm:

  • Resource: API target Anda
  • Action Type: POST
  • Body: data formulir termasuk g-recaptcha-response: {{solveCaptcha.data.token}}

Sambungkan ke tombol "Kirim Formulir" yang aktif hanya ketika {{ solveCaptcha.data?.status === 'solved' }}. Masa berlaku token terbatas, jadi jalankan solve ulang tiap kali tombol ditekan.

Berapa thread yang dibutuhkan internal tool seperti ini?

CaptchaAI menagih per thread, bukan per solve: satu thread adalah satu tantangan yang sedang berjalan, dan begitu selesai thread itu langsung menerima pekerjaan berikutnya. Jadi kebutuhan Anda sebanyak operator yang menekan tombol bersamaan — bukan sebanyak solve per bulan.

  • Lima operator satu shift masih nyaman di BASIC ($15/bulan, 5 thread)
  • Tim dua shift atau solve batch lebih pas di STANDARD ($30/bulan, 15 thread)

Tagihannya tetap berapa pun jumlah solve bulan itu. Retool Cloud maupun self-hosted sama-sama memanggil API CaptchaAI langsung; pada instalasi self-hosted di AWS ap-southeast-3 (Jakarta) atau ap-southeast-1 (Singapura), pastikan egress ke ocr.captchaai.com diizinkan — tambahan latensinya kecil dibanding waktu penyelesaian. Pastikan pula tool ini hanya mengolah data yang tim Anda berhak proses, relevan untuk kepatuhan UU Pelindungan Data Pribadi.

Masalah yang sering muncul

Lima kendala berikut menutupi hampir semua kasus:

Masalah Penyebab Solusi
ERROR_WRONG_USER_KEY Key salah atau belum ada di Secrets Store Periksa Settings -> Secrets
Respons berupa teks mentah Parameter json=1 tidak disertakan Tambahkan json: 1
Polling berakhir timeout Tipe CAPTCHA butuh waktu lebih lama Naikkan iterasi dari 20 ke 30
submitCaptcha.data undefined Query submit belum berjalan Jalankan submit sebelum polling
Query JavaScript terputus Batas 120 detik Retool untuk query JS Tahan 20 iterasi, jeda 5 detik

Pertanyaan umum

Tipe CAPTCHA apa saja yang bisa ditangani dengan pola query ini?

Pola submit-polling yang sama berlaku untuk semua tipe yang didukung — cukup ganti nilai method:

  • reCAPTCHA v2 dan v3, termasuk Enterprise
  • Cloudflare Turnstile dan Cloudflare Challenge
  • GeeTest v3, serta CAPTCHA gambar dan grid
  • hCaptcha dan FunCaptcha belum didukung; GeeTest v4 berstatus segera hadir

Berapa lama satu solve reCAPTCHA v2 berjalan di Retool?

Umumnya belasan detik; skrip di Langkah 4 sengaja menunggu 15 detik sebelum polling pertama. Siapkan UI untuk rentang 15–60 detik dan kunci tombol selama proses berjalan.

Bisakah satu token dipakai untuk beberapa pengiriman formulir?

Tidak. Token reCAPTCHA v2 sekali pakai dan berumur pendek: jalankan solveCaptcha tepat sebelum tiap pengiriman.

Bagaimana jika beberapa operator menekan tombol solve bersamaan?

Setiap klik menjadi satu tantangan yang berjalan sendiri. Selama jumlah klik serentak masih di bawah kuota thread paket Anda, semuanya jalan paralel; sisanya antre sampai ada thread yang bebas.

Artikel Terkait

Langkah Selanjutnya

Pasang penyelesaian CAPTCHA di internal tool Anda — ambil API key CaptchaAI, buat resource REST API-nya, lalu jalankan query submit pertama.

Panduan terkait:

Komentar dinonaktifkan untuk artikel ini.