← back to Nodailyworries
server.js
42 lines
// No Daily Worries — insurance guide site. Static content + a lead-capture
// endpoint. Zero-config: serves public/, appends leads to data/leads.jsonl.
const express = require('express');
const fs = require('node:fs');
const path = require('node:path');
const app = express();
const PORT = process.env.PORT || 9931;
const PUB = path.join(__dirname, 'public');
const LEADS = path.join(__dirname, 'data', 'leads.jsonl');
app.use(express.json({ limit: '16kb' }));
// ads.txt served explicitly (authorizes the AdSense account for this domain)
app.get('/ads.txt', (_req, res) => {
res.type('text/plain').send('google.com, pub-5278231299883833, DIRECT, f08c47fec0942fa0\n');
});
app.get('/healthz', (_req, res) => res.json({ ok: true, site: 'nodailyworries' }));
// lead capture — minimal validation, append-only JSONL
app.post('/api/lead', (req, res) => {
const { email = '', line = '', zip = '' } = req.body || {};
if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) return res.status(400).json({ ok: false, error: 'invalid email' });
const row = {
ts: new Date().toISOString(),
email: String(email).slice(0, 200),
line: String(line).slice(0, 60),
zip: String(zip).replace(/[^0-9]/g, '').slice(0, 5),
ip: (req.headers['x-forwarded-for'] || req.socket.remoteAddress || '').toString().split(',')[0].trim(),
};
try {
fs.mkdirSync(path.dirname(LEADS), { recursive: true });
fs.appendFileSync(LEADS, JSON.stringify(row) + '\n');
} catch (e) { return res.status(500).json({ ok: false }); }
res.json({ ok: true });
});
app.use(express.static(PUB, { extensions: ['html'] }));
app.listen(PORT, () => console.log(`nodailyworries on :${PORT}`));