Node.js-Schnellstart
Ein Node.js-Programm, das ein Token erneuert, deine Bildschirme auflistet und eine Playlist auf einen Bildschirm legt. Die Blöcke auf dieser Seite ergeben zusammen eine Datei.
1 Hol dir ein Token
Öffne das CMS unter Einstellungen, Verbundene Apps und klick auf Token generieren. Ein Mitglied ohne Administratorrechte sieht diesen Tab nicht.
Wähl danach die Organisation, die festlegt, welche Bildschirme das Programm sieht, und klick auf Zulassen. Die nächste Seite zeigt die Client-ID und das Refresh-Token, nur einmal. Kopiere beides.
Setz im Terminal die Client-ID und den Pfad der Token-Datei, und schreib das Refresh-Token in diese Datei. read -rs wartet, ohne etwas anzuzeigen: Füge das Refresh-Token ein und drück Enter, so bleibt es aus der Shell-History:
export GIBEON_CLIENT_ID=CLIENT_ID export GIBEON_REFRESH_TOKEN_FILE=./gibeon-refresh-token touch "$GIBEON_REFRESH_TOKEN_FILE" chmod 600 "$GIBEON_REFRESH_TOKEN_FILE" read -rs GIBEON_REFRESH_TOKEN && printf '%s' "$GIBEON_REFRESH_TOKEN" > "$GIBEON_REFRESH_TOKEN_FILE"
Das Programm braucht Node.js 18 oder neuer, wegen des eingebauten fetch. Du musst nichts installieren. Leg die Blöcke unten der Reihe nach in gibeon.mjs ab und starte node gibeon.mjs.
2 Erneuere das Token
Ein Access-Token gilt 60 Minuten. Jede Erneuerung liefert auch ein neues Refresh-Token, ein Wert in der Umgebung ist also nach einem Lauf veraltet.
Das Programm schreibt das neue Token in eine temporäre Datei im selben Verzeichnis, setzt chmod 600 und benennt sie über die Datei in GIBEON_REFRESH_TOKEN_FILE um. Erst danach nutzt es das Access-Token. Ein Prozess, der dabei abbricht, behält so ein gültiges Refresh-Token.
Jede Anfrage prüft den Status: Bei einem Fehler wirft check eine Ausnahme, die das Programm mit einem Exit-Code ungleich null beendet.
import { randomUUID } from 'node:crypto';
import { chmod, readFile, rename, writeFile } from 'node:fs/promises';
// An uncaught error stops the program with a non-zero exit code.
function check(response) {
if (!response.ok) {
throw new Error(`${response.status} from ${response.url}`);
}
}
const tokenFile = process.env.GIBEON_REFRESH_TOKEN_FILE;
const refreshToken = (await readFile(tokenFile, 'utf8')).trim();
let response = await fetch('https://id.gibeon.io/auth/v1/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'refresh_token',
client_id: process.env.GIBEON_CLIENT_ID,
refresh_token: refreshToken,
}),
signal: AbortSignal.timeout(30_000),
});
check(response);
const tokens = await response.json();
// Store the new refresh token before anything uses the access token.
const tmpPath = `${tokenFile}.${randomUUID()}.tmp`;
await writeFile(tmpPath, tokens.refresh_token, { mode: 0o600 });
await chmod(tmpPath, 0o600);
await rename(tmpPath, tokenFile);
const headers = { Authorization: `Bearer ${tokens.access_token}` }; 3 Liste deine Bildschirme auf
Das liefert alle Bildschirme in deinem Tenant. Das Programm gibt von jedem Bildschirm id, name und status aus, und nie ein Token.
response = await fetch('https://www.gibeon.io/v1/players', {
headers,
signal: AbortSignal.timeout(30_000),
});
check(response);
for (const player of (await response.json()).data) {
console.log(player.id, player.name, player.status);
} 4 Weise eine Playlist zu und veröffentliche
Dieser Schritt läuft nur, wenn GIBEON_PLAYER_ID und GIBEON_PLAYLIST_ID gesetzt sind. Die ID des Bildschirms steht in der Liste aus dem vorigen Schritt. Die ID der Playlist steht in der Adressleiste des CMS, wenn du eine Playlist öffnest: /playlists/PLAYLIST_ID/content. Exportiere beide und starte das Programm noch einmal.
Ein Bildschirm mit Zonen spielt diese; sonst seine Sequenz; sonst seine Planung; sonst seine eigene Playlist. Der Body leert die Sequenz und die Planung, also spielt die Playlist, außer der Bildschirm hat Zonen.
Der PATCH allein ändert nichts auf dem Bildschirm: Bis du veröffentlichst, zeigt er weiter die alte Zuweisung. Das Veröffentlichen baut einen neuen Snapshot und benachrichtigt den Bildschirm sofort.
const playerId = process.env.GIBEON_PLAYER_ID;
const playlistId = process.env.GIBEON_PLAYLIST_ID;
if (playerId && playlistId) {
response = await fetch(`https://www.gibeon.io/v1/players/${playerId}`, {
method: 'PATCH',
headers: { ...headers, 'Content-Type': 'application/json' },
body: JSON.stringify({ playlist_id: playlistId, sequence_id: null, planning_id: null }),
signal: AbortSignal.timeout(30_000),
});
check(response);
const player = (await response.json()).data;
response = await fetch(`https://www.gibeon.io/v1/players/${playerId}/publish`, {
method: 'POST',
headers,
signal: AbortSignal.timeout(30_000),
});
check(response);
console.log(player.id, player.name, player.status);
}