Captchas in Retool Workflows lösen (REST-Blöcke)

Ein Captcha-Lösevorgang in Retool Workflows besteht aus drei Blöcken: absenden, warten, lesen. Bauen Sie sie als REST resource query block statt als JavaScript- oder Python-code block, denn Retool führt code blocks in einem separaten, per Sandbox abgeschotteten Dienst aus, dessen Standard-Firewallregeln private Adressen ablehnen. Eine resource query ist Konfiguration statt eigener Code, sie läuft also nicht über diesen Dienst und erreicht einen Solver in Ihrem eigenen Netzwerk ganz ohne diese Diskussion.
Was Sie brauchen
- Eine Retool-Organisation mit Workflows, auf Retool Cloud oder selbst gehostet. Beides funktioniert, mit unterschiedlicher Netzwerkkonfiguration.
- CapSkip läuft auf einem Windows-Rechner. Local-Modus, wenn auf diesem Rechner auch ein selbst gehostetes Retool läuft, in jedem anderen Fall Server-Modus.
- Der sitekey und die Seiten-URL der Challenge, die Sie lösen.
- Ein Ort für den API-Schlüssel. Retool Secrets sind aus code blocks und aus der Resource-Konfiguration erreichbar, es muss also nichts in einen Block eingefügt werden.
CapSkip spricht auf Port 8080 die 2captcha-kompatible API, Retool braucht also keinen Connector und keine eigene Integration. Es ist eine ganz normale REST-Resource, die auf einen Rechner zeigt, der Ihnen gehört.
Schritt 1: eine REST-Resource auf den Solver richten
Legen Sie eine REST-API-Resource mit der Basis-URL des Rechners an, auf dem CapSkip läuft. Lassen Sie die Authentifizierung leer. Der API-Schlüssel wird bei jeder Anfrage als ganz normaler Parameter mitgeschickt, so funktioniert das 2captcha-kompatible Protokoll.
# Base URL for the resource. Loopback only works when Retool # is self-hosted on the same Windows box as the solver. http://127.0.0.1:8080 # Server mode, which is what you want everywhere else. http://192.168.1.40:8080
Jeder Workflow, der etwas löst, nutzt danach diese eine Resource weiter. Zwei Query-Blöcke reichen für die gesamte Aufgabe.
Schritt 2: die Challenge absenden
Fügen Sie einen resource query block hinzu, nennen Sie ihn submitCaptcha, setzen Sie den Action-Typ auf POST und den Pfad auf den Submit-Endpunkt. Der Body ist ein kleines JSON-Objekt.
{
"key": "YOUR_KEY",
"method": "userrecaptcha",
"googlekey": "YOUR_SITEKEY",
"pageurl": "https://example.com/page-with-recaptcha",
"json": 1
}Die Antwort enthält die id, mit der Sie abfragen.
{ "status": 1, "request": "2122988149" }Dieser Body ist reCAPTCHA v2. Die anderen Typen, die CapSkip unterstützt, sind derselbe Aufruf mit anderen Parametern: invisible oder enterprise auf 1 setzen, oder version auf v3 mit einem Action-Namen, oder die Methode auf turnstile oder geetest umstellen. Die vollständige Parameterliste finden Sie in der CapSkip-API-Dokumentation.
Ein resource query block übergibt drei Eigenschaften an alles, was nachgelagert ist. Der Response-Body kommt als data an, eine Fehlermeldung als error, und metadata trägt den Rest. Die gerade eingesammelte id steht dem nächsten Block also als submitCaptcha.data.request zur Verfügung.
Schritt 3: warten, dann den Token einmal lesen
Fügen Sie einen Wait block hinzu. Fünfzehn Sekunden sind eine sinnvolle erste Wartezeit für eine reCAPTCHA-v2-Checkbox. Bild-Captchas kommen nach etwa einer Sekunde zurück, v3 nach zehn bis fünfzehn, GeeTest nach etwa fünf. Ein Wait block nimmt eine Zahl oder einen JavaScript-Ausdruck entgegen, lässt sich in Sekunden, Minuten, Stunden oder Tagen konfigurieren, bis zu einer Obergrenze von sechzig Tagen, und pausiert nur die direkt nachgelagerten Blöcke.
Fügen Sie dann einen zweiten resource query block namens readResult hinzu, eingestellt auf GET.
# GET, with the id from step 2 in the query string.
/res.php?key=YOUR_KEY&action=get&id={{ submitCaptcha.data.request }}&json=1Zwei Antworten sind möglich. Ein fertiges Ergebnis hat status auf 1 und den Token im Feld request. Ein Ergebnis, das noch arbeitet, hat status auf 0 und die Zeichenkette CAPCHA_NOT_READY im Feld request, geschrieben ohne das T, und das heißt weiterwarten und nicht etwa, dass etwas schiefgegangen ist. Die Geschichte dieser Schreibweise steht in der ausführlichen Aufarbeitung der CAPCHA_NOT_READY-Antwort.
Behandeln Sie die beiden Fälle mit einem Branch block. Bedingungen sind einfaches JavaScript gegen einen vorgelagerten Block, der Test lautet also readResult.data.status === 1. Der If-Pfad trägt den Token weiter. Der Else-Pfad bekommt ein zweites Wait von zwanzig Sekunden und einen zweiten Lesevorgang.
Widerstehen Sie der Versuchung, das durch einen Loop block zu ersetzen. Dafür gibt es zwei Gründe, und der zweite ist der, der wirklich weh tut. Ein Loop block hat ein Standard-Timeout von zehn Sekunden und eine Obergrenze von zwei Minuten, deutlich unter den dreihundert Sekunden, die CapSkip einem reCAPTCHA-Lösevorgang zugesteht, eine Schleife kann den langsamen Ausläufer also ohnehin nicht abdecken. Wichtiger noch: Ein CapSkip-Ergebnis ist nur einmal lesbar. Eine Schleife, die eine bereits eingesammelte id erneut liest, bekommt den Token kein zweites Mal.
Schritt 4: die Netzwerkregel, die alles entscheidet
Das ist der Retool-spezifische Teil, und er ist der Grund, warum diese Anleitung den Lösevorgang aus resource query blocks aufbaut.
Retool führt Ihr JavaScript und Ihr Python in einem separaten Code-Executor-Dienst aus, per NsJail in einer Sandbox. Bei einem selbst gehosteten Deployment bringt dieser Dienst iptables-Regeln mit, die Link-Local-Adressen und den gesamten Bereich 192.168.0.0/16 abdecken, und Retool dokumentiert einen einzigen Schalter, der sie abschaltet: DISABLE_IPTABLES_SECURITY_CONFIGURATION. Retool sagt außerdem klar, dass es empfiehlt, den Code Executor privilegiert zu betreiben, damit eigener Code in der Sandbox bleibt. Ein code block, der nach einem Solver unter 192.168.1.40 greift, verlangt also von Ihnen, die Sandbox für die gesamte Instanz zu schwächen. Eine Resource-Query ist kein eigener Code und läuft dort nicht.
Davon unabhängig muss der Solver überhaupt erreichbar sein. CapSkip hat dafür zwei Verbindungsmodi. Local bindet an 127.0.0.1 und bedient nur dieses Gerät. Server bindet an Ihre Netzwerkadresse oder öffentliche IP, sodass ein anderer Rechner, ein Container-Host oder eine gehostete Plattform denselben Windows-Rechner über die API erreichen kann. Beide finden Sie unter Verbindungseinstellungen, und der Server-Modus ändert nur, auf welcher Adresse der Löser lauscht. Es ist weiterhin Ihre Hardware, und es wird weiterhin nicht pro Lösung abgerechnet.
| Wo Retool läuft | Welcher Modus, und was sonst noch |
|---|---|
| Selbst gehostet auf demselben Windows-Rechner wie CapSkip | Local-Modus. Die Basis-URL bleibt auf Loopback |
| Selbst gehostet auf einem anderen Rechner oder in Docker in Ihrem Netzwerk | Server-Modus mit der LAN-Adresse des Solvers. Verwenden Sie einen resource query block, keinen code block |
| Retool Cloud | Server-Modus mit einer statischen öffentlichen IP, dazu eine eingehende Firewallregel für die ausgehenden Adressen von Retool |
Retool Cloud ruft Ihre Resources von einem festen, veröffentlichten Satz an Adressen aus auf, und die Dokumentation sagt, dass Cloud-Instanzen sicherstellen müssen, dass konfigurierte Resources den Zugriff von dort erlauben. Die Standardregion ist AWS us-west-2.
# Retool Cloud outbound ranges, us-west-2, the default region. 35.90.103.132/30 44.208.168.68/30 # eu-central-1 3.77.79.248/30
Erlauben Sie diese in der Firewall vor Port 8080 und weisen Sie alles andere ab. Das ist eine viel kleinere Öffnung, als es aussieht, und damit ist zu Retool Cloud alles gesagt.
Schritt 5: die Timeouts, die entscheiden, ob ein langsamer Lösevorgang durchkommt
Retool veröffentlicht für verschiedene Blocktypen unterschiedliche Obergrenzen, und die sind hier wichtig, weil ein Lösevorgang von Natur aus langsam ist.
| Welches Limit | Wert | Warum es für eine Lösung wichtig ist |
|---|---|---|
| Resource query block, asynchroner Lauf | Bis zu 10 Minuten | Reichlich. Ein einzelner Lesevorgang kommt in deutlich unter einer Sekunde zurück |
| Resource query block, synchroner Lauf | Bis zu 2 Minuten | Für einen Lesevorgang immer noch in Ordnung, weil das Warten in einem Wait block passiert |
| Loop block | Standardmäßig 10 Sekunden, höchstens 2 Minuten | Der Grund, warum eine Polling-Schleife hier die falsche Form ist |
| Ganzer Lauf, asynchron | 30 Stunden, und unbegrenzt mit Wait blocks | Nichts an einem Lösevorgang kommt dem nahe |
| Ganzer Lauf, synchron | 15 Minuten bis zum ersten Response block eines Webhooks | Die Falle. Siehe den Absatz unten |
| Gleichzeitige externe Anfragen pro Workflow | 50 gleichzeitig | Die eigentliche Obergrenze für einen Stapel von Lösevorgängen in einem Lauf |
| Intervall des Schedule-Triggers | Mindestens eine Minute | In Ordnung, und es kostet nichts, das so oft laufen zu lassen |
Die synchrone Zahl ist die, um die herum Sie planen sollten. Ein Webhook-Trigger, der die Verbindung offen hält und mit einem Response block antwortet, gibt Ihnen fünfzehn Minuten. Das klingt großzügig, bis man sich daran erinnert, dass ein Aufrufer, der zwei Minuten lang auf einer offenen HTTP-Verbindung sitzt und auf ein reCAPTCHA wartet, schon für sich genommen ein schlechtes Design ist. Starten Sie den Workflow asynchron und lassen Sie ihn den Token dorthin schicken, wo er gebraucht wird, oder beantworten Sie den Webhook sofort und erledigen Sie den Lösevorgang dahinter.
Resource query blocks haben außerdem eigene Einstellungen für die Anzahl der Wiederholungen und für exponentielles Backoff. Schalten Sie diese für submitCaptcha ein und für readResult aus, aus dem oben genannten Grund, dass nur einmal gelesen werden kann.
Wenn Sie lieber Code schreiben
Auf einer selbst gehosteten Instanz, auf der der Code Executor den Solver erreichen kann, schrumpft der ganze Ablauf auf einen einzigen Python-Block, weil das SDK für Sie abfragt. Fügen Sie capskip zuvor im Tab Libraries in die requirements.txt des Workflows ein.
# pip install capskip - add it in the Libraries tab instead.
from capskip import CapSkip
# host is the solver machine. Keep 127.0.0.1 only when Retool
# runs on the same Windows box as CapSkip.
solver = CapSkip(host="192.168.1.40", port=8080)
result = solver.recaptcha(
sitekey="YOUR_SITEKEY",
url="https://example.com/page-with-recaptcha",
)
# Python blocks serialize their output as JSON, so return
# the token rather than the client object.
{"token": result["code"]}Das SDK beginnt mit einem Polling-Abstand von 250 Millisekunden und geht auf fünf Sekunden hoch, statt ein festes Intervall zu schlafen, deshalb kommt diese Variante meist schneller zurück als der Ablauf mit Wait blocks. Ihre Obergrenze für reCAPTCHA, Turnstile und GeeTest liegt bei dreihundert Sekunden, innerhalb des asynchronen Timeouts von zehn Minuten für code blocks. Retool Cloud betreibt standardmäßig Python 3.10, und die entsprechenden Varianten mit einem einzigen Aufruf für Node.js, PHP und C# finden Sie hier: Die Seite zu den SDKs fürs Captcha-Lösen.
Senden Sie den Token im unmittelbar folgenden Block ab. Ein reCAPTCHA-Token ist etwa zwei Minuten gültig, ein Workflow, der löst, dann auf einem langen Wait block wartet und erst danach absendet, scheitert also an einem Token, der bei seiner Erstellung gültig war. Mehr zu diesem Fehlerfall steht im Leitfaden zur Gültigkeitsdauer von reCAPTCHA-Token.
Häufige Fehler und was sie bedeuten
| Was Sie sehen | Ursache | Beheben |
|---|---|---|
| Ein code block läuft beim Zugriff auf eine LAN-Adresse in einen Timeout | Die Standard-iptables-Regeln des selbst gehosteten Code Executors decken 192.168.0.0/16 ab | Verlegen Sie den Aufruf in einen REST resource query block |
| Verbindung auf Port 8080 abgewiesen | CapSkip ist an Loopback gebunden und Retool läuft woanders | Wechseln Sie in den Server-Modus und verwenden Sie die Netzwerkadresse des Lösers |
| Retool Cloud erreicht die Resource überhaupt nicht | Die Firewall lässt die ausgehenden Adressen von Retool nicht durch | Erlauben Sie die veröffentlichten Bereiche für Ihre Region auf Port 8080 |
| readResult liefert jedes Mal CAPCHA_NOT_READY | Der Wait block ist kürzer, als der Lösevorgang dauert | Erhöhen Sie die erste Wartezeit, oder ergänzen Sie ein zweites Warten und Lesen im Else-Pfad |
| Der zweite Lesevorgang derselben id kommt leer zurück | Ein CapSkip-Ergebnis ist nur einmal lesbar | Behalten Sie den Token in der Blockausgabe, lesen Sie die id nie erneut |
| ERROR_WRONG_USER_KEY in der Antwort | Der Parameter key wurde zu einer leeren Zeichenkette aufgelöst | Prüfen Sie den Namen des Secrets, auch die genaue Groß- und Kleinschreibung |
| Ein gültiges Token wird von der Zielwebsite abgelehnt | Es ist zwischen Lösung und Absenden abgelaufen | Senden Sie im nächsten Block ab, ohne ein Wait dazwischen |
| Ein Stapel von Lösevorgängen bleibt mittendrin stecken | Ein Workflow darf 50 externe Anfragen gleichzeitig offen haben | Verarbeiten Sie den Loop block in Stapeln, oder verteilen Sie die Arbeit auf mehrere Läufe |
FAQ
Kann ich CapSkip aus Retool Cloud heraus nutzen?
Ja, mit dem Server-Modus. Retool Cloud ruft Ihre Resources aus der eigenen Infrastruktur auf, der Solver muss also auf einer Adresse lauschen, die von dort erreichbar ist: einer öffentlichen IP, idealerweise einer statischen. Retool veröffentlicht die ausgehenden Bereiche, aus denen es aufruft, die Firewallregel ist also eng statt offen für die ganze Welt. Am Solver selbst ändert sich nichts und nichts wird abgerechnet. Der einzige Unterschied ist die Adresse, auf der er lauscht.
Warum nicht einfach einen JavaScript-Block mit axios verwenden?
Wegen des Orts, an dem dieser Code läuft. Retool führt code blocks in einem separaten, mit NsJail abgeschotteten Dienst aus, und bei einem selbst gehosteten Deployment installiert dieser Dienst Firewallregeln, die private Bereiche abdecken. Sie abzuschalten ist ein dokumentierter Schalter, aber eben eine instanzweite Entscheidung, getroffen nur, um einen einzigen Workflow einfacher zu machen, und Retool rät davon ab. Ein resource query block erreicht denselben Solver ohne diese Diskussion. Nutzen Sie code blocks für die Logik und resource query blocks für das Netzwerk.
Soll der Workflow in einer Schleife laufen, bis der Token da ist?
Nein. Ein Loop block ist bei zwei Minuten am Ende, deutlich unter den dreihundert Sekunden, die einem reCAPTCHA-Lösevorgang zugestanden werden, und er durchläuft alle Iterationen, die Sie ihm gegeben haben, statt früher abzubrechen. Dazu kommt, dass ein Ergebnis nur einmal gelesen werden kann, wiederholte Lesevorgänge derselben id sind also vergebliche Wege. Ein Wait block der richtigen Länge plus ein einzelner Lesevorgang ist korrekt und günstig, und ein Branch mit einem zweiten Warten und Lesen dahinter deckt die langsamen Fälle ab.
Wie ist das im Vergleich zu n8n oder Pipedream?
Die beiden Anfragen sind in allen drei Tools identisch. Unterschiedlich ist nur das Hindernis, das jedes Tool davorstellt.
- Bei n8n ist das Hindernis das Container-Networking, hier durchgearbeitet: die n8n-Workflow-Anleitung.
- Bei Pipedream sind es die Step-Laufzeit und der Ort, an dem die Secrets liegen, behandelt in dem Pipedream-Leitfaden.
- Bei Retool ist es die eigene Firewall des Code Executors, und deshalb legt der Ablauf oben nie einen HTTP-Aufruf in einen code block.
Die Kurzfassung
Richten Sie eine REST-Resource auf den Solver, senden Sie die Challenge per POST, warten Sie fünfzehn Sekunden mit einem Wait, holen Sie das Ergebnis per GET und verzweigen Sie danach, ob es fertig ist. Lassen Sie das HTTP in resource query blocks statt in code blocks, denn die Standard-Firewallregeln des Code Executors decken private Adressen ab, und sie zu lockern ist eine instanzweite Entscheidung. Stellen Sie CapSkip auf Server-Modus um, sobald Retool nicht auf dem Rechner des Solvers selbst läuft, und lassen Sie in Retool Cloud nur die veröffentlichten ausgehenden Bereiche zu Port 8080 durch. Warten Sie nie innerhalb eines synchronen Webhooks auf einen Lösevorgang.
- Die reCAPTCHA-v2-Checkbox selbst wird behandelt auf die reCAPTCHA-v2-Solver-Seite.
- Der Python-Client aus der Variante mit code block ist dokumentiert auf der Python-Captcha-Solver-Seite.
Eines sollten Sie abwägen, bevor Sie einen geplanten Workflow jede Minute darauf ansetzen: CapSkip ist ein lokaler Captcha-Löser und läuft auf Hardware, die Sie bereits besitzen, sodass ein Workflow, der jede Minute startet, und einer, der zweimal täglich startet, genau gleich viel kosten.
