bolt-templates-sms-extensio.../server/routes/templates.js
2026-03-26 14:19:26 +05:30

135 lines
5.3 KiB
JavaScript

const express = require('express');
const router = express.Router();
const { fetchJSON, uploadJSON, listImages, listTemplateFiles } = require('../services/pixelbin');
const { processCurl } = require('../services/openai2');
// GET /api/templates/images — must be BEFORE /:slug to avoid conflict
router.get('/images', async (req, res) => {
try {
const images = await listImages(`brands/${process.env.MERCHANT_ID}/images`);
res.json({ images });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// GET /api/templates
router.get('/', async (req, res) => {
try {
const merchantId = process.env.MERCHANT_ID;
const folder = `brands/${merchantId}/templates`;
console.log(`[Templates] GET /api/templates start | merchant=${merchantId} | pid=${process.pid}`);
const slugs = await listTemplateFiles(folder);
console.log(`[Templates] GET /api/templates files | merchant=${merchantId} | slugs=[${slugs.join(', ')}]`);
const templates = [];
for (const slug of slugs) {
const tmpl = await fetchJSON(folder, slug);
if (tmpl) {
console.log(
`[Templates] GET /api/templates item | merchant=${merchantId} | slug=${slug} | eventSlug=${tmpl.eventSlug || 'n/a'} | approved=${!!tmpl.approvedVariant} | updatedAt=${tmpl.updatedAt || 'n/a'}`
);
templates.push(tmpl);
} else {
console.log(`[Templates] GET /api/templates item-miss | merchant=${merchantId} | slug=${slug}`);
}
}
console.log(`[Templates] GET /api/templates done | merchant=${merchantId} | count=${templates.length}`);
res.json({ templates });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// GET /api/templates/:slug
router.get('/:slug', async (req, res) => {
try {
const merchantId = process.env.MERCHANT_ID;
const slug = req.params.slug;
const folder = `brands/${merchantId}/templates`;
console.log(`[Templates] GET /api/templates/:slug start | merchant=${merchantId} | slug=${slug} | pid=${process.pid}`);
const tmpl = await fetchJSON(folder, slug);
if (!tmpl) return res.status(404).json({ error: 'Template not found' });
console.log(
`[Templates] GET /api/templates/:slug done | merchant=${merchantId} | slug=${slug} | approved=${!!tmpl.approvedVariant} | updatedAt=${tmpl.updatedAt || 'n/a'}`
);
res.json(tmpl);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// POST /api/templates/:slug/approve
router.post('/:slug/approve', async (req, res) => {
try {
const { approvedVariant } = req.body;
if (!approvedVariant) return res.status(400).json({ error: 'approvedVariant is required' });
const merchantId = process.env.MERCHANT_ID;
const slug = req.params.slug;
const folder = `brands/${merchantId}/templates`;
console.log(
`[Templates] POST /api/templates/:slug/approve start | merchant=${merchantId} | slug=${slug} | incomingLen=${approvedVariant.length} | pid=${process.pid}`
);
const tmpl = await fetchJSON(folder, slug);
if (!tmpl) return res.status(404).json({ error: 'Template not found' });
console.log(
`[Templates] POST /api/templates/:slug/approve before | merchant=${merchantId} | slug=${slug} | approved=${!!tmpl.approvedVariant} | updatedAt=${tmpl.updatedAt || 'n/a'}`
);
tmpl.approvedVariant = approvedVariant;
tmpl.whitelistStatus = 'submitted';
tmpl.updatedAt = new Date().toISOString();
await uploadJSON(folder, slug, tmpl);
console.log(
`[Templates] POST /api/templates/:slug/approve after | merchant=${merchantId} | slug=${slug} | approved=${!!tmpl.approvedVariant} | updatedAt=${tmpl.updatedAt}`
);
res.json(tmpl);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// POST /api/templates/:slug/curl
router.post('/:slug/curl', async (req, res) => {
try {
const { rawCurl } = req.body;
if (!rawCurl) return res.status(400).json({ error: 'rawCurl is required' });
const folder = `brands/${process.env.MERCHANT_ID}/templates`;
const tmpl = await fetchJSON(folder, req.params.slug);
if (!tmpl) return res.status(404).json({ error: 'Template not found' });
if (!tmpl.approvedVariant) return res.status(400).json({ error: 'Template must have an approved variant first' });
const { processedCurl, variableMap } = await processCurl(rawCurl, tmpl.approvedVariant, req.params.slug);
tmpl.rawCurl = rawCurl;
tmpl.processedCurl = processedCurl;
tmpl.variableMap = variableMap;
tmpl.updatedAt = new Date().toISOString();
await uploadJSON(folder, req.params.slug, tmpl);
res.json({ processedCurl, variableMap });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// POST /api/templates/:slug/image
router.post('/:slug/image', async (req, res) => {
try {
const { imagePath } = req.body;
if (imagePath === undefined) return res.status(400).json({ error: 'imagePath is required' });
const folder = `brands/${process.env.MERCHANT_ID}/templates`;
const tmpl = await fetchJSON(folder, req.params.slug);
if (!tmpl) return res.status(404).json({ error: 'Template not found' });
tmpl.selectedImagePath = imagePath;
tmpl.updatedAt = new Date().toISOString();
await uploadJSON(folder, req.params.slug, tmpl);
res.json(tmpl);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
module.exports = router;