Ga naar hoofdinhoud
Developer Guide

WebGame Connect

Bouw HTML mini games voor het mssgs platform

Overzicht

Mini games zijn webpagina's die binnen de mssgs client worden geladen via een iframe/webview. Het platform verzorgt al het sessiebeheer, speler tracking en lifecycle — jouw game hoeft alleen te reageren op webhooks en een web UI te renderen.

Hoe het werkt

Een gebruiker maakt een game sessie aan binnen een server, spelers joinen, en de client van elke speler laadt de URL van jouw game met sessieparameters. Jouw backend ontvangt webhooks wanneer spelers joinen of vertrekken.

Hoe het werkt

1

Sessie aangemaakt

Een gebruiker maakt een game sessie aan binnen een server.

2

Spelers joinen

Spelers joinen de sessie via de mssgs client.

3

Game laadt

De client van elke speler laadt de web_url van jouw game met sessieparameters.

4

Webhooks worden verstuurd

Jouw backend ontvangt webhooks wanneer spelers joinen of vertrekken.

5

Opruimen

Wanneer alle spelers vertrekken, wordt de sessie automatisch opgeruimd.

Game Registratie

Elke game wordt geregistreerd met de volgende velden:

Field Type Beschrijving
name string Weergavenaam van de game
icon_url string Game icoon URL
web_url string Basis URL van de game webpagina
max_players number Maximum aantal spelers toegestaan
min_players number Minimum aantal spelers vereist
webhook_join_url string Wordt aangeroepen wanneer een speler joint
webhook_leave_url string Wordt aangeroepen wanneer een speler vertrekt
webhook_secret string Geheime sleutel voor HMAC-SHA256 webhook signing

Web URL

Wanneer een speler een game sessie joint, laadt de mssgs client jouw web_url met query parameters:

URL Format
{web_url}?session={session_id}&game_user={game_user_id}
Parameter Type Beschrijving
session string Game sessie UUID — identificeert bij welke game sessie deze speler hoort
game_user string Unieke 8-karakter speler ID voor deze sessie

Belangrijk

De game_user is een opaque identifier. Het bevat geen persoonlijke informatie. Weergavenamen van spelers worden alleen naar jouw backend gestuurd via webhooks — stel ze nooit beschikbaar aan client-side game code tenzij jouw backend ze aanbiedt.

Webhooks

Jouw backend ontvangt POST requests met een JSON body van het mssgs platform wanneer spelers interacteren met de game sessie. Deze zijn fire-and-forget — mislukkingen hebben geen invloed op de game sessie.

Webhook Headers

Header Waarde
Content-Type application/json
User-Agent mssgs-webhook/1.0
X-Mssgs-Signature HMAC-SHA256 signature (alleen als webhook_secret is ingesteld)

Webhook JSON Body

Request Body
{
  "session": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "display_name": "CoolPlayer42",
  "game_user": "de875d3a",
  "game_guid": "f8a1b2c3-d4e5-6789-0abc-def123456789",
  "avatar_url": "https://example.com/avatar.png",
  "host": true,
  "callback_url": "https://mss.gs/api/v1/game-webhook/c9a1b2c3-d4e5-6789-0abc-def123456789"
}
Field Type Beschrijving
session string Game sessie UUID
display_name string Weergavenaam van de speler voor deze sessie
game_user string Unieke 8-karakter game user ID van de speler
game_guid string Unieke identifier van de geregistreerde game
avatar_url string Avatar URL van de speler (kan null zijn)
host boolean Alleen aanwezig wanneer de speler de sessie host is (true)
min_players number Min spelers voor sessie (alleen join webhook)
max_players number Max spelers voor sessie (alleen join webhook)
callback_url string URL om kanaal info updates naartoe te POSTen

Join Webhook

POST {webhook_join_url}

Wordt aangeroepen wanneer een speler de sessie joint. Het host veld is alleen aanwezig wanneer de joinende speler degene is die de sessie heeft aangemaakt. Gebruik dit om de game host te identificeren (bijv. voor het starten van de game, beheren van instellingen).

De min_players en max_players velden zijn opgenomen in join webhooks.

Leave Webhook

POST {webhook_leave_url}

Wordt aangeroepen wanneer een speler de sessie expliciet verlaat. Het host veld is alleen aanwezig wanneer de vertrekkende speler de sessie host is. Je wilt mogelijk host migratie afhandelen of de game beëindigen wanneer de host vertrekt.

Disconnects

Spelers worden niet automatisch verwijderd wanneer ze disconnecten (bijv. vernieuwen, achtergrond, verbindingsverlies). Ze blijven in de sessie en kunnen opnieuw joinen. Inactieve sessies worden na 1 uur automatisch opgeruimd.

Callback URL

Elke webhook bevat een callback_url — een token-geauthenticeerde URL waarmee je de game kanaal metadata kunt bijwerken die zichtbaar is voor alle serverleden.

POST {callback_url}
Request Body
{
  "description": "Round 3 — Waiting for answers...",
  "thumbnail": "data:image/png;base64,iVBORw0KGgo..."
}
Field Type Beschrijving
description string Korte tekst die onder het game kanaal wordt getoond
thumbnail string Base64-gecodeerde afbeelding (moet een data: URI zijn)

Beide velden zijn optioneel. De payload wordt samengevoegd met bestaande kanaaldata, zodat je alleen de beschrijving of alleen de thumbnail kunt bijwerken.

