Documentation
¶
Overview ¶
Package xclient is an authenticated client for x.com's internal GraphQL/REST API. It signs every request with a freshly generated x-client-transaction-id (see pkg/transaction) and a complete browser-like header set, which is what keeps cookie sessions alive instead of getting them flagged and expired.
Index ¶
- type BadgeCount
- type BookmarkFolder
- type Client
- func (c *Client) Account() *account.Account
- func (c *Client) AddListMember(ctx context.Context, listID, userID string) error
- func (c *Client) Article(ctx context.Context, tweetID string, markdown bool) (*models.Tweet, error)
- func (c *Client) Badges(ctx context.Context) (*BadgeCount, error)
- func (c *Client) Block(ctx context.Context, screenName string) error
- func (c *Client) Bookmark(ctx context.Context, tweetID string) error
- func (c *Client) BookmarkFolderTweets(ctx context.Context, folderID string, count int, cursor string) (*models.Page, error)
- func (c *Client) BookmarkFolders(ctx context.Context) ([]BookmarkFolder, error)
- func (c *Client) BookmarkToFolder(ctx context.Context, tweetID, folderID string) error
- func (c *Client) Bookmarks(ctx context.Context, count int, cursor string) (*models.Page, error)
- func (c *Client) CommunityInfo(ctx context.Context, communityID string) (map[string]any, error)
- func (c *Client) CommunityTweets(ctx context.Context, communityID string, count int, cursor string, latest bool) (*models.Page, error)
- func (c *Client) CreateBookmarkFolder(ctx context.Context, name string) (*BookmarkFolder, error)
- func (c *Client) CreateCommunity(ctx context.Context, name string) (map[string]any, error)
- func (c *Client) CreateDraft(ctx context.Context, text string, mediaIDs []string) (string, error)
- func (c *Client) CreateList(ctx context.Context, name, description string, private bool) (map[string]any, error)
- func (c *Client) Delete(ctx context.Context, tweetID string) error
- func (c *Client) DeleteBookmarkFolder(ctx context.Context, folderID string) error
- func (c *Client) DeleteDraft(ctx context.Context, draftID string) error
- func (c *Client) DeleteList(ctx context.Context, listID string) error
- func (c *Client) DeleteScheduledTweet(ctx context.Context, scheduledTweetID string) error
- func (c *Client) DirectMessages(ctx context.Context, count int) ([]DirectMessage, error)
- func (c *Client) DownloadMedia(ctx context.Context, rawURL string) ([]byte, string, error)
- func (c *Client) Drafts(ctx context.Context) ([]Draft, error)
- func (c *Client) Favoriters(ctx context.Context, tweetID string, count int, cursor string) (*models.UserPage, error)
- func (c *Client) Follow(ctx context.Context, screenName string) error
- func (c *Client) FollowTopic(ctx context.Context, topicID string) error
- func (c *Client) Followers(ctx context.Context, userID string, count int, cursor string) (*models.UserPage, error)
- func (c *Client) FollowersByScreenName(ctx context.Context, screenName string, count int, cursor string) (*models.UserPage, error)
- func (c *Client) Following(ctx context.Context, userID string, count int, cursor string) (*models.UserPage, error)
- func (c *Client) FollowingByScreenName(ctx context.Context, screenName string, count int, cursor string) (*models.UserPage, error)
- func (c *Client) GrokAsk(ctx context.Context, prompt string) (string, error)
- func (c *Client) GrokImage(ctx context.Context, prompt string) ([]string, error)
- func (c *Client) HomeTimeline(ctx context.Context, latest bool, count int, cursor string) (*models.Page, error)
- func (c *Client) JoinCommunity(ctx context.Context, communityID string) error
- func (c *Client) LeaveCommunity(ctx context.Context, communityID string) error
- func (c *Client) Like(ctx context.Context, tweetID string) error
- func (c *Client) Likes(ctx context.Context, userID string, count int, cursor string) (*models.Page, error)
- func (c *Client) LikesByScreenName(ctx context.Context, screenName string, count int, cursor string) (*models.Page, error)
- func (c *Client) ListMembers(ctx context.Context, listID string, count int, cursor string) (*models.UserPage, error)
- func (c *Client) ListTweets(ctx context.Context, listID string, count int, cursor string) (*models.Page, error)
- func (c *Client) Me(ctx context.Context) (*models.UserProfile, error)
- func (c *Client) Mentions(ctx context.Context, count int, maxID string) (*models.Page, error)
- func (c *Client) Mute(ctx context.Context, screenName string) error
- func (c *Client) Notifications(ctx context.Context, tab string, count int, cursor string) (*NotificationPage, error)
- func (c *Client) PinTweet(ctx context.Context, tweetID string) error
- func (c *Client) Post(ctx context.Context, text string, opts PostOptions) (*models.Tweet, error)
- func (c *Client) PostPoll(ctx context.Context, text string, choices []string, durationMinutes int) (*models.Tweet, error)
- func (c *Client) RemoveListMember(ctx context.Context, listID, userID string) error
- func (c *Client) Retweet(ctx context.Context, tweetID string) error
- func (c *Client) Retweeters(ctx context.Context, tweetID string, count int, cursor string) (*models.UserPage, error)
- func (c *Client) ScheduleTweet(ctx context.Context, text string, executeAt int64, mediaIDs []string) (string, error)
- func (c *Client) ScheduledTweets(ctx context.Context) ([]ScheduledTweet, error)
- func (c *Client) Search(ctx context.Context, query, product string, count int, cursor string) (*models.Page, error)
- func (c *Client) SendDM(ctx context.Context, recipientID, text string) error
- func (c *Client) SendDMMedia(ctx context.Context, recipientID, text string, data []byte, mimeType string) error
- func (c *Client) SetAltText(ctx context.Context, mediaID, text string) error
- func (c *Client) SetQueryID(op, id string)
- func (c *Client) Settings(ctx context.Context) (map[string]any, error)
- func (c *Client) SubscribeList(ctx context.Context, listID string) error
- func (c *Client) TrendLocations(ctx context.Context) ([]TrendLocation, error)
- func (c *Client) Trends(ctx context.Context, woeid string) ([]Trend, error)
- func (c *Client) TweetDetail(ctx context.Context, tweetID string) (*models.Page, error)
- func (c *Client) Unblock(ctx context.Context, screenName string) error
- func (c *Client) Unbookmark(ctx context.Context, tweetID string) error
- func (c *Client) Unfollow(ctx context.Context, screenName string) error
- func (c *Client) UnfollowTopic(ctx context.Context, topicID string) error
- func (c *Client) Unlike(ctx context.Context, tweetID string) error
- func (c *Client) Unmute(ctx context.Context, screenName string) error
- func (c *Client) UnpinTweet(ctx context.Context, tweetID string) error
- func (c *Client) Unretweet(ctx context.Context, tweetID string) error
- func (c *Client) UnsubscribeList(ctx context.Context, listID string) error
- func (c *Client) UpdateAvatar(ctx context.Context, image []byte) error
- func (c *Client) UpdateBanner(ctx context.Context, image []byte) error
- func (c *Client) UpdateProfile(ctx context.Context, f ProfileFields) error
- func (c *Client) UpdateSettings(ctx context.Context, fields map[string]string) error
- func (c *Client) UploadMedia(ctx context.Context, data []byte, mediaType, category string) (string, error)
- func (c *Client) UserByRestId(ctx context.Context, userID string) (*models.UserProfile, error)
- func (c *Client) UserByScreenName(ctx context.Context, screenName string) (*models.UserProfile, error)
- func (c *Client) UserMedia(ctx context.Context, userID string, count int, cursor string) (*models.Page, error)
- func (c *Client) UserPosts(ctx context.Context, screenName string, count int, cursor string) (*models.Page, error)
- func (c *Client) UserTweets(ctx context.Context, userID string, count int, cursor string) (*models.Page, error)
- func (c *Client) VotePoll(ctx context.Context, tweetID string, choice int) error
- type DirectMessage
- type Draft
- type LoginResult
- type NotificationItem
- type NotificationPage
- type Option
- type PostOptions
- type ProfileFields
- type RateLimit
- type ScheduledTweet
- type Trend
- type TrendLocation
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BadgeCount ¶
type BadgeCount struct {
Notifications int `json:"notifications"`
DM int `json:"dm"`
XChat int `json:"xchat"`
Total int `json:"total"`
}
BadgeCount holds the unread counters x.com shows on its nav badges.
type BookmarkFolder ¶
BookmarkFolder is a named bookmark collection.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client talks to x.com on behalf of a single account.
func (*Client) AddListMember ¶
AddListMember adds a user (by numeric id) to a List the account owns.
func (*Client) Article ¶
Article fetches a single tweet by id via TweetResultByRestId and populates the X Article fields when the tweet is a long-form article. markdown renders the article body as markdown instead of plain text. Non-article tweets are returned with empty article fields.
func (*Client) Badges ¶
func (c *Client) Badges(ctx context.Context) (*BadgeCount, error)
Badges returns the account's unread counts (notifications, DMs, XChat) via the v2 badge_count endpoint.
func (*Client) BookmarkFolderTweets ¶
func (c *Client) BookmarkFolderTweets(ctx context.Context, folderID string, count int, cursor string) (*models.Page, error)
BookmarkFolderTweets returns the tweets saved in a bookmark folder.
func (*Client) BookmarkFolders ¶
func (c *Client) BookmarkFolders(ctx context.Context) ([]BookmarkFolder, error)
BookmarkFolders lists the account's bookmark folders.
func (*Client) BookmarkToFolder ¶
BookmarkToFolder bookmarks a tweet into a specific folder.
func (*Client) CommunityInfo ¶
CommunityInfo returns metadata about a Community (name, description, member count, join policy, role) by its numeric id.
func (*Client) CommunityTweets ¶
func (c *Client) CommunityTweets(ctx context.Context, communityID string, count int, cursor string, latest bool) (*models.Page, error)
CommunityTweets returns the timeline of posts in a Community. When latest is true the timeline is ranked by recency, otherwise by relevance (the x.com web defaults).
func (*Client) CreateBookmarkFolder ¶
CreateBookmarkFolder creates a new bookmark folder and returns it.
func (*Client) CreateCommunity ¶
CreateCommunity creates a new Community with the given name and returns its id and name. NOTE: creating a Community is a permanent, public action and is not undoable via this client. x.com also gates creation by account standing: ineligible accounts get a CommunityCreateActionUnavailable result, surfaced here as an error (verified live — a fresh burner cannot create Communities, so no Community is actually created in that case).
func (*Client) CreateDraft ¶
CreateDraft saves a draft tweet and returns its id.
func (*Client) CreateList ¶
func (c *Client) CreateList(ctx context.Context, name, description string, private bool) (map[string]any, error)
CreateList creates a List owned by the authenticated account and returns its id and name.
func (*Client) DeleteBookmarkFolder ¶
DeleteBookmarkFolder deletes a bookmark folder by id.
func (*Client) DeleteDraft ¶
DeleteDraft removes a draft tweet by id.
func (*Client) DeleteList ¶
DeleteList deletes a List owned by the authenticated account.
func (*Client) DeleteScheduledTweet ¶
DeleteScheduledTweet removes a pending scheduled tweet by id.
func (*Client) DirectMessages ¶
DirectMessages lists recent DMs (incoming and outgoing, including message requests) via the rich inbox_initial_state endpoint, newest first. The older events/list.json endpoint omits some conversations, so this one is used.
func (*Client) DownloadMedia ¶
DownloadMedia fetches the bytes of an auth-gated media URL (e.g. a DM attachment on ton.twitter.com / video.twimg.com) using the account's cookies, returning the body and its Content-Type.
func (*Client) Favoriters ¶
func (c *Client) Favoriters(ctx context.Context, tweetID string, count int, cursor string) (*models.UserPage, error)
Favoriters returns the accounts that liked a tweet.
func (*Client) Follow ¶
Follow / Unfollow / Mute / Unmute / Block / Unblock act on another user by @handle via the legacy v1.1 endpoints, which accept screen_name directly.
func (*Client) FollowTopic ¶
FollowTopic / UnfollowTopic manage the account's followed Topics.
func (*Client) Followers ¶
func (c *Client) Followers(ctx context.Context, userID string, count int, cursor string) (*models.UserPage, error)
Followers fetches a user's followers by numeric user id.
func (*Client) FollowersByScreenName ¶
func (c *Client) FollowersByScreenName(ctx context.Context, screenName string, count int, cursor string) (*models.UserPage, error)
FollowersByScreenName / FollowingByScreenName resolve a @handle first.
func (*Client) Following ¶
func (c *Client) Following(ctx context.Context, userID string, count int, cursor string) (*models.UserPage, error)
Following fetches the accounts a user follows by numeric user id.
func (*Client) FollowingByScreenName ¶
func (*Client) GrokAsk ¶
GrokAsk sends a single prompt to Grok and returns the assembled reply. It creates a fresh conversation, posts the prompt to the streaming /2/grok/add_response endpoint, and concatenates the streamed answer tokens.
func (*Client) GrokImage ¶
GrokImage asks Grok to generate image(s) and returns their attachment URLs. With toolOverrides.imageGen the add_response stream itself carries the generated image cards (imageAttachment.mediaId), so the ids are read straight from the stream.
func (*Client) HomeTimeline ¶
func (c *Client) HomeTimeline(ctx context.Context, latest bool, count int, cursor string) (*models.Page, error)
HomeTimeline fetches the authenticated home timeline. When latest is true it returns the chronological "Following" feed instead of "For You".
func (*Client) JoinCommunity ¶
JoinCommunity joins the Community with the given id.
func (*Client) LeaveCommunity ¶
LeaveCommunity leaves the Community with the given id.
func (*Client) Likes ¶
func (c *Client) Likes(ctx context.Context, userID string, count int, cursor string) (*models.Page, error)
Likes fetches the tweets a user has liked, by numeric user id.
func (*Client) LikesByScreenName ¶
func (c *Client) LikesByScreenName(ctx context.Context, screenName string, count int, cursor string) (*models.Page, error)
LikesByScreenName resolves a @handle then fetches that user's likes.
func (*Client) ListMembers ¶
func (c *Client) ListMembers(ctx context.Context, listID string, count int, cursor string) (*models.UserPage, error)
ListMembers returns the accounts that belong to a List (its members), by the List's numeric id.
func (*Client) ListTweets ¶
func (c *Client) ListTweets(ctx context.Context, listID string, count int, cursor string) (*models.Page, error)
ListTweets fetches the latest tweets of a List by its id.
func (*Client) Me ¶
Me returns the authenticated user's own profile. It resolves the logged-in screen name via the v1.1 account/settings endpoint, then fetches the full profile through the GraphQL UserByScreenName path.
func (*Client) Mentions ¶
Mentions fetches tweets mentioning the authenticated user via the v1.1 mentions_timeline. Pagination is id-based: the returned NextCursor is the max_id for the next (older) page.
func (*Client) Notifications ¶
func (c *Client) Notifications(ctx context.Context, tab string, count int, cursor string) (*NotificationPage, error)
Notifications fetches the v2 notifications timeline. tab is one of "all", "mentions", or "verified" (defaults to "all").
func (*Client) PinTweet ¶
PinTweet pins one of the authenticated account's own tweets to its profile.
func (*Client) PostPoll ¶
func (c *Client) PostPoll(ctx context.Context, text string, choices []string, durationMinutes int) (*models.Tweet, error)
PostPoll creates a poll card (2–4 text choices, duration in minutes) and posts a tweet carrying it.
func (*Client) RemoveListMember ¶
RemoveListMember removes a user (by numeric id) from a List the account owns.
func (*Client) Retweeters ¶
func (c *Client) Retweeters(ctx context.Context, tweetID string, count int, cursor string) (*models.UserPage, error)
Retweeters returns the accounts that retweeted a tweet.
func (*Client) ScheduleTweet ¶
func (c *Client) ScheduleTweet(ctx context.Context, text string, executeAt int64, mediaIDs []string) (string, error)
ScheduleTweet queues a tweet for publication at executeAt (unix seconds) and returns the scheduled tweet id. mediaIDs are optional attached media.
func (*Client) ScheduledTweets ¶
func (c *Client) ScheduledTweets(ctx context.Context) ([]ScheduledTweet, error)
ScheduledTweets lists the account's pending scheduled tweets, soonest first.
func (*Client) Search ¶
func (c *Client) Search(ctx context.Context, query, product string, count int, cursor string) (*models.Page, error)
Search runs an advanced search. product is one of Top, Latest, People, Photos, Videos.
func (*Client) SendDM ¶
SendDM sends a direct message to a recipient user id via the v1.1 DM events endpoint. Resolve a @handle to an id with UserByScreenName first.
func (*Client) SendDMMedia ¶
func (c *Client) SendDMMedia(ctx context.Context, recipientID, text string, data []byte, mimeType string) error
SendDMMedia uploads media (DM category) and sends it as a DM attachment, with optional accompanying text.
func (*Client) SetAltText ¶
SetAltText attaches accessibility alt text to an uploaded media id (call after UploadMedia, before posting).
func (*Client) SetQueryID ¶
SetQueryID overrides a single operation's query id (used when x.com rotates them and a fresh id is discovered).
func (*Client) Settings ¶
Settings returns the authenticated account's settings (privacy, DM, discovery) via the v1.1 account/settings endpoint.
func (*Client) SubscribeList ¶
SubscribeList follows (subscribes to) a List owned by anyone, so it appears in the authenticated account's Lists.
func (*Client) TrendLocations ¶
func (c *Client) TrendLocations(ctx context.Context) ([]TrendLocation, error)
TrendLocations lists the places (with WOEIDs) that have trending data, via the v1.1 trends/available endpoint.
func (*Client) Trends ¶
Trends returns the trending topics for a WOEID location (1 = worldwide) via the v1.1 trends/place endpoint.
func (*Client) TweetDetail ¶
TweetDetail fetches a tweet and its conversation thread.
func (*Client) Unbookmark ¶
Unbookmark removes a saved tweet.
func (*Client) UnfollowTopic ¶
func (*Client) UnpinTweet ¶
UnpinTweet removes the pinned tweet from the authenticated account's profile.
func (*Client) UnsubscribeList ¶
UnsubscribeList unfollows a List the authenticated account subscribed to.
func (*Client) UpdateAvatar ¶
UpdateAvatar sets the account's profile picture from raw image bytes.
func (*Client) UpdateBanner ¶
UpdateBanner sets the account's profile banner from raw image bytes.
func (*Client) UpdateProfile ¶
func (c *Client) UpdateProfile(ctx context.Context, f ProfileFields) error
UpdateProfile edits the authenticated account's profile (name, bio, location, url) via the v1.1 account/update_profile endpoint. Only the non-empty fields are sent.
func (*Client) UpdateSettings ¶
UpdateSettings posts the given fields to account/settings (e.g. protected, allow_dms_from, discoverable_by_email). Only the provided keys are changed.
func (*Client) UploadMedia ¶
func (c *Client) UploadMedia(ctx context.Context, data []byte, mediaType, category string) (string, error)
UploadMedia performs a chunked INIT/APPEND/FINALIZE upload and returns the media_id to attach to a tweet. mediaType is the MIME type (e.g. image/jpeg); category is the x.com media_category (tweet_image / tweet_video / tweet_gif), derived automatically when empty. Video/gif uploads are polled to completion.
func (*Client) UserByRestId ¶
UserByRestId resolves a profile by its numeric user id (the counterpart to UserByScreenName).
func (*Client) UserByScreenName ¶
func (c *Client) UserByScreenName(ctx context.Context, screenName string) (*models.UserProfile, error)
UserByScreenName resolves a profile by @handle.
func (*Client) UserMedia ¶
func (c *Client) UserMedia(ctx context.Context, userID string, count int, cursor string) (*models.Page, error)
UserMedia fetches the photos/videos tab of a user's profile by numeric id.
func (*Client) UserPosts ¶
func (c *Client) UserPosts(ctx context.Context, screenName string, count int, cursor string) (*models.Page, error)
UserPosts is a convenience wrapper that resolves a @handle then fetches posts.
func (*Client) UserTweets ¶
func (c *Client) UserTweets(ctx context.Context, userID string, count int, cursor string) (*models.Page, error)
UserTweets fetches a user's posts by numeric user id.
type DirectMessage ¶
type DirectMessage struct {
ID string `json:"id"`
ConversationID string `json:"conversationId,omitempty"`
Text string `json:"text"`
SenderID string `json:"senderId"`
SenderScreenName string `json:"senderScreenName,omitempty"`
RecipientID string `json:"recipientId,omitempty"`
Media []models.Media `json:"media,omitempty"` // attached photo/video/gif
CreatedAt string `json:"createdAt"` // unix millis as returned by x.com
}
DirectMessage is a single DM, normalised from the inbox state.
type LoginResult ¶
LoginResult carries the cookies obtained from a successful password login.
func Login ¶
func Login(ctx context.Context, username, password, proxyURL string) (*LoginResult, error)
Login performs x.com's onboarding "login" flow with a username/handle and password, returning the resulting auth_token and ct0 cookies. It cannot solve interactive challenges (2FA codes, e-mail/phone verification) and returns a descriptive error when one is required. proxyURL (optional, http(s):// or socks5://) routes every request — useful because x.com blocks login from datacenter IPs, so a residential proxy is usually required.
type NotificationItem ¶
type NotificationItem struct {
Kind string `json:"kind"` // "notification" or "tweet"
ID string `json:"id,omitempty"`
Message string `json:"message,omitempty"`
Icon string `json:"icon,omitempty"` // template icon, e.g. heart_icon
Timestamp string `json:"timestampMs,omitempty"`
Tweet *models.Tweet `json:"tweet,omitempty"`
}
NotificationItem is one row of the notifications timeline: either a notification message ("X and 3 others liked your post") or a tweet surfaced in the tab (e.g. a mention/reply).
type NotificationPage ¶
type NotificationPage struct {
Items []NotificationItem `json:"items"`
NextCursor string `json:"nextCursor,omitempty"`
}
NotificationPage is a page of notifications plus a pagination cursor.
type Option ¶
type Option func(*Client)
Option customises a Client.
func WithHTTPClient ¶
WithHTTPClient overrides the HTTP client (e.g. to plug in a utls transport for JA3 impersonation, or a proxy).
func WithLocale ¶
WithLocale sets the x-twitter-client-language header (default "en").
func WithTransactionProvider ¶
func WithTransactionProvider(p *transaction.Provider) Option
WithTransactionProvider shares a pre-warmed transaction.Provider.
func WithUTLS ¶
func WithUTLS() Option
WithUTLS makes the client dial TLS through uTLS, sending a Chrome-like ClientHello (JA3) so authenticated traffic better matches real browser fingerprints — the same goal as the per-request x-client-transaction-id, one layer lower. ALPN advertises both h2 and http/1.1; whichever the server negotiates is used (so HTTP/2 is preserved over the Chrome fingerprint).
type PostOptions ¶
type PostOptions struct {
// ReplyToID, when set, makes this a reply.
ReplyToID string
// QuoteTweetID, when set, makes this a quote tweet.
QuoteTweetID string
// MediaIDs are pre-uploaded media ids (see UploadMedia) to attach.
MediaIDs []string
// CardURI, when set (e.g. a poll card), attaches a card to the tweet.
CardURI string
// EditTweetID, when set, edits that existing tweet (Premium-gated).
EditTweetID string
}
PostOptions configures a tweet creation.
type ProfileFields ¶
type ProfileFields struct {
Name string // display name
Description string // bio
Location string
URL string
}
ProfileFields are the editable profile attributes. Empty fields are omitted, so callers can update just the ones they pass.
type RateLimit ¶
type RateLimit struct {
Limit int `json:"limit"`
Remaining int `json:"remaining"`
ResetAt int64 `json:"resetAt"` // unix seconds
}
RateLimit is a snapshot of an endpoint's x-rate-limit-* headers.
func LastRateLimit ¶
func LastRateLimit() *RateLimit
LastRateLimit returns the most recently observed rate-limit snapshot, or nil if no rate-limited response has been seen yet.
type ScheduledTweet ¶
type ScheduledTweet struct {
ID string `json:"id"`
ExecuteAt string `json:"executeAt,omitempty"` // unix seconds
State string `json:"state,omitempty"` // e.g. "Scheduled"
Text string `json:"text,omitempty"`
}
ScheduledTweet is a tweet queued for future publication.
type Trend ¶
type Trend struct {
Name string `json:"name"`
URL string `json:"url,omitempty"`
TweetVolume int `json:"tweetVolume,omitempty"`
}
Trend is a single trending topic.
type TrendLocation ¶
type TrendLocation struct {
Name string `json:"name"`
WOEID int `json:"woeid"`
Country string `json:"country,omitempty"`
}
TrendLocation is a place trends are available for (WOEID + name).