// Outbound mail via SendGrid v3 (domain-authenticated instantadpay.com). // Key sources: SENDGRID_KEY env, else DATA_DIR/sendgrid.key in the volume. // No key = email sign-in stays feature-flagged off in production. const fs = require('fs'); const path = require('path'); const https = require('https'); let DATA_DIR = null; const FROM = { email: 'no-reply@instantadpay.com', name: 'InstantAdPay' }; function init(opts) { DATA_DIR = opts.dataDir; } function key() { if (process.env.SENDGRID_KEY) return process.env.SENDGRID_KEY.trim(); try { return fs.readFileSync(path.join(DATA_DIR, 'sendgrid.key'), 'utf8').trim(); } catch (e) { return ''; } } function hasKey() { return !!key(); } function send(to, subject, text) { return new Promise((resolve, reject) => { const body = JSON.stringify({ personalizations: [{ to: [{ email: to }] }], from: FROM, subject, content: [{ type: 'text/plain', value: text }] }); const req = https.request({ hostname: 'api.sendgrid.com', path: '/v3/mail/send', method: 'POST', headers: { Authorization: 'Bearer ' + key(), 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) }, timeout: 15000 }, res => { let d = ''; res.on('data', c => d += c); res.on('end', () => res.statusCode < 300 ? resolve(true) : reject(new Error('sendgrid ' + res.statusCode + ': ' + d.slice(0, 200)))); }); req.on('error', reject); req.on('timeout', () => req.destroy(new Error('sendgrid timeout'))); req.end(body); }); } function sendCode(to, code) { return send(to, code + ' is your InstantAdPay sign-in code', 'Your sign-in code is: ' + code + '\n\n' + 'It works for 15 minutes. If you did not request it, ignore this email.\n\n' + 'InstantAdPay\nAdvertise and earn instantly. Locked in code, not promises.\nhttps://instantadpay.com'); } module.exports = { init, hasKey, send, sendCode };