{"id":38203650,"url":"https://github.com/steampoweredtaco/gotiktoklive","last_synced_at":"2026-01-17T00:31:46.075Z","repository":{"id":256326514,"uuid":"854338037","full_name":"steampoweredtaco/gotiktoklive","owner":"steampoweredtaco","description":"A go port of TikTokLive connector","archived":false,"fork":false,"pushed_at":"2025-09-14T22:25:25.000Z","size":344,"stargazers_count":26,"open_issues_count":5,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-15T00:21:17.446Z","etag":null,"topics":["golang","library","tiktok"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/steampoweredtaco.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-09-09T01:37:44.000Z","updated_at":"2025-09-14T22:17:13.000Z","dependencies_parsed_at":"2024-09-14T16:59:01.591Z","dependency_job_id":"502b1a0f-115e-4509-8c7a-9818fa2e1877","html_url":"https://github.com/steampoweredtaco/gotiktoklive","commit_stats":null,"previous_names":["steampoweredtaco/gotiktoklive"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/steampoweredtaco/gotiktoklive","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steampoweredtaco%2Fgotiktoklive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steampoweredtaco%2Fgotiktoklive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steampoweredtaco%2Fgotiktoklive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steampoweredtaco%2Fgotiktoklive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/steampoweredtaco","download_url":"https://codeload.github.com/steampoweredtaco/gotiktoklive/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steampoweredtaco%2Fgotiktoklive/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28490163,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T23:55:29.509Z","status":"ssl_error","status_checked_at":"2026-01-16T23:55:29.108Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","library","tiktok"],"created_at":"2026-01-17T00:31:45.497Z","updated_at":"2026-01-17T00:31:46.054Z","avatar_url":"https://github.com/steampoweredtaco.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GoDoc](https://godoc.org/github.com/steampoweredtaco/gotiktoklive?status.svg)](https://godoc.org/github.com/steampoweredtaco/gotiktoklive) [![Go Report Card](https://goreportcard.com/badge/github.com/steampoweredtaco/gotiktoklive)](https://goreportcard.com/report/github.com/steampoweredtaco/gotiktoklive)\n\n# WARNING this fork of [Davincible's GotTikTokLive](https://github.com/Davincible/gotiktoklive) is in an alpha state at the moment\n\n# To add to project\n`go get github.com/steampoweredtaco/gotiktoklive`\n\n# Do not use any v1.0.7-8 tags\nThese tags are bogus and have been retracted and should not be grabbed via `go get` any longer. As of now v0 tags are the only valid tags.\n\n## Current Known working state of implementation\n- [x] Using the new signing server and endpoints and can provide API key and secret\n- [x] working live user and room id tracking\n- [x] updated protobuf version 3 messages and synced with python's types\n- [x] Websocket event system\n- [x] GetPriceList\n- [x] DownloadStream (18+ with id_session not verified)\n\n## Planned updates\n- [ ] Support many of the new event features over the last two years\n   * [ ] Pinned webchat messages, currently in alpha using ChatMessage event type, will move to a new type.\n   * [ ] Intro messages for live stream categories, these currently will be RoomEvents\n     * [x] WebcastLiveGameIntroMessage \n     * Others TBD.\n\n## Unknown state:\n- GetUserInfo\n- GetRoomInfo\n- NewFeed\n- Using session_id functionality\n\n# GoTikTokLive\n\nA 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](https://www.tiktok.com/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](#ChatEvent), other events such as [Members Joining](#UserEvent), [Gifts](#GiftEvent), [Viewers](#ViewersEvent), [Follows](#UserEvent), [Shares](#UserEvent), [Questions](#QuestionEvent), [Likes](#LikeEvent) and [Battles](#BattlesEvent) can be tracked.\n\nLooking for a Python implementation of this library? Check out [TikTok-Live-Connector](https://github.com/isaackogan/TikTok-Live-Connector) by [**@isaackogan**](https://github.com/isaackogan)\n\nLooking for a Node.js implementation of this library? Check out [TikTok-Livestream-Chat-Connector](https://github.com/zerodytrash/TikTok-Livestream-Chat-Connector) by [**@zerodytrash**](https://github.com/zerodytrash)\n\n**NOTE:** This is not an official API, and is no way affiliated to or sponsored by TikTok.\n\nGo rewrite of [zerodytrash/TikTok-Livestream-Chat-Connector](https://github.com/zerodytrash/TikTok-Livestream-Chat-Connector)\n\n#### Overview\n\n- [Getting started](#getting-started)\n- [Options](#options)\n- [Methods](#methods)\n- [Events](#events)\n- [Examples](#examples)\n- [Contributing](#contributing)\n\n## Getting started\n1. Install the package using the Go package manager\n```sh\ngo get github.com/steampoweredtaco/gotiktoklive\n```\n2. Create your first chat connection\n\n```go\n// Create TikTok Instance\ntiktok := gotiktoklive.NewTikTok()\n\n// Track a TikTok user by username\nlive, err := tiktok.TrackUser(\"promobot.robots\")\nif err != nil {\n    panic(err)\n}\n\n// Start downloading stream Make sure you have the ffmpeg binary installed, and present in\n// your path.\nif err := live.DownloadStream(); err != nil {\n    panic(err)\n}\n\n// Receive livestream events through the live.Events channel\nfor event := range live.Events {\n    switch e := event.(type) {\n\n    // You can specify what to do for specific events. All events are listed below.\n    case gotiktoklive.UserEvent:\n        fmt.Printf(\"%T : %s %s\\n\", e, e.Event, e.User.Username)\n\n    // List viewer count\n    case gotiktoklive.ViewersEvent:\n        fmt.Printf(\"%T : %d\\n\", e, e.Viewers)\n\n    // Specify the action for all remaining events\n    default:\n        fmt.Printf(\"%T : %+v\\n\", e, e)\n    }\n}\n```\n## Options\nOptions are used when creating a new TikTokLive instance and are used to modify the default behavior of the system in various ways.\n\n```go\n// SigningApiKey sets the singer API key.\nfunc SigningApiKey(apiKey string) TikTokLiveOption {}\n\n// SigningUrl defines the signer. The default is https://tiktok.eulerstream.com. Supports\n// any signer that supports the signing api as defined by\n// https://www.eulerstream.com/docs/openapi\nfunc (url string) TikTokLiveOption {}\n\n// DisableSigningLimitsValidation will disable querying the signer for limits and using\n// those as the reasonable limits for signing requests per second. Instead, this library\n// will be limited to signing only 5 signing requests per minute and may limit\n// functionality compared to the request limit the signer provides.\nfunc DisableSigningLimitsValidation(t *TikTok) {}\n\n// EnableExperimentalEvents enables experimental events that have not been figured out yet\n// and the API for them is not stable. It may also induce additional logging that might be\n// undesirable.\nfunc EnableExperimentalEvents(t *TikTok) {}\n\n// EnableExtraWebCastDebug an unreasonable amount of debug for library development and\n// troubleshooting. This option makes no guarantee of ever having the same output and is\n// only for development and triage purposes.\nfunc EnableExtraWebCastDebug(t *TikTok) {}\n\n// EnableWSTrace will put traces for all websocket messages into the given file. The file\n// will be overwritten so if you want multiple traces make sure handle giving a unique\n// filename each startup.\nfunc EnableWSTrace(file string) func(t *TikTok) {}\n```\n### Example Usage\n```go\n// Create TikTok instance, do not reconnect when tracking and use an API key for the\n// signer\ntiktok := gotiktoklive.NewTikTok(SigningApiKey(\"\u003csecretkey\u003e\"), DisableSigningLimitsValidation)\n\n```\n## Methods\n\n```go\n// TikTok allows you to track and discover current live streams.\ntype TikTok struct {\n\n\tDebug bool\n\n\t// LogRequests when set to true will log all made requests in JSON to debugHandler\n\tLogRequests bool\n}\n\n// NewTikTok creates a tiktok instance that allows you to track live streams\n//  and discover current livestreams.\nfunc NewTikTok() *TikTok {}\n\n// TrackUser will start to track the livestream of a user, if live.\n// To listen to events emitted by the livestream, such as comments and viewer\n//  count, listen to the Live.Events channel.\n// It will start a go routine and connect to the tiktok websocket.\nfunc (t *TikTok) TrackUser(username string) (*Live, error) {}\n\n// TrackRoom will start to track a room by room ID.\n// It will start a go routine and connect to the tiktok websocket.\nfunc (t *TikTok) TrackRoom(roomId string) (*Live, error) {}\n\n// GetUserInfo will fetch information about the user, such as follwers stats,\n//  their user ID, as well as the RoomID, with which you can tell if they are live.\nfunc (t *TikTok) GetUserInfo(user string) (*UserInfo, error) {}\n\n// GetRoomInfo will only fetch the room info, normally available with Live.Info\n//  but not start tracking a live stream.\nfunc (t *TikTok) GetRoomInfo(username string) (*RoomInfo, error) {}\n\n// GetPriceList fetches the price list of tiktok coins. Prices will be given in\n//  USD cents and the cents equivalent of the local currency of the IP location.\n// To fetch a different currency, use a VPN or proxy to change your IP to a\n//  different country.\nfunc (t *TikTok) GetPriceList() (*PriceList, error) {}\n\n// NewFeed creates a new Feed instance. Start fetching reccomended livestreams\n//  with Feed.Next().\nfunc (t *TikTok) NewFeed() *Feed {}\n\nfunc (t *TikTok) SetDebugHandler(f func(...interface{})) {}\n\nfunc (t *TikTok) SetErrorHandler(f func(error)) {}\n\nfunc (t *TikTok) SetInfoHandler(f func(...interface{})) {}\n\nfunc (t *TikTok) SetWarnHandler(f func(...interface{})) {}\n\n// SetProxy will set a proxy for both the http client as well as the websocket.\n// You can manually set a proxy with this method, or by using the HTTPS_PROXY\n//  environment variable.\n// ALL_PROXY can be used to set a proxy only for the websocket.\nfunc (t *TikTok) SetProxy(url string, insecure bool) error {}\n```\n\n## Events\n\n- [`RoomEvent`](#RoomEvent)\n- [`ChatEvent`](#ChatEvent)\n- [`UserEvent`](#UserEvent)\n- [`ViewersEvent`](#ViewersEvent)\n- [`GiftEvent`](#GiftEvent)\n- [`LikeEvent`](#LikeEvent)\n- [`QuestionEvent`](#QuestionEvent)\n- [`ControlEvent`](#ControlEvent)\n- [`MicBattleEvent`](#MicBattleEvent)\n- [`BattlesEvent`](#BattlesEvent)\n- [`RoomBannerEvent`](#RoomBannerEvent)\n- [`IntroEvent`](#IntroEvent)\n\n### RoomEvent\n\nRoom events are messages broadcast in the room. The most common event, is the\n`Type: SystemMessage` at broadcast the beginning a stream gets watched, saying \"Welcome to TikTok LIVE! Have fun interacting with others in real-time an\nd remember to follow our Community Guidelines.\"\n\n```go\ntype RoomEvent struct {\n\tType    string\n\tMessage string\n}\n```\n\n### ChatEvent\n\nChat events are broadcasted when a user posts a chat message, aka comment to a livestream.\n\n```go\ntype ChatEvent struct {\n\tComment   string\n\tUser      *User\n\tTimestamp int64\n}\n```\n\n### UserEvent\n\nUser events are used when a user either joins the stream, shares the stream, or \nfollows the host.\n\n```go\ntype UserEvent struct {\n\tEvent userEventType\n\tUser  *User\n}\n\ntype User struct {\n\tID              int64\n\tUsername        string\n\tNickname        string\n\tProfilePicture  *ProfilePicture\n\tExtraAttributes *ExtraAttributes\n\tBadge           *BadgeAttributes\n}\n\n// User Event Types\nconst (\n\tUSER_JOIN   userEventType = \"user joined the stream\"\n\tUSER_SHARE  userEventType = \"user shared the stream\"\n\tUSER_FOLLOW userEventType = \"user followed the host\"\n)\n```\n\n### ViewersEvent\n\nViewer events broadcast the current amount of users watching the livestream.\n\n```go\ntype ViewersEvent struct {\n\tViewers int\n}\n```\n\n### GiftEvent\n\nGift events are broadcast when a user buys a gift for the host.\nTo get more information about the gift, such as the price in coins,\nfind the gift by ID in the `live.GiftInfo.Gifts`.\n\nGift events with `GiftEvent.Type == 1` are streakable, meaning multiple gifts can \nbe sent in sequence, such as roses. For these sequences, multiple events are broadcast.\nUpon every subsequent gift in the streak, the `GiftEvent.RepeatCount` will increase by one.\nTo prevent the duplicate processing of streakable gifts, you should only process \n`if event.Type == 1 \u0026\u0026 event.RepeatEnd`, as this will be the final message of the streak, \nand includes the total number of gifts sent in the streak.\n\n```go\ntype GiftEvent struct {\n\tID          int\n\tName        string\n\tDescribe    string\n\tCost        int\n\tRepeatCount int\n\tRepeatEnd   bool\n\tType        int\n\tToUserID    int64\n\tTimestamp   int64\n\tUser        *User\n}\n\ntype User struct {\n\tID              int64\n\tUsername        string\n\tNickname        string\n\tProfilePicture  *ProfilePicture\n\tExtraAttributes *ExtraAttributes\n\tBadge           *BadgeAttributes\n}\n```\n\n### LikeEvent\n\nLike events are broadcast when a user likes the livestream. The event includes\nthe number of likes the user sent, as well as new total number of likes.\n\n```go\ntype LikeEvent struct {\n\tLikes       int\n\tTotalLikes  int\n\tUser        *User\n\tDisplayType string\n\tLabel       string\n}\n```\n\n### QuestionEvent\n\nQuestion events are emitted when a question has been posted by a user. It includes\nthe question text, and the user that posted the question.\n\n```go\ntype QuestionEvent struct {\n\tQuesion string\n\tUser    *User\n}\n```\n\n### ControlEvent\n\nControl events are used to broadcast the status of the livestream.\n\nAction values:\n\n- 3: live stream ended\n\n```go\ntype ControlEvent struct {\n\tAction int\n}\n```\n\n### MicBattleEvent\n\n```go\ntype MicBattleEvent struct {\n\tUsers []*User\n}\n```\n\n### BattlesEvent\n\n```go\ntype BattlesEvent struct {\n\tStatus  int\n\tBattles []*Battle\n}\n\ntype Battle struct {\n\tHost   int64\n\tGroups []*BattleGroup\n}\n\ntype BattleGroup struct {\n\tPoints int\n\tUsers  []*User\n}\n```\n\n### RoomBannerEvent\n\nRoom banner event contains the JSON data unmarshaled into an interface that was\npassed with the message.\n\n```go\ntype RoomBannerEvent struct {\n\tData interface{}\n}\n```\n\n### IntroEvent\n\nIntro events are broadcast upon connecting to a livestream.\n\n```go\ntype IntroEvent struct {\n\tID    int\n\tTitle string\n\tUser  *User\n}\n```\n\n## Examples\n\n### Fetching Recommended Live Streams\n\nWith a feed instance you can fetch a list of recommended livestreams, and directly\nstart tracking them with a single call.\n\n```go\ntiktok := NewTikTok()\nfeed := tiktok.NewFeed()\n\n// Fetch 5 pages of recommended streams, usually 6 are returned at a time\nfor i := 0; i \u003c 5; i++ {\n\tfeedItem, err := feed.Next()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfor _, stream := range feedItem.LiveStreams {\n\t\tfmt.Printf(\"%s : %d viewers\\n\", stream.Room.Owner.Nickname, stream.Room.UserCount)\n\t}\n\n\tif !feedItem.Extra.HasMore {\n\t\tbreak\n\t}\n}\n\nrecommendedStreams := feed.LiveStreams\n\n// Start tracking the first stream\nlive, err := recommendedStreams[0].Track()\nif err != nil {\n\tpanic(err)\n}\n\n// Process events\n...\n\n```\n\n### Error Handling\n\nGotiktoklive uses Go routines to fetch events using either websockets or HTTP polling.\nThese go routines need an error hander, that defaults to panic. You can overwrite this\nbehavior:\n\n```go\ntiktok.SetErrorHandler(func(err error) {\n    ...\n  })\n\n```\n\n## Contributing\n\nYour improvements are welcome! Feel free to open an \u003ca href=\"https://github.com/steampoweredtaco/gotiktoklive/issues\"\u003eissue\u003c/a\u003e or \u003ca href=\"https://github.com/steampoweredtaco/gotiktoklive/pulls\"\u003epull request\u003c/a\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteampoweredtaco%2Fgotiktoklive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsteampoweredtaco%2Fgotiktoklive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteampoweredtaco%2Fgotiktoklive/lists"}