← back to Abramsagency
server.js
59 lines
const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();
const PORT = process.env.PORT || 9788;
const DATA = path.join(__dirname, 'data', 'leads.jsonl');
// --- Lead notification email (env-gated, OFF by default) ---
// George's send-gate blocks a form emailing its OWN new-domain info@ (fail-closed),
// so notifications route to a KNOWN-GOOD inbox, not info@abramsagency.com.
const LEAD_NOTIFY = process.env.LEAD_NOTIFY === '1'; // flip to 1 to enable
const LEAD_TO = process.env.LEAD_TO || 'steve@designerwallcoverings.com';
const GEORGE_SEND = process.env.GEORGE_SEND || 'http://127.0.0.1:9850/api/send';
async function notify(lead) {
if (!LEAD_NOTIFY) return;
const body = {
to: LEAD_TO,
subject: `New AbramsAgency lead: ${lead.name} — ${lead.need}`,
text: `Name: ${lead.name}\nEmail: ${lead.email}\nNeed: ${lead.need}\n\n${lead.message}\n\n(${lead.ts})`
};
try {
await fetch(GEORGE_SEND, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
} catch (e) { console.warn('[lead] notify failed:', e.message); } // never block the user on notify failure
}
try { fs.mkdirSync(path.dirname(DATA), { recursive: true }); } catch (_) {} // ensure data/ exists on a fresh box
app.use(express.json({ limit: '32kb' }));
app.use(express.static(path.join(__dirname, 'public'), { extensions: ['html'] }));
// Lead capture — stores locally (append-only). Email wiring (George) is a gated follow-up.
app.post('/api/contact', (req, res) => {
const { name, email, need, message } = req.body || {};
if (!name || !email || !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) {
return res.status(400).json({ ok: false, error: 'name and a valid email are required' });
}
const lead = {
ts: new Date().toISOString(),
name: String(name).slice(0, 200),
email: String(email).slice(0, 200),
need: String(need || '').slice(0, 200),
message: String(message || '').slice(0, 4000),
ip: req.headers['x-forwarded-for'] || req.socket.remoteAddress || ''
};
try {
fs.appendFileSync(DATA, JSON.stringify(lead) + '\n');
} catch (e) {
return res.status(500).json({ ok: false, error: 'could not save' });
}
console.log(`[lead] ${lead.ts} ${lead.name} <${lead.email}> — ${lead.need}`);
notify(lead); // fire-and-forget; env-gated, never blocks the response
res.json({ ok: true });
});
app.get('/healthz', (_req, res) => res.json({ ok: true, service: 'abramsagency' }));
app.listen(PORT, () => console.log(`Abrams Agency site on http://127.0.0.1:${PORT}`));