Blog

Live engagementHow-toAPI

Verbinden Sie Ihre Fotobox mit der grossen Leinwand

Ihre Fotobox macht schon gute Bilder. Mit der Engagement API landet jede Aufnahme Sekunden später an der Polaroid-Wall, und der Gast scannt einen QR-Code, um sie mitzunehmen. Die drei Aufrufe und ein Rezept für Sparkbooth, pibooth, dslrBooth und jede Fotobox mit Ausgabeordner.

The Wunderframe team 8 min read

Die Fotobox ist an den meisten Festen die belebteste Ecke. Aber was sie aufnimmt, bleibt meist in der Box: Der Gast sieht sein Bild ein paar Sekunden auf einem kleinen Bildschirm, alle anderen sehen nichts, bis eine Woche später der Link zur Galerie kommt.

Läuft der Anlass mit Wunderframe, kann Ihre Fotobox direkt ins Engagement des Abends posten, dasselbe, in das die Gäste von ihren Handys posten. Die Aufnahme hängt Sekunden später an der Polaroid-Wall, und der Gast scannt einen QR-Code, um sie mitzunehmen. Sie behalten Ihre Fotobox, Ihre Kamera und Ihre Software. Dazu kommen ein paar Zeilen Code.

Warum Fotobox-Bilder auf die grosse Leinwand gehören

  • Es geht sofort. Der Abzug entwickelt sich an der Wall, während der Gast noch die Requisiten ablegt. Genau dann schauen die Leute hin.
  • Alle sehen es. Aus einer Fotobox wird eine Show für den ganzen Saal, neben den Fotos und Notizen, die Gäste von ihren Handys senden.
  • Gäste nehmen es mit. Jede Aufnahme erhält ihren eigenen Take-home-Link: eine Seite auf dem Handy des Gasts mit seinem Bild und den Schaltflächen Teilen und Sichern. Keine App, keine E-Mail-Adresse, keine Galerie zum Durchsuchen.
Ein breiter dunkler Bildschirm mit dem Titel «Shoot a polaroid» und einer Reihe schräg hängender Sofortbilder – ein Sonnenuntergang am Hafen, Bühnenlicht an einer Konferenz, ein Tram in der Stadt, Konfetti mit «Day 1!», Workshop-Skizzen, ein Blick auf den See und ein Latte –, jedes mit handschriftlicher Bildunterschrift, und ein QR-Code in der Ecke.

Die Polaroid-Wall. Hier hängt ein Fotobox-Bild neben den Fotos, die Gäste von ihren Handys senden.

Der Ablauf: drei Aufrufe und kurz warten

Erstellen Sie zuerst als Owner des Workspaces unter Settings → Integrations einen API-Schlüssel mit Live engagements (engagements:write). Bewahren Sie ihn auf dem Computer der Fotobox oder Ihrem Server auf, nie in einer Webseite. GET /api/v1/engagements liefert die id des Engagements, seine rooms mit ihren Schlüsseln und ob es eine Einwilligung (consent) verlangt. Dann für jede Aufnahme:

  1. Upload anfordern. POST /api/v1/engagements/{id}/uploads mit kind, mime und der genauen Grösse in bytes. Sie erhalten eine upload_id und eine signierte upload_url.
  2. Datei senden. Die Bytes per PUT an upload_url schicken, mit den headers aus der Antwort, und zwar sofort: Die URL ist kurzlebig und funktioniert einmal.
  3. Posten. POST /api/v1/engagements/{id}/posts mit der upload_id, einem client_label wie Booth 1, dem Schlüssel des room, falls das Engagement Räume hat, und "consent": true, wenn es eine Einwilligung verlangt. Senden Sie einen Header Idempotency-Key: Der Hash der Datei eignet sich gut dafür.
  4. Auf die Kopie warten. GET /api/v1/engagements/{id}/posts/{post_id} alle zwei Sekunden abfragen, bis share_ready true ist, dann take_home_url als QR-Code zeigen.

