← back to Koroseal Quote Only

scripts/rollback-gmc-exclude.js

42 lines

#!/usr/bin/env node
/**
 * rollback-gmc-exclude.js — undo for gmc-exclude-koroseal.js (TK-11106).
 * Re-publishes every id in data/rollback-map.json back to Google & YouTube.
 * Usage: node scripts/rollback-gmc-exclude.js --apply
 */
const fs = require('fs');
const path = require('path');
const ROOT = path.resolve(__dirname, '..');
const STORE = 'designer-laboratory-sandbox.myshopify.com';
const TOKEN = process.env.SHOPIFY_ADMIN_TOKEN || (() => {
  const env = fs.readFileSync(path.join(process.env.HOME, 'Projects/secrets-manager/.env'), 'utf8');
  return (env.match(/^SHOPIFY_ADMIN_TOKEN=(.+)$/m) || [])[1].replace(/["']/g, '').trim();
})();
const URL = `https://${STORE}/admin/api/2024-10/graphql.json`;
const APPLY = process.argv.includes('--apply');
const sleep = ms => new Promise(r => setTimeout(r, ms));
async function gql(q, v) {
  for (let a = 0; a < 6; a++) {
    const r = await fetch(URL, { method: 'POST', headers: { 'X-Shopify-Access-Token': TOKEN, 'Content-Type': 'application/json' }, body: JSON.stringify({ query: q, variables: v }) });
    const j = await r.json();
    if (j.errors) { if (JSON.stringify(j.errors).includes('THROTTLED')) { await sleep(2000 * (a + 1)); continue; } throw new Error(JSON.stringify(j.errors).slice(0, 300)); }
    return j.data;
  }
  throw new Error('throttled');
}
(async () => {
  const map = JSON.parse(fs.readFileSync(path.join(ROOT, 'data/rollback-map.json'), 'utf8'));
  console.log(`rollback ${APPLY ? 'APPLY' : 'DRY-RUN'}: ${map.ids.length} ids → re-publish to ${map.channel}`);
  if (!APPLY) return;
  let done = 0, failed = 0;
  for (const w of map.ids) {
    try {
      const d = await gql(`mutation($id:ID!,$pid:ID!){ publishablePublish(id:$id, input:[{publicationId:$pid}]){ userErrors{ field message } } }`, { id: w.id, pid: map.publicationId });
      const ue = d.publishablePublish.userErrors;
      if (ue && ue.length) { failed++; console.error(w.id, ue); } else done++;
    } catch (e) { failed++; console.error(w.id, e.message.slice(0, 120)); }
    await sleep(350);
  }
  console.log(`rollback done=${done} failed=${failed}`);
})();