feat: add backend proxy endpoints for sticker wall retrieval and rendering
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
60
backend/routes/stickerwalls.js
Normal file
60
backend/routes/stickerwalls.js
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const { authenticateToken } = require('../middleware/auth');
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
const VOTE_APP_URL = process.env.VOTE_APP_URL;
|
||||||
|
const VOTE_APP_API_KEY = process.env.VOTE_APP_API_KEY;
|
||||||
|
|
||||||
|
router.get('/:sessionId', authenticateToken, async (req, res) => {
|
||||||
|
const { sessionId } = req.params;
|
||||||
|
if (!VOTE_APP_URL) {
|
||||||
|
return res.status(503).json({ error: 'Vote app not configured' });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const upstream = await fetch(`${VOTE_APP_URL}/stickerwalls/${sessionId}.png`);
|
||||||
|
if (!upstream.ok) {
|
||||||
|
return res.status(upstream.status).end();
|
||||||
|
}
|
||||||
|
res.set('Content-Type', 'image/png');
|
||||||
|
const cacheControl = upstream.headers.get('cache-control');
|
||||||
|
if (cacheControl) {
|
||||||
|
res.set('Cache-Control', cacheControl);
|
||||||
|
}
|
||||||
|
const buffer = Buffer.from(await upstream.arrayBuffer());
|
||||||
|
res.send(buffer);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Sticker wall GET proxy error:', err.message);
|
||||||
|
res.status(502).json({ error: 'Failed to fetch sticker wall' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/:sessionId/render', authenticateToken, async (req, res) => {
|
||||||
|
const { sessionId } = req.params;
|
||||||
|
if (!VOTE_APP_URL || !VOTE_APP_API_KEY) {
|
||||||
|
return res.status(503).json({ error: 'Vote app not configured' });
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const upstream = await fetch(`${VOTE_APP_URL}/api/stickerwalls/${sessionId}/render`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'X-API-Key': VOTE_APP_API_KEY },
|
||||||
|
});
|
||||||
|
if (!upstream.ok) {
|
||||||
|
return res.status(upstream.status).end();
|
||||||
|
}
|
||||||
|
res.set('Content-Type', 'image/png');
|
||||||
|
const rendered = upstream.headers.get('x-sticker-wall-rendered');
|
||||||
|
if (rendered) {
|
||||||
|
res.set('X-Sticker-Wall-Rendered', rendered);
|
||||||
|
}
|
||||||
|
const buffer = Buffer.from(await upstream.arrayBuffer());
|
||||||
|
res.send(buffer);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Sticker wall render proxy error:', err.message);
|
||||||
|
res.status(502).json({ error: 'Failed to render sticker wall' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
@@ -27,6 +27,7 @@ const statsRoutes = require('./routes/stats');
|
|||||||
const pickerRoutes = require('./routes/picker');
|
const pickerRoutes = require('./routes/picker');
|
||||||
const votesRoutes = require('./routes/votes');
|
const votesRoutes = require('./routes/votes');
|
||||||
const webhooksRoutes = require('./routes/webhooks');
|
const webhooksRoutes = require('./routes/webhooks');
|
||||||
|
const stickerwallsRoutes = require('./routes/stickerwalls');
|
||||||
|
|
||||||
app.use('/api/auth', authRoutes);
|
app.use('/api/auth', authRoutes);
|
||||||
app.use('/api/games', gamesRoutes);
|
app.use('/api/games', gamesRoutes);
|
||||||
@@ -35,6 +36,7 @@ app.use('/api/stats', statsRoutes);
|
|||||||
app.use('/api', pickerRoutes);
|
app.use('/api', pickerRoutes);
|
||||||
app.use('/api/votes', votesRoutes);
|
app.use('/api/votes', votesRoutes);
|
||||||
app.use('/api/webhooks', webhooksRoutes);
|
app.use('/api/webhooks', webhooksRoutes);
|
||||||
|
app.use('/api/stickerwalls', stickerwallsRoutes);
|
||||||
|
|
||||||
// Error handling middleware
|
// Error handling middleware
|
||||||
app.use((err, req, res, next) => {
|
app.use((err, req, res, next) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user