> ## Documentation Index
> Fetch the complete documentation index at: https://sparkggdocs.internal.tuniform.tn/llms.txt
> Use this file to discover all available pages before exploring further.

# Integration guide

> Complete code examples and best practices for building a production-ready integration with Tuniform Stream Alerts.

## JavaScript integration example

The following class provides a complete, production-ready WebSocket client for consuming Tuniform Stream Alerts events.

```javascript TuniformAlerts.js theme={null}
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

```javascript theme={null}
const alerts = new TuniformAlerts("a1b2c3d4e5f6...64_char_hex_token");
alerts.connect();
```

<Note>
  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.
</Note>

***

## Best practices

Follow these guidelines to build a robust, production-ready integration:

<AccordionGroup>
  <Accordion title="1. Handle the handshake first" icon="handshake">
    The first message after connection is always `{"type":"CONNECTED",...}`. Process it separately from event payloads to correctly initialize your session state.

    ```javascript theme={null}
    if (data.type === "CONNECTED") {
        console.log("Authenticated as user:", data.user_id);
        return; // Don't process as an event
    }
    ```
  </Accordion>

  <Accordion title="2. Always auto-reconnect" icon="rotate">
    Networks are unstable. Implement automatic reconnection with a **3–5 second delay** on disconnect.

    ```javascript theme={null}
    this.socket.onclose = () => {
        setTimeout(() => this.connect(), 5000);
    };
    ```
  </Accordion>

  <Accordion title="3. Handle unknown event types" icon="circle-question">
    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.

    ```javascript theme={null}
    default:
        console.log(`Unknown event type: ${data.type}`, data);
    ```
  </Accordion>

  <Accordion title="4. Check boolean flags before using URLs" icon="toggle-on">
    Always check `have_tts` before using `tts_url`, and `have_voice_message` before using `voice_message`. The URL fields may be **empty strings**.

    ```javascript theme={null}
    if (data.have_tts) {
        playAudio(data.tts_url);
    }
    if (data.have_voice_message) {
        playAudio(data.voice_message);
    }
    ```
  </Accordion>

  <Accordion title="5. Implement idempotency" icon="clone">
    While rare, duplicate messages can theoretically occur. Use the `timestamp` field or a client-side deduplication mechanism if you need strictly unique events.
  </Accordion>

  <Accordion title="6. Keep-alive is automatic" icon="heart-pulse">
    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.
  </Accordion>

  <Accordion title="7. Support multiple audio formats" icon="volume-high">
    * **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.
  </Accordion>
</AccordionGroup>

***

## Audio playback reference

| Source         | Format         | Field           | Check                         |
| -------------- | -------------- | --------------- | ----------------------------- |
| Text-to-Speech | MP3            | `tts_url`       | `have_tts === true`           |
| Voice Message  | MP3, WebM, OGG | `voice_message` | `have_voice_message === true` |

***

## Quick reference

<CardGroup cols={2}>
  <Card title="WebSocket connection" icon="plug" href="/sparkgg/websocket">
    Authentication and connection details.
  </Card>

  <Card title="Event payloads" icon="code" href="/sparkgg/events">
    Full JSON schemas for all event types.
  </Card>

  <Card title="Platform overview" icon="circle-info" href="/sparkgg/overview">
    Understand Tuniform's features and context.
  </Card>

  <Card title="Support" icon="envelope" href="mailto:support@tuniform.tn">
    Contact the Tuniform team for integration help.
  </Card>
</CardGroup>
