Documentation
¶
Overview ¶
Package tiktok is a pure-Go, dependency-free, best-effort read client for public TikTok content, talking to TikTok's undocumented web JSON endpoints.
Best-effort and fragile by nature ¶
TikTok does not publish or support a stable public web API. The endpoints used here are the ones its own website calls, and TikTok actively defends them. This client computes the "X-Bogus" request signature in pure Go (see XBogus, verified against the public reference implementation) and folds it into every signed request, but X-Bogus alone is no longer sufficient: TikTok also requires a browser-minted msToken cookie and a newer "X-Gnarly" signature, both derived from JavaScript fingerprinting that cannot be reproduced without a browser. Supply an msToken and sessionid captured from a real logged-in browser via WithMSToken and WithSessionID. TikTok returns anti-bot responses (HTTP 403/429, or a 200 with an empty or "{}" body) when it decides a request looks automated.
Consequently this client is BEST-EFFORT: it builds correct requests and parses correct responses, but it can and will break without notice when TikTok changes its web API or tightens its bot defenses. Use it accordingly, respect TikTok's Terms of Service, and do not rely on it for anything critical. Supplying msToken via WithMSToken and a sessionid via WithSessionID improves — but does not guarantee — success.
Index ¶
- Constants
- func XBogus(query, userAgent string, unixSeconds int64) string
- type Client
- func (c *Client) Following(ctx context.Context, secUid string, count int, maxCursor string) (*FollowingList, error)
- func (c *Client) FollowingFeed(ctx context.Context, count int, maxCursor string) (*UserFeed, error)
- func (c *Client) ProfileSecUID(ctx context.Context, username string) (string, error)
- func (c *Client) Recommend(ctx context.Context, count int, cursor string) (*UserFeed, error)
- func (c *Client) UserPosts(ctx context.Context, secUid string, count int, cursor string) (*UserFeed, error)
- func (c *Client) ViewerSecUID(ctx context.Context) (string, error)
- type FollowedUser
- type FollowingList
- type Option
- type UserFeed
- type Video
Constants ¶
const DefaultBaseURL = "https://www.tiktok.com"
DefaultBaseURL is the default TikTok web origin.
const DefaultUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " +
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
DefaultUserAgent is a plausible desktop browser User-Agent. TikTok inspects this header; an empty or obviously automated value is more likely blocked.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Client ¶
type Client struct {
// BaseURL is the TikTok web origin (default https://www.tiktok.com).
BaseURL string
// HTTPClient performs requests (default http.DefaultClient).
HTTPClient *http.Client
// UserAgent is sent as the User-Agent header.
UserAgent string
// MSToken is TikTok's msToken, sent as both a query param and a cookie
// when non-empty.
MSToken string
// SessionID is the sessionid cookie for authenticated reads, sent when
// non-empty.
SessionID string
// contains filtered or unexported fields
}
Client is a best-effort read client for public TikTok content.
A zero Client is not ready for use; construct one with New.
func (*Client) Following ¶ added in v0.2.0
func (c *Client) Following(ctx context.Context, secUid string, count int, maxCursor string) (*FollowingList, error)
Following fetches one page of the accounts secUid follows via TikTok's web user list API:
GET {BaseURL}/api/user/list/?scene=21&secUid=<secUid>&count=<n>&maxCursor=<c>&...
It sets the same web parameters, headers and cookies (User-Agent, Referer, sessionid, msToken) as Client.UserPosts. count is the requested page size and maxCursor is the pagination cursor ("0" or "" for the first page).
IMPORTANT — this is behind TikTok's request-signing wall. The endpoint requires a valid signed parameter (X-Bogus / _signature) derived from the viewer's own secUid, which a pure-Go client cannot forge. Unsigned, TikTok answers an anti-bot response — a non-2xx status, an empty body, or a 200 whose statusCode field is non-zero — each returned here as an error. A caller should treat that as "this needs a signed/authenticated request" rather than as a transient bug.
func (*Client) FollowingFeed ¶ added in v0.3.0
FollowingFeed fetches one page of the authenticated viewer's following feed — the videos from accounts they follow — via TikTok's web following item_list endpoint:
GET {BaseURL}/api/following/item_list/?count=<n>&maxCursor=<c>&...&X-Bogus=…
It requires a session (see WithSessionID) and a browser-minted msToken (see WithMSToken); without a valid msToken TikTok answers the anti-bot empty body even though the X-Bogus signature is correct — see the note on XBogus.
func (*Client) ProfileSecUID ¶ added in v0.3.0
ProfileSecUID fetches a public profile page and returns that account's secUid (the opaque id Client.UserPosts and Client.Following take). username is the @handle without the leading "@". This needs no signing and works anonymously.
func (*Client) Recommend ¶ added in v0.3.0
Recommend fetches one page of the "For You" / home recommend feed via TikTok's web recommend item_list endpoint:
GET {BaseURL}/api/recommend/item_list/?count=<n>&...&X-Bogus=…
Like Client.FollowingFeed it needs a browser-minted msToken to get past the anti-bot layer; the request is otherwise correctly signed.
func (*Client) UserPosts ¶
func (c *Client) UserPosts(ctx context.Context, secUid string, count int, cursor string) (*UserFeed, error)
UserPosts fetches a user's recent videos via TikTok's web item_list API:
GET {BaseURL}/api/post/item_list/?secUid=<secUid>&count=<n>&cursor=<c>&...
The secUid is TikTok's opaque secondary user id; the caller obtains it once (for example from a profile page's embedded JSON) and passes it here. count is the requested page size and cursor is the pagination cursor ("0" or "" for the first page). Headers (User-Agent, Referer) and cookies (sessionid, msToken) are set when configured.
An empty result (no videos, HasMore=false) is returned without error. A non-2xx status, an empty/anti-bot body, or malformed JSON returns an error.
func (*Client) ViewerSecUID ¶ added in v0.3.0
ViewerSecUID returns the authenticated viewer's own secUid. It fetches a TikTok web app page carrying the session cookie and reads the viewer out of the embedded rehydration JSON's app-context. A session is required (see WithSessionID); without one, TikTok serves a logged-out page that carries no viewer identity and this returns an error.
type FollowedUser ¶ added in v0.2.0
type FollowedUser struct {
SecUID string // TikTok's opaque per-account id (the channel [Client.UserPosts] takes)
UniqueID string // the @handle, without the "@"
Nickname string // the display name ("" when the account sets none)
}
FollowedUser is one account the viewer follows, as returned by the user list.
type FollowingList ¶ added in v0.2.0
type FollowingList struct {
Users []FollowedUser
MaxCursor string
HasMore bool
}
FollowingList is one page of the viewer's following list. MaxCursor is the pagination cursor to pass on the next call, and HasMore reports whether another page exists.
type Option ¶
type Option func(*Client)
Option configures a Client.
func WithBaseURL ¶
WithBaseURL overrides the TikTok web origin (useful for testing).
func WithHTTPClient ¶
WithHTTPClient sets the underlying http.Client.
func WithMSToken ¶
WithMSToken sets the msToken query param / cookie.
func WithSessionID ¶
WithSessionID sets the sessionid cookie for authenticated reads.
func WithUserAgent ¶
WithUserAgent overrides the User-Agent header.
type Video ¶
type Video struct {
ID string
Description string
Author string // unique_id / username
Permalink string // https://www.tiktok.com/@<author>/video/<id>
CoverURL string // thumbnail
PlayURL string // video URL (often expiring)
Likes int
Comments int
Plays int
CreateTime time.Time
}
Video is a single public TikTok video.
