A clean-room TeamSpeak client protocol library written in pure Go.
Compatible with TeamSpeak 3, 5 & 6. No proprietary SDK. No copy-pasted code.
- Full protocol handshake — ECDH key exchange, RSA puzzle, EAX-encrypted transport
- Command & notification system — Send commands, receive server events
- Event-driven API — Register handlers for text messages, client enter/leave, channel moves, kicks, etc.
- Voice data — Send Opus voice packets (codec 4 & 5)
- File transfers — Upload, download, and delete files on the server
- Address resolution — SRV records, TSDNS, and direct address support
- Middleware — Pluggable command and event middleware chains
- Built-in rate limiter — Token-bucket throttling to prevent server-side flood kicks
- Identity management — Generate, import/export, and upgrade security level of identities
- Zero CGO — Pure Go, cross-compile anywhere
go get github.com/honeybbq/teamspeak-goRequires Go 1.26 or later.
package main
import (
"context"
"fmt"
"log"
"os"
"os/signal"
"time"
teamspeak "github.com/honeybbq/teamspeak-go"
"github.com/honeybbq/teamspeak-go/crypto"
)
func main() {
// Generate a new identity (or load an existing one)
identity, err := crypto.GenerateIdentity(8)
if err != nil {
log.Fatal(err)
}
// Create the client
client := teamspeak.NewClient(
identity,
"localhost",
"GoBot",
teamspeak.WithServerPassword(os.Getenv("TEAMSPEAK_SERVER_PASSWORD")),
teamspeak.WithDefaultChannel("Lobby"),
teamspeak.WithDefaultChannelPassword(os.Getenv("TEAMSPEAK_DEFAULT_CHANNEL_PASSWORD")),
)
// Register event handlers
client.OnConnected(func() {
fmt.Println("Connected to server!")
})
client.OnTextMessage(func(msg teamspeak.TextMessage) {
fmt.Printf("[%s]: %s\n", msg.InvokerName, msg.Message)
})
client.OnDisconnected(func(err error) {
fmt.Println("Disconnected:", err)
})
// Connect
if err := client.Connect(); err != nil {
log.Fatal(err)
}
// Wait until connected
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
if err := client.WaitConnected(ctx); err != nil {
log.Fatal(err)
}
// Wait for interrupt signal
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt)
<-sig
client.Disconnect()
}| Method | Description |
|---|---|
NewClient(identity, addr, nickname, ...opts) |
Create a new client |
Connect() |
Initiate connection to the server |
WaitConnected(ctx) |
Block until the handshake completes |
Disconnect() |
Gracefully disconnect |
| Method | Description |
|---|---|
OnConnected(func()) |
Fires when fully connected |
OnDisconnected(func(error)) |
Fires on disconnect |
OnTextMessage(func(TextMessage)) |
Fires on text messages |
OnClientEnter(func(ClientInfo)) |
Fires when a client joins |
OnClientLeave(func(ClientLeftViewEvent)) |
Fires when a client leaves |
OnClientMoved(func(ClientMovedEvent)) |
Fires when a client moves channels |
OnKicked(func(string)) |
Fires when the bot is kicked |
| Method | Description |
|---|---|
SendTextMessage(targetMode, targetID, msg) |
Send a text message |
ClientMove(clid, channelID, password) |
Move a client to a channel |
Poke(clid, message) |
Poke a client |
SendVoice(data, codec) |
Send Opus voice data |
ListChannels() |
List all channels |
ListClients() |
List all connected clients |
GetClientInfo(clid) |
Get detailed client information |
ExecCommand(cmd, timeout) |
Execute a raw command |
ExecCommandWithResponse(cmd, timeout) |
Execute a command and return response data |
| Method | Description |
|---|---|
FileTransferInitUpload(...) |
Initialize a file upload |
FileTransferInitDownload(...) |
Initialize a file download |
FileTransferDeleteFile(...) |
Delete files on the server |
UploadFileData(host, info, reader) |
Transfer file data to the server |
DownloadFileData(host, info, writer) |
Receive file data from the server |
// Generate a new identity with security level 8
identity, err := crypto.GenerateIdentity(8)
// Export to string for persistent storage
exported := identity.String()
// Import from a previously exported string
identity, err = crypto.IdentityFromString(exported)
// Upgrade security level (CPU-intensive)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
err = identity.UpgradeToLevel(10, ctx)client := teamspeak.NewClient(identity, "ts.example.com", "Bot",
teamspeak.WithLogger(slog.Default()),
teamspeak.WithResolver(customResolver),
teamspeak.WithCommandMiddleware(loggingMiddleware),
teamspeak.WithEventMiddleware(filterMiddleware),
teamspeak.WithServerPassword(os.Getenv("TEAMSPEAK_SERVER_PASSWORD")),
teamspeak.WithDefaultChannel("Lobby"),
teamspeak.WithDefaultChannelPassword(os.Getenv("TEAMSPEAK_DEFAULT_CHANNEL_PASSWORD")),
)Connection auth options:
WithServerPassword(password)accepts the plain-text server password and sends the TeamSpeak protocol hash duringclientinitWithDefaultChannel(channel)requests a default channel duringclientinitWithDefaultChannelPassword(password)accepts the plain-text channel password and sends the TeamSpeak protocol hash for the configured default channel
teamspeak-go/
├── client.go # Client lifecycle, connection management
├── api.go # High-level API (messages, channels, clients)
├── commands.go # Command sending and response tracking
├── events.go # Event handler registration and middleware
├── notifications.go # Server notification parsing and dispatch
├── handshake.go # Protocol handshake orchestration
├── transfer.go # File transfer operations
├── crypto/ # ECDH, EAX encryption, identity management
├── handshake/ # Crypto handshake and license verification
├── transport/ # UDP packet framing, ACK, compression
├── commands/ # Command builder and parser
└── discovery/ # SRV / TSDNS / direct address resolution
Protocol knowledge was primarily informed by the TSLib implementation in TS3AudioBot by Splamy. Huge thanks to the TS3AudioBot project and its contributors.
TeamSpeak is a registered trademark of TeamSpeak Systems GmbH. This project is not affiliated with, endorsed by, or associated with TeamSpeak Systems GmbH in any way.
This library is a clean-room implementation developed from publicly available documentation, protocol analysis of network traffic, and independent research. No proprietary TeamSpeak SDK code, headers, or libraries were used in its creation.