Reliez votre photobooth au grand écran
Votre photobooth fait déjà de belles photos. Avec l’API Engagement, chaque prise arrive quelques secondes plus tard sur le mur de polaroids, et l’invité scanne un QR code pour l’emporter. Les trois appels, et une recette pour Sparkbooth, pibooth, dslrBooth et tout photobooth avec un dossier de sortie.
The Wunderframe team 8 min read
Le photobooth est le coin le plus animé de la plupart des fêtes. Mais ce qu’il photographie reste en général dans la cabine : l’invité voit sa photo quelques secondes sur un petit écran, et les autres ne voient rien jusqu’à ce que le lien de la galerie arrive une semaine plus tard.
Si l’événement tourne avec Wunderframe, votre photobooth peut publier directement dans l’engagement de la soirée, le même que celui où les invités publient depuis leur téléphone. La photo s’affiche sur le mur de polaroids quelques secondes plus tard, et l’invité scanne un QR code pour l’emporter. Vous gardez votre photobooth, votre appareil photo et votre logiciel. Vous ajoutez quelques lignes de code.
Pourquoi les photos du photobooth ont leur place sur le grand écran
- C’est instantané. Le tirage se révèle sur le mur pendant que l’invité pose encore les accessoires. C’est le moment où les gens lèvent les yeux.
- Tout le monde le voit. Un seul photobooth devient un spectacle pour toute la salle, à côté des photos et des notes que les invités envoient depuis leur téléphone.
- Les invités l’emportent. Chaque photo reçoit son propre lien à emporter : une page sur le téléphone de l’invité avec sa photo et les boutons Partager et Enregistrer. Pas d’application, pas d’adresse e-mail, pas de galerie à fouiller.
Le mur de polaroids. Une photo du photobooth y prend place à côté des photos que les invités envoient depuis leur téléphone.
Le déroulement : trois appels et une courte attente
D’abord, en tant que propriétaire (owner) du workspace, créez une clé d’API sous Settings → Integrations avec Live engagements (engagements:write). Gardez-la sur l’ordinateur du photobooth ou sur votre serveur, jamais dans une page web. GET /api/v1/engagements vous donne l’id de l’engagement, ses rooms avec leurs clés, et s’il demande un consentement (consent). Ensuite, pour chaque photo :
- Demander un upload.
POST /api/v1/engagements/{id}/uploadsaveckind,mimeet la taille exacte enbytes. Vous recevez unupload_idet uneupload_urlsignée. - Envoyer le fichier. Envoyez les octets par PUT à
upload_url, avec lesheadersindiqués dans la réponse, tout de suite : l’URL est de courte durée et ne sert qu’une fois. - Publier.
POST /api/v1/engagements/{id}/postsavec l’upload_id, unclient_labelcomme Booth 1, la clé de laroomsi l’engagement a des salles, et"consent": trues’il demande un consentement. Envoyez un en-têteIdempotency-Key: le hash du fichier convient très bien. - Attendre la copie. Interrogez
GET /api/v1/engagements/{id}/posts/{post_id}toutes les deux secondes jusqu’à ce queshare_readysoit true, puis afficheztake_home_urlen QR code.
Tout le déroulement en Node.js 18 ou plus récent, sans rien installer :
// 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])));L’API s’occupe de plusieurs choses pour vous. La publication passe par la modération de l’engagement comme celle d’un invité : avec approval, elle attend la régie avant d’arriver sur les murs. Le lien à emporter est valable 24 heures, et chaque interrogation renvoie le même lien. Si quelqu’un scanne avant que la copie soit prête, la page attend simplement quelques secondes. Avec le plan gratuit, la copie partagée porte une petite marque Wunderframe dans un coin ; les murs affichent toujours la photo sans elle. Les mêmes quelques lignes en Python se trouvent dans la documentation.
Une recette pour votre photobooth
Les logiciels de photobooth se rangent en trois familles : certains envoient vers un serveur que vous indiquez, d’autres lancent un plugin ou un script après chaque photo, d’autres encore ne font qu’écrire des fichiers dans un dossier. Il existe une porte d’entrée pour les trois.
Sparkbooth : un petit relais
Le Custom Upload
de Sparkbooth envoie chaque photo en POST multipart vers une Service URL de votre choix, avec les
champs media, username, password, name,
email et message. Il attend en retour
{"status":true,"url":"…"} et
affiche cette url en QR code
sur son écran de partage. Un relais reçoit donc l’upload, appelle l’API Engagement et répond avec
le lien à emporter :
// 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);
Répondez vite : Sparkbooth attend le relais, et la page à emporter attend la copie d’elle-même.
La clé ne se trouve que dans le relais, et celui-ci ignore email, dont Wunderframe
n’a pas besoin.
pibooth : un plugin de quelques lignes
pibooth,
le photobooth pour Raspberry Pi, exécute des plugins Python sur des hooks. Après le traitement,
la photo finale est app.previous_picture_file. Un plugin d’upload renseigne
app.previous_picture_url, comme le fait
pibooth-google-photo, et
pibooth-qrcode l’affiche lorsque son
prefix_url vaut {url}. Une esquisse, où post_shot est la
version Python des trois appels tirée de la documentation :
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 onlinedslrBooth et LumaBooth pour Windows : un trigger
Ces photobooths ont des Triggers : lors d’événements comme processing_start, qui transmet le final_file, ou session_end, ils appellent une URL de webhook ou lancent une application. Pointez-en un vers send-shot.mjs ou vers un petit webhook local, et le fichier final part sur le mur. Leurs propres QR codes mènent à l’hébergement de Lumasoft : affichez donc vous-même le QR code à emporter, comme décrit plus bas.
PhotoboothProject et photobooth-app : une commande ou un plugin
Le PhotoboothProject, basé sur le web, lance après chaque photo une commande où %s est le nom du fichier : node send-shot.mjs %s suffit. photobooth-app accepte comme pibooth des plugins Python sur ses hooks, et son synchroniseur rclone peut aussi copier les photos dans un dossier que la recette suivante surveille.
Tout autre photobooth : surveiller le dossier de sortie
Les applications fermées comme LumaBooth sur iPad, Darkroom ou Breeze écrivent leurs photos
finales dans un dossier de sortie. Surveillez ce dossier et envoyez chaque nouveau fichier : avec
inotifywait ou rclone sous Linux, avec Hazel sous macOS. Attendez que le fichier soit
entièrement écrit, sinon vous envoyez une demi-photo. Sous Linux, close_write et
moved_to ne se déclenchent qu’à ce moment-là :
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/
doneAfficher le QR code
Sur le photobooth, quand il le permet. Sparkbooth affiche l’url que votre relais renvoie, et pibooth-qrcode affiche app.previous_picture_url. L’invité scanne au moment même où il voit sa photo, c’est-à-dire quand il la veut.
À côté du photobooth, quand il ne le permet pas. Si le photobooth n’affiche que son propre code, laissez votre script afficher le QR code à emporter : une fenêtre de navigateur en plein écran sur un second moniteur du photobooth, ou un petit écran juste à côté, toujours avec le lien le plus récent. Les grands écrans près du mur de polaroids font alors ce qu’ils font de mieux : montrer chaque photo dès son arrivée, avec le QR code de l’engagement, pour que les invités sans photobooth puissent publier depuis leur téléphone.
Laissez un code à emporter près du photobooth et affiché une vingtaine de secondes. Il ouvre la photo d’une seule personne, il n’a donc pas sa place sur l’écran de scène, où toute la salle peut le scanner.
Le photobooth prend la photo. Le mur la montre à la salle. Le QR code l’envoie à la maison.
Liste de contrôle pour la protection des données et la fiabilité
- Demander, puis publier. Si l’engagement demande un consentement, affichez son
consent.textsur l’écran d’accueil du photobooth et n’envoyez"consent": truequ’après l’accord de l’invité. Placez au photobooth une mention bien visible indiquant que ses photos apparaissent sur les écrans. - Modérer avant d’afficher. Réglez l’engagement sur approval si une personne doit voir chaque photo avant la salle. Une publication refusée perd son lien à emporter.
- Collecter le moins possible. Wunderframe n’a besoin ni d’adresse e-mail ni de nom.
client_labeldésigne le photobooth, pas la personne. La durée de conservation de l’engagement s’applique aux photos du photobooth comme à toutes les autres. - Mettre en file d’attente hors ligne. Gardez chaque photo sur le photobooth et envoyez-la dès que le réseau revient. Le photobooth continue de photographier.
- Réessayer sans risque. Réessayez une publication avec le même
upload_idet la mêmeIdempotency-Key: vous recevez la première publication au lieu d’une seconde. Une fois publié, réessayez la publication, jamais l’upload. - Surveiller l’URL d’upload. Elle est de courte durée et ne sert qu’une fois. Si le PUT échoue ou arrive trop tard, demandez un nouvel upload : rien n’a encore été publié.
- Vérifier avant que l’invité se présente. Lisez l’engagement : si son
stateestclosed, les publications sont refusées avec423. Que le photobooth le dise, plutôt que de prendre une photo qui ne pourra pas s’afficher. - Protéger la clé. Elle peut publier dans chaque engagement de votre workspace. Gardez-la sur l’ordinateur du photobooth ou dans le relais, et révoquez-la sous Settings → Integrations si elle fuite.
Reliez votre photobooth avant le prochain événement
Chaque champ, chaque erreur et chaque limite se trouvent dans The Engagement API, avec l’exemple du photobooth en curl, Node.js et Python, et dans la référence de l’API. Le fonctionnement du mur de polaroids est décrit dans Du QR code au mur de polaroids, et la façon dont photobooth et écrans travaillent ensemble dans Louer un photobooth ou un photobooth numérique sur vos écrans ? Vous exploitez des photobooths à titre professionnel ? Voyez Wunderframe pour les photographes. Les plans sont sur la page Tarifs. Commencez gratuitement, créez un engagement et une clé d’API, et envoyez une photo de test sur le mur.
Related posts
From QR code to polaroid wall: engage 1,000 guests without an app
A QR code, a phone browser and your screens. How to set up sticky notes, questions and a polaroid wall for a big crowd, and what changes when a thousand people post.
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.
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.

