← back to Ventura Corridor
scripts/purelymail_alias.cjs
97 lines
/**
* Set up `info@venturablvd.agentabrams.com` on Purelymail.
*
* Per Purelymail v0 API: routing rules are scoped to a registered domain.
* Subdomains are NOT inherited from the parent — venturablvd.agentabrams.com
* must be added as its own domain, then the rule is created against it.
*
* Flow:
* 1. listDomains — see if venturablvd.agentabrams.com is already registered
* 2. addDomain — register the subdomain if missing (returns DKIM/SPF/MX records to publish)
* 3. createRoutingRule on venturablvd.agentabrams.com (matchUser=info → info@designerwallcoverings.com)
*
* Reads PURELYMAIL_API_TOKEN from ~/Projects/secrets-manager/.env.
*
* Run: node scripts/purelymail_alias.cjs
*/
const fs = require('fs');
const path = require('path');
const os = require('os');
const ENV_PATH = path.join(os.homedir(), 'Projects/secrets-manager/.env');
let TOKEN = process.env.PURELYMAIL_API_TOKEN || '';
if (!TOKEN) {
try {
const txt = fs.readFileSync(ENV_PATH, 'utf8');
const m = txt.match(/^PURELYMAIL_API_TOKEN=(.+)$/m);
if (m) TOKEN = m[1].trim();
} catch {}
}
if (!TOKEN) {
console.error('[purelymail] no PURELYMAIL_API_TOKEN in', ENV_PATH);
console.error(' Generate one at https://purelymail.com/manage → API,');
console.error(' then: node ~/Projects/secrets-manager/cli.js add PURELYMAIL_API_TOKEN <value>');
process.exit(1);
}
const API = 'https://purelymail.com/api/v0';
const SUBDOMAIN = 'venturablvd.agentabrams.com';
const TARGET = 'info@designerwallcoverings.com';
async function call(endpoint, body) {
const r = await fetch(API + '/' + endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Purelymail-Api-Token': TOKEN },
body: JSON.stringify(body || {}),
});
const text = await r.text();
let json = null;
try { json = JSON.parse(text); } catch {}
const ok = r.ok && json && json.type === 'success';
return { ok, status: r.status, json, text };
}
(async () => {
console.log('[purelymail] step 1 · listDomains');
const list = await call('listDomains', {});
if (!list.ok) {
console.error(' failed:', list.status, (list.text || '').slice(0, 200));
process.exit(2);
}
const domains = list.json?.result?.domains || list.json?.domains || [];
const have = domains.some((d) => (d.name || d.domain) === SUBDOMAIN);
console.log(` ${SUBDOMAIN} present:`, have);
if (!have) {
console.log('[purelymail] step 2 · addDomain', SUBDOMAIN);
const add = await call('addDomain', { domainName: SUBDOMAIN });
if (!add.ok) {
console.error(' failed:', add.status, (add.text || '').slice(0, 300));
console.error(' (If "domain not owned" — set the verification TXT record on the parent zone first.)');
process.exit(3);
}
console.log(' ✓ added. Publish these DNS records on agentabrams.com:');
console.log(' (Purelymail returns the exact record set in the response below.)');
console.log(JSON.stringify(add.json, null, 2));
console.log(' After DNS propagates, re-run this script to create the routing rule.');
process.exit(0);
}
console.log('[purelymail] step 3 · createRoutingRule');
console.log(` info@${SUBDOMAIN} → ${TARGET}`);
const rule = await call('createRoutingRule', {
domainName: SUBDOMAIN,
matchUser: 'info',
targetAddresses: [TARGET],
catchAll: false,
prefix: false,
});
if (rule.ok) {
console.log(' ✓ rule created.');
process.exit(0);
}
console.error(' failed:', rule.status, (rule.text || '').slice(0, 300));
process.exit(4);
})();