← back to Dw Marketing Reels

scripts/build-dw-accounts.js

47 lines

#!/usr/bin/env node
/*
 * build-dw-accounts.js — regenerate data/dw-canonical-accounts.json, the canonical
 * list of every DW-owned Instagram account, from Norma's postable-accounts registry.
 *
 * The Reels console keeps its own data/ig-accounts.json as the "managed / has-creds"
 * layer (ids + publish tokens for the accounts we actually post from). This canonical
 * file is unioned on top at read time (server.js → readAccountsUnion) so EVERY owned
 * account is pickable in the console list AND the publish dropdown — the ones without
 * creds simply show "(needs creds)". One source of truth, mirrored from the same Norma
 * origin the main Marketing Command Center uses.
 *
 * Source (overridable via env):
 *   NORMA_ACCOUNTS  (default ~/Projects/Norma/agents/instagram-agent/accounts.json)
 *
 * Runs on Mac2 (where Norma lives). The OUT file is committed so it ships to Kamatera,
 * where Norma is unreachable. If the source is missing, the existing file is preserved.
 * Idempotent.  →  node scripts/build-dw-accounts.js
 */
import { readFileSync, writeFileSync, existsSync, renameSync } from 'node:fs';
import { homedir } from 'node:os';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
const SRC = process.env.NORMA_ACCOUNTS ||
  join(homedir(), 'Projects', 'Norma', 'agents', 'instagram-agent', 'accounts.json');
const OUT = join(ROOT, 'data', 'dw-canonical-accounts.json');

if (!existsSync(SRC)) {
  const n = existsSync(OUT) ? (JSON.parse(readFileSync(OUT, 'utf8')).accounts || []).length : 0;
  console.log(`• Norma source missing (${SRC}) — preserving existing ${n} accounts`);
  process.exit(0);
}

const reg = JSON.parse(readFileSync(SRC, 'utf8'));
const accounts = Object.values(reg.accounts || {})
  .filter(a => a && a.handle)
  .map(a => ({ handle: String(a.handle), name: String(a.page_name || a.handle), ig_user_id: a.ig_user_id || null }))
  .sort((x, y) => x.handle.localeCompare(y.handle));

const out = { source: 'Norma/agents/instagram-agent/accounts.json', generated_at: new Date().toISOString(), count: accounts.length, accounts };
const tmp = OUT + '.tmp';
writeFileSync(tmp, JSON.stringify(out, null, 2));
renameSync(tmp, OUT);
console.log(`wrote data/dw-canonical-accounts.json — ${accounts.length} DW-owned accounts`);