[object Object]

← back to Pattern Vault

wpb-uploaders: generic session-capture (CM/Redbubble/Society6/Patternbank) — headed login → storageState, run by Steve

e610955c2d0b0464ab95c99ec46ad7c6d128620e · 2026-07-09 18:55:33 -0700 · Steve

Files touched

Diff

commit e610955c2d0b0464ab95c99ec46ad7c6d128620e
Author: Steve <steve@designerwallcoverings.com>
Date:   Thu Jul 9 18:55:33 2026 -0700

    wpb-uploaders: generic session-capture (CM/Redbubble/Society6/Patternbank) — headed login → storageState, run by Steve
---
 wpb-uploaders/capture-session.js | 46 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/wpb-uploaders/capture-session.js b/wpb-uploaders/capture-session.js
new file mode 100644
index 0000000..3565c67
--- /dev/null
+++ b/wpb-uploaders/capture-session.js
@@ -0,0 +1,46 @@
+#!/usr/bin/env node
+/*
+ * Capture a logged-in session (Playwright storageState) for any WPB uploader platform.
+ * Opens a HEADED browser to the platform's login/home page; YOU log in manually (SSO, 2FA,
+ * CAPTCHA — all fine, it's a real window); then press Enter in this terminal to save the session.
+ *
+ *   node capture-session.js <platform>       # etsy* | creativemarket | redbubble | society6 | patternbank
+ *
+ * (*Etsy uses OAuth, not a browser session — for Etsy, paste an ETSY_OAUTH_TOKEN instead.)
+ * Writes sessions/<platform>-state.json. Nothing is uploaded — this only captures the login.
+ * MUST be run by Steve in an interactive terminal (it waits for your Enter).
+ */
+const path = require('path'), fs = require('fs'), readline = require('readline');
+const { chromium } = require('/Users/macstudio3/.npm-global/lib/node_modules/playwright');
+
+const platform = process.argv[2];
+const PLATFORMS = ['creativemarket', 'redbubble', 'society6', 'patternbank'];
+if (!platform || !PLATFORMS.includes(platform)) {
+  console.error(`usage: node capture-session.js <${PLATFORMS.join('|')}>`);
+  if (platform === 'etsy') console.error('  (Etsy uses OAuth, not a browser session — paste an ETSY_OAUTH_TOKEN instead)');
+  process.exit(1);
+}
+const cfg = require(path.join(__dirname, 'platforms', `${platform}.js`));
+const OUT = cfg.sessionFile;
+const LOGIN = { creativemarket: 'https://creativemarket.com/login', redbubble: 'https://www.redbubble.com/auth/login',
+  society6: 'https://society6.com/login', patternbank: 'https://patternbank.com/login' }[platform];
+
+const ask = q => new Promise(r => { const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question(q, a => { rl.close(); r(a); }); });
+
+(async () => {
+  fs.mkdirSync(path.dirname(OUT), { recursive: true });
+  console.log(`\n🔐 Capturing ${cfg.name} session → ${OUT}`);
+  console.log(`   A browser window will open at ${LOGIN}`);
+  console.log(`   Log in fully (SSO / 2FA / CAPTCHA all OK), reach your dashboard, THEN come back here.\n`);
+  const b = await chromium.launch({ headless: false, args: ['--start-maximized'] });
+  const ctx = await b.newContext({ viewport: null });
+  const pg = await ctx.newPage();
+  await pg.goto(LOGIN, { waitUntil: 'domcontentloaded', timeout: 60000 }).catch(() => {});
+
+  await ask('   ▶ When you are fully logged in, press ENTER here to save the session… ');
+  await ctx.storageState({ path: OUT });
+  await b.close();
+  const ok = fs.existsSync(OUT) && fs.statSync(OUT).size > 200;
+  console.log(ok ? `\n✅ Saved ${cfg.name} session (${fs.statSync(OUT).size} bytes) → ${OUT}` : `\n⚠️ Session file looks empty — did the login complete?`);
+  console.log(`   Next: verify with  node run.js ${platform} <manifest>  (still fail-loud + <=4/day).`);
+})();

← 27a5610 STATUS: Spoonflower WORKS (id 22723313 proven); note test ar  ·  back to Pattern Vault  ·  gitignore: uploader sessions + ARMED runtime flags b68bdf0 →