Zeitplan-Trigger: Cron mit Zeitzone
Führe einen Workflow nach Cron-Plan in einer IANA-Zeitzone aus. Was an den Umstellungstagen gilt, was nach Ausfällen — und was das Firings-Log erklärt.
Zuletzt aktualisiert:
Wanduhrzeit, wörtlich gemeint
Ein Zeitplan ist ein Cron-Ausdruck plus eine IANA-Zone — Europe/Berlin, nie ein UTC-Offset, denn ein Offset ist das halbe Jahr über falsch. Die Wanduhr-Semantik gilt wörtlich, gerade an den Tagen, die sie auf die Probe stellen. In der Nacht, in der die Uhren zurückgestellt werden, feuert ein täglicher Job einmal, nicht zweimal: Auf einem Portal mit nur einer Sitzung pro Login würde die zweite Anmeldung die erste verdrängen. In der Nacht der Vorstellung feuert ein Job aus der fehlenden Stunde, sobald die Lücke endet — statt gar nicht.
Für Ausfälle gilt dieselbe Disziplin: Egal wie lange die Plattform stand, es gibt genau eine Nachhol-Entscheidung — catchUp überspringt die verpassten Termine oder feuert genau einmal nach. Nie eine Salve von Runs hintereinander.
Einen nächtlichen Trigger anlegen
Voraussetzungen: api-key
BASE="https://browserberg.com"
AUTH="Authorization: Bearer $BROWSERBERG_API_KEY"
JSON="Content-Type: application/json"
WFID=$(curl -s -X POST "$BASE/v1/workflows" -H "$AUTH" -H "$JSON" -d '{
"title": "Nightly example check",
"blocks": [ { "blockType": "navigation", "label": "Open_page", "url": "https://example.com" } ]
}' | python3 -c 'import json,sys; print(json.load(sys.stdin)["workflow"]["workflowId"])')
# A schedule is a cron expression plus an IANA zone -- never a UTC offset.
# Wall-clock time is meant literally, including on the DST switch days.
TRIGGER=$(curl -s -X POST "$BASE/v1/workflows/$WFID/triggers" -H "$AUTH" -H "$JSON" -d '{
"kind": "schedule",
"name": "Nightly at 02:30 Berlin time",
"cron": "30 2 * * *",
"timezone": "Europe/Berlin",
"catchUp": "run_once",
"session": { "ttlSeconds": 900 }
}')
echo "$TRIGGER" | python3 -c 'import json,sys; t = json.load(sys.stdin)["trigger"]; print(json.dumps({
"id": t["id"], "status": t["status"], "nextFireAt": t["nextFireAt"],
"catchUp": t["catchUp"], "overlap": t["overlap"]}, indent=2))'
TID=$(echo "$TRIGGER" | python3 -c 'import json,sys; print(json.load(sys.stdin)["trigger"]["id"])')
curl -s -X DELETE "$BASE/v1/triggers/$TID" -H "$AUTH" > /dev/null
{
"id": "trg_xxxxxxxx",
"status": "active",
"nextFireAt": "2026-01-01T00:00:00.000Z",
"catchUp": "run_xxxxxxxx",
"overlap": "skip"
}
Zeitplan-Optionen
Das Mindestintervall zwischen zwei Terminen beträgt 5 Minuten.
| Name | Typ | Beschreibung |
|---|---|---|
cron
erforderlich
|
string | Gewöhnlicher Cron-Ausdruck mit fünf Feldern. |
timezone
erforderlich
|
string | Ein IANA-Zonenname wie Europe/Berlin. Offsets werden abgelehnt. |
catchUp
|
skip | run_once | skip lässt verpasste Termine aus; run_once holt genau einen nach. |
misfireGraceSeconds
|
integer |
Wie spät ein Termin noch feuern darf und als pünktlich gilt (60 bis 21600).
Standard: 300
|
overlap
|
skip | allow | skip verweigert ein neues Feuern, solange der vorige Run läuft; allow startet trotzdem. |
session
|
object | Die Session für jedes Feuern: poolId, profileId, locale, timezone, ttlSeconds. |
version
|
integer | Fixiert die auszuführende Workflow-Version; ohne Angabe läuft jeweils die neueste. |
Das Firings-Log beantwortet die Morgenfrage
GET /v1/triggers/:id/firings verzeichnet jeden Termin, an dem der Trigger fällig wurde — auch die, an denen nichts lief, mit dem Ausgang started, skipped oder refused und dem Grund. Wenn du morgens fragst, warum letzte Nacht nichts gelaufen ist, ist das Log die Antwort, kein Achselzucken.
Ein gescheiterter Run pausiert keinen Trigger; für Scheitern gibt es Retries und den nächsten Termin. Pausiert wird nur bei einem Fehler, der sich nie von selbst beheben kann — ein gelöschter Workflow, ein widerrufener Zugangsdatensatz.