package instagram import ( "encoding/json" "fmt" "net/http" "time" "git.linuxforward.com/byom/byom-trends/config" "git.linuxforward.com/byom/byom-trends/logger" "github.com/sirupsen/logrus" ) type Client struct { httpClient *http.Client apiKey string baseURL string logger *logrus.Entry } type ProfileStats struct { Username string `json:"username"` FollowerCount int64 `json:"follower_count"` Following int64 `json:"following"` PostCount int64 `json:"post_count"` Engagement float64 `json:"engagement"` } type Post struct { ID string `json:"id"` Type string `json:"type"` Caption string `json:"caption"` MediaURL string `json:"media_url"` Timestamp time.Time `json:"timestamp"` LikeCount int64 `json:"like_count"` CommentCount int64 `json:"comment_count"` } func NewClient(cfg *config.InstagramConfig) *Client { return &Client{ httpClient: &http.Client{ Timeout: time.Second * 10, }, apiKey: cfg.APIKey, baseURL: cfg.BaseURL, logger: logger.NewLogger("instagram-client"), } } func (c *Client) GetProfileStats(username string) (*ProfileStats, error) { if username == "" { return nil, fmt.Errorf("username cannot be empty") } url := fmt.Sprintf("%s/users/%s", c.baseURL, username) req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, fmt.Errorf("create request: %w", err) } req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.apiKey)) resp, err := c.httpClient.Do(req) if err != nil { return nil, fmt.Errorf("do request: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode) } var stats ProfileStats if err := json.NewDecoder(resp.Body).Decode(&stats); err != nil { return nil, fmt.Errorf("decode response: %w", err) } return &stats, nil } func (c *Client) GetRecentPosts(username string, limit int) ([]Post, error) { url := fmt.Sprintf("%s/users/%s/media/recent?limit=%d", c.baseURL, username, limit) req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, fmt.Errorf("create request: %w", err) } req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.apiKey)) resp, err := c.httpClient.Do(req) if err != nil { return nil, fmt.Errorf("do request: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode) } var posts []Post if err := json.NewDecoder(resp.Body).Decode(&posts); err != nil { return nil, fmt.Errorf("decode response: %w", err) } return posts, nil } func (c *Client) CalculateEngagement(posts []Post) float64 { if len(posts) == 0 { return 0 } var totalEngagement int64 for _, post := range posts { totalEngagement += post.LikeCount + post.CommentCount } return float64(totalEngagement) / float64(len(posts)) }