Integrations

Power Automate + CaptchaAI : résolution de CAPTCHA Microsoft Flow

Power Automate ne propose aucune action native pour les CAPTCHA : dès qu'un formulaire protégé apparaît dans un flux, l'exécution s'arrête et attend une intervention humaine. Trois actions du connecteur HTTP suffisent pourtant — envoyer le défi à CaptchaAI, interroger le résultat dans une boucle Do until, puis injecter le token.

Ce guide le construit pour reCAPTCHA v2 : paramètres exacts de chaque action, attente bornée, erreurs fréquentes en production.


Ce qu'il faut préparer

Élément Détail
Connecteur HTTP Action Premium. Sans licence Premium : connecteur personnalisé ou Azure Function
Clé API CaptchaAI Facturation au thread — BASIC ($15/mois, 5 threads) autorise 5 défis simultanés
Sitekey et URL Les deux valeurs de la page protégée par reCAPTCHA v2
Type de défi reCAPTCHA v2 et v3, Cloudflare Turnstile, Cloudflare Challenge et GeeTest v3 sont pris en charge. hCaptcha et FunCaptcha ne le sont pas, GeeTest v4 est annoncé « à venir », CaptchaFox, Friendly Captcha et Lemin restent en bêta
Stockage de la clé Variable d'environnement Power Platform ou Azure Key Vault, jamais en dur dans le flux

Un cas concret : rapprochement de factures fournisseurs

Une équipe finance basée à Lyon récupère chaque lundi les relevés d'un portail fournisseur protégé par reCAPTCHA v2. Jusqu'ici, un comptable ouvrait le portail, cliquait la case, exportait le CSV. Le flux reprend cette séquence sans l'attente.

Deux réflexes dès la conception : hébergez l'environnement Power Platform dans une région européenne si vos données le justifient, et n'écrivez ni identifiants ni données personnelles dans les sorties d'actions — l'historique d'exécution les conserve, ce qui touche vos obligations RGPD.


Étape 1 : créer le flux et ses entrées

Créez un flux cloud instantané avec un déclencheur manuel (un déclencheur planifié convient aussi), puis ajoutez-lui deux entrées texte :

Entrée Type Contenu
sitekey Texte La clé de site reCAPTCHA v2
pageurl Texte L'URL de la page qui affiche le défi

Les passer en entrée rend le flux réutilisable pour tous vos portails.

Étape 2 : envoyer le défi à CaptchaAI

L'action HTTP de soumission

Ajoutez une action HTTP. Les noms de paramètres sont sensibles à la casse.

Champ Valeur
Method GET
URI https://ocr.captchaai.com/in.php
Query key votre clé API CaptchaAI
Query method userrecaptcha
Query googlekey @{triggerBody()['text']} (entrée sitekey)
Query pageurl @{triggerBody()['text_1']} (entrée pageurl)
Query json 1

Lire la réponse

Ajoutez une action Analyser JSON juste après, avec ce schéma :

{
  "type": "object",
  "properties": {
    "status": { "type": "integer" },
    "request": { "type": "string" }
  }
}

Contenu : @{body('HTTP')}

Étape 3 : valider la réponse de soumission

Une action Condition sur @{body('Parse_JSON')?['status']} sépare les deux sorties possibles.

Résultat Ce que fait le flux
status vaut 1 request porte l'identifiant de la tâche : enchaînez sur la boucle
Toute autre valeur Action Terminer, statut « Échec », message Submit error: @{body('Parse_JSON')?['request']}

Étape 4 : construire la boucle d'interrogation

Avant la boucle, initialisez deux variables de type Chaîne : solveStatus à pending et solvedToken vide.

Dans la branche « Si oui », ajoutez une boucle Do until dont la condition est : @{variables('solveStatus')} n'est pas égal à pending. Quatre actions s'y enchaînent :

  1. Délai de 5 secondes — interroger plus vite n'accélère rien.
  2. HTTP vers res.php, qui réclame le résultat.
  3. Analyser JSON, schéma de l'étape 2, nommée Parse_JSON_2.
  4. Condition sur le statut renvoyé.

La requête d'interrogation se configure ainsi :

Champ Valeur
Method GET
URI https://ocr.captchaai.com/res.php
Query key votre clé API CaptchaAI
Query action get
Query id @{body('Parse_JSON')?['request']}
Query json 1

La condition finale, @{body('Parse_JSON_2')?['status']} est égal à 1, tranche trois cas :

