package auth import ( "context" "encoding/json" "fmt" "net/http" "net/url" "time" ) // Kavenegar کلاینت ارسال OTP از طریق verify/lookup (معادل KavenegarService.php). type Kavenegar struct { APIKey string Template string // مثل "loginotp" client *http.Client } func NewKavenegar(apiKey, template string) *Kavenegar { return &Kavenegar{ APIKey: apiKey, Template: template, client: &http.Client{Timeout: 5 * time.Second}, } } // SendVerify کد را با تمپلیت verify ارسال می‌کند. func (k *Kavenegar) SendVerify(ctx context.Context, mobile, token string) error { if k.APIKey == "" { return fmt.Errorf("KAVE_API_KEY is null") } endpoint := fmt.Sprintf("https://api.kavenegar.com/v1/%s/verify/lookup.json", k.APIKey) q := url.Values{} q.Set("receptor", mobile) q.Set("token", token) q.Set("template", k.Template) req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint+"?"+q.Encode(), nil) if err != nil { return err } resp, err := k.client.Do(req) if err != nil { return err } defer resp.Body.Close() var out struct { Return struct { Status int `json:"status"` Message string `json:"message"` } `json:"return"` } if err := json.NewDecoder(resp.Body).Decode(&out); err != nil { return fmt.Errorf("kavenegar decode: %w", err) } if out.Return.Status != 200 { return fmt.Errorf("kavenegar failed: status=%d msg=%s", out.Return.Status, out.Return.Message) } return nil }