thread-master/backend/internal/library/threadsapi/media.go

98 lines
2.4 KiB
Go
Raw Normal View History

2026-06-27 16:03:28 +00:00
package threadsapi
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
)
type MediaStats struct {
LikeCount int `json:"like_count"`
ReplyCount int `json:"reply_count"`
RepostCount int `json:"repost_count"`
QuoteCount int `json:"quote_count"`
}
func GetMediaStats(ctx context.Context, accessToken, mediaID string) (*MediaStats, error) {
u := fmt.Sprintf("%s/%s", graphBaseURL, mediaID)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
if err != nil {
return nil, err
}
q := url.Values{}
q.Set("fields", "like_count,reply_count,repost_count,quote_count")
q.Set("access_token", accessToken)
req.URL.RawQuery = q.Encode()
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("threads api media stats error: %s", resp.Status)
}
var raw struct {
ID string `json:"id"`
LikeCount int `json:"like_count"`
ReplyCount int `json:"reply_count"`
RepostCount int `json:"repost_count"`
QuoteCount int `json:"quote_count"`
}
if err := json.NewDecoder(resp.Body).Decode(&raw); err != nil {
return nil, err
}
return &MediaStats{
LikeCount: raw.LikeCount,
ReplyCount: raw.ReplyCount,
RepostCount: raw.RepostCount,
QuoteCount: raw.QuoteCount,
}, nil
}
type TokenRefreshResult struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
}
func RefreshAccessToken(ctx context.Context, currentToken string) (*TokenRefreshResult, error) {
u := fmt.Sprintf("%s/refresh_access_token", graphBaseURL)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
if err != nil {
return nil, err
}
q := url.Values{}
q.Set("grant_type", "th_refresh_token")
q.Set("access_token", currentToken)
req.URL.RawQuery = q.Encode()
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("threads api token refresh error: %s", resp.Status)
}
var result TokenRefreshResult
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, err
}
if result.AccessToken == "" {
return nil, fmt.Errorf("threads api token refresh returned empty token")
}
return &result, nil
}
func NsFromNow(seconds int) int64 {
return time.Now().UnixNano() + int64(seconds)*1e9
}