Bots und Manifest
Ein Bot ist eine App mit eigenem Token. Du beschreibst sie in einem Manifest, der Besitzer eines Servers installiert sie dort, und sie handelt nie mit mehr Rechten als er.
Wie Bots funktionieren
- Du legst einen Bot im Kundenbereich unter Entwickler an. Pro Konto sind höchstens 10 Bots möglich.
- Der Bot bekommt ein eigenes Token mit dem Präfix
zhb_. - Der Besitzer eines Servers installiert den Bot im Reiter „Bots“ dieses Servers und stimmt den Rechten zu. Mitbenutzer können keine Bots installieren.
- Der Bot läuft bei dir oder auf einem eigenen Zenit-Server. Zenit führt keinen Bot-Code für dich aus.
Manifest
Das Manifest legt fest, was der Bot höchstens darf und wofür er sich interessiert.
| Feld | Bedeutung |
|---|---|
| slug | Kennung des Bots: Kleinbuchstaben, Ziffern und Bindestriche, 3 bis 48 Zeichen, am Anfang und Ende kein Bindestrich. Du kannst sie nach dem Anlegen nicht ändern. Kennungen mit dem Präfix zenit sind reserviert. Eine vergebene Kennung antwortet mit 409 BOT_SLUG_TAKEN. |
| name | Anzeigename, 1 bis 64 Zeichen. |
| description | Beschreibung, optional, höchstens 500 Zeichen. |
| homepageUrl | Adresse einer Seite zum Bot, optional, nur https, höchstens 512 Zeichen. |
| requestedScopes | Die Rechte, die der Bot höchstens bekommen kann. Welche es gibt, steht unter Rechte. |
| eventTypes | Die Ereignisse, die der Bot abonnieren kann. Abonnierbar ist server.activity. |
| webhook | Adresse und Zustand des Webhooks, optional. Siehe Webhooks prüfen. |
Verkleinerst du das Manifest, kürzen sich bestehende Installationen entsprechend. Erweiterst du es, erweitert sich keine Installation von selbst.
Installation pro Server
Eine Installation verbindet einen Bot mit einem Server. Sie hält fest, welche Rechte (grantedScopes) und Ereignisse (eventTypes) der Besitzer erteilt hat, und ihren Status: active oder suspended. Der Besitzer kann die Rechte einer Installation später nur verringern, nicht erhöhen. Einen Bot installierst du auf einem Server nur einmal, ein zweiter Versuch antwortet mit 409 BOT_ALREADY_INSTALLED.
Mit dem Token des Bots listet GET /installations alle Installationen. Ein Zugriffstoken bekommt hier 403 FORBIDDEN.
# ZENIT_TOKEN ist hier das Token des Bots (zhb_…) curl "https://api.zenit-hosting.de/api/developer/v1/installations?limit=25" \ -H "Authorization: Bearer $ZENIT_TOKEN"
Wirksame Rechte
Bei jedem Aufruf eines Bots gilt die Schnittmenge aus drei Mengen:
- den Rechten des Bots,
- den Rechten seiner Installation auf diesem Server,
- den aktuellen Rechten des Users, der den Bot installiert hat.
Hat der Bot servers:read und servers:power, die Installation aber nur servers:read, antwortet ein Start-Aufruf mit 403 INSUFFICIENT_SCOPE. Verliert der Installierende seine Freigabe auf dem Server, verliert der Bot sie dort ebenfalls. Die Rechte im Einzelnen stehen unter Rechte.
Deaktivierter und gesperrter Bot
Ein Bot ist active, disabled (du hast ihn deaktiviert) oder suspended (er ist gesperrt). Ist er nicht aktiv, bekommt sein Token auf der Developer-API 401 TOKEN_INVALID, und Zenit stellt keine Ereignisse zu. 409 BOT_NOT_ACTIVE betrifft dagegen die Verwaltung im Kundenbereich, etwa das Installieren eines nicht aktiven Bots.
Bot-Token und Erneuerung
- Beim Anlegen des Bots gibt es noch kein Token. Das erste Token erstellst du unter „Zugangsdaten“ des Bots. Es erscheint dort und bei jeder Erneuerung genau einmal und verlangt deinen zweiten Faktor. Kopiere es sofort.
- Ein Bot-Token läuft nicht ab.
- Eine Erneuerung erzeugt ein neues Token. Das alte Token gilt noch 24 Stunden, die Antwort nennt den Zeitpunkt in
previousTokenValidUntil. Tausche das Token in deinem Bot in dieser Zeit aus. - Das Webhook-Secret ist ein eigenes Geheimnis und wird getrennt erneuert, siehe Webhooks prüfen.
Ereignisse abrufen
Ohne Webhook holt dein Bot Ereignisse mit GET /events?after= ab. Das geht nur mit einem Bot-Token. Die Antwort ist { data, nextCursor }. nextCursor ist die Position nach dem zuletzt gelesenen Ereignis. Reiche ihn beim nächsten Aufruf als after zurück, damit du nur neue Ereignisse bekommst. Ist data leer, bist du auf dem neuesten Stand: Warte kurz und frage erneut. Ohne aktiven Webhook liefert der Feed nur server.activity. Die Installationen deines Bots liest du mit GET /installations. Was nextCursor im Feed von anderen Listen unterscheidet, steht unter Pagination. Zenit bewahrt Ereignisse 14 Tage auf, hole sie vorher ab. Die Ereignistypen und ihre Payloads stehen unter Webhooks prüfen.
const BASE = 'https://api.zenit-hosting.de/api/developer/v1';
// Den letzten Cursor speicherst du dauerhaft, damit ein Neustart nichts doppelt oder gar nicht abholt.
let after = null;
async function pollEvents() {
const url = new URL(BASE + '/events');
url.searchParams.set('limit', '100');
if (after) url.searchParams.set('after', after);
// ZENIT_TOKEN ist hier das Token des Bots (zhb_…)
const response = await fetch(url, {
headers: { Authorization: 'Bearer ' + process.env.ZENIT_TOKEN },
});
if (!response.ok) throw new Error('HTTP ' + response.status);
const page = await response.json();
for (const event of page.data) {
handleEvent(event); // nach event.id deduplizieren
}
// Im Feed ist nextCursor die Position nach dem zuletzt gelesenen Ereignis. Immer speichern, wenn er nicht null ist.
if (page.nextCursor) after = page.nextCursor;
return page.data.length;
}
async function run() {
while (true) {
const count = await pollEvents();
// Leere data heißt: aufgeholt. Kurz warten und mit demselben Cursor erneut fragen.
if (count === 0) await new Promise((resolve) => setTimeout(resolve, 5000));
}
}Beispiel: Zenit Git
„Zenit Git“ (Kennung zenit-git) ist ein Bot von Zenit selbst. Er zeigt, wie ein Bot aufgebaut ist:
- Sein Manifest nennt die Rechte
git:read,git:deploy,git:manage,servers:powerundservers:consolesowie das Ereignisserver.activity. - Er gilt als installiert, sobald ein Server eine Git-Quelle hat. Du musst ihn nicht installieren. Im Reiter „Bots“ des Servers steht er als eigene Zeile, und „Verwalten“ führt zum Deploy-Bereich des Servers.
- Über die API liest du die Git-Quellen eines Servers, löst Deploys aus und fragst Deployments ab. Dafür brauchst du
git:readundgit:deployund, als Mitbenutzer, die FreigabencanViewServerundcanDeployGit. - Ein Deploy hat den Auslöser
api. Ist das Paket des Servers nicht für Git-Deployments freigegeben, antwortet die API mit 409GIT_DEPLOY_NOT_ALLOWED.
# Git-Quellen des Servers lesen (Recht git:read)
curl "https://api.zenit-hosting.de/api/developer/v1/servers/$SERVER_ID/git/sources" \
-H "Authorization: Bearer $ZENIT_TOKEN"
# Deploy auslösen (Recht git:deploy); sha ist optional, 7 bis 64 Hexzeichen
curl -X POST "https://api.zenit-hosting.de/api/developer/v1/servers/$SERVER_ID/git/sources/$SOURCE_ID/deploy" \
-H "Authorization: Bearer $ZENIT_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"sha": "3f9c2ab"}' Die Endpunkte GET /servers/{id}/git/deployments und GET /servers/{id}/git/deployments/{deploymentId} liefern den Stand eines Deployments. Alle Felder stehen in der API-Referenz.
