70 lines
1.6 KiB
Go
70 lines
1.6 KiB
Go
|
|
package threadsapi
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"encoding/json"
|
||
|
|
"fmt"
|
||
|
|
"io"
|
||
|
|
"net/http"
|
||
|
|
"net/url"
|
||
|
|
"strings"
|
||
|
|
)
|
||
|
|
|
||
|
|
type ReplyItem struct {
|
||
|
|
ID string `json:"id"`
|
||
|
|
Text string `json:"text"`
|
||
|
|
Username string `json:"username"`
|
||
|
|
Permalink string `json:"permalink"`
|
||
|
|
Timestamp string `json:"timestamp"`
|
||
|
|
LikeCount int `json:"like_count"`
|
||
|
|
ParentID string `json:"parent_id"`
|
||
|
|
}
|
||
|
|
|
||
|
|
func (c *Client) MediaReplies(ctx context.Context, mediaID string, limit int) ([]ReplyItem, error) {
|
||
|
|
if !c.Enabled() {
|
||
|
|
return nil, fmt.Errorf("threads api access token is required")
|
||
|
|
}
|
||
|
|
mediaID = strings.TrimSpace(mediaID)
|
||
|
|
if mediaID == "" {
|
||
|
|
return nil, fmt.Errorf("threads media id is required")
|
||
|
|
}
|
||
|
|
if limit <= 0 {
|
||
|
|
limit = 10
|
||
|
|
}
|
||
|
|
if limit > 50 {
|
||
|
|
limit = 50
|
||
|
|
}
|
||
|
|
|
||
|
|
params := url.Values{}
|
||
|
|
params.Set("access_token", c.accessToken)
|
||
|
|
params.Set("fields", "id,text,username,permalink,timestamp,like_count,parent_id")
|
||
|
|
params.Set("limit", fmt.Sprintf("%d", limit))
|
||
|
|
|
||
|
|
endpoint := graphBaseURL + "/" + url.PathEscape(mediaID) + "/replies?" + params.Encode()
|
||
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
res, err := c.http.Do(req)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
defer res.Body.Close()
|
||
|
|
|
||
|
|
body, err := io.ReadAll(io.LimitReader(res.Body, 1<<20))
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
if res.StatusCode != http.StatusOK {
|
||
|
|
return nil, parseAPIError(body, res.StatusCode)
|
||
|
|
}
|
||
|
|
|
||
|
|
var payload struct {
|
||
|
|
Data []ReplyItem `json:"data"`
|
||
|
|
}
|
||
|
|
if err := json.Unmarshal(body, &payload); err != nil {
|
||
|
|
return nil, fmt.Errorf("parse threads replies: %w", err)
|
||
|
|
}
|
||
|
|
return payload.Data, nil
|
||
|
|
}
|