Documentation
¶
Overview ¶
Package api is the real Threads API client (direct HTTP to graph.threads.net). It maps Graph errors onto the tool's stable exit codes, honors Retry-After / rate-limit signals, and retries transient failures with backoff. Tokens are sent as the access_token query param (per Threads docs). See spec.md §Verified API facts.
Index ¶
- type AccountInsightsOpts
- type Client
- func (c *Client) AccountInsights(ctx context.Context, o AccountInsightsOpts) (map[string]any, error)
- func (c *Client) Conversation(ctx context.Context, mediaID string, o PageOpts) ([]Reply, string, error)
- func (c *Client) DeletePost(ctx context.Context, id string) (*DeleteResult, error)
- func (c *Client) GetPost(ctx context.Context, id string) (*Post, error)
- func (c *Client) ListPosts(ctx context.Context, o PageOpts) ([]Post, string, error)
- func (c *Client) ListReplies(ctx context.Context, mediaID string, o PageOpts) ([]Reply, string, error)
- func (c *Client) ManageReply(ctx context.Context, replyID string, hide bool) (*Reply, error)
- func (c *Client) Mentions(ctx context.Context, o PageOpts) ([]Post, string, error)
- func (c *Client) PostInsights(ctx context.Context, mediaID string) (map[string]any, error)
- func (c *Client) Profile(ctx context.Context, userID string) (*Profile, error)
- func (c *Client) Publish(ctx context.Context, r PublishReq) (*Post, error)
- func (c *Client) PublishingLimit(ctx context.Context) (*Quota, error)
- func (c *Client) Repost(ctx context.Context, id string) (string, error)
- func (c *Client) Search(ctx context.Context, o SearchOpts) ([]Post, string, string, error)
- func (c *Client) WithBaseURL(u string) *Client
- func (c *Client) WithHTTP(h *http.Client) *Client
- type DeleteResult
- type PageOpts
- type Post
- type Profile
- type PublishReq
- type Quota
- type Reply
- type SearchOpts
- type Threads
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AccountInsightsOpts ¶
AccountInsightsOpts parameterizes account-level insights.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client talks to the Threads Graph API for one authenticated user.
func New ¶
New constructs a client. userID may be "me". An empty token is allowed (calls will fail with AUTH_REQUIRED) so doctor/status can construct a client without credentials.
func (*Client) AccountInsights ¶
func (c *Client) AccountInsights(ctx context.Context, o AccountInsightsOpts) (map[string]any, error)
AccountInsights returns account-level metrics + demographics.
func (*Client) Conversation ¶
func (c *Client) Conversation(ctx context.Context, mediaID string, o PageOpts) ([]Reply, string, error)
Conversation returns the full reply tree for a post (reverse-chronological).
func (*Client) DeletePost ¶
DeletePost deletes a post. It is idempotent: a not-found target is a soft success (existed=false), so an agent's retries don't hard-fail (contract §9).
func (*Client) ListPosts ¶
ListPosts returns the authenticated user's posts (newest first) + the next cursor.
func (*Client) ListReplies ¶
func (c *Client) ListReplies(ctx context.Context, mediaID string, o PageOpts) ([]Reply, string, error)
ListReplies returns top-level replies to a post.
func (*Client) ManageReply ¶
ManageReply hides or unhides a reply on the user's post. Idempotent.
func (*Client) PostInsights ¶
PostInsights returns per-post metrics.
func (*Client) Publish ¶
Publish runs the two-step container+publish flow (with VIDEO status polling) and returns the published post. Single-media/text only for carousels-of-one; multi-image carousels are left to a follow-up (the container path supports children but the CLI surface posts one item).
func (*Client) PublishingLimit ¶
PublishingLimit returns the remaining 24h post-publish quota.
func (*Client) Search ¶
Search runs a keyword or topic-tag search. It returns the results, the next cursor, and a best-effort scope ("public" if any result is authored by someone other than the authed user, else "self") so an agent knows whether advanced access was actually in effect.
func (*Client) WithBaseURL ¶
WithBaseURL overrides the API base (for tests).
type DeleteResult ¶
type DeleteResult struct {
OK bool `json:"ok"`
ID string `json:"id"`
DeletedID string `json:"deletedId,omitempty"`
Existed bool `json:"existed"`
}
DeleteResult is the spec-shaped delete response.
type Post ¶
type Post struct {
ID string `json:"id"`
Username string `json:"username,omitempty"`
Text *string `json:"text"`
MediaType string `json:"mediaType,omitempty"`
MediaURL *string `json:"mediaUrl"`
Permalink *string `json:"permalink"`
Timestamp string `json:"timestamp,omitempty"`
IsQuotePost bool `json:"isQuotePost"`
ReplyAudience *string `json:"replyAudience,omitempty"`
LinkAttachmentURL *string `json:"linkAttachmentUrl"`
QuotedPostID *string `json:"quotedPostId"`
}
Post is the spec-shaped post object.
type Profile ¶
type Profile struct {
ID string `json:"id"`
Username string `json:"username,omitempty"`
Name string `json:"name,omitempty"`
Biography string `json:"biography,omitempty"`
ProfilePictureURL string `json:"profilePictureUrl,omitempty"`
IsVerified bool `json:"isVerified"`
}
Profile is the spec-shaped profile object.
type PublishReq ¶
type PublishReq struct {
Text string
ImageURLs []string
VideoURLs []string
Link string
ReplyToID string
QuotePostID string
Topic string
ReplyControl string
}
PublishReq is a normalized publish request (container step 1).
type Quota ¶
type Quota struct {
Used int `json:"used"`
Total int `json:"total"`
Remaining int `json:"remaining"`
}
Quota is the remaining-publish-quota view (from threads_publishing_limit).
type Reply ¶
type Reply struct {
Post
HideStatus string `json:"hideStatus,omitempty"`
RepliedToID *string `json:"repliedToId"`
RootPostID *string `json:"rootPostId"`
HasReplies bool `json:"hasReplies"`
}
Reply extends Post with reply-management fields.
type SearchOpts ¶
type SearchOpts struct {
Query string
MediaType string // text|image|video (mapped to API enums)
Tag bool // search_mode=TAG
PageOpts
}
SearchOpts parameterizes keyword/topic search.
type Threads ¶
type Threads interface {
Profile(ctx context.Context, userID string) (*Profile, error)
ListPosts(ctx context.Context, o PageOpts) ([]Post, string, error)
GetPost(ctx context.Context, id string) (*Post, error)
Publish(ctx context.Context, r PublishReq) (*Post, error)
Repost(ctx context.Context, id string) (string, error)
DeletePost(ctx context.Context, id string) (*DeleteResult, error)
ListReplies(ctx context.Context, mediaID string, o PageOpts) ([]Reply, string, error)
Conversation(ctx context.Context, mediaID string, o PageOpts) ([]Reply, string, error)
ManageReply(ctx context.Context, replyID string, hide bool) (*Reply, error)
Mentions(ctx context.Context, o PageOpts) ([]Post, string, error)
Search(ctx context.Context, o SearchOpts) ([]Post, string, string, error)
PostInsights(ctx context.Context, mediaID string) (map[string]any, error)
AccountInsights(ctx context.Context, o AccountInsightsOpts) (map[string]any, error)
PublishingLimit(ctx context.Context) (*Quota, error)
}
Threads is the surface the CLI commands depend on. *Client implements it; tests inject fakes. Keeping commands behind this interface keeps them unit-testable without a live API.