Der ganze Ablauf in Node.js 18 oder neuer, ohne etwas zu installieren:

// send-shot.mjs
import { readFile } from 'node:fs/promises';
import { createHash } from 'node:crypto';

const API = 'https://www.wunderframe.com/api/v1';
const ENG = process.env.WUNDERFRAME_ENGAGEMENT; // the engagement id
const KEY = process.env.WUNDERFRAME_KEY;        // engagements:write

async function call(method, path, body, headers = {}) {
  const res = await fetch(API + path, { method, body: body && JSON.stringify(body),
    headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json', ...headers } });
  const data = await res.json();
  if (!res.ok) throw new Error(`${res.status} ${data.error.code}: ${data.error.message}`);
  return data;
}

/** Upload, post, wait for the copy. Returns the link for the QR code. */
export async function sendShot(bytes, { room, label = 'Booth 1', wait = true } = {}) {
  const hash = createHash('sha256').update(bytes).digest('hex');
  const up = await call('POST', `/engagements/${ENG}/uploads`,
    { kind: 'photo', mime: 'image/jpeg', bytes: bytes.length });
  const put = await fetch(up.upload_url, { method: up.method, headers: up.headers, body: bytes });
  if (!put.ok) throw new Error(`upload ${put.status}`);
  // consent: true only once the guest agreed on the booth's screen
  let post = await call('POST', `/engagements/${ENG}/posts`,
    { kind: 'photo', upload_id: up.upload_id, client_label: label, room, consent: true },
    { 'Idempotency-Key': hash });
  for (let i = 0; wait && i < 30 && post.take_home_url && !post.share_ready; i++) {
    await new Promise((r) => setTimeout(r, 2000));
    post = await call('GET', `/engagements/${ENG}/posts/${post.post_id}`);
  }
  return post.take_home_url;
}

// node send-shot.mjs shot.jpg
if (process.argv[2]) console.log(await sendShot(await readFile(process.argv[2])));

Einiges erledigt die API für Sie. Der Post läuft durch die Moderation des Engagements wie der eines Gasts: Mit approval wartet er auf die Regie, bevor er an die Walls kommt. Der Take-home-Link gilt 24 Stunden, und jede Abfrage liefert denselben Link. Scannt jemand, bevor die Kopie bereit ist, wartet die Seite einfach ein paar Sekunden. Im Gratis-Plan trägt die geteilte Kopie ein kleines Wunderframe-Zeichen in einer Ecke; die Walls zeigen das Foto immer ohne. Dieselben paar Zeilen in Python stehen in der Dokumentation.

Ein Rezept für Ihre Fotobox

Fotobox-Software gibt es in drei Sorten: Manche lädt auf einen Server hoch, den Sie angeben, manche führt nach jeder Aufnahme ein Plugin oder ein Skript aus, und manche schreibt nur Dateien in einen Ordner. Für alle drei gibt es einen Weg.

Sparkbooth: ein kleines Relay

Der Custom Upload von Sparkbooth schickt jedes Foto als Multipart-POST an eine Service URL Ihrer Wahl, mit den Feldern media, username, password, name, email und message. Zurück erwartet er {"status":true,"url":"…"} und zeigt diese url als QR-Code auf seinem Teilen-Bildschirm. Ein Relay nimmt also den Upload entgegen, ruft die Engagement API auf und antwortet mit dem Take-home-Link:

// relay.mjs, next to send-shot.mjs
import { createServer } from 'node:http';
import { sendShot } from './send-shot.mjs';

createServer(async (req, res) => {
  const form = await new Request('http://relay' + req.url,
    { method: 'POST', headers: req.headers, body: req, duplex: 'half' }).formData();
  if (form.get('password') !== process.env.RELAY_PASSWORD) return res.writeHead(401).end();
  try {
    const bytes = Buffer.from(await form.get('media').arrayBuffer());
    const url = await sendShot(bytes, { wait: false }); // the page waits for the copy itself
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ status: true, url }));
  } catch (err) {
    res.writeHead(502).end(); // and keep the bytes in a queue to retry
  }
}).listen(8080);

