Вместо многократного опроса /res.php вы можете указать URL-адрес обратного вызова. CaptchaAI отправляет решенный токен непосредственно на ваш сервер, когда он будет готов. Это устраняет накладные расходы на опрос и уменьшает задержку.
Как работают обратные вызовы
Standard polling approach:
Submit ──▶ Wait ──▶ Poll ──▶ Poll ──▶ Poll ──▶ Result
(many requests, wasted time between polls)
Callback approach:
Submit (with callback URL) ──▶ ... CaptchaAI solves ...
│
Your server receives POST ◀───────────────┘
(one request, instant delivery)
Отправить с URL обратного вызова
Добавьте параметр pingback в свой запрос на отправку:
import requests
API_KEY = "YOUR_API_KEY"
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"pingback": "https://your-server.com/captcha-callback",
"json": 1,
})
result = resp.json()
task_id = result["request"]
print(f"Task submitted: {task_id}")
# No polling needed — result comes via webhook
Поддерживается для всех типов CAPTCHA
# reCAPTCHA v2
data = {
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"pingback": "https://your-server.com/callback",
"json": 1,
}
# Turnstile
data = {
"key": API_KEY,
"method": "turnstile",
"sitekey": "SITE_KEY",
"pageurl": "https://example.com",
"pingback": "https://your-server.com/callback",
"json": 1,
}
# Image CAPTCHA
data = {
"key": API_KEY,
"method": "base64",
"body": base64_image,
"pingback": "https://your-server.com/callback",
"json": 1,
}
Создайте приемник обратного вызова (Flask)
from flask import Flask, request
import threading
import logging
app = Flask(__name__)
logger = logging.getLogger(__name__)
# Store results by task ID
results = {}
events = {}
@app.route("/captcha-callback", methods=["POST", "GET"])
def captcha_callback():
"""Receive solved CAPTCHA tokens from CaptchaAI."""
# CaptchaAI sends parameters as query string or form data
task_id = request.args.get("id") or request.form.get("id")
code = request.args.get("code") or request.form.get("code")
if not task_id or not code:
logger.warning("Callback missing id or code")
return "ERROR", 400
logger.info("Received result for task %s", task_id)
results[task_id] = code
# Notify waiting threads
event = events.get(task_id)
if event:
event.set()
return "OK"
def wait_for_result(task_id, timeout=120):
"""Wait for a callback result."""
event = threading.Event()
events[task_id] = event
if task_id in results:
return results.pop(task_id)
event.wait(timeout=timeout)
if task_id in results:
return results.pop(task_id)
raise TimeoutError(f"No callback received for task {task_id}")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Полный рабочий процесс
import requests
import threading
import time
API_KEY = "YOUR_API_KEY"
CALLBACK_URL = "https://your-server.com/captcha-callback"
def solve_with_callback(sitekey, pageurl):
"""Submit CAPTCHA and wait for callback."""
# Submit with callback URL
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"pingback": CALLBACK_URL,
"json": 1,
})
result = resp.json()
if result.get("status") != 1:
raise RuntimeError(f"Submit failed: {result.get('request')}")
task_id = result["request"]
print(f"Task {task_id} submitted, waiting for callback...")
# Wait for callback on the receiver
token = wait_for_result(task_id, timeout=120)
print(f"Token received via callback: {token[:50]}...")
return token
Сравнение обратного вызова и опроса
| Фактор | Опрос | Перезвонить |
|---|---|---|
| API-запросы | Многие (отправить + N опросов) | 2 (отправить + обратный звонок) |
| Задержка | Задержка интервала опроса | Мгновенная доставка |
| Нагрузка на сервер | Клиентские опросы проводятся постоянно | CaptchaAI отправляет результат |
| Сложность | Простой (только для клиента) | Требуется общедоступная конечная точка |
| Требования к брандмауэру | Только исходящие | Должен принимать входящий POST |
| подходящий для | Простые скрипты | Производственные трубопроводы |
Когда использовать обратные вызовы
| Сценарий | Рекомендуемый подход |
|---|---|
| Быстрый сценарий, мало решений | Опрос |
| Производственный трубопровод, большой объем | Перезвонить |
| Бессерверная технология (лямбда, облачные функции) | Опрос (без постоянного сервера) |
| За брандмауэром, без публичного IP-адреса | Опрос |
| Микросервисная архитектура | Перезвонить |
Защита конечной точки обратного вызова
Убедитесь, что обратные вызовы действительно исходят от CaptchaAI:
from flask import Flask, request, abort
app = Flask(__name__)
# Store submitted task IDs to validate callbacks
pending_tasks = set()
def submit_captcha(sitekey, pageurl):
"""Submit and track task ID."""
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"pingback": CALLBACK_URL,
"json": 1,
})
task_id = resp.json()["request"]
pending_tasks.add(task_id)
return task_id
@app.route("/captcha-callback", methods=["POST", "GET"])
def secure_callback():
"""Validate callback before processing."""
task_id = request.args.get("id") or request.form.get("id")
# Reject unknown task IDs
if task_id not in pending_tasks:
abort(403)
code = request.args.get("code") or request.form.get("code")
pending_tasks.discard(task_id)
results[task_id] = code
return "OK"
Поиск неисправностей
| Проблема | Причина | Исправить |
|---|---|---|
| Обратный звонок не получен | Сервер не является общедоступным | Используйте ngrok для тестирования или разверните в облаке. |
| URL обратного вызова отклонен | URL недоступен с CaptchaAI | Убедитесь, что URL-адрес общедоступен |
| Частичные результаты | Некоторые обратные вызовы не работают | Записывать все обратные вызовы, добавить резервную копию retry/polling |
| Дублирующиеся обратные вызовы | Повторная попытка сети | Использовать дедупликацию идентификатора задачи |
Часто задаваемые вопросы
Нужен ли URL-адрес обратного вызова HTTPS?
HTTPS рекомендуется для производства. HTTP работает для тестирования, но предоставляет токены при передаче.
Что делать, если мой сервер обратного вызова не работает?
CaptchaAI может повторить обратный вызов, но для надежности вам следует реализовать резервный вариант опроса. Проверьте результаты через /res.php, если обратный вызов не получен в течение ожидаемого времени.
Могу ли я использовать разные URL-адреса обратного вызова для каждого запроса?
Да. Каждый параметр pingback предназначен для каждого запроса. Различные типы или проекты CAPTCHA могут использовать разные конечные точки обратного вызова.
Связанные руководства
- Pingback и шаблоны уведомлений
- Проверка баланса и автоматическое пополнение
Устранение накладных расходов на опросы —попробуйте обратные вызовы CaptchaAIдля мгновенной доставки токенов.