Durum webhook'u
Fotoğraf kabini durumunu belirli aralıklarla işletmecinin girdiği bir adrese bildirir. Her bildirim, uzaktan yönetim portalının bu fotoğraf kabini için gösterdiği değerlerin aynısını içeren bir JSON'dur. Alıcının bununla ne yapacağına alıcının kendisi karar verir.
Bu, yönetim alanında "Ağ ve uzaktan yönetim" > "Durum webhook'u" altında açılır. Bunun için uzaktan yönetim gerekmez: Webhook portalı olmayan bir fotoğraf kabininde de çalışır.
Ne işe yarar#
- Fotoğraf kabininin o anda kullanımda olup olmadığını ve şimdiye kadar kaç fotoğraf çekildiğini kendi web sitenizde gösterin.
- Mevcut bir sistemde birden fazla fotoğraf kabini için kendi genel bakışınızı tutun.
- Kâğıt azaldığında, kamera pili zayıfladığında veya bir fotoğraf kabini artık bildirim göndermediğinde bildirim alın - bir ev otomasyonu veya sohbet üzerinden.
- Örneğin müşteriyle hesaplaşma için sayaçları kaydedin.
Durum webhook'u mu tetikleyiciler mi?#
İkisi de dışarıya bildirir, ama farklı şekilde:
| Durum webhook'u | Harici programlar için tetikleyiciler | |
|---|---|---|
| Ne zaman | sabit aralıklarla, fabrika ayarında her 30 saniyede | bir adım gerçekleştiği anda |
| Ne | fotoğraf kabininin tüm durumu | birkaç değerli tek bir olay |
| Nereye | internette veya ağda bir adres | fotoğraf kabininde bir adres veya program |
| Tipik | gösterim, izleme, istatistik | ışık, prizler, akıştaki betikler |
İkisi aynı anda kullanılabilir. Tetikleyicileri Harici programlar için tetikleyiciler bölümü anlatır.
Kurulum#
- Bir alıcı hazırlayın: JSON içeren bir POST isteğini kabul eden ve 200 ile 299 arasında bir durumla yanıt veren bir adres. Aşağıdaki örnekler bunun için yeterlidir.
- "Durum webhook'u" bölümünde adresi girin ve kaydedin. Bu sırada imza için anahtar oluşur.
- Anahtarı "Kopyala" ile alın ve alıcıya girin.
- "Test bildirimi gönder"e basın. Altında alıcının yanıtı ve gönderilen içerik görünür.
- "Durum webhook'unu kullan"ı açın. İlk bildirim hemen, ardından ayarlanan aralıkla gönderilir.
Neler gelir#
Her bildirim şu başlıkları içeren bir POST isteğidir:
| Başlık | İçerik |
|---|---|
Content-Type | application/json; charset=utf-8 |
User-Agent | RAWCaptureBooth-Statuswebhook/<Version> |
X-RAWCaptureBooth-Timestamp | 1970'ten bu yana saniye cinsinden bildirim zamanı (Unix zamanı) |
X-RAWCaptureBooth-Signature | sha256= ve imza, aşağıya bakın |
İçerik şöyle görünür (birer yazıcı ve buzzer'a kısaltılmış):
{
"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 }
]
}
]
}
Kendi fotoğraf kabininizin gerçek içeriğini "Test bildirimi gönder", "Gönderilen içerik" altında gösterir.
Alanlar#
Değeri olmayan bir alan null olarak yer alır. Sonraki sürümlerde yeni alanlar eklenebilir; alıcı bilmediğini atlar. schema_version yalnızca bir alanın anlamı değiştiğinde veya bir alan kalktığında artar.
| Alan | İçerik |
|---|---|
schema_version | Bildirimin yapısı, şu anda 1 |
sent_at | Fotoğraf kabininin yerel saatinde, saat dilimiyle gönderim zamanı |
report_interval_seconds | Saniye cinsinden bildirim aralığı |
computer_name | Fotoğraf kabininin bilgisayar adı - birden fazla kabin aynı alıcıya bildirim gönderiyorsa tanımlayıcı |
rawcapturebooth_version | Kurulu sürüm |
rawcapturebooth_latest_version | Yayımlanmış en yeni sürüm, fotoğraf kabini onu alamadığı sürece boş |
cockpit_version, cockpit_latest_version | RAWCaptureBooth Cockpit için aynısı, Cockpit yoksa boş |
uptime | Program başlangıcından bu yana çalışma süresi, örneğin 5:12:03 veya 1 day, 2:03:04 |
network_status | Gerçek ağ durumu: LAN, WLAN (Netzname), Online veya Offline |
connectivity_mode | Ayarlı işletim türü: online veya offline |
email_enabled, print_enabled, cloud_enabled | E-posta gönderimi, baskı ve bulut yüklemesinin açık olup olmadığı |
event_name | Etkin etkinliğin adı |
sessions_total, sessions_since_start | Toplam ve program başlangıcından bu yana oturumlar |
session_limit | Oturum üst sınırı, 0 limit yok demektir |
total_print_jobs, print_jobs_since_start, print_limit | Baskı işleri için aynısı |
ai_portraits_total, ai_portraits_since_start, ai_portrait_limit | YZ portreleri için aynısı |
ai_portrait_warn_threshold | Fotoğraf kabininin uyardığı YZ portresi sayısı, 0 kapalı demektir |
last_session_at, last_capture_at | Son oturumun ve son çekimin zamanı, çoğunlukla UTC olarak (Z ile biter) |
error_count | Program başlangıcından bu yana hatalar |
last_error, last_error_at | Zamanıyla birlikte metin olarak son hata |
cpu_used_percent | Son bildirimden bu yana işlemci yükü, başlangıçtan sonraki ilk bildirimde boş |
memory_used_percent | Kullanılan çalışma belleği |
disk_free_gb, disk_total_gb | Çekimlerin bulunduğu sürücünün boş ve toplam alanı |
outbox_pending | Bekleyen e-postalar ve yüklemeler, örneğin ağ yokken |
outbox_email_pending, outbox_cloud_pending | Bunlardan e-postalar ve bulut yüklemeleri |
camera_battery_percent | Yüzde olarak kamera pili, güç adaptöründe veya kamera bildirmiyorsa boş |
camera_power_source | battery, ac (güç adaptörü) veya boş |
printers | Her yazıcı için bir girdi, aşağıya bakın |
buzzers | Her kablosuz buzzer için bir girdi, aşağıya bakın |
lightcontrol | Her LightControl için bir girdi, aşağıya bakın; LightControl kapalı olduğu sürece boş |
printers içindeki bir girdi:
| Alan | İçerik |
|---|---|
role | print (fotoğraf yazıcısı) veya strip (fotoğraf şeridi yazıcısı) |
mode | single (tek yazıcı) veya pool (yazıcı havuzu, o zaman ayrıca strategy) |
name | Yazıcının Windows'taki adı |
available | Yazıcının hazır olup olmadığı |
state | Durum, örneğin ready, printing, paused, error, offline veya unknown |
queue_length | Kuyruktaki işler |
issues | Bildirilen sorunların listesi, bulgu yoksa boş |
media_remaining, media_capacity | Sayfa olarak kalan malzeme ve kapasite, yazıcı bilgi vermiyorsa boş |
total_prints | Kullanım ömrü boyunca baskılar, yalnızca DNP yazıcılarda |
buzzers içindeki bir girdi:
| Alan | İçerik |
|---|---|
name | Kablosuz buzzer'ın adı |
connection | connected, sleeping, disconnected, never (hiç bağlanmadı) veya unavailable (Bluetooth kullanılamıyor) |
battery_level | Üç kademede pil: 3 dolu, 2 yarım, 1 zayıf, 0 bilinmiyor |
millivolt | Milivolt cinsinden pil gerilimi |
seconds_since_press | Son basıştan bu yana saniye, henüz basılmadıysa boş |
lightcontrol içindeki bir girdi:
| Alan | İçerik |
|---|---|
id | Kontrol biriminin tanımlayıcısı |
name | Yönetim alanındaki ad, ad yoksa boş |
model | LightControl V2, LightControl V2 Temp veya LightControl V2 Mini |
connected | Kontrol biriminin bağlı olup olmadığı |
temperatures | Sensör başına sensor (adres), celsius ve alarm (high, low veya boş) |
İmzayı doğrulama#
Her bildirim yönetim alanındaki anahtarla imzalanır. Alıcı imzayı kendisi hesaplar ve bildirimi yalnızca ikisi eşleşirse kabul eder:
- İçeriği geldiği gibi bayt olarak okuyun - önce JSON olarak okuyup yeniden üretmeyin.
X-RAWCaptureBooth-Timestamp'teki zaman damgasını, bir noktayı ve içeriği birleştirin.- Bunun üzerinden anahtarla HMAC-SHA256 hesaplayın, onaltılık dize olarak, ve başına
sha256=ekleyin. X-RAWCaptureBooth-Signatureile sabit sürede karşılaştırın.- Zaman damgası kendi saatinizden beş dakikadan fazla sapan bildirimleri reddedin. Böylece ele geçirilmiş bir bildirim daha sonra yeniden gönderilemez.
Yönetim alanındaki "Yeniden oluştur" anahtarı değiştirir. Alıcıda güncellenene kadar alıcı her bildirimi reddeder.
Örnek: kendi web sitenizde gösterim#
Bir web sitesi bildirimi kendisi kabul edemez - sunucuda küçük bir betiğe ihtiyaç duyar. Bu PHP betiği imzayı doğrular ve yalnızca herkese açık olması gereken değerleri bir fotobox-status.json dosyasına kaydeder:
<?php
// fotobox-webhook.php - yönetim alanında adres olarak girin
$secret = 'ANAHTARI-BURAYA-GIRIN';
$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;
}
// Yalnızca web sitesine ait olanları ilet
$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);
Web sitesi dosyayı okur ve fotoğraf kabinine ulaşılıp ulaşılamayacağına kendisi karar verir:
<p id="fotobox">Fotoğraf kabini: yükleniyor …</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
? 'Fotoğraf kabini kullanımda, ' + status.sessions_since_start + ' oturum (başlangıçtan beri)'
: 'Fotoğraf kabinine şu anda ulaşılamıyor';
});
</script>
Örnek: Node.js'te alıcı#
Ek paket olmadan, yerleşik http modülüyle:
const http = require('http');
const crypto = require('crypto');
const SECRET = 'ANAHTARI-BURAYA-GIRIN';
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);
Bir fotoğraf kabininin artık bildirim göndermediğini fark etme#
Bir fotoğraf kabini "çevrimdışı" olduğunu kendisi bildiremez - bağlantı olmadan bildirim de gelmez. Alıcı bu yüzden son bildirimin ne zaman geldiğini hatırlar. Bildirim iki bildirim aralığından (report_interval_seconds) uzun süre gelmezse fotoğraf kabinine ulaşılamıyordur. Bir aralık yerine iki aralık, tek bir gecikmiş bildirimi yakalar.
Sorun giderme#
- "Test bildirimi gönder" HTTP 401 veya 403 bildiriyor: Alıcı imzayı reddediyor. Anahtar doğru mu? Ham içerik mi doğrulanıyor (yukarıya bakın)? Sunucunun saati doğru mu?
- HTTP 404: Adres doğru değil - yolu ve dosya adını kontrol edin.
- Yönlendirme: Adres yönlendiriyor, çoğu zaman
http://'denhttps://'ye veyawwwiçeren bir adrese. Fotoğraf kabini yönlendirmeleri izlemez; bildirimdeki hedef adresi doğrudan girin. - 15 saniye içinde yanıt yok: Alıcıya ulaşılamıyor veya çok yavaş yanıt veriyor. Bildirimi kabul edip önce çalışmaya devam etmek yerine hemen yanıt vermelidir.
- Bildirimler ayarlanandan daha seyrek geliyor: Bir başarısızlıktan sonra fotoğraf kabini bir sonraki denemeye kadar daha uzun bekler - önce 15 saniye, sonra iki katı, en fazla çeyrek saat. İlk başarıda yeniden ayarlanan aralık geçerli olur. Art arda kaç denemenin başarısız olduğu bölümde "Test ve durum" altında yazar.