Status-webhook
Fotoboksen melder sin tilstand i takt til en adresse, som operatøren indtaster. Hver melding er en JSON med de samme værdier, som fjernadministrationens portal viser for denne fotoboks. Hvad modtageren gør med den, bestemmer modtageren selv.
Det slås til i administrationsområdet "Netværk og fjernadministration" > "Status-webhook". Fjernadministrationen er ikke nødvendig til det: Webhooken kører også på en fotoboks uden portal.
Hvad det er godt til#
- Vis på den egne hjemmeside, om fotoboksen lige nu er i brug, og hvor mange fotos der allerede er taget.
- Hav en egen oversigt over flere fotobokse i et eksisterende system.
- Bliv underrettet, når papiret slipper op, kamerabatteriet bliver svagt, eller en fotoboks ikke længere melder sig - via et hjemmeautomatiseringssystem eller en chat.
- Skriv tællere med, f.eks. til afregning med kunden.
Status-webhook eller udløsere?#
Begge melder udadtil, men forskelligt:
| Status-webhook | Udløsere til eksterne programmer | |
|---|---|---|
| Hvornår | i fast takt, fra fabrikken hvert 30. sekund | i det øjeblik et trin sker |
| Hvad | fotoboksens samlede tilstand | en enkelt hændelse med få værdier |
| Hvorhen | en adresse på internettet eller i netværket | en adresse eller et program på fotoboksen |
| Typisk | visning, overvågning, statistik | lys, stikkontakter, scripts i forløbet |
Begge kan bruges samtidig. Udløserne beskrives i kapitlet Udløsere til eksterne programmer.
Opsætning#
- Stil en modtager til rådighed: en adresse, der tager imod en POST-forespørgsel med JSON og svarer med en status fra 200 til 299. Eksemplerne længere nede er nok til det.
- Indtast adressen i området "Status-webhook", og gem. Derved opstår nøglen til signaturen.
- Overtag nøglen med "Kopiér", og indtast den hos modtageren.
- Tryk på "Send testmelding". Nedenunder vises modtagerens svar og det sendte indhold.
- Slå "Brug status-webhook" til. Den første melding sendes straks, derefter med det indstillede interval.
Hvad der ankommer#
Hver melding er en POST-forespørgsel med disse headere:
| Header | Indhold |
|---|---|
Content-Type | application/json; charset=utf-8 |
User-Agent | RAWCaptureBooth-Statuswebhook/<Version> |
X-RAWCaptureBooth-Timestamp | Meldingens tidspunkt i sekunder siden 1970 (Unix-tid) |
X-RAWCaptureBooth-Signature | sha256= og signaturen, se nedenfor |
Indholdet ser sådan ud (forkortet til én printer og én buzzer):
{
"schema_version": 1,
"sent_at": "2026-10-03T21:14:05+02:00",
"report_interval_seconds": 30,
"computer_name": "FOTOBOX-01",
"rawcapturebooth_version": "3.28.0",
"rawcapturebooth_latest_version": "3.28.0",
"cockpit_version": null,
"cockpit_latest_version": null,
"uptime": "5:12:03",
"network_status": "WLAN (Festsaal)",
"connectivity_mode": "online",
"email_enabled": true,
"print_enabled": true,
"cloud_enabled": false,
"event_name": "Hochzeit Müller",
"sessions_total": 1843,
"sessions_since_start": 112,
"session_limit": 0,
"total_print_jobs": 2210,
"print_jobs_since_start": 131,
"print_limit": 300,
"ai_portraits_total": 0,
"ai_portraits_since_start": 0,
"ai_portrait_limit": 0,
"ai_portrait_warn_threshold": 0,
"last_session_at": "2026-10-03T19:13:40Z",
"last_capture_at": "2026-10-03T19:13:40Z",
"error_count": 0,
"last_error": null,
"last_error_at": null,
"cpu_used_percent": 23.5,
"memory_used_percent": 61.2,
"disk_free_gb": 182.4,
"disk_total_gb": 476.3,
"outbox_pending": 0,
"outbox_email_pending": 0,
"outbox_cloud_pending": 0,
"camera_battery_percent": null,
"camera_power_source": "ac",
"printers": [
{
"role": "print",
"mode": "single",
"name": "DP-DS620",
"available": true,
"state": "ready",
"queue_length": 0,
"issues": [],
"media_remaining": 268,
"media_capacity": 400,
"total_prints": 15320
}
],
"buzzers": [
{
"name": "Buzzer 1",
"connection": "connected",
"battery_level": 3,
"millivolt": 4010,
"seconds_since_press": 25
}
],
"lightcontrol": [
{
"id": "7F3A92C1",
"name": "Licht links",
"model": "LightControl V2 Temp",
"connected": true,
"temperatures": [
{ "sensor": "28FF000000000001", "celsius": 31.44, "alarm": null }
]
}
]
}
Det rigtige indhold fra den egne fotoboks viser "Send testmelding" under "Sendt indhold".
Felterne#
Et felt uden værdi står som null. Nye felter kan komme til i senere versioner; en modtager springer over det, den ikke kender. schema_version stiger kun, når et felts betydning ændres, eller et felt bortfalder.
| Felt | Indhold |
|---|---|
schema_version | Meldingens opbygning, i øjeblikket 1 |
sent_at | Afsendelsestidspunkt i fotoboksens lokale tid, med tidszone |
report_interval_seconds | Meldingsinterval i sekunder |
computer_name | Fotoboksens computernavn - kendetegnet, når flere bokse melder til samme modtager |
rawcapturebooth_version | Installeret version |
rawcapturebooth_latest_version | Nyeste udgivne version, tom så længe fotoboksen ikke har kunnet hente den |
cockpit_version, cockpit_latest_version | Det samme for RAWCaptureBooth Cockpit, tom uden Cockpit |
uptime | Kørselstid siden programstart, f.eks. 5:12:03 eller 1 day, 2:03:04 |
network_status | Faktisk netværkssituation: LAN, WLAN (Netzname), Online eller Offline |
connectivity_mode | Indstillet driftsform: online eller offline |
email_enabled, print_enabled, cloud_enabled | Om mailafsendelse, udskrift og cloud-upload er slået til |
event_name | Navnet på det aktive event |
sessions_total, sessions_since_start | Sessioner i alt og siden programstart |
session_limit | Grænse for sessioner, 0 betyder ingen grænse |
total_print_jobs, print_jobs_since_start, print_limit | Det samme for udskriftsjob |
ai_portraits_total, ai_portraits_since_start, ai_portrait_limit | Det samme for AI-portrætter |
ai_portrait_warn_threshold | Fra dette antal AI-portrætter advarer fotoboksen, 0 betyder slået fra |
last_session_at, last_capture_at | Tidspunkt for den seneste session og den seneste optagelse, oftest i UTC (ender på Z) |
error_count | Fejl siden programstart |
last_error, last_error_at | Den seneste fejl som tekst, med tidspunkt |
cpu_used_percent | Processorbelastning siden sidste melding, tom ved første melding efter start |
memory_used_percent | Optaget arbejdshukommelse |
disk_free_gb, disk_total_gb | Ledig og samlet plads på drevet med optagelserne |
outbox_pending | Ventende mails og uploads, f.eks. uden netværk |
outbox_email_pending, outbox_cloud_pending | Heraf mails og cloud-uploads |
camera_battery_percent | Kamerabatteri i procent, tom ved strømforsyning, eller når kameraet ikke melder det |
camera_power_source | battery, ac (strømforsyning) eller tom |
printers | Én post pr. printer, se nedenfor |
buzzers | Én post pr. trådløs buzzer, se nedenfor |
lightcontrol | Én post pr. LightControl, se nedenfor; tom, så længe LightControl er slået fra |
En post i printers:
| Felt | Indhold |
|---|---|
role | print (fotoprinter) eller strip (fotostrip-printer) |
mode | single (én printer) eller pool (printerpool, så desuden strategy) |
name | Printerens navn i Windows |
available | Om printeren er klar |
state | Tilstand, f.eks. ready, printing, paused, error, offline eller unknown |
queue_length | Job i køen |
issues | Liste over meldte problemer, tom uden fund |
media_remaining, media_capacity | Restmateriale og kapacitet i ark, tom uden oplysning fra printeren |
total_prints | Udskrifter over levetiden, kun ved DNP-printere |
En post i buzzers:
| Felt | Indhold |
|---|---|
name | Den trådløse buzzers navn |
connection | connected, sleeping, disconnected, never (aldrig forbundet) eller unavailable (Bluetooth ikke tilgængelig) |
battery_level | Batteri i tre trin: 3 fuldt, 2 halvt, 1 svagt, 0 ukendt |
millivolt | Batterispænding i millivolt |
seconds_since_press | Sekunder siden seneste tryk, tom hvis der endnu ikke er trykket |
En post i lightcontrol:
| Felt | Indhold |
|---|---|
id | Styringens kendetegn |
name | Navn fra administrationsområdet, tom uden navn |
model | LightControl V2, LightControl V2 Temp eller LightControl V2 Mini |
connected | Om styringen er forbundet |
temperatures | Pr. sensor sensor (adresse), celsius og alarm (high, low eller tom) |
Kontrollér signaturen#
Hver melding er signeret med nøglen fra administrationsområdet. Modtageren beregner selv signaturen og tager kun imod meldingen, når begge stemmer overens:
- Læs indholdet sådan som det ankommer som bytes - ikke først indlæst som JSON og udskrevet igen.
- Sæt tidsstemplet fra
X-RAWCaptureBooth-Timestamp, et punktum og indholdet sammen. - Beregn HMAC-SHA256 over det med nøglen, som hex-streng, og sæt
sha256=foran. - Sammenlign med
X-RAWCaptureBooth-Signaturei konstant tid. - Afvis meldinger, hvis tidsstempel afviger mere end fem minutter fra den egne tid. Så kan en opfanget melding ikke afspilles igen senere.
"Generér ny" i administrationsområdet erstatter nøglen. Indtil den er indtastet hos modtageren, afviser denne hver melding.
Eksempel: visning på den egne hjemmeside#
En hjemmeside kan ikke selv tage imod en melding - den kræver et lille script på serveren. Dette PHP-script kontrollerer signaturen og gemmer kun de værdier, der må være offentlige, i en fil fotobox-status.json:
<?php
// fotobox-webhook.php - angives som adresse i administrationsområdet
$secret = 'INDSAET-NOEGLEN-HER';
$body = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_RAWCAPTUREBOOTH_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_RAWCAPTUREBOOTH_SIGNATURE'] ?? '';
$expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $body, $secret);
if (!hash_equals($expected, $signature) || abs(time() - (int) $timestamp) > 300) {
http_response_code(401);
exit;
}
$status = json_decode($body, true);
if (!is_array($status)) {
http_response_code(400);
exit;
}
// Giv kun det videre, der hører hjemme på hjemmesiden
$public = [
'event_name' => $status['event_name'] ?? null,
'sessions_since_start' => $status['sessions_since_start'] ?? 0,
'report_interval_seconds' => $status['report_interval_seconds'] ?? 30,
'received_at' => time(),
];
file_put_contents(__DIR__ . '/fotobox-status.json', json_encode($public), LOCK_EX);
http_response_code(204);
Hjemmesiden læser filen og afgør selv, om fotoboksen kan nås:
<p id="fotobox">Fotoboks: indlæses …</p>
<script>
fetch('/fotobox-status.json', { cache: 'no-store' })
.then((response) => response.json())
.then((status) => {
const age = Date.now() / 1000 - status.received_at;
const online = age <= 2 * status.report_interval_seconds;
document.getElementById('fotobox').textContent = online
? 'Fotoboksen er i brug, ' + status.sessions_since_start + ' sessioner siden start'
: 'Fotoboksen kan ikke nås lige nu';
});
</script>
Eksempel: modtager i Node.js#
Uden ekstra pakker, med det indbyggede http-modul:
const http = require('http');
const crypto = require('crypto');
const SECRET = 'INDSAET-NOEGLEN-HER';
http.createServer((req, res) => {
const chunks = [];
req.on('data', (chunk) => chunks.push(chunk));
req.on('end', () => {
const body = Buffer.concat(chunks);
const timestamp = req.headers['x-rawcapturebooth-timestamp'] || '';
const signature = req.headers['x-rawcapturebooth-signature'] || '';
const expected = 'sha256=' + crypto.createHmac('sha256', SECRET)
.update(timestamp + '.').update(body).digest('hex');
const valid = signature.length === expected.length
&& crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))
&& Math.abs(Date.now() / 1000 - Number(timestamp)) <= 300;
if (!valid) {
res.writeHead(401).end();
return;
}
const status = JSON.parse(body.toString('utf8'));
console.log(status.computer_name, status.event_name, status.sessions_total);
res.writeHead(204).end();
});
}).listen(8080);
Opdag, at en fotoboks ikke længere melder#
"Offline" kan en fotoboks ikke selv melde - uden forbindelse ankommer der heller ingen melding. Modtageren husker derfor, hvornår den seneste melding ankom. Udebliver den i mere end to meldingsintervaller (report_interval_seconds), kan fotoboksen ikke nås. To intervaller i stedet for ét fanger en enkelt forsinket melding op.
Fejlfinding#
- "Send testmelding" melder HTTP 401 eller 403: Modtageren afviser signaturen. Stemmer nøglen? Kontrolleres råindholdet (se ovenfor)? Går serverens ur rigtigt?
- HTTP 404: Adressen stemmer ikke - kontrollér sti og filnavn.
- Omdirigering: Adressen omdirigerer, ofte fra
http://tilhttps://eller til en adresse medwww. Fotoboksen følger ikke omdirigeringer; indtast måladressen fra meldingen direkte. - Intet svar inden for 15 sekunder: Modtageren kan ikke nås eller svarer for langsomt. Den bør tage imod meldingen og svare straks i stedet for først at arbejde videre.
- Meldinger kommer sjældnere end indstillet: Efter et fejlslag venter fotoboksen længere til næste forsøg - først 15 sekunder, derefter dobbelt så længe, højst et kvarter. Ved første succes gælder igen det indstillede interval. Hvor mange forsøg der er mislykkedes i træk, står i området under "Test og status".