Cas Action dans la boucle
Résolu solvedToken = @{body('Parse_JSON_2')?['request']}, puis solveStatus = solved
request vaut CAPCHA_NOT_READY Ne rien faire : la boucle repart
Autre valeur solveStatus = error

Bornez enfin la boucle dans ses paramètres avancés : 20 itérations maximum, délai d'expiration PT3M (3 minutes). Sans ces bornes, un portail muet fait tourner le flux jusqu'au quota.

Étape 5 : injecter le token résolu

Après la boucle, une Condition sur @{variables('solveStatus')} sépare les deux issues. Si la valeur est solved, poussez le token dans la requête finale, ou transmettez-le à un autre connecteur (Teams, Outlook, Dataverse).

Champ Valeur
Method POST
URI URL du formulaire cible
Body {"g-recaptcha-response": "@{variables('solvedToken')}", "other_field": "value"}

Sinon, notifiez l'échec avec l'identifiant de la tâche. Le token est à usage unique et sa durée de vie est courte : soumettez le formulaire dans la même exécution.


Dépannage

Le flux ne démarre pas

Problème Cause Correctif
L'action HTTP est absente du sélecteur Connecteur Premium hors licence Licence Premium, ou connecteur personnalisé
Erreur 403 renvoyée par l'API Clé incorrecte ou restriction d'IP Recopiez la clé, vérifiez la liste blanche d'IP
ERROR_ZERO_BALANCE Solde épuisé Rechargez, puis rejouez l'exécution

Le flux démarre puis dérape

Problème Cause Correctif
L'action Analyser JSON échoue Réponse en texte brut, pas en JSON Vérifiez que json vaut 1
La boucle ne s'arrête jamais solveStatus jamais mis à jour Contrôlez les noms dans « Définir la variable »
Le flux expire dans la boucle Une action isolée expire à 2 minutes Le délai PT3M du Do until couvre ce cas

Dimensionner les threads

Un thread reste occupé de la soumission jusqu'au retour du token : un flux quotidien n'en mobilise qu'un, et BASIC couvre cinq flux simultanés. Si vous parallélisez une liste avec Appliquer à chacun, ne dépassez pas vos threads disponibles — au-delà, les tâches attendent et les boucles épuisent leurs 20 itérations pour rien.

Récapitulatif : le flux complet

[Manual Trigger (sitekey, pageurl)]
    ↓
[Initialize Variables: solveStatus, solvedToken]
    ↓
[HTTP: Submit to CaptchaAI /in.php]
    ↓
[Parse JSON]
    ↓
[Condition: status = 1?]
    ↓ Yes
[Do Until: solveStatus ≠ pending]
    ├── [Delay: 5 seconds]
    ├── [HTTP: Poll CaptchaAI /res.php]
    ├── [Parse JSON]
    └── [Condition: Solved or Error?]
    ↓
[Condition: solveStatus = solved?]
    ↓ Yes
[HTTP: Submit form with token]
    ↓
[Compose: Success response]

Dupliquez ce squelette pour chaque portail : seules les entrées changent.

Questions fréquentes

Faut-il une licence Power Automate Premium pour ce flux ?

Oui, pour le connecteur HTTP. Deux replis possibles : un connecteur personnalisé, ou une Azure Function appelée depuis le flux.

Combien de threads ce flux consomme-t-il ?

Un seul par CAPTCHA en cours, libéré dès le retour du token. La facturation dépend des résolutions simultanées, pas du temps d'attente.

CaptchaAI prend-il en charge hCaptcha depuis Power Automate ?

Non — hCaptcha n'est pas pris en charge, FunCaptcha non plus. Pour un type pris en charge, changez method : turnstile pour Cloudflare Turnstile, post pour les CAPTCHA d'image.

Que se passe-t-il si la boucle atteint ses 20 itérations sans token ?

Le flux sort avec solveStatus resté à pending et part dans la branche d'échec. Relancez l'exécution plutôt que de rallonger l'attente : le défi expire aussi côté portail.

Où lire le code d'erreur quand une exécution échoue ?

Dans l'historique d'exécution, sur la sortie de l'action HTTP concernée : le champ request y porte le code exact, ERROR_ZERO_BALANCE ou ERROR_WRONG_USER_KEY par exemple.

Pour aller plus loin

Montez ce flux dans votre environnement de test, puis récupérez votre clé API CaptchaAI pour le passer en production.

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