Antworten Sie rasch: Sparkbooth wartet auf das Relay, und die Take-home-Seite wartet von selbst auf die Kopie. Nur im Relay liegt der Schlüssel, und es ignoriert email, weil Wunderframe sie nicht braucht.

pibooth: ein Plugin aus wenigen Zeilen

pibooth, die Fotobox für den Raspberry Pi, führt Python-Plugins an Hooks aus. Nach der Verarbeitung ist das fertige Bild app.previous_picture_file. Ein Upload-Plugin setzt app.previous_picture_url, so wie es pibooth-google-photo tut, und pibooth-qrcode zeigt sie, wenn sein prefix_url auf {url} steht. Eine Skizze, mit post_shot als den drei Aufrufen in Python aus der Dokumentation:

import pibooth
from booth import post_shot  # upload, post, wait: returns take_home_url

@pibooth.hookimpl(tryfirst=True)  # set the URL before the QR plugin reads it
def state_processing_exit(cfg, app, win):
    try:
        app.previous_picture_url = post_shot(app.previous_picture_file)
    except Exception:
        app.previous_picture_url = None
        queue_for_later(app.previous_picture_file)  # retry when back online

dslrBooth und LumaBooth für Windows: ein Trigger

Diese Fotoboxen haben Triggers: Bei Ereignissen wie processing_start, das die final_file mitgibt, oder session_end rufen sie eine Webhook-URL auf oder starten ein Programm. Richten Sie einen davon auf send-shot.mjs oder einen kleinen lokalen Webhook, und die fertige Datei geht an die Wall. Ihre eigenen QR-Codes führen zum Hosting von Lumasoft, zeigen Sie den Take-home-QR-Code also selbst, wie unten beschrieben.

PhotoboothProject und photobooth-app: ein Befehl oder ein Plugin

Das webbasierte PhotoboothProject führt nach jedem Foto einen Befehl aus, in dem %s der Dateiname ist: node send-shot.mjs %s genügt. photobooth-app nimmt wie pibooth Python-Plugins an seinen Hooks, und sein rclone-Synchronizer kann die Aufnahmen auch in einen Ordner kopieren, den das nächste Rezept überwacht.

Jede andere Fotobox: den Hot Folder überwachen

Geschlossene Apps wie LumaBooth auf dem iPad, Darkroom oder Breeze schreiben ihre fertigen Bilder in einen Ausgabeordner. Überwachen Sie diesen Ordner und senden Sie jede neue Datei: unter Linux mit inotifywait oder rclone, unter macOS mit Hazel. Warten Sie, bis die Datei ganz geschrieben ist, sonst laden Sie ein halbes Bild hoch. Unter Linux melden sich close_write und moved_to erst dann:

inotifywait -m -e close_write -e moved_to --format '%w%f' /srv/booth/out |
while read -r file; do
  node send-shot.mjs "$file" || cp "$file" /srv/booth/queue/
done

Den QR-Code zeigen

Auf der Fotobox, wo sie es kann. Sparkbooth zeigt die url, die Ihr Relay zurückgibt, und pibooth-qrcode zeigt app.previous_picture_url. Der Gast scannt im selben Moment, in dem er sein Bild sieht, und genau dann will er es haben.

Neben der Fotobox, wo sie es nicht kann. Zeigt die Fotobox nur ihren eigenen Code, lassen Sie Ihr Skript stattdessen den Take-home-QR-Code zeigen: in einem Browserfenster im Vollbild auf einem zweiten Monitor an der Fotobox oder auf einem kleinen Bildschirm direkt daneben, jeweils mit dem neusten Link. Die grossen Bildschirme bei der Polaroid-Wall tun dann, was sie am besten können: jede Aufnahme zeigen, sobald sie ankommt, mit dem QR-Code des Engagements, damit auch Gäste ohne Fotobox von ihrem Handy posten können.

