AWS Builder Center
Cómo construí un Kiosko para eventos del AWS Student Builder Group con HTML, Amplify y EmailJS

Cómo construí un Kiosko para eventos del AWS Student Builder Group con HTML, Amplify y EmailJS

por Fernando Gutiérrez — AWS Student Builder Group at Instituto Tecnológico de Ocotlán 💜 En nuestro grupo AWS Student Builder Group at ITO CardenalITO's queríamos una experiencia diferente para los asistentes de nuestros eventos: que pudieran tomarse una foto, agregarle stickers con la identidad visual del programa, y recibirla por correo. Sin frameworks, sin backend complejo — solo HTML puro, AWS Amplify y EmailJS. Te cuento cómo lo construimos, los retos que enfrentamos y qué aprendimos en el camino.

El problema

En el AWS Student Builder Group at ITO Ocotlán organizamos eventos donde queremos que los asistentes se lleven algo más que conocimiento. Queríamos una experiencia memorable: que cada persona pudiera tomarse una foto en el evento, personalizarla con stickers de la identidad visual del programa y recibirla directo en su correo.
Como en el eventos de la JSConf en el Both de AWS — donde vimos algo similar — pero construido por nosotros, con nuestra identidad, para nuestra comunidad.
Referencias al cual queria llegar
El reto: hacerlo sin presupuesto, sin dispositivos especiales y que funcionara desde cualquier teléfono o laptop en el evento.

La idea

Un kiosko digital accesible desde el browser. Sin instalar nada. Sin apps. Solo abrir un link.
La experiencia sería:
  1. Abrir la URL en tu teléfono o en una laptop del evento
  2. Tomar una foto con la cámara
  3. Agregar stickers de los iconos oficiales del SBG
  4. Activar el marco "AWS Student Builder Group"
  5. Descargar la foto o recibirla por correo
Simple en concepto. Interesante en ejecución.

Stack técnico
Decidí mantenerlo lo más simple posible:
CapaTecnologíaPor qué
FrontendHTML + CSS + JS vanillaSin frameworks, cero dependencias de build
CámaraWeb API getUserMediaNativa en todos los browsers modernos
EdiciónHTML5 Canvas APIPara combinar foto + stickers en una imagen
HostingAWS AmplifyDeploy en segundos, URL pública, gratis
EmailEmailJSSin backend, directo desde el browser
ImágenesImgBB CDNPara hostear los 60+ iconos sin peso en el repo

Construyendo el Photo Booth
La cámara
Lo primero fue acceder a la cámara. Con la Web API getUserMedia es directo:
1
2
3
4
5
const stream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: 'user', width: { ideal: 1280 } },
audio: false
});
video.srcObject = stream;
El video se muestra en vivo sobre el stage. Al tomar la foto se dibuja el frame del video en un <canvas>.
Los stickers arrastrables
Cada icono del SBG se coloca como un div absoluto sobre el stage con pointer-events y drag usando la Pointer API:
1
2
3
4
5
6
el.addEventListener('pointerdown', (e) => {
state.activeSticker = el;
state.dragOffset.x = e.clientX - rect.left;
state.dragOffset.y = e.clientY - rect.top;
el.setPointerCapture(e.pointerId);
});
Esto funciona igual en mouse y touch — importante para que funcione en teléfono durante el evento.
También agregué un handle de resize en la esquina inferior derecha de cada sticker para que la gente pueda ajustar el tamaño.

El marco y el watermark

El marco es un overlay HTML con position: absolute que se activa con un toggle. Al descargar, todo se aplana en un canvas con drawImage:
1
2
3
// Logo AWS siempre en la foto - similar al marco del evento de la JSConf
await drawImg(ctx, 'https://i.ibb.co/Ng3GhCf7/AWS-smile-RGB-WHT.png',
stageW - 110, stageH - 54, 96, 40);
Logo AWS siempre en la foto - similar al marco del evento de la JSConf

Los retos reales
  1. El problema del file://
    El primer obstáculo fue intentar probar la app abriéndola como archivo local. El browser bloquea fetch y getUserMedia desde file:// por políticas de seguridad.
