← 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}`));