Intégrations

Airtable et CaptchaAI pour déclencher la résolution de CAPTCHA depuis la base

Airtable sert souvent de couche d'orchestration pour des workflows de collecte, de traitement d'URL ou d'automatisation sans interface lourde. Quand un enregistrement Airtable doit lancer une action sur un service protégé par CAPTCHA, la limite apparaît vite. CaptchaAI permet d'intégrer la résolution directement dans vos Automations ou vos scripts Airtable, sans sortir du workflow métier.

L'idée n'est pas seulement de résoudre un CAPTCHA depuis Airtable, mais de faire d'un enregistrement un véritable job technique avec statut, horodatage, erreur et résultat réutilisable.

Cas concret

Vous stockez des URL cibles dans une table Airtable. Chaque URL correspond à une page qui demande un reCAPTCHA avant l'étape suivante de traitement. Lorsqu'un nouvel enregistrement arrive :

  1. Une Automation Airtable détecte le nouvel élément.
  2. Un script envoie les paramètres CAPTCHA à CaptchaAI.
  3. CaptchaAI renvoie un token résolu.
  4. Le token, le statut et l'horodatage sont enregistrés dans Airtable.

Structure de table recommandée

Créez une table nommée CAPTCHA Tasks avec les champs suivants :

Champ Type Rôle
URL URL Page cible
Sitekey Texte Sitekey reCAPTCHA
Status Single select pending, solving, solved, failed
Token Long text Token CAPTCHA renvoyé
Solved At Date/time Date et heure de résolution
Error Texte Message d'erreur en cas d'échec

Ce modèle simple suffit pour suivre l'état du job et relancer proprement les échecs sans bricoler des colonnes à chaque itération.

Étape 1 : créer l'Automation

Dans Airtable :

  1. Ouvrez l'onglet Automations.
  2. Cliquez sur Create automation.
  3. Donnez-lui un nom explicite, par exemple Solve CAPTCHA on New Record.

Déclencheur

Choisissez When record matches conditions :

  • Table : CAPTCHA Tasks
  • Condition : Status est égal à pending

Ce choix est utile parce qu'il couvre à la fois les nouveaux enregistrements et les relances manuelles après échec.

Étape 2 : ajouter l'action de script

Ajoutez une action 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}`);
}

Configurer les entrées de script

Dans le panneau de gauche de l'action de script, mappez les variables d'entrée :

  • recordId -> Record ID issu du trigger
  • sitekey -> champ Sitekey
  • pageurl -> champ URL

En production, pensez à passer la clé API via input.config() ou une variable secrète plutôt qu'en dur dans le script.

Étape 3 : traitement par lot avec Scripting Extension

Si vous voulez traiter plusieurs enregistrements en une fois, utilisez la Scripting extension d'Airtable :

// 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');

Dépannage

Probleme Cause probable Correctif
L'automatisation ne part pas Le record ne correspond pas à pending Vérifiez exactement la valeur du champ Status
fetch is not defined Selon le contexte Airtable, il faut remoteFetchAsync Essayez remoteFetchAsync à la place
Le script expire Les Automations ont une limite de temps courte Réduisez le nombre de polls et augmentez le délai initial
La mise à jour du record échoue Noms de champs incohérents Vérifiez les labels exacts utilisés dans updateRecordAsync
La clé API est visible Clé codée en dur Utilisez input.config() avec un secret

FAQ

Quelle est la limite de temps d'exécution d'un script dans Airtable ?

Pour les Automations, la fenêtre est courte, donc il faut éviter un polling trop dense. Si le solve prend plus longtemps, augmentez le délai initial et réduisez le nombre d'itérations. La Scripting extension laisse un peu plus de souplesse pour des traitements manuels ou par lot.

Peut-on utiliser le même schéma pour les CAPTCHA image ?

Oui. Il suffit de changer method pour un mode adapté au type de CAPTCHA et de transmettre l'image ou les paramètres attendus. Airtable peut servir de couche de stockage et de reprise pour ces jobs aussi.

Comment protéger la clé API ?

Dans une Automation, utilisez les variables d'entrée ou un secret. Dans la Scripting extension, vous pouvez la demander à l'exécution avec input.textAsync() si vous ne voulez pas la stocker dans le code.

Peut-on relancer les échecs ?

Oui. Remettez le champ Status sur pending pour relancer l'automation. Ajoutez un compteur de retries si vous voulez éviter les boucles infinies.

Articles connexes

  • Comment résoudre le callback reCAPTCHA v2 avec l'API
  • Gérer reCAPTCHA v2 et Turnstile sur le même site
  • Comprendre le callback reCAPTCHA v2

Prochaines étapes

Si Airtable pilote déjà vos opérations, récupérez votre clé API CaptchaAI et transformez chaque enregistrement critique en tâche de résolution traçable et rejouable.

Guides associes :

Les commentaires sont désactivés pour cet article.