שימוש ב-SDK של Go בשרת net/http

מאת solvethree4 דקות קריאה

צרו לקוח solvethree משותף אחד, החזירו את מזהה המשימה מבקשת POST מאומתת ואחזרו את המצב שלה באמצעות GET נפרד. אל תקראו ל-Solve בתוך מטפל היצירה: האינטגרציה הזו מאפשרת לקורא להמתין לתוצאה בלי להשאיר את הבקשה המקורית פתוחה.

בדף הזה

הגדירו את השרת והיעד

  1. 1.

    התקינו את ה-SDK של Go

    השתמשו ב-Go 1.22 ומעלה. במודול Go שכבר אותחל, התקינו את ה-SDK הרשמי באמצעות go get solvethree.com/[email protected]. שמרו את הדוגמה שלהלן בשם main.go.

  2. 2.

    הגדרת סביבת השרת

    הגדירו את SOLVETHREE_API_KEY למפתח ה-API של סביבת העבודה שלכם, ואת INTEGRATION_KEY לסוד נפרד עבור הקוראים לשרת הפנימי הזה. הגדירו את CAPTCHA_SITE לשם המארח של היעד ואת SOLVETHREE_PROXY לכתובת ה-URL של פרוקסי HTTP או HTTPS המשמש לפתרון. שמרו את שני המפתחות בשרתים מהימנים.

  3. 3.

    הכינו את היעד שהוגדר

    ודאו שלאתר יש פרופיל פעיל שזמין לסביבת העבודה שלכם; ראו הגדרת פרופיל אתר. בדוגמה הפעולה קבועה ל-login. שנו אותה לפעולה שהיעד מצפה לה לפני הרצת השרת. אספקת שם מארח ופעולה אינה יוצרת פרופיל.

Go net/http · יצירה ואחזור של משימות
package main

import (
    "context"
    "encoding/json"
    "errors"
    "log"
    "net/http"
    "os"
    "time"
    solvethree "solvethree.com/sdk"
)

func main() {
    client, err := solvethree.NewClient(os.Getenv("SOLVETHREE_API_KEY"), nil)
    if err != nil { log.Fatal(err) }
    secret := os.Getenv("INTEGRATION_KEY")
    if secret == "" { log.Fatal("Set INTEGRATION_KEY") }
    authorize := func(w http.ResponseWriter, r *http.Request) bool {
        if r.Header.Get("X-Integration-Key") != secret { http.Error(w, "Unauthorized", 401); return false }
        return true
    }
    respond := func(w http.ResponseWriter, result *solvethree.TaskResult, err error) {
        w.Header().Set("Content-Type", "application/json")
        if err != nil {
            var recovery *solvethree.Error
            w.WriteHeader(http.StatusBadGateway)
            ids := map[string]string{"error": "Solver request failed"}
            if errors.As(err, &recovery) { ids["requestId"] = recovery.RequestID; ids["taskId"] = recovery.TaskID }
            _ = json.NewEncoder(w).Encode(ids)
            return
        }
        _ = json.NewEncoder(w).Encode(result)
    }
    mux := http.NewServeMux()
    mux.HandleFunc("POST /captcha/tasks", func(w http.ResponseWriter, r *http.Request) {
        if !authorize(w,r) { return }
        input := solvethree.TaskRequest{Site: os.Getenv("CAPTCHA_SITE"), Action:"login",
            Proxy:os.Getenv("SOLVETHREE_PROXY"), RequestID:r.Header.Get("X-Request-ID")}
        if err := input.Validate(); err != nil { http.Error(w,"Invalid task input",400);return }
        ctx,cancel := context.WithTimeout(r.Context(),20*time.Second);defer cancel()
        zero:=0
        result,err:=client.CreateTask(ctx,input,&zero)
        respond(w,result,err)
    })
    mux.HandleFunc("GET /captcha/tasks/{id}", func(w http.ResponseWriter, r *http.Request) {
        if !authorize(w,r) { return }
        ctx,cancel:=context.WithTimeout(r.Context(),25*time.Second);defer cancel()
        result,err:=client.GetTask(ctx,r.PathValue("id"),15000)
        respond(w,result,err)
    })
    server:=&http.Server{Addr:"127.0.0.1:3000", Handler:mux, ReadHeaderTimeout:5*time.Second}
    log.Fatal(server.ListenAndServe())
}

הריצו את המודול באמצעות go run .. השרת מאזין ב-127.0.0.1:3000. הוא משתמש בנתב net/http הסטנדרטי של Go, כך שאין צורך בפריימוורק. לקוח ה-SDK נוצר פעם אחת ובטוח לשימוש מקבילי.

המשימה משתמשת במצב reCAPTCHA ברירת המחדל enterprise-v3. היא מספקת שם מארח של אתר, פעולה ופרוקסי יחיד — לא type או url. גוף ה-POST אינו בשימוש, ולכן הקוראים אינם יכולים לבחור יעדים או שרתי פרוקסי שרירותיים.

שלחו POST פעם אחת ושמרו את מזהה המשימה

