101 lines
3.2 KiB
Markdown
101 lines
3.2 KiB
Markdown
|
|
# Sticker Wall Images — Integration Guide
|
|||
|
|
|
|||
|
|
The vote-app renders per-session sticker walls as 1920×1080 PNG images with transparent backgrounds. These can be loaded directly as `<img>` sources to display a session's sticker wall.
|
|||
|
|
|
|||
|
|
## Endpoints
|
|||
|
|
|
|||
|
|
### Retrieve Sticker Wall Image
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
GET /stickerwalls/{sessionID}.png
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Authentication:** None (public endpoint)
|
|||
|
|
|
|||
|
|
**Response:**
|
|||
|
|
- `200 OK` — image/png body, `Cache-Control: public, max-age=3600`
|
|||
|
|
- `404 Not Found` — no render has been performed for this session yet
|
|||
|
|
|
|||
|
|
**Usage:** Load directly as an image source:
|
|||
|
|
```html
|
|||
|
|
<img src="https://vote-app.example.com/stickerwalls/42.png" />
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Trigger Render
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
POST /api/stickerwalls/{sessionID}/render
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Authentication:** Required — `X-API-Key` header with the upstream API key.
|
|||
|
|
|
|||
|
|
**Response:**
|
|||
|
|
- `200 OK` — image/png body with the rendered sticker wall
|
|||
|
|
- `403 Forbidden` — missing or invalid API key
|
|||
|
|
- `404 Not Found` — session has no placed stickers
|
|||
|
|
|
|||
|
|
**Response Headers:**
|
|||
|
|
- `X-Sticker-Wall-Rendered: true` — a fresh render was performed
|
|||
|
|
- `X-Sticker-Wall-Rendered: false` — served from cache (no new stickers since last render)
|
|||
|
|
|
|||
|
|
## Behavior
|
|||
|
|
|
|||
|
|
### Active Sessions
|
|||
|
|
|
|||
|
|
During an active session, stickers are placed by voters and stored in the database. The sticker wall image is **not** automatically re-rendered on each sticker purchase (to avoid thrashing).
|
|||
|
|
|
|||
|
|
To get a fresh image during an active session:
|
|||
|
|
1. Call `POST /api/stickerwalls/{sessionID}/render`
|
|||
|
|
2. If new stickers were placed since the last render, a fresh image is generated
|
|||
|
|
3. The response contains the image bytes directly
|
|||
|
|
|
|||
|
|
### Session End
|
|||
|
|
|
|||
|
|
When a session ends, the vote-app automatically renders the final sticker wall image. After this point:
|
|||
|
|
- The image is **immutable** — it will never be re-rendered
|
|||
|
|
- `GET /stickerwalls/{sessionID}.png` returns the final image directly
|
|||
|
|
- `POST /api/stickerwalls/{sessionID}/render` returns the cached final image (with `X-Sticker-Wall-Rendered: false`)
|
|||
|
|
|
|||
|
|
### Historical Sessions
|
|||
|
|
|
|||
|
|
Sessions that existed before this feature was deployed will be rendered on first request (via the render endpoint). Once rendered, they are cached and served normally.
|
|||
|
|
|
|||
|
|
## Suggested Integration
|
|||
|
|
|
|||
|
|
### Post-Session Retrieval (most common)
|
|||
|
|
|
|||
|
|
After a session ends, load the sticker wall for display or archival:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
const sessionId = 42;
|
|||
|
|
const img = new Image();
|
|||
|
|
img.src = `https://vote-app.example.com/stickerwalls/${sessionId}.png`;
|
|||
|
|
img.onload = () => { /* display it */ };
|
|||
|
|
img.onerror = () => { /* no sticker wall for this session */ };
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Active Session Preview
|
|||
|
|
|
|||
|
|
To show a "live preview" of the current sticker wall during a session:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
async function refreshStickerWall(sessionId) {
|
|||
|
|
const res = await fetch(`/api/stickerwalls/${sessionId}/render`, {
|
|||
|
|
method: 'POST',
|
|||
|
|
headers: { 'X-API-Key': API_KEY }
|
|||
|
|
});
|
|||
|
|
if (res.ok) {
|
|||
|
|
const blob = await res.blob();
|
|||
|
|
const url = URL.createObjectURL(blob);
|
|||
|
|
document.getElementById('sticker-wall-preview').src = url;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Image Format
|
|||
|
|
|
|||
|
|
- **Dimensions:** 1920×1080 pixels
|
|||
|
|
- **Format:** PNG with alpha transparency
|
|||
|
|
- **Background:** Fully transparent — overlay on any background
|
|||
|
|
- **Sticker rendering:** Positioned, scaled, and rotated to match the live display
|