package facepp import ( "encoding/json" "errors" "fmt" "io" "net/http" "net/url" "strings" "time" ) const ( DefaultEndpoint = "https://api-cn.faceplusplus.com/facepp/v1/skinanalyze_pro" defaultTimeout = 60 * time.Second MapRedArea = "red_area" MapBrownArea = "brown_area" MapTextureEnhancedPores = "texture_enhanced_pores" MapTextureEnhancedLines = "texture_enhanced_lines" DefaultReturnMaps = "red_area,brown_area,texture_enhanced_pores,texture_enhanced_lines" DefaultReturnMarks = "wrinkle_mark,right_nasolabial_list,right_mouth_list,right_eye_wrinkle_list,right_crowsfeet_list,right_cheek_list,left_nasolabial_list,left_mouth_list,left_eye_wrinkle_list,left_crowsfeet_list,left_cheek_list,glabella_wrinkle_list,forehead_wrinkle_list,dark_circle_outline,sensitivity_mark,melanin_mark,cheekbone_mark,blackheads_mark,pores_mark" ) type Client struct { apiKey string apiSecret string endpoint string httpClient *http.Client } func NewClient(apiKey, apiSecret string) *Client { return &Client{ apiKey: apiKey, apiSecret: apiSecret, endpoint: DefaultEndpoint, httpClient: &http.Client{ Timeout: defaultTimeout, }, } } func (c *Client) WithEndpoint(endpoint string) *Client { if endpoint != "" { c.endpoint = endpoint } return c } func (c *Client) WithHTTPClient(httpClient *http.Client) *Client { if httpClient != nil { c.httpClient = httpClient } return c } func (c *Client) postForm(values url.Values) ([]byte, error) { if c.apiKey == "" || c.apiSecret == "" { return nil, errors.New("facepp: api_key or api_secret is empty") } values.Set("api_key", c.apiKey) values.Set("api_secret", c.apiSecret) req, err := http.NewRequest(http.MethodPost, c.endpoint, strings.NewReader(values.Encode())) if err != nil { return nil, err } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") resp, err := c.httpClient.Do(req) if err != nil { return nil, err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return nil, err } if err := checkAPIError(body); err != nil { return body, err } if resp.StatusCode != http.StatusOK { return body, fmt.Errorf("facepp: http %d: %s", resp.StatusCode, strings.TrimSpace(string(body))) } return body, nil } func checkAPIError(body []byte) error { var apiErr APIError if err := json.Unmarshal(body, &apiErr); err != nil { return nil } if apiErr.ErrorMessage == "" { return nil } return &apiErr }