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
Sessie aangemaakt
Een gebruiker maakt een game sessie aan binnen een server.
Spelers joinen
Spelers joinen de sessie via de mssgs client.
Game laadt
De client van elke speler laadt de web_url van jouw game met sessieparameters.
Webhooks worden verstuurd
Jouw backend ontvangt webhooks wanneer spelers joinen of vertrekken.
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:
{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
{
"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
{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
{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.
{callback_url}
{
"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
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:
- De
sessioneen bekende, actieve sessie is (ontvangen via een join webhook) - De
game_usergeregistreerd is via een join webhook voor die sessie - De
game_userniet 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
- Lees de ruwe request body (voordat JSON wordt geparsed)
- Bereken HMAC-SHA256 met jouw
webhook_secret - Vergelijk het resultaat met de
X-Mssgs-Signatureheader
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)
);
}
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.
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ 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