Việc thăm dò các kết quả CAPTCHA liên kết các luồng và tạo ra sự liên kết chặt chẽ giữa bộ sao chép của bạn và quy trình giải quyết. AWS SNS (Dịch vụ thông báo đơn giản) giải quyết những mối lo ngại này — CaptchaAI gửi kết quả tới cuộc gọi lại của bạn, cuộc gọi lại sẽ xuất bản lên SNS và bất kỳ số lượng người tiêu dùng tiếp theo nào sẽ phản ứng độc lập.
Tổng quan về kiến trúc
[Scraper] → Submit CAPTCHA → [CaptchaAI API]
↓
Solve completes
↓
Callback → [API Gateway + Lambda]
↓
Publish → [SNS Topic]
↓
┌───────────────┼───────────────┐
↓ ↓ ↓
[SQS Queue] [Lambda Logger] [Email Alert]
(result store) (audit trail) (on failure)
SNS cung cấp phân xuất: một kết quả CAPTCHA sẽ kích hoạt nhiều người tiêu dùng mà trình xử lý gọi lại không biết về họ.
Bước 1: Tạo chủ đề SNS
AWS CLI
aws sns create-topic --name captcha-results --output text
# Returns: arn:aws:sns:us-east-1:123456789:captcha-results
Python (boto3)
import boto3
sns = boto3.client("sns", region_name="us-east-1")
response = sns.create_topic(Name="captcha-results")
topic_arn = response["TopicArn"]
print(f"Topic ARN: {topic_arn}")
Bước 2: Xây dựng bộ thu gọi lại
Hàm Lambda này nhận kết quả gọi lại CaptchaAI và xuất bản chúng lên SNS.
Python (Trình xử lý Lambda)
import json
import os
import boto3
sns = boto3.client("sns")
TOPIC_ARN = os.environ["SNS_TOPIC_ARN"]
def lambda_handler(event, context):
"""Receive CaptchaAI callback and publish to SNS."""
# Parse query parameters from API Gateway
params = event.get("queryStringParameters", {}) or {}
task_id = params.get("id", "")
solution = params.get("code", "")
if not task_id or not solution:
return {"statusCode": 400, "body": "Missing id or code"}
# Publish to SNS
message = {
"task_id": task_id,
"solution": solution,
"status": "solved"
}
sns.publish(
TopicArn=TOPIC_ARN,
Message=json.dumps(message),
Subject="captcha-solved",
MessageAttributes={
"task_id": {
"DataType": "String",
"StringValue": task_id
}
}
)
return {"statusCode": 200, "body": "OK"}
JavaScript (Trình xử lý Lambda)
const { SNSClient, PublishCommand } = require("@aws-sdk/client-sns");
const sns = new SNSClient({ region: "us-east-1" });
const TOPIC_ARN = process.env.SNS_TOPIC_ARN;
exports.handler = async (event) => {
const params = event.queryStringParameters || {};
const taskId = params.id;
const solution = params.code;
if (!taskId || !solution) {
return { statusCode: 400, body: "Missing id or code" };
}
const message = {
task_id: taskId,
solution: solution,
status: "solved",
};
await sns.send(
new PublishCommand({
TopicArn: TOPIC_ARN,
Message: JSON.stringify(message),
Subject: "captcha-solved",
MessageAttributes: {
task_id: { DataType: "String", StringValue: taskId },
},
})
);
return { statusCode: 200, body: "OK" };
};
Bước 3: Gửi CAPTCHA kèm theo URL gọi lại
Trỏ pingback của CaptchaAI vào điểm cuối Cổng API của bạn:
Python
import os
import requests
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
CALLBACK_URL = os.environ["CALLBACK_GATEWAY_URL"] # API Gateway URL
def submit_captcha(sitekey, pageurl):
"""Submit CAPTCHA with SNS-backed callback."""
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"pingback": CALLBACK_URL,
"json": 1
})
data = resp.json()
if data.get("status") == 1:
return data["request"] # task_id
raise RuntimeError(f"Submit failed: {data.get('request')}")
Bước 4: Đăng ký người tiêu dùng
Hàng đợi SQS (Lưu trữ kết quả)
# Subscribe an SQS queue to receive all results
sqs_arn = "arn:aws:sqs:us-east-1:123456789:captcha-results-queue"
sns.subscribe(
TopicArn=topic_arn,
Protocol="sqs",
Endpoint=sqs_arn
)
Lambda (Trình ghi nhật ký kiểm tra)
# Subscribe a Lambda for audit logging
lambda_arn = "arn:aws:lambda:us-east-1:123456789:function:captcha-audit-logger"
sns.subscribe(
TopicArn=topic_arn,
Protocol="lambda",
Endpoint=lambda_arn
)
Email (Cảnh báo lỗi)
# Subscribe email for error notifications with filter
sns.subscribe(
TopicArn=topic_arn,
Protocol="email",
Endpoint="ops@example.com"
)
Bước 5: Sử dụng kết quả từ SQS
Công cụ quét của bạn đọc các giải pháp từ SQS thay vì thăm dò CaptchaAI:
Python
import json
import boto3
sqs = boto3.client("sqs", region_name="us-east-1")
QUEUE_URL = os.environ["SQS_QUEUE_URL"]
def get_solved_captcha(timeout=30):
"""Wait for a CAPTCHA solution from the SQS queue."""
response = sqs.receive_message(
QueueUrl=QUEUE_URL,
MaxNumberOfMessages=1,
WaitTimeSeconds=min(timeout, 20) # Long polling (max 20s)
)
messages = response.get("Messages", [])
if not messages:
return None
msg = messages[0]
# SNS wraps the message — unwrap it
sns_envelope = json.loads(msg["Body"])
result = json.loads(sns_envelope["Message"])
# Delete message after processing
sqs.delete_message(
QueueUrl=QUEUE_URL,
ReceiptHandle=msg["ReceiptHandle"]
)
return result
JavaScript
const {
SQSClient,
ReceiveMessageCommand,
DeleteMessageCommand,
} = require("@aws-sdk/client-sqs");
const sqs = new SQSClient({ region: "us-east-1" });
const QUEUE_URL = process.env.SQS_QUEUE_URL;
async function getSolvedCaptcha(timeout = 30) {
const response = await sqs.send(
new ReceiveMessageCommand({
QueueUrl: QUEUE_URL,
MaxNumberOfMessages: 1,
WaitTimeSeconds: Math.min(timeout, 20),
})
);
const messages = response.Messages || [];
if (messages.length === 0) return null;
const msg = messages[0];
const snsEnvelope = JSON.parse(msg.Body);
const result = JSON.parse(snsEnvelope.Message);
await sqs.send(
new DeleteMessageCommand({
QueueUrl: QUEUE_URL,
ReceiptHandle: msg.ReceiptHandle,
})
);
return result;
}
Lọc tin nhắn SNS
Định tuyến các kết quả khác nhau đến những người tiêu dùng khác nhau:
# Only send failures to the ops queue
sns.subscribe(
TopicArn=topic_arn,
Protocol="sqs",
Endpoint=failure_queue_arn,
Attributes={
"FilterPolicy": json.dumps({
"status": ["failed", "error"]
})
}
)
Khắc phục sự cố
| Vấn đề | Nguyên nhân | Cách xử lý |
|---|---|---|
| Gọi lại trả về 403 | Chặn xác thực API Gateway CaptchaAI | Vô hiệu hóa xác thực trên tuyến gọi lại; thay vào đó hãy sử dụng xác thực dựa trên mã thông báo |
| Tin nhắn SQS không đến | SNS †' Thiếu quyền SQS | Thêm quyền sns:Publish vào chính sách hàng đợi SQS |
| Kết quả trùng lặp được xử lý | SNS cung cấp ít nhất một lần | Triển khai tính tạm thời – kiểm tra task_id trước khi xử lý |
| Khởi động nguội Lambda trì hoãn cuộc gọi lại | Đồng thời được cung cấp chưa được đặt | Bật tính năng đồng thời được cung cấp cho lệnh gọi lại Lambda |
Câu hỏi thường gặp
Tại sao nên sử dụng SNS thay vì xử lý kết quả trực tiếp trong lệnh gọi lại Lambda?
SNS tách trình xử lý gọi lại khỏi logic xuôi dòng. Bạn có thể thêm người tiêu dùng mới (ghi nhật ký, cảnh báo, phân tích) mà không cần sửa đổi lệnh gọi lại Lambda. Cuộc gọi lại vẫn đơn giản và nhanh chóng.
Độ trễ được thêm vào từ lớp SNS là bao nhiêu?
SNS tăng thêm 10–50 mili giây cho mỗi tin nhắn. Vì việc giải CAPTCHA mất 5–30 giây nên chi phí này không đáng kể.
Tôi có thể sử dụng SNS FIFO để xử lý đơn hàng không?
Vâng. Sử dụng chủ đề SNS FIFO với hàng đợi SQS FIFO nếu bạn cần kết quả được sắp xếp. Đặt MessageGroupId thành ID nhiệm vụ để sắp xếp thứ tự cho mỗi nhiệm vụ.
bài viết liên quan
- Xây dựng đường dẫn Captcha của khách hàng Captchaai
- Xây dựng Captchaai tự động hóa có trách nhiệm
- Xây dựng giám sát bảng điều khiển sử dụng Captchaai
Các bước tiếp theo
Xây dựng giải pháp CAPTCHA theo sự kiện —lấy khóa API CaptchaAI của bạnvà kết nối nó với quy trình sự kiện AWS của bạn.
Hướng dẫn liên quan:
- Tích hợp máy chủ AWS Lambda + CaptchaAI
- URL gọi lại và hướng dẫn Webhook
- Bảo mật Webhook: Xác thực lệnh gọi lại