package giphy import ( "encoding/json" "fmt" "net/http" "net/url" "time" ) const apiBase = "https://api.giphy.com/v1/gifs" type Client struct { apiKey string client *http.Client } func NewClient(apiKey string) *Client { if apiKey == "" { return nil } return &Client{ apiKey: apiKey, client: &http.Client{Timeout: 10 * time.Second}, } } type Image struct { URL string `json:"url"` Width string `json:"width"` Height string `json:"height"` } type Images struct { Original Image `json:"original"` FixedHeight Image `json:"fixed_height"` FixedWidth Image `json:"fixed_width"` } type Gif struct { ID string `json:"id"` Title string `json:"title"` URL string `json:"url"` Slug string `json:"slug"` Images Images `json:"images"` Username string `json:"username"` } type SearchResponse struct { Data []Gif `json:"data"` } func (c *Client) Search(query string, limit int) ([]Gif, error) { if c == nil { return nil, fmt.Errorf("giphy client not configured") } if limit <= 0 || limit > 50 { limit = 25 } u, err := url.Parse(apiBase + "/search") if err != nil { return nil, err } q := u.Query() q.Set("api_key", c.apiKey) q.Set("q", query) q.Set("limit", fmt.Sprintf("%d", limit)) q.Set("rating", "pg-13") q.Set("lang", "en") u.RawQuery = q.Encode() req, err := http.NewRequest("GET", u.String(), nil) if err != nil { return nil, err } resp, err := c.client.Do(req) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("giphy API returned %d", resp.StatusCode) } var sr SearchResponse if err := json.NewDecoder(resp.Body).Decode(&sr); err != nil { return nil, err } return sr.Data, nil } func (c *Client) GetTrending(limit int) ([]Gif, error) { if c == nil { return nil, fmt.Errorf("giphy client not configured") } if limit <= 0 || limit > 50 { limit = 25 } u, err := url.Parse(apiBase + "/trending") if err != nil { return nil, err } q := u.Query() q.Set("api_key", c.apiKey) q.Set("limit", fmt.Sprintf("%d", limit)) q.Set("rating", "pg-13") u.RawQuery = q.Encode() resp, err := c.client.Get(u.String()) if err != nil { return nil, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("giphy API returned %d", resp.StatusCode) } var sr SearchResponse if err := json.NewDecoder(resp.Body).Decode(&sr); err != nil { return nil, err } return sr.Data, nil }