שלחו POST /captcha/tasks עם הכותרת X-Integration-Key. שלחו גם X-Request-ID שנוצר על ידי הקורא, כדי שתוכלו לשחזר את המשימה אם החיבור יסתיים לפני שתקבלו את המזהה שלה. השתמשו ב-1–64 אותיות ASCII, ספרות, קווים תחתונים או מקפים.

המטפל מאמת את המשימה שהוגדרה, ואז קורא ל-CreateTask עם ערך המתנה אפס. הוא מבקש ליצור משימה בלי להמתין לסיום הפתרון. ההקשר שלו, שנמשך 20 שניות, מגביל את זמן ההמתנה של בקשת ה-HTTP הזו; הוא אינו מגבלת זמן לפתרון.

בהצלחה, המטפל מחזיר את תוצאת המשימה מה-SDK. שמרו את מזהה המשימה שלה והשתמשו בנתיב GET לבדיקות הבאות. אל תפרשו POST מוצלח כטוקן שמיש.

שני הנתיבים דורשים את מפתח האינטגרציה. זהו ממשק פנימי מהימן, ולא הרשאה לפי משתמש: קוראים שמחזיקים במפתח הזה חולקים גישה דרך סביבת העבודה שהוגדרה.

אחזרו את המשימה הקיימת באמצעות GET עד שתסתיים

שלחו GET /captcha/tasks/{id} עם אותה כותרת של מפתח האינטגרציה. המטפל קורא רק ל-GetTask; הוא לעולם אינו יוצר משימה חלופית. הוא מבקש להמתין עד 15 שניות בתוך הקשר בקשה של 25 שניות.

  • pending או solving: שמרו את אותו מזהה משימה ואחזרו אותה שוב.
  • ready: קראו את הפתרון. זהו המצב היחיד שיש בו תוצאה שמישה.
  • failed: הפסיקו לתשאל ובדקו את errorCode ואת error. תקנו את הגורם לפני שתחליטו אם ליצור משימה נוספת.

בדקו את קוד המצב של תגובת ה-HTTP לפני פענוח תוצאת משימה מוצלחת. בשרת הזה, בקשות ללא הרשאה מחזירות 401, קלטי משימה לא תקינים מחזירים 400 ושגיאות בקשה של ה-SDK מחזירות 502. משימה שהוחזרה במצב failed היא תוצאה שונה מכישלון של בקשת HTTP.

שחזרו לאחר חריגה מזמן ההמתנה בלי ליצור פתרון נוסף

חריגה מזמן ההמתנה אינה מוכיחה שיצירת המשימה נכשלה. ביטול הקשר הבקשה מפסיק את ההמתנה המקומית, לא את המשימה המרוחקת. ה-SDK לעולם אינו מנסה שוב אוטומטית את בקשת ה-POST ליצירה.

  1. 1.

    אם יש לכם מזהה משימה, אחזרו אותה

    השתמשו בנתיב GET עם המזהה הזה. בשגיאות SDK, תגובת השגיאה ב-JSON שבדוגמה כוללת את taskId ואת requestId כאשר ה-SDK חושף אותם.

  2. 2.

    אם יש לכם רק מזהה בקשה, שלחו שוב את בקשת היצירה המקורית

    שלחו שוב את ה-POST עם אותו X-Request-ID ובלי לשנות את קלטי המשימה. כלומר, השאירו ללא שינוי את שם המארח, הפעולה והפרוקסי שהוגדרו. אותו מזהה בקשה ואותה בקשת משימה משחזרים את המשימה הקיימת; קלטים שונים עם אותו מזהה יוצרים התנגשות.

  3. 3.

    שמרו את המזהה לפני הבקשה הראשונה

    ה-SDK יוצר מזהה בקשה כאשר לא מסופק מזהה, אך קורא שהתנתק עלול לא לקבל אותו כלל. בחירה ושמירה של X-Request-ID לפני ה-POST מונעות תלות בתגובת השגיאה לצורך שחזור.

השתמשו בתוצאה המוכנה עם אותו פרוקסי

השרת הזה מחזיר את התוצאה; ה-SDK אינו שולח אותה ליעד. קוד השליחה שלכם חייב להשתמש בטוקן, בזהות הדפדפן שהוחזרה בשדות userAgent ו-secChUa, ובפרוקסי שהצליח. בדוגמה הזו, שמשתמשת בפרוקסי יחיד, המשיכו להשתמש בפרוקסי שהוגדר במקום להחליף כתובות IP לאחר הפתרון.

משימה במצב ready פירושה שנוצר פתרון, ולא שהיעד קיבל את בקשת היישום שלכם. אם השליחה נכשלת, בדקו את הטוקן היוצא, הזהות, הפרוקסי והבקשה ליעד לפני שתשלמו על פתרון נוסף.

הפעלת המשימה הראשונה שלך.

התחילו עם $5 בקרדיט לסביבת העבודה.

יצירת סביבת עבודה
שימוש ב-SDK של Go בשרת net/http · solvethree