Solución: Subir a AWS Amplify desde el principio y probar desde la URL pública.
  1. Espacios en nombres de archivo
    Los assets del SBG tienen nombres como AWS Student Builder Group_RGB_Icons_Teams_Magenta.png. Los browsers no cargan imágenes con espacios en rutas locales.
Solución: Hostear todos los iconos en ImgBB y usar URLs directas. Eliminó el problema completamente y además el repo queda limpio y liviano.
  1. CORS duplicado en Lambda
    Intenté primero con una Lambda en Python + Resend para el envío de correos. El error más frustrante fue este:
1
The 'Access-Control-Allow-Origin' header contains multiple values '*, *'
La Lambda retornaba el header CORS en el código Python y la Function URL de AWS lo agregaba automáticamente. Se duplicaban y Chrome lo rechazaba.
Solución: Quitar los headers CORS del código Python y dejar que AWS los maneje solo.
  1. Límite de 50KB en EmailJS
    Al final migré a EmailJS para simplificar — sin Lambda, sin AWS para el correo. Pero EmailJS tiene un límite de 50KB por request y una foto en base64 pesa varios MB.
Solución: Comprimir la foto antes de enviarla:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function compressPhoto(dataUrl, maxSize, quality) {
return new Promise((resolve) => {
const img = new Image();
img.onload = () => {
const canvas = document.createElement('canvas');
const ratio = Math.min(maxSize / img.width, maxSize / img.height, 1);
canvas.width = Math.round(img.width * ratio);
canvas.height = Math.round(img.height * ratio);
canvas.getContext('2d').drawImage(img, 0, 0, canvas.width, canvas.height);
resolve(canvas.toDataURL('image/jpeg', quality));
};
img.src = dataUrl;
});
}

// Comprimir a 400px, calidad 50% → ~15-20KB
const compressed = await compressPhoto(photoDataUrl, 400, 0.5);
De varios MB a menos de 20KB. El correo llega con la foto incluida.

El resultado

Una app de una sola página (index.html) que:
  • Abre la cámara del dispositivo
  • Permite agregar 60+ stickers de la identidad visual del SBG en 7 colores
  • Activa un marco oficial "AWS Student Builder Group"
  • Descarga la foto con todos los elementos
  • Envía la foto por correo con un mensaje personalizado:
"Hola [Nombre], Futuro Builder Member 💜 — Esta es tu foto del evento. ¡Saliste muy Guap@! Esperamos que te unas a nuestra comunidad."
Deploy: AWS Amplify — URL pública lista en minutos
Costo: $0

Lo que aprendí

  • HTML puro sigue siendo poderoso. Canvas API + Pointer API + getUserMedia hacen cosas que hace unos años requerían Flash o apps nativas.
  • Simplificar la arquitectura ahorra horas. Empecé con Lambda + Resend + API Gateway. Terminé con EmailJS directo desde el browser. Menos piezas, menos problemas.
  • Hostear assets en CDN desde el principio. Los nombres de archivo con espacios y el problema de file:// se resuelven solos cuando las imágenes viven en una URL.
  • AWS Amplify para static hosting es imbatible. ZIP, drag & drop, URL pública en 2 minutos

Links
Demo: https://staging.d2pm9uwh5z4g6s.amplifyapp.com
GitHub: https://github.com/EnderlotLG/aws-sbg-photobooth
AWS Student Builder Group at ITO CardenalITO's: https://builder.aws.com/community/student-builder-groups

Próximos pasos
Agregar modo galería para ver las fotos del evento en tiempo real
Integrar con AWS S3 para guardar las fotos
Versión multilingüe (EN/ES)
QR code en el evento para acceder directo desde el teléfono

Construido con Amor💜 para los CardenalITOs — AWS Student Builder Group at Instituto Tecnológico de Ocotlán & AWS Community Latam & AWS SBG WW
¿Tienes un grupo SBG y quieres usar esto en tu próximo evento? El código está en GitHub — fork it y personalízalo con tu identidad.

Te dejo unos ejemplos de las fotos del Photo Booth interactivo*:*
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article