← back to Designer Wallcoverings
mailers/cc-api/sync-china-seas.js
100 lines
'use strict';
/**
* sync-china-seas.js — re-PUT the updated mailer HTML onto the existing
* China Seas DRAFT activity, PRESERVING from/subject/reply/address AND the
* attached contact_list_ids (PUT is full-replace — dropping the list wipes it).
*
* Phase 1 (default, read-only): discover the China Seas campaign + primary
* activity, GET its current state, print what WOULD change. No write.
* Phase 2 (--confirm + CC_LIVE=1): PUT the new HTML, re-including the
* activity's existing contact_list_ids. NOT a send — draft content only.
*/
const fs = require('fs');
const path = require('path');
try { require('dotenv').config({ path: path.join(__dirname, '.env') }); } catch {}
const cc = require('./cc-client.js');
const HTML_PATH = path.join(__dirname, '..', 'china-seas-launch.html');
const CONFIRM = process.argv.includes('--confirm');
// minimal authed fetch reusing the client's token (CC_LIVE gate enforced there)
async function authed(method, urlPath, body) {
const token = await cc.getAccessToken();
const url = urlPath.startsWith('http') ? urlPath : `https://api.cc.email/v3${urlPath}`;
const res = await fetch(url, {
method,
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/json',
...(body !== undefined ? { 'Content-Type': 'application/json' } : {}),
},
...(body !== undefined ? { body: JSON.stringify(body) } : {}),
});
const txt = await res.text();
let j; try { j = txt ? JSON.parse(txt) : {}; } catch { j = { raw: txt }; }
if (!res.ok) throw new Error(`${method} ${url} → ${res.status}: ${txt}`);
return j;
}
(async () => {
if (process.env.CC_LIVE !== '1') {
console.log('CC_LIVE!=1 — read calls NO-OP. Set CC_LIVE=1 to run live.');
return;
}
const html = fs.readFileSync(HTML_PATH, 'utf8');
console.log(`loaded HTML: ${html.length} bytes`);
// 1) find the China Seas campaign
const camps = await authed('GET', '/emails?limit=50');
const list = camps.campaigns || [];
const cs = list.find(c => /china seas/i.test(c.name || ''));
if (!cs) { console.log('No China Seas campaign found. Campaigns:', list.map(c => c.name)); return; }
console.log(`campaign: "${cs.name}" id=${cs.campaign_id} status=${cs.current_status}`);
// 2) find the primary_email activity id
const detail = await authed('GET', `/emails/${cs.campaign_id}`);
const acts = detail.campaign_activities || [];
const primary = acts.find(a => a.role === 'primary_email') || acts[0];
if (!primary) { console.log('No activity found on campaign.'); return; }
const activityId = primary.campaign_activity_id;
console.log(`primary activity id=${activityId}`);
// 3) GET current activity state (with html so we can diff size) + list attachment
const cur = await authed('GET', `/emails/activities/${activityId}?include=html_content,physical_address_in_footer`);
const curLists = cur.contact_list_ids || [];
console.log(`current: subject="${cur.subject}" from=${cur.from_email} lists=[${curLists.join(', ')}] html=${(cur.html_content||'').length}b`);
if (!curLists.length) {
console.log('⚠️ WARNING: activity currently has NO contact_list_ids attached.');
}
// 4) build the full-replace payload — preserve everything, swap html only,
// and RE-INCLUDE contact_list_ids so the PUT doesn't wipe the list.
const payload = {
format_type: 5,
from_name: cur.from_name,
from_email: cur.from_email,
reply_to_email: cur.reply_to_email,
subject: cur.subject,
...(cur.preheader ? { preheader: cur.preheader } : {}),
html_content: html,
physical_address_in_footer: cur.physical_address_in_footer,
...(curLists.length ? { contact_list_ids: curLists } : {}),
};
if (!CONFIRM) {
console.log('\n[DRY-RUN] Would PUT updated HTML to activity', activityId);
console.log(' preserving from/subject/reply/address; re-including lists:', curLists);
console.log(' new html bytes:', html.length);
console.log('Run again with --confirm to push (CC_LIVE=1 already set).');
return;
}
console.log('\nPUT (live) updated HTML →', activityId);
const resp = await authed('PUT', `/emails/activities/${activityId}`, payload);
// verify
const after = await authed('GET', `/emails/activities/${activityId}?include=html_content`);
console.log('✅ updated. after: html=%db lists=[%s]',
(after.html_content||'').length, (after.contact_list_ids||[]).join(', '));
})().catch(e => { console.error('ERR', e.message); process.exit(1); });