/ scripts / send-test-email.mjs
send-test-email.mjs
 1  #!/usr/bin/env node
 2  /**
 3   * One-shot script: send a representative sample outreach email to deliverability
 4   * test addresses (mail-tester.com, Email on Acid, etc.)
 5   *
 6   * Usage:
 7   *   node scripts/send-test-email.mjs
 8   *   node scripts/send-test-email.mjs recipient@example.com
 9   */
10  
11  import '../src/utils/load-env.js';
12  
13  const {RESEND_API_KEY} = process.env;
14  if (!RESEND_API_KEY) { console.error('RESEND_API_KEY not set'); process.exit(1); }
15  
16  const SENDER_NAME    = process.env.SENDER_NAME    || 'Marcus Webb';
17  const SENDER_EMAIL   = process.env.SENDER_EMAIL   || 'marcus@auditandfix.com';
18  const SIGNATURE      = (process.env.EMAIL_SIGNATURE || `Best regards,\n${SENDER_NAME}\nAudit&Fix`).replace(/\\n/g, '\n');
19  const PHYSICAL_ADDR  = process.env.CAN_SPAM_PHYSICAL_ADDRESS || '';
20  const UNSUBSCRIBE_URL = 'https://auditandfix.com/unsubscribe?id=test&token=abc123test';
21  
22  const SUBJECT = "your electrician website isn't converting visitors";
23  
24  const BODY = `Hi there,
25  
26  Your tarelectric.ca website scored 51.4/100 (D grade). We've analysed 43,000+ local business sites, and your homepage lacks clear trust signals and a compelling unique selling proposition.
27  
28  Nothing is broken, but you could be missing out on up to 22-32% more leads just from the way your homepage and call-to-action are structured above the fold.
29  
30  I do simple Website Conversion Audits that break this down and show exactly what to change for fast lead increases. It's a one-time service — 24-hour turnaround — and the audit is yours to keep.
31  
32  Would you be interested in seeing what I found?`;
33  
34  function buildHtml(body, sig, unsubUrl, physAddr, senderName) {
35    const toHtml = t => t.split('\n')
36      .map(l => l.replace(/(https?:\/\/[^\s]+)/g, '<a href="$1" style="color:#0066cc;">$1</a>'))
37      .join('<br>');
38    const physHtml = physAddr
39      ? `<div style="margin-top:10px;font-size:11px;color:#999;">${physAddr}</div>` : '';
40    return `<!DOCTYPE html>
41  <html>
42  <head>
43    <meta charset="utf-8">
44    <meta name="viewport" content="width=device-width, initial-scale=1.0">
45    <title>${senderName} — website review</title>
46  </head>
47  <body style="font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;line-height:1.6;color:#333;max-width:600px;margin:0 auto;padding:20px;">
48    <div style="white-space:pre-wrap;">${toHtml(body)}</div>
49    <div style="margin-top:20px;padding-top:20px;border-top:1px solid #eee;white-space:pre-wrap;">${toHtml(sig)}${physHtml}</div>
50    <div style="margin-top:30px;padding-top:20px;border-top:1px solid #eee;font-size:12px;color:#666;">
51      <p>You received this email because ${senderName} found your business online and believes our web optimisation services may be relevant to you. This is a one-time outreach, not a mailing list.</p>
52      <p>If you'd prefer not to receive emails from us, <a href="${unsubUrl}" style="color:#666;">unsubscribe here</a>.</p>
53    </div>
54  </body>
55  </html>`.trim();
56  }
57  
58  const html = buildHtml(BODY, SIGNATURE, UNSUBSCRIBE_URL, PHYSICAL_ADDR, SENDER_NAME);
59  const text = `${BODY}\n\n${SIGNATURE}${PHYSICAL_ADDR ? `\n\n${  PHYSICAL_ADDR}` : ''}\n\n---\nYou received this email because ${SENDER_NAME} found your business online.\nTo unsubscribe: ${UNSUBSCRIBE_URL}`;
60  
61  const targets = process.argv[2]
62    ? [process.argv[2]]
63    : [
64        'test-vk2xyxbp1@srv1.mail-tester.com',
65        'mailteser+default@precheck.emailonacid.com',
66      ];
67  
68  for (const to of targets) {
69    process.stdout.write(`Sending to ${to}... `);
70    const res = await fetch('https://api.resend.com/emails', {
71      method: 'POST',
72      headers: {
73        Authorization: `Bearer ${RESEND_API_KEY}`,
74        'Content-Type': 'application/json',
75        'User-Agent': '333Method/1.0',
76      },
77      body: JSON.stringify({
78        from: `${SENDER_NAME} <${SENDER_EMAIL}>`,
79        to,
80        subject: SUBJECT,
81        html,
82        text,
83        headers: {
84          'List-Unsubscribe': `<${UNSUBSCRIBE_URL}>`,
85          'List-Unsubscribe-Post': 'List-Unsubscribe=One-Click',
86        },
87      }),
88    });
89    const data = await res.json();
90    if (res.ok) {
91      console.log(`✓  Resend ID: ${data.id}`);
92    } else {
93      console.error(`✗  ${res.status}: ${JSON.stringify(data)}`);
94    }
95  }