← back to Designer Wallcoverings
mailers/cc-api/update-pj-fall-2026-draft.js
65 lines
'use strict';
/**
* update-pj-fall-2026-draft.js — TK-10899
*
* Pushes the current phillip-jeffries-fall-2026-launch.html into the EXISTING
* Constant Contact DRAFT activity (PUT /v3/emails/activities/{id}).
*
* WHY THIS AND NOT build-phillip-jeffries-campaign.js --confirm:
* The draft ALREADY EXISTS (created 2026-08-31). Re-running the build script's
* --confirm would create a SECOND, duplicate draft. Use this to update in place.
*
* Updating a DRAFT's content is NOT a send. Still double-gated: CC_LIVE=1 AND --confirm.
* The live send remains a separate, explicit action in Steve's Constant Contact console.
*
* node update-pj-fall-2026-draft.js # dry-run (NO-OP, no network)
* CC_LIVE=1 node update-pj-fall-2026-draft.js --confirm # update the draft in place
*/
const fs = require('fs');
const path = require('path');
const cc = require('./cc-client');
const ACTIVITY_ID = '54105fd3-5114-4090-94a2-24fd31d3de52'; // PJ Fall 2026 primary_email, DRAFT
const MAILER = path.join(__dirname, '..', 'phillip-jeffries-fall-2026-launch.html');
const CONFIRM = process.argv.slice(2).includes('--confirm');
const CAMPAIGN = {
subject: 'Phillip Jeffries Fall 2026 — fifty years in the making',
preheader: 'A celebration of artisanal history: Idyllic, Cirque de Soho, Coco Weave & Plush Pillars — the new Phillip Jeffries Fall 2026 Collection. Explore it online or experience Phillip Jeffries materials at our Sherman Oaks showroom.',
fromName: 'Designer Wallcoverings',
fromEmail: 'steve@designerwallcoverings.com',
replyTo: 'steve@designerwallcoverings.com',
// Real, staffed physical address — CAN-SPAM §5(a)(5). Matches what is already on the draft.
physicalAddress: {
address_line1: '15442 Ventura Blvd', city: 'Sherman Oaks',
state_code: 'CA', postal_code: '91403', country_code: 'US',
},
};
async function main() {
const html = fs.readFileSync(MAILER, 'utf8');
// Guard: refuse to push content that still hotlinks the vendor CDN. Re-hosting is the
// whole point of the TK-10899 asset swap; pushing un-swapped HTML would silently undo it.
const vendorHosts = ['api.phillipjeffries.com', 'cdn2.webdamdb.com'];
const leaks = vendorHosts.filter((h) => html.includes(h));
if (leaks.length) {
console.error(`[update-pj-draft] REFUSING: mailer still hotlinks vendor CDN (${leaks.join(', ')}).`);
console.error(' Run the asset swap first: node ../tools/pj-asset-swap.mjs --apply (Steve-gated)');
process.exitCode = 1;
return;
}
console.log(`[update-pj-draft] activity ${ACTIVITY_ID} html=${html.length} bytes confirm=${CONFIRM} CC_LIVE=${process.env.CC_LIVE === '1' ? '1' : '(unset)'}`);
const res = await cc.updateCampaignActivity(ACTIVITY_ID, {
subject: CAMPAIGN.subject, preheader: CAMPAIGN.preheader,
fromEmail: CAMPAIGN.fromEmail, fromName: CAMPAIGN.fromName, replyTo: CAMPAIGN.replyTo,
htmlContent: html, physicalAddress: CAMPAIGN.physicalAddress,
}, CONFIRM);
console.log('[update-pj-draft] result:', JSON.stringify(res).slice(0, 300));
}
main().catch((e) => { console.error('[update-pj-draft] ERROR:', e.message); process.exitCode = 1; });