Skip to main content

JavaScript integration example

The following class provides a complete, production-ready WebSocket client for consuming Tuniform Stream Alerts events.
TuniformAlerts.js
class TuniformAlerts {
    constructor(token) {
        this.token = token;
        this.url = "wss://stream-alerts.tuniform.tn/ws?token=" + token;
        this.socket = null;
    }

    connect() {
        this.socket = new WebSocket(this.url);

        this.socket.onopen = () => {
            console.log("Connected to Tuniform Stream Alerts");
        };

        this.socket.onmessage = (event) => {
            try {
                const data = JSON.parse(event.data);

                // First message is always the handshake confirmation
                if (data.type === "CONNECTED") {
                    console.log("Authenticated as user:", data.user_id);
                    console.log("Kick username:", data.kick_username);
                    return;
                }

                // All subsequent messages are event payloads
                this.handleEvent(data);
            } catch (e) {
                console.error("Error parsing message:", e);
            }
        };

        this.socket.onclose = () => {
            console.log("Disconnected. Reconnecting in 5s...");
            setTimeout(() => this.connect(), 5000);
        };

        this.socket.onerror = (err) => {
            console.error("WebSocket Error:", err);
        };
    }

    handleEvent(data) {
        switch (data.type) {
            case "donation":
                console.log(`💰 Donation: ${data.amount} ${data.currency} from ${data.sender_username}`);
                console.log(`💬 Message: ${data.message}`);
                if (data.have_tts) {
                    console.log(`🔊 TTS Audio: ${data.tts_url}`);
                    // Play the TTS audio file
                }
                if (data.have_voice_message) {
                    console.log(`🎤 Voice Message: ${data.voice_message}`);
                    // Play the voice message audio file
                }
                break;

            case "subscription":
                console.log(`⭐ Subscription: ${data.sender_username}${data.tier}`);
                console.log(`🔁 Streak: ${data.streak} | Period: ${data.period}`);
                break;

            default:
                console.log(`Unknown event type: ${data.type}`, data);
        }
    }
}

// Usage
const alerts = new TuniformAlerts("YOUR_STREAM_TOKEN_HERE");
alerts.connect();

Usage

const alerts = new TuniformAlerts("a1b2c3d4e5f6...64_char_hex_token");
alerts.connect();
Replace YOUR_STREAM_TOKEN_HERE with the creator’s actual 64-character hex stream token. Each creator has a unique token available in their Stream Alerts dashboard.

Best practices

Follow these guidelines to build a robust, production-ready integration:
The first message after connection is always {"type":"CONNECTED",...}. Process it separately from event payloads to correctly initialize your session state.
if (data.type === "CONNECTED") {
    console.log("Authenticated as user:", data.user_id);
    return; // Don't process as an event
}
Networks are unstable. Implement automatic reconnection with a 3–5 second delay on disconnect.
this.socket.onclose = () => {
    setTimeout(() => this.connect(), 5000);
};
New event types may be added in the future (e.g., follow, raid, host). Your integration should log or ignore events with a type it doesn’t recognize, rather than crashing.
default:
    console.log(`Unknown event type: ${data.type}`, data);
Always check have_tts before using tts_url, and have_voice_message before using voice_message. The URL fields may be empty strings.
if (data.have_tts) {
    playAudio(data.tts_url);
}
if (data.have_voice_message) {
    playAudio(data.voice_message);
}
While rare, duplicate messages can theoretically occur. Use the timestamp field or a client-side deduplication mechanism if you need strictly unique events.
The server sends Ping frames at regular intervals. Standard WebSocket clients (browser WebSocket API, libraries like ws) handle this transparently — no action needed on your side.
  • TTS audio files are always MP3.
  • Voice messages can be MP3, WebM, OGG, or other browser-compatible formats.
Ensure your audio player supports these formats for full compatibility.

Audio playback reference

SourceFormatFieldCheck
Text-to-SpeechMP3tts_urlhave_tts === true
Voice MessageMP3, WebM, OGGvoice_messagehave_voice_message === true

Quick reference

WebSocket connection

Authentication and connection details.

Event payloads

Full JSON schemas for all event types.

Platform overview

Understand Tuniform’s features and context.

Support

Contact the Tuniform team for integration help.