Dokumentation
0.1.4 - Genereret torsdag den 19. marts 2026Kontakt
Har du spørgsmål, fundet en fejl eller idéer til forbedringer? Så er du meget velkommen til at kontakte os:
+45 53 64 09 34
anders@immer.co
Terminologi
- container/container-element
- DOM-elementet det enkelte spil "lever" i.
- Klient
- Konteksten, spillet bliver indlejret i — dette kan f.eks. været et website eller mobil-applikation.
- Indgående handlinger
- Handlinger fra klienten, som sendes til spillet.
- Udgående handlinger
- Handlinger, sendt fra spillet, som klienten kan lytte til.
- Udvekslings-ID
- En unik nøgle for hver registreret bruger, der bruges til at udveksle indhold mellem Immer’s API og klienten uden at identificere den enkelte brugers oplysninger.
- Sessions-ID
- En unik nøgle tildelt af klienten, der kan bruges til at gemme spildata på brugere, som ikke er registreret endnu.
- Klient API-nøgle
- En API-nøgle, der bruges til at sende og modtage indhold fra Immer’s API, men med begrænset rettigheder. Denne nøgle bruges til at sende og hente data på de enkelte spil og den enkelte spillers statistik.
- API-nøgle
- En API-nøgle, der ikke eksponeres for klienten, med flere rettigheder. Denne nøgle kan f.eks. bruges til at hente data på tværs af spillere og spil, eller udtræk af events og lignende.
Hurtig start
Immer’s spil bliver aktiveret ved at tilføje et HTML-element og script-tag til siden eller web-viewet, det skal indlejres i.
Eksempel
I dette eksempel indlejre vi spillet Gitter på en almindelig HTML-side:
<html>
<head>
…
</head>
<body>
<!-- HTML-elementet spillet skal indlejres i -->
<div id="immer-gitter" data-api-key="DIN_KLIENT_API_NØGLE_HER"></div>
<!-- Henvisning til JavaScript-koden der eksekverer spillet -->
<script src="https://acme.immerspiele.com/games/gitter/gitter.js"></script>
</body>
</html>Opsætning
Et spil kan konfigureres med forskellige attributter. Disse kan sættes på spillets container-element eller via. en global JavaScript-funktion.
Opsætning på spillets container-element
<div id="immer-gitter" data-api-key="DIN_KLIENT_API_NØGLE_HER"></div>Opsætning via. global JavaScript-funktion
Funktionen skal hedde immerSetup og returnere et objekt. Denne funktionen skal defineres
inden selve scriptet til spillet bliver indlæst.
<script>
function immerSetup() {
return {
apiKey: 'DIN_KLIENT_API_NØGLE_HER',
};
}
</script>
<!-- Henvisning til JavaScript-koden der eksekverer spillet -->
<script src="https://acme.immerspiele.com/games/gitter/gitter.js"></script>
Egenskaber
| Data-attribut | Object-nøgle | Beskrivelse |
|---|---|---|
| data-api-key | apiKey | Klient API-nøgle som bruges til at hente og sende data til Immer’s API. |
| data-login-url | loginUrl | URL til login-side. Hvis denne ikke er sat, vil spillet sende en udgående handling med ID 1 når brugeren ønsker at logge ind. |
| data-proxy | proxy | URL til en server-side proxy, der kan bruges til at skjule klient API-nøglen og spillerens ID. Se Grundlæggende for mere information. |
| data-player-id | playerId | Udvekslings-ID for den aktuelle bruger. Denne bruges til at hente og sende data til Immer’s API. |
Sikkerhed mellem klient og API
Når en bruger starter, spiller eller afslutter et spil skal informationen sendes til Immer’s API så sikkert og enkelt som muligt.
Grundlæggende
- Alle API-forespørgsler er krypteret med TLS.
- Alle API-forespørgsler skal sikres via. en API-nøgle til klienten eller serveren.
- Udveksling af brugernes spilhistorik skal ske på baggrund af et unikt udvekslings-ID og ikke personfølsomme oplysninger som e-mail, abonnementsnummer, telefonnummer eller lignende.
Implementeringer
Server-side “proxy” 🔒🔒🔒
Vi vurderer, at denne løsning er den mest sikre og holdbare da ingen oplysninger eksponeres i klienten.
Alle forespørgsler, der sendes til Immer’s API, kører igennem en server-side “proxy”. Denne proxy beriger alle forespørgsler med en API-nøgle og et udvekslings-ID. På denne måde behøver vi ikke afsløre følsomme oplysninger i klienten. Dette giver - potentielt - også en lille hastighedsforøgelse da browseren ikke behøver at sende et ekstra preflight-request pga. CORS.
Eksempel
Når Wørdle starter, laver spillet selv et kald til Immer’s API for at indlæse dagens ord. Hvis brugeren allerede har eller er i gang med at spille, skal dette “state” også genskabes via. API-kaldet.
Eksempel på første forespørgelse i Wørdle hvis brugeren er logget ind:
GET https://acme.immerspiele.com/api/woerdle/latest
# Headers der — som minimum — skal bruges:
Authorization: Bearer tqrnlFGwtXBFRaOALLQiVKVCpi0DCTtyrem8UJ7XuEdUx
X-Immer-Player-ID: 6ac1d26b284a25f733135a5e0eed542b3f6261ecFor at skjule følsomme oplysninger, kan spillet konfigureres til, at kører igennem en proxy:
<div
id="immer-woerdle"
data-proxy="https://www.acme.dk/spil-proxy-endpoint"
>
</div>
<!-- Eller, hvis proxy-adressen er på samme host: -->
<div
id="immer-woerdle"
data-proxy="/spil-proxy-endpoint"
>
</div>
<!-- Alternativt, kan spillet opsættes med en global JavaScript-funktion: -->
<script>
function immerSetup() {
return {
proxy: '/spil-proxy-endpoint',
};
}
</script>Første forespørgelse i Wørdle vil nu se sådan ud:
GET https://www.acme.dk/spil-proxy-endpoint/woerdle/latestPå server-siden viderestilles forespørgslen til Immer’s API inklusiv API-nøgle og udvekslings-ID (som givetvis findes eller kan fortolkes i et sessions-lag eller via. en cookie):
GET https://www.acme.dk/spil-proxy-endpoint/woerdle/latest
# Headers tilføjet af proxy
Authorization: Bearer tqrnlFGwtXBFRaOALLQiVKVCpi0DCTtyrem8UJ7XuEdUx
X-Immer-Player-ID: 6ac1d26b284a25f733135a5e0eed542b3f6261ecAndre relevante headers som X-Request-ID og X-Forwarded-For kan også medtages ifht. logning og fejlfinding.
Signeret API-nøgle 🔒🔒
For at begrænse eksponering af klient API-nøglen, kan nøglen signeres server-side, så den er unik pr. udvekslings-ID eller sessions-ID og spil.
Der laves en signeret HMAC-værdi med SHA-256 og følgende værdier:
{spillets nøgle}+{udvekslings-ID eller sessions-ID} med API-nøglen som den “hemmelige nøgle”. Resultatet præfikses med sign_.
Du kan finde listen over spil og deres nøgler her.
Eksempel
hashed = hmac(
message: 'Wordle+6ac1d26b284a25f733135a5e0eed542b3f6261ec',
secret: 'tqrnlFGwtXBFRaOALLQiVKVCpi0DCTtyrem8UJ7XuEdUx'
)
=> hashed: 'e9fa3cb0b12770c744976738b55c99732c507f4fa64e5b895c2a47ce75b49c9e'
key = 'sign_' + hashed
=> key: 'sign_e9fa3cb0b12770c744976738b55c99732c507f4fa64e5b895c2a47ce75b49c9e'Ved opsætning kan værdien nu bruges som API-nøgle:
<div
id="immer-woerdle"
data-api-key="sign_e9fa3cb0b12770c744976738b55c99732c507f4fa64e5b895c2a47ce75b49c9e"
data-player-id="6ac1d26b284a25f733135a5e0eed542b3f6261ec"
>
</div>Klient API-nøgle 🔒
Integrationen til Immer’s API kan også ske via. en klient API-nøgle. Denne løsning er mindre sikker, da API-nøglen og udvekslings-ID’et vil være eksponeret for klienten.
Eksempel
Ved opsætning kan spillet konfigureres med en API-nøgle og et udvekslings-ID (hvis brugeren er logget ind).
<div
id="immer-woerdle"
data-api-key="dT5ElhVVRmbzPz4yO0rB5yhoPbqSF2fun6Y634iGAqIEBNlVZtj11FgH31nZ0iXB"
data-player-id="6ac1d26b284a25f733135a5e0eed542b3f6261ec"
>
</div>
<!-- Alternativt, kan spillet opsættes med en global JavaScript-funktion: -->
<script>
function immerSetup() {
return {
apiKey: 'dT5ElhVVRmbzPz4yO0rB5yhoPbqSF2fun6Y634iGAqIEBNlVZtj11FgH31nZ0iXB',
playerId: '6ac1d26b284a25f733135a5e0eed542b3f6261ec'
};
}
</script>Åbn modal-vinduer programmatisk
Der er flere modal-vinduer i spillene, der kan åbnes programmatisk, så de kan integreres i forskellige kontekst - f.eks. en menu, en mobil-app osv.
Et modal-vindue åbnes ved at afvikle et CustomEvent med typen på spillets container-element.showModal
Eventets detail-egenskab skal indeholde et objekt med modal-vinduets ID.
// Opret event
const helpModalEvent = new CustomEvent('showModal', {
detail: {
id: 1,
},
});
// Find container-elementet, som spillet vises indeni.
// I dette eksempel har elementet klassenavnet "game-container".
const container = document.querySelector('.game-container');
// Afvikl eventet på elementet
container.dispatchEvent(helpModalEvent);
Modal-ID'er
| ID | Navn |
|---|---|
1 | Hjælp & regler |
2 | Statistik |
3 | Tidligere/gårsdagens løsning |
4 | Ledetråde |
5 | Rang |
6 | Kontakt |
Indgående handlinger
Udvalgte handlinger, der sker udenfor spillets område, kan sendes fra klienten til spillet. Dette kan f.eks. være, at fortælle spillet, at brugeren er logget ind.
Indgående handlinger kan sendes til spillet ved at bruge et CustomEvent med typen på spillets container-element.gameAction
Eventets detail-egenskab skal indeholde et objekt med handlingens ID.
// Opret event
const authenticateEvent = new CustomEvent('gameAction', {
detail: {
id: 1,
},
});
// Find container-elementet, som spillet vises indeni.
// I dette eksempel har elementet klassenavnet "game-container".
const container = document.querySelector('.game-container');
// Afvikl eventet på elementet
container.dispatchEvent(authenticateEvent);Handlings-ID'er
| ID | Handling | Beskrivelse |
|---|---|---|
1 | Log ind | Brugeren er logget ind og dette skal reflekteres i spillet. |
Udgående handlinger
Udvalgte handlinger, der foretages inde i spillet er tilgængelige for klienten, som spillet indlejres i.
Handlinger sendes fra spillet med et CustomEvent med typen på spillets container-element.gameEvent
Eventets detail-egenskab skal indeholde et objekt med handlingens ID.
// Find container-elementet, som spillet vises indeni.
// I dette eksempel har elementet klassenavnet "game-container".
const container = document.querySelector('.game-container');
// Tilføj event listener til container-elementet
container.addEventListener('gameEvent', (event) => {
const id = event.detail.id;
// Brug handlingens ID…
});Handlings-ID'er
| ID | Handling | Beskrivelse |
|---|---|---|
1 | Log ind | Brugeren ønsker at logge ind |
2 | Opret bruger | Bruger ønsker at oprette en profil |
3 | Skærmændring | Spillet skifter skærm - f.eks. fra "velkomstskærm" til "spil". |
Yderligere data på handlinger
Visse handlinger indeholder ekstra information.
| ID | Handling | Struktur |
|---|---|---|
3 | Skærmændring | Se skærm-ID'er |
Skærme
Skærm-ID'er
| ID | Navn | Beskrivelse |
|---|---|---|
0 | Indlæsning | Vises når spillet indlæses. |
1 | Velkomst | Velkomstskærm. |
2 | Spil | Spilskærm. |
3 | Breaker | Vises i spil, der understøtter "breaker"-skærme (f.eks. Satellit). |
4 | Spil afsluttet | Vises når et spil afsluttes. |
Spil
Denne liste indeholder alle spil, der er tilgængelige i Immer’s API. For hvert spil er der et unikt ID og en nøgle, der bruges til at implementere spillet og hente data via. API’et.
| ID | Nøgle | Navn |
|---|---|---|
1 | Wordle | Wørdle |
2 | Satellite | Satellit |
3 | Grid | Gitter |
4 | Twenty3 | Præcis23 |
5 | Shift | Skæft |
6 | Relation | Relation |
7 | Clover | Ordkløver |
8 | Fallout | Indfald |
9 | Across | Tværs |
10 | Splice | Splejser |
11 | Sudokuish | Sudokuish |
12 | Ordwerk | Ordwærk |
13 | Between | Mælm |