Zum Inhalt
RAWCaptureBooth Kullanım kılavuzu
Sürüm 4.3.0

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'uHarici programlar için tetikleyiciler
Ne zamansabit aralıklarla, fabrika ayarında her 30 saniyedebir adım gerçekleştiği anda
Nefotoğraf kabininin tüm durumubirkaç değerli tek bir olay
Nereyeinternette veya ağda bir adresfotoğraf kabininde bir adres veya program
Tipikgö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#

  1. 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.
  2. "Durum webhook'u" bölümünde adresi girin ve kaydedin. Bu sırada imza için anahtar oluşur.
  3. Anahtarı "Kopyala" ile alın ve alıcıya girin.
  4. "Test bildirimi gönder"e basın. Altında alıcının yanıtı ve gönderilen içerik görünür.
  5. "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-Typeapplication/json; charset=utf-8
User-AgentRAWCaptureBooth-Statuswebhook/<Version>
X-RAWCaptureBooth-Timestamp1970'ten bu yana saniye cinsinden bildirim zamanı (Unix zamanı)
X-RAWCaptureBooth-Signaturesha256= 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_versionBildirimin yapısı, şu anda 1
sent_atFotoğraf kabininin yerel saatinde, saat dilimiyle gönderim zamanı
report_interval_secondsSaniye cinsinden bildirim aralığı
computer_nameFotoğraf kabininin bilgisayar adı - birden fazla kabin aynı alıcıya bildirim gönderiyorsa tanımlayıcı
rawcapturebooth_versionKurulu sürüm
rawcapturebooth_latest_versionYayımlanmış en yeni sürüm, fotoğraf kabini onu alamadığı sürece boş
cockpit_version, cockpit_latest_versionRAWCaptureBooth Cockpit için aynısı, Cockpit yoksa boş
uptimeProgram başlangıcından bu yana çalışma süresi, örneğin 5:12:03 veya 1 day, 2:03:04
network_statusGerçek ağ durumu: LAN, WLAN (Netzname), Online veya Offline
connectivity_modeAyarlı işletim türü: online veya offline
email_enabled, print_enabled, cloud_enabledE-posta gönderimi, baskı ve bulut yüklemesinin açık olup olmadığı
event_nameEtkin etkinliğin adı
sessions_total, sessions_since_startToplam ve program başlangıcından bu yana oturumlar
session_limitOturum üst sınırı, 0 limit yok demektir
total_print_jobs, print_jobs_since_start, print_limitBaskı işleri için aynısı
ai_portraits_total, ai_portraits_since_start, ai_portrait_limitYZ portreleri için aynısı
ai_portrait_warn_thresholdFotoğraf kabininin uyardığı YZ portresi sayısı, 0 kapalı demektir
last_session_at, last_capture_atSon oturumun ve son çekimin zamanı, çoğunlukla UTC olarak (Z ile biter)
error_countProgram başlangıcından bu yana hatalar
last_error, last_error_atZamanıyla birlikte metin olarak son hata
cpu_used_percentSon bildirimden bu yana işlemci yükü, başlangıçtan sonraki ilk bildirimde boş
memory_used_percentKullanılan çalışma belleği
disk_free_gb, disk_total_gbÇekimlerin bulunduğu sürücünün boş ve toplam alanı
outbox_pendingBekleyen e-postalar ve yüklemeler, örneğin ağ yokken
outbox_email_pending, outbox_cloud_pendingBunlardan e-postalar ve bulut yüklemeleri
camera_battery_percentYüzde olarak kamera pili, güç adaptöründe veya kamera bildirmiyorsa boş
camera_power_sourcebattery, ac (güç adaptörü) veya boş
printersHer yazıcı için bir girdi, aşağıya bakın
buzzersHer kablosuz buzzer için bir girdi, aşağıya bakın
lightcontrolHer LightControl için bir girdi, aşağıya bakın; LightControl kapalı olduğu sürece boş

printers içindeki bir girdi:

Alanİçerik
roleprint (fotoğraf yazıcısı) veya strip (fotoğraf şeridi yazıcısı)
modesingle (tek yazıcı) veya pool (yazıcı havuzu, o zaman ayrıca strategy)
nameYazıcının Windows'taki adı
availableYazıcının hazır olup olmadığı
stateDurum, örneğin ready, printing, paused, error, offline veya unknown
queue_lengthKuyruktaki işler
issuesBildirilen sorunların listesi, bulgu yoksa boş
media_remaining, media_capacitySayfa olarak kalan malzeme ve kapasite, yazıcı bilgi vermiyorsa boş
total_printsKullanım ömrü boyunca baskılar, yalnızca DNP yazıcılarda

buzzers içindeki bir girdi:

Alanİçerik
nameKablosuz buzzer'ın adı
connectionconnected, 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
millivoltMilivolt cinsinden pil gerilimi
seconds_since_pressSon basıştan bu yana saniye, henüz basılmadıysa boş

lightcontrol içindeki bir girdi:

Alanİçerik
idKontrol biriminin tanımlayıcısı
nameYönetim alanındaki ad, ad yoksa boş
modelLightControl V2, LightControl V2 Temp veya LightControl V2 Mini
connectedKontrol biriminin bağlı olup olmadığı
temperaturesSensö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:

  1. İçeriği geldiği gibi bayt olarak okuyun - önce JSON olarak okuyup yeniden üretmeyin.
  2. X-RAWCaptureBooth-Timestamp'teki zaman damgasını, bir noktayı ve içeriği birleştirin.
  3. Bunun üzerinden anahtarla HMAC-SHA256 hesaplayın, onaltılık dize olarak, ve başına sha256= ekleyin.
  4. X-RAWCaptureBooth-Signature ile sabit sürede karşılaştırın.
  5. 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://'den https://'ye veya www iç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.

Güncelleme: 06.11.2026 · Sürüm 4.3.0