api

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 25, 2026 License: MIT Imports: 11 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AccountInsightsOpts

type AccountInsightsOpts struct {
	Metrics []string
	Since   string
	Until   string
}

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

func New(token, userID string) *Client

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

func (c *Client) DeletePost(ctx context.Context, id string) (*DeleteResult, error)

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) GetPost

func (c *Client) GetPost(ctx context.Context, id string) (*Post, error)

GetPost fetches one post by media id.

func (*Client) ListPosts

func (c *Client) ListPosts(ctx context.Context, o PageOpts) ([]Post, string, error)

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

func (c *Client) ManageReply(ctx context.Context, replyID string, hide bool) (*Reply, error)

ManageReply hides or unhides a reply on the user's post. Idempotent.

func (*Client) Mentions

func (c *Client) Mentions(ctx context.Context, o PageOpts) ([]Post, string, error)

Mentions returns public posts mentioning the authenticated user.

func (*Client) PostInsights

func (c *Client) PostInsights(ctx context.Context, mediaID string) (map[string]any, error)

PostInsights returns per-post metrics.

func (*Client) Profile

func (c *Client) Profile(ctx context.Context, userID string) (*Profile, error)

Profile fetches a profile. userID "" or "me" → the authenticated user.

func (*Client) Publish

func (c *Client) Publish(ctx context.Context, r PublishReq) (*Post, error)

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

func (c *Client) PublishingLimit(ctx context.Context) (*Quota, error)

PublishingLimit returns the remaining 24h post-publish quota.

func (*Client) Repost

func (c *Client) Repost(ctx context.Context, id string) (string, error)

Repost reposts a post. Returns the repost's id.

func (*Client) Search

func (c *Client) Search(ctx context.Context, o SearchOpts) ([]Post, string, string, error)

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

func (c *Client) WithBaseURL(u string) *Client

WithBaseURL overrides the API base (for tests).

func (*Client) WithHTTP

func (c *Client) WithHTTP(h *http.Client) *Client

WithHTTP overrides the HTTP client (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 PageOpts

type PageOpts struct {
	Limit  int
	Cursor string
	Since  string
	Until  string
}

PageOpts are common list/pagination options.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL