WARNING this fork of Davincible's GotTikTokLive is in an alpha state at the moment
- Using the new signing server and endpoints and can provide API key and secret
- working live user and room id tracking
- updated protobuf version 3 messages and synced with python's types
- Websocket event system
- GetPriceList
- DownloadStream (18+ with id_session not verified)
- Support many of the new event features over the last two years
- Pinned webchat messages, currently in alpha using ChatMessage event type, will move to a new type.
- Intro messages for live stream categories, these currently will be RoomEvents
- WebcastLiveGameIntroMessage
- Others TBD.
- GetUserInfo
- GetRoomInfo
- NewFeed
- Using session_id functionality
A Go module to download livestreams and discover, receive and decode livestreams and the livestream events such as comments and gifts in realtime from TikTok LIVE by connecting to TikTok's internal WebCast push service. The package includes a wrapper that connects to the WebCast service using just the username (uniqueId
). This allows you to connect to your own live chat as well as the live chat of other streamers. No credentials are required. Besides Chat Comments, other events such as Members Joining, Gifts, Viewers, Follows, Shares, Questions, Likes and Battles can be tracked.
Looking for a Python implementation of this library? Check out TikTok-Live-Connector by @isaackogan
Looking for a Node.js implementation of this library? Check out TikTok-Livestream-Chat-Connector by @zerodytrash
NOTE: This is not an official API, and is no way affiliated to or sponsored by TikTok.
Go rewrite of zerodytrash/TikTok-Livestream-Chat-Connector
- Install the package using the Go package manager
go get github.com/steampoweredtaco/gotiktoklive
- Create your first chat connection
// Create TikTok Instance
tiktok := gotiktoklive.NewTikTok()
// Track a TikTok user by username
live, err := tiktok.TrackUser("promobot.robots")
if err != nil {
panic(err)
}
// Start downloading stream Make sure you have the ffmpeg binary installed, and present in
// your path.
if err := live.DownloadStream(); err != nil {
panic(err)
}
// Receive livestream events through the live.Events channel
for event := range live.Events {
switch e := event.(type) {
// You can specify what to do for specific events. All events are listed below.
case gotiktoklive.UserEvent:
fmt.Printf("%T : %s %s\n", e, e.Event, e.User.Username)
// List viewer count
case gotiktoklive.ViewersEvent:
fmt.Printf("%T : %d\n", e, e.Viewers)
// Specify the action for all remaining events
default:
fmt.Printf("%T : %+v\n", e, e)
}
}
Options are used when creating a new TikTokLive instance and are used to modify the default behavior of the system in various ways.
// SigningApiKey sets the singer API key.
func SigningApiKey(apiKey string) TikTokLiveOption {}
// SigningUrl defines the signer. The default is https://tiktok.eulerstream.com. Supports
// any signer that supports the signing api as defined by
// https://www.eulerstream.com/docs/openapi
func (url string) TikTokLiveOption {}
// DisableSigningLimitsValidation will disable querying the signer for limits and using
// those as the reasonable limits for signing requests per second. Instead, this library
// will be limited to signing only 5 signing requests per minute and may limit
// functionality compared to the request limit the signer provides.
func DisableSigningLimitsValidation(t *TikTok) {}
// EnableExperimentalEvents enables experimental events that have not been figured out yet
// and the API for them is not stable. It may also induce additional logging that might be
// undesirable.
func EnableExperimentalEvents(t *TikTok) {}
// EnableExtraWebCastDebug an unreasonable amount of debug for library development and
// troubleshooting. This option makes no guarantee of ever having the same output and is
// only for development and triage purposes.
func EnableExtraWebCastDebug(t *TikTok) {}
// EnableWSTrace will put traces for all websocket messages into the given file. The file
// will be overwritten so if you want multiple traces make sure handle giving a unique
// filename each startup.
func EnableWSTrace(file string) func(t *TikTok) {}
// Create TikTok instance, do not reconnect when tracking and use an API key for the
// signer
tiktok := gotiktoklive.NewTikTok(SigningApiKey("<secretkey>"), DisableSigningLimitsValidation)
// TikTok allows you to track and discover current live streams.
type TikTok struct {
Debug bool
// LogRequests when set to true will log all made requests in JSON to debugHandler
LogRequests bool
}
// NewTikTok creates a tiktok instance that allows you to track live streams
// and discover current livestreams.
func NewTikTok() *TikTok {}
// TrackUser will start to track the livestream of a user, if live.
// To listen to events emitted by the livestream, such as comments and viewer
// count, listen to the Live.Events channel.
// It will start a go routine and connect to the tiktok websocket.
func (t *TikTok) TrackUser(username string) (*Live, error) {}
// TrackRoom will start to track a room by room ID.
// It will start a go routine and connect to the tiktok websocket.
func (t *TikTok) TrackRoom(roomId string) (*Live, error) {}
// GetUserInfo will fetch information about the user, such as follwers stats,
// their user ID, as well as the RoomID, with which you can tell if they are live.
func (t *TikTok) GetUserInfo(user string) (*UserInfo, error) {}
// GetRoomInfo will only fetch the room info, normally available with Live.Info
// but not start tracking a live stream.
func (t *TikTok) GetRoomInfo(username string) (*RoomInfo, error) {}
// GetPriceList fetches the price list of tiktok coins. Prices will be given in
// USD cents and the cents equivalent of the local currency of the IP location.
// To fetch a different currency, use a VPN or proxy to change your IP to a
// different country.
func (t *TikTok) GetPriceList() (*PriceList, error) {}
// NewFeed creates a new Feed instance. Start fetching reccomended livestreams
// with Feed.Next().
func (t *TikTok) NewFeed() *Feed {}
func (t *TikTok) SetDebugHandler(f func(...interface{})) {}
func (t *TikTok) SetErrorHandler(f func(error)) {}
func (t *TikTok) SetInfoHandler(f func(...interface{})) {}
func (t *TikTok) SetWarnHandler(f func(...interface{})) {}
// SetProxy will set a proxy for both the http client as well as the websocket.
// You can manually set a proxy with this method, or by using the HTTPS_PROXY
// environment variable.
// ALL_PROXY can be used to set a proxy only for the websocket.
func (t *TikTok) SetProxy(url string, insecure bool) error {}
RoomEvent
ChatEvent
UserEvent
ViewersEvent
GiftEvent
LikeEvent
QuestionEvent
ControlEvent
MicBattleEvent
BattlesEvent
RoomBannerEvent
IntroEvent
Room events are messages broadcast in the room. The most common event, is the
Type: SystemMessage
at broadcast the beginning a stream gets watched, saying "Welcome to TikTok LIVE! Have fun interacting with others in real-time an
d remember to follow our Community Guidelines."
type RoomEvent struct {
Type string
Message string
}
Chat events are broadcasted when a user posts a chat message, aka comment to a livestream.
type ChatEvent struct {
Comment string
User *User
Timestamp int64
}
User events are used when a user either joins the stream, shares the stream, or follows the host.
type UserEvent struct {
Event userEventType
User *User
}
type User struct {
ID int64
Username string
Nickname string
ProfilePicture *ProfilePicture
ExtraAttributes *ExtraAttributes
Badge *BadgeAttributes
}
// User Event Types
const (
USER_JOIN userEventType = "user joined the stream"
USER_SHARE userEventType = "user shared the stream"
USER_FOLLOW userEventType = "user followed the host"
)
Viewer events broadcast the current amount of users watching the livestream.
type ViewersEvent struct {
Viewers int
}
Gift events are broadcast when a user buys a gift for the host.
To get more information about the gift, such as the price in coins,
find the gift by ID in the live.GiftInfo.Gifts
.
Gift events with GiftEvent.Type == 1
are streakable, meaning multiple gifts can
be sent in sequence, such as roses. For these sequences, multiple events are broadcast.
Upon every subsequent gift in the streak, the GiftEvent.RepeatCount
will increase by one.
To prevent the duplicate processing of streakable gifts, you should only process
if event.Type == 1 && event.RepeatEnd
, as this will be the final message of the streak,
and includes the total number of gifts sent in the streak.
type GiftEvent struct {
ID int
Name string
Describe string
Cost int
RepeatCount int
RepeatEnd bool
Type int
ToUserID int64
Timestamp int64
User *User
}
type User struct {
ID int64
Username string
Nickname string
ProfilePicture *ProfilePicture
ExtraAttributes *ExtraAttributes
Badge *BadgeAttributes
}
Like events are broadcast when a user likes the livestream. The event includes the number of likes the user sent, as well as new total number of likes.
type LikeEvent struct {
Likes int
TotalLikes int
User *User
DisplayType string
Label string
}
Question events are emitted when a question has been posted by a user. It includes the question text, and the user that posted the question.
type QuestionEvent struct {
Quesion string
User *User
}
Control events are used to broadcast the status of the livestream.
Action values:
- 3: live stream ended
type ControlEvent struct {
Action int
}
type MicBattleEvent struct {
Users []*User
}
type BattlesEvent struct {
Status int
Battles []*Battle
}
type Battle struct {
Host int64
Groups []*BattleGroup
}
type BattleGroup struct {
Points int
Users []*User
}
Room banner event contains the JSON data unmarshaled into an interface that was passed with the message.
type RoomBannerEvent struct {
Data interface{}
}
Intro events are broadcast upon connecting to a livestream.
type IntroEvent struct {
ID int
Title string
User *User
}
With a feed instance you can fetch a list of recommended livestreams, and directly start tracking them with a single call.
tiktok := NewTikTok()
feed := tiktok.NewFeed()
// Fetch 5 pages of recommended streams, usually 6 are returned at a time
for i := 0; i < 5; i++ {
feedItem, err := feed.Next()
if err != nil {
panic(err)
}
for _, stream := range feedItem.LiveStreams {
fmt.Printf("%s : %d viewers\n", stream.Room.Owner.Nickname, stream.Room.UserCount)
}
if !feedItem.Extra.HasMore {
break
}
}
recommendedStreams := feed.LiveStreams
// Start tracking the first stream
live, err := recommendedStreams[0].Track()
if err != nil {
panic(err)
}
// Process events
...
Gotiktoklive uses Go routines to fetch events using either websockets or HTTP polling. These go routines need an error hander, that defaults to panic. You can overwrite this behavior:
tiktok.SetErrorHandler(func(err error) {
...
})
Your improvements are welcome! Feel free to open an issue or pull request.