api

package
v0.1.11 Latest Latest
Warning

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

Go to latest
Published: Aug 4, 2026 License: MIT Imports: 35 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrSessionExpired = errors.New("session expired or invalid; run 'xeet auth' to reconnect")

ErrSessionExpired means X rejected the saved cookies. Callers should tell the user to re-run 'xeet auth'; wrapping sites add HTTP detail with %w.

Functions

func DetectBrowsers

func DetectBrowsers() []string

DetectBrowsers returns installed browsers with at least one cookie database. Detection never opens the keyring, so browser listing cannot trigger an unlock prompt. Import verifies that an x.com session is actually present.

func DiscoverCreateTweetQueryID

func DiscoverCreateTweetQueryID(ctx context.Context, authToken, ct0 string) (string, error)

DiscoverCreateTweetQueryID fetches x.com's JS bundles and extracts the current CreateTweet persisted-query id. Cookies are optional; they only help the home page reference the composer's chunk. Returns an error if it can't be found.

func DiscoverOperationQueryID

func DiscoverOperationQueryID(ctx context.Context, authToken, ct0, operation string) (string, error)

DiscoverOperationQueryID finds a current persisted-query id in X's live web bundles. It also reconstructs lazy webpack chunk URLs from the runtime map, which is necessary for route-specific operations such as HomeTimeline.

func ErrorDiagnostic

func ErrorDiagnostic(err error) string

ErrorDiagnostic returns safe response-shape detail attached to err.

func SupportedBrowsers

func SupportedBrowsers() []string

SupportedBrowsers returns the browser choices shown by `xeet auth`, in UI preference order. Return a copy so callers cannot mutate the shared list.

Types

type Account

type Account struct {
	ID       string
	Name     string
	Handle   string
	Verified bool
}

Account is the identity attached to the imported browser session.

type AmbiguousPostError

type AmbiguousPostError struct {
	Reconciliation string
}

AmbiguousPostError means the CreateTweet mutation returned without a trustworthy success id or a structured rejection. The post may exist, so callers must preserve the draft and must not automatically retry.

func (*AmbiguousPostError) Error

func (e *AmbiguousPostError) Error() string

type AutomationBlockedError

type AutomationBlockedError struct {
	Message string
}

AutomationBlockedError means X accepted the HTTP request but rejected this post as suspected automation or spam. The decision can be content-sensitive, so callers must not claim the whole session is blocked or retry the mutation automatically.

func (*AutomationBlockedError) Error

func (e *AutomationBlockedError) Error() string

type ConnectionError

type ConnectionError struct {
	Kind string
	Err  error
}

ConnectionError gives network failures a stable, actionable message while retaining the original error for errors.Is/errors.As checks and diagnostics.

func (*ConnectionError) Error

func (e *ConnectionError) Error() string

func (*ConnectionError) Unwrap

func (e *ConnectionError) Unwrap() error

type ConversationPage

type ConversationPage struct {
	Posts      []ConversationPost
	Unresolved []TimelinePost
	Cursor     string
}

ConversationPage is one ordered page from X's TweetDetail timeline.

type ConversationPost

type ConversationPost struct {
	TimelinePost
	Depth int
}

ConversationPost is one post in a TweetDetail conversation. Depth is relative to the focal post (the focal post itself has depth zero).

type DiagnosticError

type DiagnosticError interface {
	error
	Diagnostic() string
}

DiagnosticError is implemented by errors that carry a sanitized diagnostic string. Diagnostics contain response shape and request metadata only, never cookies or post contents.

type LoginResult

type LoginResult struct {
	AuthToken    string
	CT0          string
	Profile      string
	CookieDomain string
	ExpiresAt    time.Time
	LastUsedAt   time.Time
}

LoginResult is the session material an auth method yields.

func ImportBrowserSession

func ImportBrowserSession(name string) (*LoginResult, string, error)

type Notification added in v0.1.11

type Notification struct {
	ID   string
	Kind NotificationKind
	Post TimelinePost
}

Notification is a reply or mention with the post that caused it.

type NotificationKind added in v0.1.11

type NotificationKind string

NotificationKind identifies the actionable conversation events Xeet shows.

const (
	NotificationReply   NotificationKind = "reply"
	NotificationMention NotificationKind = "mention"
)

type NotificationPage added in v0.1.11

type NotificationPage struct {
	Notifications []Notification
	Cursor        string
	AccountID     string
}

NotificationPage is one page from the authenticated notification timeline.

type PostEvent

type PostEvent struct {
	Stage            PostStage
	Current          int
	Total            int
	Name             string
	TransferredBytes int64
	TotalBytes       int64
}

PostEvent reports coarse posting progress. The callback is optional. Chunked uploads additionally fill the byte counters so UIs can show a percentage while a video transfers.

type PostStage

type PostStage string
const (
	PostStageUploading   PostStage = "uploading"
	PostStageProcessing  PostStage = "processing"
	PostStageDiscovering PostStage = "discovering"
	PostStagePublishing  PostStage = "publishing"
	PostStageReconciling PostStage = "reconciling"
	PostStageComplete    PostStage = "complete"
)

type PostingRestrictedError

type PostingRestrictedError struct{}

PostingRestrictedError means X rejected this particular post under an account or content posting restriction.

func (*PostingRestrictedError) Error

func (e *PostingRestrictedError) Error() string

type ProgressFunc

type ProgressFunc func(PostEvent)

type RateLimitError

type RateLimitError struct {
	Reset time.Time
}

RateLimitError means X throttled the request (HTTP 429 or GraphQL code 88). Reset is when the limit window ends, when X told us; zero otherwise.

func (*RateLimitError) Error

func (e *RateLimitError) Error() string