Lassen Sie einen Take-home-Code nahe bei der Fotobox und etwa zwanzig Sekunden lang stehen. Er öffnet das Bild einer einzelnen Person und gehört darum nicht auf die Bühnenleinwand, wo der ganze Saal ihn scannen kann.

Die Fotobox macht das Bild. Die Wall zeigt es dem Saal. Der QR-Code schickt es nach Hause.

Der Ablauf in einem Satz

Checkliste für Datenschutz und Zuverlässigkeit

  • Erst fragen, dann posten. Verlangt das Engagement eine Einwilligung, zeigen Sie seinen consent.text auf dem Startbildschirm der Fotobox und senden "consent": true erst, wenn der Gast zugestimmt hat. Bringen Sie an der Fotobox einen gut sichtbaren Hinweis an, dass ihre Fotos auf den Bildschirmen erscheinen.
  • Vor dem Zeigen moderieren. Stellen Sie das Engagement auf approval, wenn ein Mensch jede Aufnahme sehen soll, bevor der Saal sie sieht. Ein abgelehnter Post verliert seinen Take-home-Link.
  • So wenig Daten wie möglich. Wunderframe braucht weder E-Mail-Adresse noch Namen. client_label benennt die Fotobox, nicht die Person. Die Aufbewahrungsfrist des Engagements gilt für Fotobox-Bilder wie für alle anderen.
  • Offline zwischenspeichern. Behalten Sie jede Aufnahme auf der Fotobox und senden Sie sie, sobald das Netz zurück ist. Die Fotobox fotografiert weiter.
  • Sicher wiederholen. Wiederholen Sie einen Post mit derselben upload_id und demselben Idempotency-Key, erhalten Sie den ersten Post zurück statt eines zweiten. Nach dem Posten wiederholen Sie den Post, nie den Upload.
  • Auf die Upload-URL achten. Sie ist kurzlebig und funktioniert einmal. Schlägt der PUT fehl oder kommt er zu spät, fordern Sie einen neuen Upload an: Gepostet wurde noch nichts.
  • Prüfen, bevor der Gast hinsteht. Lesen Sie das Engagement: Ist sein state closed, werden Posts mit 423 abgelehnt. Lassen Sie die Fotobox das sagen, statt ein Bild zu machen, das nicht an die Wall kann.
  • Den Schlüssel schützen. Er kann in jedes Engagement Ihres Workspaces posten. Bewahren Sie ihn auf dem Computer der Fotobox oder im Relay auf, und widerrufen Sie ihn unter Settings → Integrations, falls er in falsche Hände gerät.

Verbinden Sie Ihre Fotobox vor dem nächsten Anlass

Jedes Feld, jeden Fehler und jedes Limit finden Sie unter The Engagement API, mit dem Fotobox-Beispiel in curl, Node.js und Python, sowie in der API-Referenz. Wie die Polaroid-Wall funktioniert, steht in Vom QR-Code zur Polaroid-Wall, und wie Fotobox und Bildschirme zusammenspielen, in Fotobox mieten oder digitale Fotobox auf Ihren Bildschirmen? Sie betreiben Fotoboxen beruflich? Lesen Sie Wunderframe für Fotografen. Die Pläne finden Sie unter Preise. Starten Sie kostenlos, erstellen Sie ein Engagement und einen API-Schlüssel und schicken Sie eine Testaufnahme an die Wall.

Live engagement, How-to

A guest photo wall for your wedding, no app needed

Guests take the best photos of a wedding, and the couple usually sees them weeks later. A photo wall puts them on the big screen during the party. How to set one up, what makes guests use it, and what to decide about privacy first.

The Wunderframe team 3 min read

Event production, Live presenters

Live speakers without surprises: a playbook for event managers

Rehearsals, the backstage link, a network you control, operators for every room and a Q&A that knows who picks the questions. What to prepare with your speakers before the day, and how the day itself runs.

The Wunderframe team 13 min read