[object Object]

← back to Designer Wallcoverings

CC client: add updateCampaignActivity + getCampaignActivity; pushed Figma-matched HTML to live China Seas draft

70d82e0e6392b3fe6655c02ce8bf913d90ab819e · 2026-06-24 13:15:45 -0700 · Steve

Files touched

Diff

commit 70d82e0e6392b3fe6655c02ce8bf913d90ab819e
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Jun 24 13:15:45 2026 -0700

    CC client: add updateCampaignActivity + getCampaignActivity; pushed Figma-matched HTML to live China Seas draft
---
 mailers/cc-api/cc-client.js                    | 34 ++++++++++++++++++++++++++
 shopify/display-variant-backfill/failures.json |  6 +++++
 shopify/display-variant-backfill/progress.json |  2 +-
 3 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/mailers/cc-api/cc-client.js b/mailers/cc-api/cc-client.js
index 3565f4ee..7b6c19ee 100644
--- a/mailers/cc-api/cc-client.js
+++ b/mailers/cc-api/cc-client.js
@@ -263,10 +263,44 @@ async function scheduleCampaign(activityId, scheduledDate, confirm = false) {
   });
 }
 
+/**
+ * PUT /v3/emails/activities/{id} — update an existing campaign activity's content.
+ * GATED OUTWARD WRITE: requires CC_LIVE === '1' AND confirm === true.
+ */
+async function updateCampaignActivity(activityId, p, confirm = false) {
+  if (!activityId) throw new Error('updateCampaignActivity: activityId required');
+  const {
+    subject, fromEmail, fromName, replyTo, htmlContent, physicalAddress, preheader,
+  } = p || {};
+  if (!isLive(confirm)) {
+    const reason = noopReason(confirm, true);
+    log(`REFUSING live activity update — ${reason}.`);
+  }
+  const payload = {
+    format_type: 5,
+    from_name: fromName,
+    from_email: fromEmail,
+    reply_to_email: replyTo,
+    subject,
+    ...(preheader ? { preheader } : {}),
+    html_content: htmlContent,
+    physical_address_in_footer: physicalAddress,
+  };
+  return apiFetch('PUT', `/emails/activities/${activityId}`, { body: payload, confirm, writeOp: true });
+}
+
+/** GET /v3/emails/activities/{id} — read a campaign activity back (read-only). */
+async function getCampaignActivity(activityId) {
+  if (!activityId) throw new Error('getCampaignActivity: activityId required');
+  return apiFetch('GET', `/emails/activities/${activityId}`, { writeOp: false });
+}
+
 module.exports = {
   getAccessToken,
   listContactLists,
   createCustomCodeCampaign,
+  updateCampaignActivity,
+  getCampaignActivity,
   scheduleCampaign,
   // exposed for tests/build script
   _internal: { isLive, noopReason, TOKEN_URL, API_BASE, TOKEN_CACHE },
diff --git a/shopify/display-variant-backfill/failures.json b/shopify/display-variant-backfill/failures.json
new file mode 100644
index 00000000..f09edaed
--- /dev/null
+++ b/shopify/display-variant-backfill/failures.json
@@ -0,0 +1,6 @@
+[
+  {
+    "gid": "gid://shopify/Product/1498917142640",
+    "err": "\"Internal Server Error\""
+  }
+]
\ No newline at end of file
diff --git a/shopify/display-variant-backfill/progress.json b/shopify/display-variant-backfill/progress.json
index bd3510c3..f4bb82e5 100644
--- a/shopify/display-variant-backfill/progress.json
+++ b/shopify/display-variant-backfill/progress.json
@@ -1 +1 @@
-{"status":"running","total":20137,"tagged":16974,"failed":1,"priorityCount":266,"restCount":19871,"startedAt":1782330432823,"updatedAt":1782331923750,"currentGid":"gid://shopify/Product/6679605444659","rate":11.4,"etaSec":278,"note":"priority = products purchased in last 90d (client-engaged), tagged first"}
\ No newline at end of file
+{"status":"done","total":20137,"tagged":20136,"failed":1,"priorityCount":266,"restCount":19871,"startedAt":1782330432823,"updatedAt":1782332138504,"currentGid":null,"rate":11.8,"etaSec":0,"note":"priority = products purchased in last 90d (client-engaged), tagged first"}
\ No newline at end of file

← ce5c0772 China Seas mailer: match Figma — overlaid wordmark on darken  ·  back to Designer Wallcoverings  ·  China Seas mailer: move heritage-house logos to a single str e6cedea9 →