TikTok Live client in POSIX sh. Decodes chat, gifts, likes, joins, follows, shares, and viewer counts in real-time. Hand-rolled WebSocket framing and protobuf decoding with nothing but shell builtins and openssl.
$ ./tiktok-live.sh zooich
[*] fetching ttwid...
[*] resolving room for zooich...
[*] connected to zooich (room 7352941680123)
[chat] Maria (@maria_xyz): hello from Romania!
[gift] Alex (@alex99) sent Rose x5 (1 diamonds)
[like] João (@jp_live) (4821 total)
[join] Sofia (@sofia_abc)
[follow] Dan (@dan_ro)
bpkg install PirateTok/live-shOr manually:
cp lib/piratetok.sh /usr/local/lib/piratetok/piratetok.sh
cp tiktok-live.sh /usr/local/bin/tiktok-live
chmod +x /usr/local/bin/tiktok-live| Language | Install | Repo |
|---|---|---|
| Rust | cargo add piratetok-live-rs |
live-rs |
| Go | go get github.com/PirateTok/live-go |
live-go |
| Python | pip install piratetok-live-py |
live-py |
| JavaScript | npm install piratetok-live-js |
live-js |
| C# | dotnet add package PirateTok.Live |
live-cs |
| Java | com.piratetok:live |
live-java |
| Lua | luarocks install piratetok-live-lua |
live-lua |
| Elixir | {:piratetok_live, "~> 0.1"} |
live-ex |
| Dart | dart pub add piratetok_live |
live-dart |
| C | #include "piratetok.h" |
live-c |
| PowerShell | Install-Module PirateTok.Live |
live-ps1 |
sh and openssl. That's it.
Runs on any Linux install from this century. Alpine, Debian, Arch, Ubuntu, a Raspberry Pi, your router running OpenWrt. If it has a shell and TLS, it can watch TikTok Live.
lib/piratetok.sh is a sourceable library. Define event handlers, then call pt_connect:
#!/bin/sh
. /usr/local/lib/piratetok/piratetok.sh
on_chat() { echo "CHAT: $1 said $2"; }
on_gift() { echo "GIFT: $1 sent $2 x$3 ($4 diamonds)"; }
on_like() { echo "LIKE: $1 ($2 total)"; }
on_join() { echo "JOIN: $1"; }
on_follow() { echo "FOLLOW: $1"; }
on_share() { echo "SHARE: $1"; }
on_ended() { echo "STREAM ENDED"; }
pt_connect "username_here"For reconnection loops or custom flows:
. /path/to/piratetok.sh
PT_UA=$(pt_random_ua)
pt_fetch_ttwid # sets PT_TTWID
pt_resolve_room "user" # sets PT_ROOM_ID, PT_ROOM_RESP
pt_wss_open # opens WSS on fds 3/4, starts heartbeat
pt_read_loop # blocking — calls event handlers until disconnect
pt_wss_close # cleanupresult=$(pt_check_online "username_here")
case "$result" in
LIVE:*) echo "live, room ${result#LIVE:}" ;;
OFF) echo "offline" ;;
404) echo "not found" ;;
esacOverride before calling pt_*:
PT_CDN="webcast-ws.eu.tiktok.com" # EU / US / Global (default)
PT_HEARTBEAT_SEC=10 # heartbeat interval
PT_UA="custom UA string" # override random UA pool| Handler | Arguments | Event |
|---|---|---|
on_chat |
USER CONTENT | Chat message |
on_gift |
USER GIFT_NAME REPEAT DIAMONDS | Gift sent |
on_like |
USER TOTAL | Likes |
on_join |
USER | Room join |
on_follow |
USER | Follow |
on_share |
USER | Share |
on_viewers |
COUNT | Viewer count update |
on_ended |
— | Stream ended |
on_status |
MESSAGE | Status update |
on_error |
MESSAGE | Fatal error |
- Authenticates and opens a direct WSS connection via
openssl s_client - Resolves username to room ID via TikTok JSON API (raw HTTP)
- Hand-crafts WebSocket upgrade request with
printf - Builds WebSocket frames — masking, length encoding, the whole RFC 6455 spec
- Decodes protobuf varints and length-delimited fields with shell arithmetic
- Decompresses gzip payloads with
gzip -dc - Sends protobuf heartbeats every 10 seconds to keep the connection alive
- Handles
needs_ackresponses so TikTok doesn't drop us
No curl. No wget. No websocat. No Python. No Node. No external binary except openssl for TLS.
No bashisms. No /dev/tcp. No [[ ]]. No arrays. No local. Tested with dash and busybox sh.
The entire WebSocket protocol and protobuf wire format are implemented in:
dd— read exact byte countsod— binary to hexprintf— hex to binarycut/sed/tr— string manipulation$(( ))— arithmetic (varint decoding)mkfifo— bidirectional pipe to opensslgzip -dc— payload decompression
- Zero signing dependency — no API keys, no signing server, no external auth
- Sourceable library —
lib/piratetok.shfor building your own tools - UA rotation — 6 user agents (3 Firefox, 3 Chrome, mixed OS)
- System timezone — auto-detected from env/filesystem, falls back to UTC
- 7 event types — chat, gift, like, join, follow, share, viewer count
- Sub-routed convenience events — follow/share from SocialMessage, join from MemberMessage
- POSIX sh — runs on dash, busybox sh, any POSIX-compliant shell
0BSD