Responses

Status Body
200 OK { "success": true }
400 { "error": "THUMBNAIL_MUST_BE_BASE64" }
404 { "error": "SESSION_NOT_FOUND" }

Hoe het werkt

Jouw backend ontvangt een webhook en POSTt vervolgens naar de callback_url. Het mssgs platform broadcast een CHANNEL_UPDATE event naar alle serverleden, waardoor het game kanaal in real time wordt bijgewerkt. Het callback token verloopt wanneer de sessie eindigt.

Voorbeeld

Node.js
const thumbnailBase64 = 'data:image/png;base64,' + fs.readFileSync('thumbnail.png', 'base64');
await fetch(callbackUrl, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    description: `Round ${round} of ${totalRounds} — ${currentQuestion}`,
    thumbnail: thumbnailBase64
  })
});

Beveiliging

Gebruik game_user voor Speler Identiteit

De game_user ID is de enige speler identifier die naar de client-side game wordt gestuurd (via de web URL). Het is:

  • Uniek per speler per sessie
  • Een opaque 8-karakter string
  • Wordt niet hergebruikt tussen sessies

Weergavenamen van spelers worden alleen naar jouw backend gestuurd via webhooks, nooit naar de client-side game. Dit voorkomt dat spelers identiteiten kunnen vervalsen en houdt persoonlijke informatie uit de browser.

Valideer session en game_user op je Backend

De webpagina van jouw game stuurt session en game_user naar jouw backend (bijv. via WebSocket of API calls). Valideer altijd dat:

  1. De session een bekende, actieve sessie is (ontvangen via een join webhook)
  2. De game_user geregistreerd is via een join webhook voor die sessie
  3. De game_user niet al vertrokken is (ontvangen via een leave webhook)

Webhook Signature Verificatie

Als webhook_secret is geconfigureerd, bevat elke webhook een X-Mssgs-Signature header met een HMAC-SHA256 signature van de request body.

Het signature formaat is: sha256={hex_signature}

Verificatiestappen

  1. Lees de ruwe request body (voordat JSON wordt geparsed)
  2. Bereken HMAC-SHA256 met jouw webhook_secret
  3. Vergelijk het resultaat met de X-Mssgs-Signature header
Node.js
const crypto = require('crypto');

function verifyWebhook(req, webhookSecret) {
  const signature = req.headers['x-mssgs-signature'];
  if (!signature) return false;

  const expectedSig = 'sha256=' + crypto
    .createHmac('sha256', webhookSecret)
    .update(req.rawBody)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSig)
  );
}
Python
import hmac
import hashlib

def verify_webhook(raw_body: bytes, signature: str, webhook_secret: str) -> bool:
    expected = 'sha256=' + hmac.new(
        webhook_secret.encode(),
        raw_body,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

Constant-time vergelijking

Gebruik altijd constant-time vergelijkingsfuncties (crypto.timingSafeEqual in Node.js, hmac.compare_digest in Python) om timing attacks te voorkomen.

Game Lifecycle

Event Wat er gebeurt
Sessie aangemaakt Een game kanaal verschijnt in de server
Speler joint Join webhook wordt verstuurd, spelerslijst wordt bijgewerkt in kanaal
Speler vertrekt Leave webhook wordt verstuurd, spelerslijst wordt bijgewerkt
Alle spelers vertrekken Sessie wordt verwijderd, game kanaal wordt verwijderd
1 uur inactiviteit Sessie wordt automatisch opgeruimd

Architectuur

Jouw backend beheert de game state. Het mssgs platform verzorgt alleen de sessie lifecycle en speler tracking — alle game logica draait aan jouw kant.

Architectuur Overzicht
┌─────────────────┐     ┌──────────────────┐     ┌─────────────────┐
│  mssgs Client   │     │  mssgs Gateway   │     │  Jouw Backend   │
│ (laadt iframe)  │     │  (orchestrator)  │     │  (game logica)  │
└────────┬────────┘     └────────┬─────────┘     └────────┬────────┘
         │                       │                         │
         │  Speler joint sessie  │                         │
         │──────────────────────>│                         │
         │                       │  POST webhook_join_url  │
         │                       │────────────────────────>│
         │                       │                         │ Speler opslaan
         │  Laad web_url?session=&game_user=               │
         │<──────────────────────│                         │
         │                       │                         │
         │  Verbind met je backend met session+game_user   │
         │────────────────────────────────────────────────>│
         │                       │                         │ Valideer
         │                       │                         │ game_user
         │  Game data (via je eigen WebSocket/API)         │
         │<────────────────────────────────────────────────│
         │                       │                         │

Best Practices

Vertrouw de client niet

Valideer session en game_user op jouw backend tegen webhook data.

Ga netjes om met disconnects

Spelers kunnen onverwacht vertrekken. Handel de leave webhook altijd netjes af en houd rekening met reconnectie scenario's.

Host detectie

Gebruik het host: true webhook veld om te identificeren wie de game bestuurt (bijv. voor het starten van rondes, beheren van instellingen).

Stateless webpagina

Jouw game pagina moet puur initialiseren vanuit URL params. Vertrouw niet op cookies of local storage voor sessie-identiteit.

Responsive design

Games worden geladen in een webview. Zorg ervoor dat je UI werkt op zowel mobiel als desktop.

Vragen?

We helpen je graag verder met je game integratie.

developers@mss.gs