קריאה ל-solvethree מצד שרת של ASP.NET Core
רשמו HttpClient מטיפוס מוגדר, צרו את המשימה פעם אחת ואז שלפו את הסטטוס שלה עם מועד סיום מוגדר. שמרו את מפתח ה-API בשרת והגנו על כל נתיבי האפליקציה שקוראים ללקוח.
הדוגמה שלהלן היא מחלקת עזר ל-REST עבור reCAPTCHA Enterprise, ולא SDK רשמי ל-C#. היא מפרידה בין יצירת המשימה לשליפתה, כדי שהאפליקציה שלכם לא תצטרך להשאיר בקשה נכנסת אחת פתוחה עד לסיום הפתרון.
בדף הזה
רישום הלקוח מטיפוס מוגדר
תחילה, הפעילו במסוף את פרופיל אתר היעד עבור סביבת העבודה שלכם. שליחת שם מארח ופעולה לא תיצור פרופיל. ראו הגדרת פרופיל אתר אם האתר עדיין לא מוגדר.
הגדירו את מפתח סביבת העבודה בתצורת השרת בתור SOLVETHREE_API_KEY. הוסיפו את מחלקת הלקוח, ואז הסירו את סימון ההערה מקוד הרישום שמוצג תחת Program.cs והציבו אותו לפני builder.Build().
// CaptchaClient.cs; .NET 8+, System.Net.Http.Json and System.Text.Json.Nodes.
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json.Nodes;
public sealed class CaptchaClient(HttpClient http)
{
public async Task<JsonObject> CreateAsync(string site, string proxy, string requestId,
CancellationToken cancellationToken)
{
using var response = await http.PostAsJsonAsync("tasks?waitMs=0",
new { site, action = "login", proxy, requestId }, cancellationToken);
response.EnsureSuccessStatusCode();
return (await response.Content.ReadFromJsonAsync<JsonObject>(cancellationToken))!;
}
public async Task<JsonObject> GetAsync(string id, CancellationToken cancellationToken)
{
using var response = await http.GetAsync("tasks/" + Uri.EscapeDataString(id) + "?waitMs=15000",
cancellationToken);
response.EnsureSuccessStatusCode();
return (await response.Content.ReadFromJsonAsync<JsonObject>(cancellationToken))!;
}
}
// Program.cs, before builder.Build(), in an existing authenticated ASP.NET app:
// builder.Services.AddHttpClient<CaptchaClient>(http => {
// http.BaseAddress = new Uri("https://api.solvethree.com/v1/");
// http.Timeout = TimeSpan.FromSeconds(25);
// http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
// "Bearer", builder.Configuration["SOLVETHREE_API_KEY"]
// ?? throw new InvalidOperationException("Missing API key"));
// }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler {
// AllowAutoRedirect = false
// });
// Inject CaptchaClient into your authenticated controller/service. Pass its
// cancellation token, create once, save id and poll GetAsync with a finite deadline.הרישום מגדיר את כתובת הבסיס של ה-API, אימות Bearer וזמן קצוב של 25 שניות לתעבורה, ומשבית הפניות אוטומטיות. השאירו את הלוכסן שבסוף כתובת הבסיס: נתיבי tasks היחסיים של הלקוח חייבים להתפרש תחת /v1/.
מחלקת העזר משתמשת בהרחבות JSON של HttpClient ומחזירה JsonObject. שתי המתודות בודקות הצלחת HTTP לפני ביצוע דה-סריאליזציה. הזריקו את CaptchaClient לבקר או לשירות שמוגנים באימות; מחלקת העזר עצמה אינה מאמתת את הפונים לאפליקציה שלכם ואינה בודקת את הרשאותיהם.
יצירה פעם אחת ושמירת פרטי השחזור
- 1.
בחירת האתר, הפעולה והפרוקסי
העבירו את שם מארח היעד בתור site, ולא כתובת URL מלאה. הדוגמה הזו מקבעת את action לערך login; שנו אותו לפעולה שהיעד שלכם מצפה לה. היא שולחת פרוקסי אחד ומסתמכת על מצב reCAPTCHA המוגדר כברירת מחדל, enterprise-v3. אל תוסיפו שדות type או url.
- 2.
שמירת requestId לפני הקריאה ל-CreateAsync
השתמשו ב-1–64 אותיות ASCII, ספרות, קווים תחתונים או מקפים. שמרו אותו יחד עם נתוני הקלט המדויקים של המשימה, כדי שתוכלו לשחזר את אותה משימה לוגית אם התגובה תאבד.
- 3.
קריאה ל-CreateAsync ושמירת מזהה המשימה שהוחזר
CreateAsync מבצעת בקשת POST אחת עם waitMs=0. העבירו את ה-CancellationToken של הקורא. לאחר שקיבלתם את מזהה המשימה, השתמשו ב-GetAsync כדי לשלוף את המשימה הזו במקום ליצור משימה נוספת.
הכפיפו את ההרשאה להשתמש בקרדיטים של סביבת העבודה לבדיקות ההרשאה של האפליקציה שלכם. אם הערכים האלה מגיעים מבקשה נכנסת, ודאו שהאתר, הפעולה והפרוקסי המבוקשים נכללים במה שהפונה רשאי להשתמש בו.
תשאול עם מועד סיום כולל
GetAsync מבצעת escaping למזהה המשימה הידוע ומבקשת waitMs=15000. הזמן הקצוב של HttpClient, שעומד על 25 שניות, מגביל כל בקשת HTTP; הוא אינו מגביל את הזמן הכולל שהאפליקציה מקדישה לתשאול. הגדירו מועד סיום כולל נפרד והעבירו את אות הביטול בכל קריאה.
pendingאוsolving: המשיכו רק כל עוד מועד סיום התשאול וביטול מצד הקורא מאפשרים זאת.ready: הפסיקו את התשאול וקראו את הפתרון. זהו הסטטוס היחיד שמכיל פתרון שמיש.failed: הפסיקו לתשאל ובדקו אתerrorCodeואתerror.
באפליקציה שמשרתת דפדפן, השאירו את היצירה ואת בדיקות הסטטוס המאוחרות כפעולות נפרדות ומוגנות, במקום להריץ לולאה בתוך בקשה נכנסת אחת עד לסיום המשימה. שמרו את מזהה המשימה כשמועד הסיום המקומי מגיע, כדי שבקשה מורשית מאוחרת יותר תוכל לשלוף אותה.
בעת שליחת הטוקן ליעד המיועד שלו, השתמשו בזהות userAgent ו-secChUa שהוחזרה בפתרון ובאותו פרוקסי ששימש לפתרון. משימה מוכנה פירושה שנוצר פתרון — לא שבקשת האפליקציה שלכם הצליחה.
שחזור לאחר חריגה מהזמן הקצוב ללא יצירת עבודה כפולה
- CreateAsync חורגת מהזמן הקצוב או מבוטלת לפני שמתקבל מזהה.
ייתכן שהשרת כבר יצר את המשימה. ביטול מקומי אינו מבטל עבודה מרוחקת.
כדאי לנסות: לצורך שחזור, שלחו שוב את אותם נתוני קלט של המשימה עם ה-requestId ששמרתם. אותו מזהה ואותם נתוני קלט מחזירים את המשימה הקיימת; שינוי נתוני הקלט תוך שימוש חוזר באותו מזהה גורם להתנגשות.
- GetAsync חורגת מהזמן הקצוב או שמועד סיום התשאול מגיע.
כבר יש לכם מזהה משימה, ולכן תגובה חסרה אינה מחייבת משימה חלופית.
כדאי לנסות: שמרו את המזהה ושלפו את המשימה הזו בהמשך במסגרת פעולה חדשה שמוגבלת בזמן.
- קריאת HTTP מחזירה תגובה שאינה מציינת הצלחה.
EnsureSuccessStatusCode זורקת חריגה לפני שמחלקת העזר קוראת תוכן של תגובת הצלחה. מצב זה שונה מקבלת משימה שהסטטוס שלה הוא failed.
כדאי לנסות: טפלו בשגיאת HTTP בנפרד. תקנו נתוני קלט לא תקינים במקום לנסות לשלוח אותם שוב ללא שינוי.
- המשימה מגיעה לסטטוס failed.
קראו את errorCode ואת error כדי לברר את סיבת כישלון המשימה, למשל site-unreachable.
כדאי לנסות: הפסיקו לתשאל את המשימה וטפלו בגורם שדווח לפני שתתחילו ניסיון פתרון נוסף.
היעזרו במדריך שגיאות ה-API כשצריך להבחין בין בקשת API שנדחתה לבין כישלון סופי של ניסיון פתרון.
מקורות ותיעוד API
הפעלת המשימה הראשונה שלך.
התחילו עם $5 בקרדיט לסביבת העבודה.