← back to Gmc 425 Supplemental Feed
recheck-reorder-canary.mjs
25 lines
#!/usr/bin/env node
/** recheck-reorder-canary.mjs — READ-ONLY. Run a few HOURS after the reorder canary (post Google re-sync).
* Re-classifies the 10 reordered pids in live Merchant Center: did the Roll offer appear + $4.25 Sample drop? */
import fs from 'node:fs'; import crypto from 'node:crypto';
const HOME=process.env.HOME, MERCHANT='146735262';
const SA_PATH=HOME+'/Projects/secrets-manager/gmc-sa-146735262.json';
const b64=b=>Buffer.from(b).toString('base64').replace(/=/g,'').replace(/\+/g,'-').replace(/\//g,'_');
async function mcToken(){const SA=JSON.parse(fs.readFileSync(SA_PATH,'utf8'));const now=Math.floor(Date.now()/1000);
const si=b64(JSON.stringify({alg:'RS256',typ:'JWT'}))+'.'+b64(JSON.stringify({iss:SA.client_email,scope:'https://www.googleapis.com/auth/content',aud:'https://oauth2.googleapis.com/token',iat:now,exp:now+3600}));
const s=crypto.createSign('RSA-SHA256');s.update(si);const jwt=si+'.'+b64(s.sign(SA.private_key));
const r=await fetch('https://oauth2.googleapis.com/token',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:new URLSearchParams({grant_type:'urn:ietf:params:oauth:grant-type:jwt-bearer',assertion:jwt})});
return (await r.json()).access_token;}
const rows=JSON.parse(fs.readFileSync(new URL('./out/supp-cant-help.json',import.meta.url),'utf8')).slice(0,10);
const tok=await mcToken(); const H={Authorization:`Bearer ${tok}`};
async function inFeed(pid,vid){const oid=`online:en:US:shopify_US_${pid}_${vid}`;
const r=await fetch(`https://shoppingcontent.googleapis.com/content/v2.1/${MERCHANT}/productstatuses/${encodeURIComponent(oid)}`,{headers:H});return r.status!==404;}
let fixed=0,stillLeaking=0;
for(const r of rows){
const roll=await inFeed(r.pid,r.rollVid), samp=await inFeed(r.pid,r.sampleVid);
const verdict = roll&&!samp ? 'FIXED (roll in, sample out)' : roll&&samp ? 'BOTH in feed (partial)' : !roll&&samp ? 'STILL LEAKING (roll absent)' : 'off-feed';
if(roll&&!samp) fixed++; if(!roll&&samp) stillLeaking++;
console.log(`${r.pid} ${verdict}`);
}
console.log(`\nRESULT: ${fixed}/10 FIXED, ${stillLeaking}/10 still leaking. If majority FIXED -> reorder works -> scale to the remaining SUPP_CANT_HELP. If not -> use republish-to-channel instead.`);