type RecentlyPostedError

type RecentlyPostedError struct{}

RecentlyPostedError means X classified the text as recently posted. Xeet attributes that decision to X instead of claiming the posts are identical.

func (*RecentlyPostedError) Error

func (e *RecentlyPostedError) Error() string

type RequestShape

type RequestShape struct {
	HeaderNames     []string
	CookieNames     []string
	BodyKeys        []string
	VariableKeys    []string
	FeatureKeys     []string
	UserAgentFamily string
	UserAgentMajor  string
	Platform        string
}

RequestShape contains only structural metadata from a CreateTweet request. It intentionally excludes every header value, cookie value, and body value.

type RequestShapeComparison

type RequestShapeComparison struct {
	Browser RequestShape
	Xeet    RequestShape
}

RequestShapeComparison compares a successful browser request with the request Xeet currently builds. Every field is safe to print.

func CompareCreateTweetHAR

func CompareCreateTweetHAR(reader io.Reader) (*RequestShapeComparison, error)

CompareCreateTweetHAR finds the last CreateTweet POST in a browser HAR and compares its safe structural shape with Xeet's current request.

func (*RequestShapeComparison) String

func (c *RequestShapeComparison) String() string

type ServiceUnavailableError

type ServiceUnavailableError struct{ Status int }

ServiceUnavailableError means X's servers failed after bounded retries.

func (*ServiceUnavailableError) Error

func (e *ServiceUnavailableError) Error() string

type TimelineMedia

type TimelineMedia struct {
	URL      string
	Type     string
	AltText  string
	Width    int
	Height   int
	VideoURL string
}

type TimelinePage

type TimelinePage struct {
	Posts  []TimelinePost
	Cursor string
}

type TimelinePost

type TimelinePost struct {
	ID             string
	Text           string
	AuthorName     string
	Handle         string
	CreatedAt      time.Time
	ReplyCount     int
	RepostCount    int
	LikeCount      int
	ViewCount      string
	MediaCount     int
	Media          []TimelineMedia
	Liked          bool
	InReplyToID    string
	ConversationID string
}

type Upload

type Upload struct {
	Filename    string
	ContentType string
	Data        []byte
	Path        string
}

Upload is one media item to upload and attach to a post. Images travel in Data; large media (video) sets Path instead and streams from disk through the chunked endpoint.

type WebClient

type WebClient struct {
	// contains filtered or unexported fields
}

WebClient posts through x.com's internal GraphQL API using a logged-in browser session (auth_token + ct0 cookies) instead of the developer API.

func NewWebClient

func NewWebClient(cfg *config.Config) *WebClient

func (*WebClient) ApplyRefreshedQueryIDs

func (c *WebClient) ApplyRefreshedQueryIDs(cfg *config.Config) bool

ApplyRefreshedQueryIDs copies operation ids discovered by this client into cfg. It reports whether there is anything for the caller to persist.

func (*WebClient) FetchBookmarks added in v0.1.10

func (c *WebClient) FetchBookmarks(ctx context.Context, cursor string, count int) (*TimelinePage, error)

FetchBookmarks returns a page of the authenticated user's bookmarks.

func (*WebClient) FetchFollowingTimeline

func (c *WebClient) FetchFollowingTimeline(ctx context.Context, cursor string, count int) (*TimelinePage, error)

FetchFollowingTimeline retrieves one page of the authenticated Following feed.

func (*WebClient) FetchHomeTimeline

func (c *WebClient) FetchHomeTimeline(ctx context.Context, cursor string, count int) (*TimelinePage, error)

FetchHomeTimeline retrieves one page of the authenticated For You feed.

func (*WebClient) FetchNotifications added in v0.1.11

func (c *WebClient) FetchNotifications(ctx context.Context, cursor string, count int) (*NotificationPage, error)

FetchNotifications returns actionable replies and mentions from X's NotificationsTimeline. Other notification unions (likes, follows, reposts) are intentionally ignored because they have no post Xeet can reply to.

func (*WebClient) FetchSearchTimeline added in v0.1.10

func (c *WebClient) FetchSearchTimeline(ctx context.Context, query, cursor string, count int) (*TimelinePage, error)

FetchSearchTimeline returns a page of search results for query.

func (*WebClient) FetchTweetDetail

func (c *WebClient) FetchTweetDetail(ctx context.Context, tweetID, cursor string, count int) (*ConversationPage, error)

FetchTweetDetail retrieves a post and the replies X returns for it.

func (*WebClient) FetchViewer

func (c *WebClient) FetchViewer(ctx context.Context) (*Account, error)

FetchViewer returns the account represented by the client's session cookies. It is a read-only request and refreshes X's rotating Viewer operation id once when necessary.

func (*WebClient) LastDiagnostic

func (c *WebClient) LastDiagnostic() string

LastDiagnostic returns sanitized response-shape metadata from the most recent CreateTweet call. It never includes cookies, request bodies, or post text.

func (*WebClient) PostTweet

func (c *WebClient) PostTweet(ctx context.Context, text, replyToID string, uploads []Upload, progress ProgressFunc) (string, error)

PostTweet posts through the web GraphQL endpoint and returns the created id. Media is uploaded first and attached to the same CreateTweet operation.

func (*WebClient) SetTweetLiked

func (c *WebClient) SetTweetLiked(ctx context.Context, tweetID string, liked bool) error

SetTweetLiked likes or unlikes a post using X's web GraphQL mutation.

func (*WebClient) Verify

func (c *WebClient) Verify(ctx context.Context) error

Verify confirms the session cookies with a non-mutating authenticated timeline read. Account identity is a separate question, answered by FetchViewer.

Jump to

Keyboard shortcuts

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