Integrations

Retool + CaptchaAI:内部工具验证码表单处理

先说结论:别试图在 Retool 里渲染 reCAPTCHA v2 小部件。查询跑在服务端,没有能加载 Google 验证码脚本的浏览器上下文。可行做法是把 sitekey 和页面 URL 交给识别接口,拿回 token,让下游那条提交请求带着它走。

在 Retool 上,这条链就是一个 REST API 资源、两个 GET 查询、一个负责轮询的 JavaScript 查询,界面五个组件收尾。

前置准备

  • Retool 账号:Cloud 与自托管版都支持 REST API 资源和 JS 查询
  • CaptchaAI 账号与 API Key
  • sitekey:一般在页面源码的 data-sitekey 属性里
  • 验证码所在页的完整 URL:填首页无效

整条链四步:读入 sitekey 与页面 URL,submitCaptcha 提交任务,solveCaptcha 轮询取回 token,submitForm 带着 token 提交表单。

适用范围: 仅限你自己拥有或已获授权的门户系统,并遵守 robots 协议与《网络安全法》相关要求。

什么样的内部工具用得上

典型场景是“境内团队 + 海外门户”:跨境供应链团队的 Retool 面板,运营每天把报关数据推到海外承运商门户,而提交页挂着 reCAPTCHA v2,只能有人守着一条条点。国内站点多用 GeeTest(极验)、网易易盾,reCAPTCHA 与 Turnstile 主要在海外站点——这类团队最容易撞上。CaptchaAI 支持 GeeTest v3,极验 v4 还要等官方支持。

步骤 1:把 CaptchaAI 配成 REST API 资源

进入 ResourcesCreate NewREST API,填三项:

配置项 填写值
Name CaptchaAI
Base URL https://ocr.captchaai.com
Authentication 留空,API Key 走查询参数

保存后即可在查询里选用。

步骤 2:提交查询 submitCaptcha

新建查询 submitCaptcha,资源选 CaptchaAI,GET,URL Path 填 /in.php。参数五个:

参数名 填写值
key {{secretsStore.CAPTCHAAI_API_KEY}}
method userrecaptcha
googlekey {{sitekeyInput.value}}
pageurl {{pageurlInput.value}}
json 1

API Key 放进 Secrets Store(Settings → Secrets)再引用,别硬编码。json 必须带,否则接口返回纯文本,data 会是字符串。

Transformer(可选):

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

步骤 3:取结果查询 pollResult

同样挂 CaptchaAI 资源,GET,URL Path 换成 /res.php,参数改成按任务 ID 查:

  • key{{secretsStore.CAPTCHAAI_API_KEY}}
  • actionget
  • id{{submitCaptcha.data.request}}
  • json1

Transformer:

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' };

CAPCHA_NOT_READY 表示任务还在队列里,属正常状态;返回其他字符串才算出错。

步骤 4:用 JavaScript 查询串起提交与轮询

分别手点两个查询没有意义,编排逻辑放进 solveCaptcha 这个 JavaScript 查询:

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

三个数字是配套的:首轮等 15 秒,之后每 5 秒一次,最多 20 次,上限约 115 秒,卡在 Retool 对 JS 查询的 120 秒上限内。

步骤 5:界面只要五个组件

组件 作用与绑定
Text Input sitekeyInput / pageurlInput 接收 sitekey 与页面 URL
Button solveButton 标签“开始识别”,绑定 solveCaptcha.trigger()
Loading Indicator 可见条件 {{ solveCaptcha.isFetching }}
Text Area tokenOutput 只读,取 solveCaptcha.data?.token
Status Badge {{ solveCaptcha.data?.status }} 显示状态

加载指示器别省:轮询期间界面静默一分多钟,没有反馈,运营会以为卡死而反复点击。

步骤 6:把 token 交给下游请求

再建查询 submitForm,资源指向目标 API,POST,Body 带上 g-recaptcha-response: {{solveCaptcha.data.token}}。绑到“提交表单”按钮,启用条件设成 {{ solveCaptcha.data?.status === 'solved' }}。token 一次性且有有效期,尽快提交。

常见报错与处理

现象 原因 处理方式
ERROR_WRONG_USER_KEY Key 填错或不存在 到 Settings → Secrets 核对
返回纯文本而非 JSON 少了 json=1 参数里补上 json: 1
轮询跑满仍 timeout 识别耗时偏长 次数加到 30 或缩短间隔
submitCaptcha.data 为 undefined 提交没跑过 循环里先触发提交
JS 查询被中断 撞上 120 秒上限 保持 20 次 × 5 秒,或改用 Workflows
token 被目标站拒绝 sitekey 或 pageurl 填错 核对取值页面

套餐怎么选:算并发,不算次数

CaptchaAI 按并发线程计费,不按次数:一个线程就是一个在处理的验证码,完成后立刻释放,套餐内次数不设上限。

套餐 价格 线程数 适合的规模
BASIC $15/月 5 单个面板,几个人用
STANDARD $30/月 15 多个内部应用共用
ADVANCE $90/月 50 批量提交几十条

要问的是“同时有几个请求在飞”,不是“一天识别多少次”:五个运营各点一次,峰值也就 5 个线程。价格按美元计价。

常见问题

轮询一直返回 CAPCHA_NOT_READY 直到超时,怎么排查?

先确认 sitekey 与 pageurl 取自同一页面,对不上任务会长期挂在队列里。再看提交返回的 status 是否为 1,不为 1 说明任务没建上。都正常就把次数提到 30 再观察。

120 秒不够用时,该改成 Retool Workflows 吗?

批量或耗时波动大的场景值得改:提交与取结果拆成两个节点,用循环控制间隔,不受执行上限约束。代价是延迟更高;交互式面板留在 JS 查询更顺手。

hCaptcha 和 GeeTest v4 能不能走同一套流程?

都不支持,GeeTest v4 的官方口径是即将支持、尚未上线。可套用本文流程的类型:reCAPTCHA v2 / v3(含 Enterprise)、Cloudflare Turnstile、GeeTest v3、图片/OCR 与九宫格验证码;CaptchaFox、Friendly Captcha、Lemin 为测试版。

换成 Turnstile 或图片验证码要改哪里?

只改提交查询的 method 与对应参数,轮询、循环和界面都不用动。回填时换字段名:Turnstile 用 cf-turnstile-response

相关文章

下一步

先配好资源和两个查询,拿已知 sitekey 的测试页跑通,再接业务表单——领取 CaptchaAI API Key

延伸阅读:

该文章已禁用评论。