← back to Designerwallcoverings
stout-onboard: fix Sirv (cdn.estout.com) image fetch — add stouttextiles referer+UA, strip thumbnail query (was 403→fail-closed BLOCK on all 180)
acc693b9269c805ad29e7484496d8fb5bd70ba24 · 2026-07-26 16:21:02 -0700 · Steve Abrams
Files touched
M scripts/stout-onboard/create-drafts.mjsM scripts/stout-onboard/settlement-gate.mjs
Diff
commit acc693b9269c805ad29e7484496d8fb5bd70ba24
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sun Jul 26 16:21:02 2026 -0700
stout-onboard: fix Sirv (cdn.estout.com) image fetch — add stouttextiles referer+UA, strip thumbnail query (was 403→fail-closed BLOCK on all 180)
---
scripts/stout-onboard/create-drafts.mjs | 6 +++++-
scripts/stout-onboard/settlement-gate.mjs | 6 +++++-
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/scripts/stout-onboard/create-drafts.mjs b/scripts/stout-onboard/create-drafts.mjs
index de0a9ca..b4945d3 100644
--- a/scripts/stout-onboard/create-drafts.mjs
+++ b/scripts/stout-onboard/create-drafts.mjs
@@ -54,10 +54,14 @@ function dbWriteBack(sku, mfrSku, pid) {
}
// localize: download the vendor hotlink, POST the bytes (base64) → Shopify re-hosts on its CDN.
+// Sirv (cdn.estout.com) hotlink-protects: needs the stouttextiles.com Referer; the vendor
+// thumbnail query 400s → fetch the bare .jpg (full-res original) so Shopify re-hosts the full image.
+const SIRV_HDRS = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120 Safari/537.36', 'Referer': 'https://www.stouttextiles.com/' };
+const bareImg = u => String(u).split('?')[0];
async function attachImage(pid, url, filename) {
if (!url) return 'no-url';
try {
- const resp = await fetch(url, { signal: AbortSignal.timeout(30000) });
+ const resp = await fetch(bareImg(url), { headers: SIRV_HDRS, signal: AbortSignal.timeout(30000) });
if (!resp.ok) return `dl-${resp.status}`;
const b64 = Buffer.from(await resp.arrayBuffer()).toString('base64');
const r = await rest(`/products/${pid}/images.json`, { method: 'POST', body: { image: { attachment: b64, filename } } });
diff --git a/scripts/stout-onboard/settlement-gate.mjs b/scripts/stout-onboard/settlement-gate.mjs
index 88bf129..de7e7be 100644
--- a/scripts/stout-onboard/settlement-gate.mjs
+++ b/scripts/stout-onboard/settlement-gate.mjs
@@ -49,8 +49,12 @@ Acceptable (carveout): Does it clearly contain tree trunks, clearly-drawn branch
Respond with ONLY this JSON, booleans true/false (never null), plus a 3-6 word evidence string each:
{"a1":bool,"a2":bool,"a3":bool,"b":bool,"acceptable":bool,"evidence":{"a1":"","a2":"","a3":"","b":"","acceptable":""}}`;
+// Sirv (cdn.estout.com) hotlink-protects: it needs the stouttextiles.com Referer, and the
+// vendor thumbnail query (?=&thumbnail=...) 400s — so fetch the bare .jpg (full-res original).
+const SIRV_HDRS = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120 Safari/537.36', 'Referer': 'https://www.stouttextiles.com/' };
+const bareImg = u => String(u).split('?')[0];
async function fetchB64(url) {
- const r = await fetch(url, { signal: AbortSignal.timeout(30000) });
+ const r = await fetch(bareImg(url), { headers: SIRV_HDRS, signal: AbortSignal.timeout(30000) });
if (!r.ok) throw new Error(`img ${r.status}`);
const ct = r.headers.get('content-type') || 'image/jpeg';
const buf = Buffer.from(await r.arrayBuffer());
← cf087fb stout-onboard: full engine (build-payloads/create-drafts/go-
·
back to Designerwallcoverings
·
Stroheim onboard: ready-to-run DRAFT scripts (DWST, BUDGET_C 7ec91f4 →