← back to Linenwallpaper
add gated IG post script: genuine-linen Sag Harbor post for @linenwallpaper
b99182ca5eb9c2241a500e6421f08e92805075fd · 2026-08-12 09:41:25 -0700 · steve
Files touched
A scripts/post-linen-ig.js
Diff
commit b99182ca5eb9c2241a500e6421f08e92805075fd
Author: steve <steve@designerwallcoverings.com>
Date: Wed Aug 12 09:41:25 2026 -0700
add gated IG post script: genuine-linen Sag Harbor post for @linenwallpaper
---
scripts/post-linen-ig.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/scripts/post-linen-ig.js b/scripts/post-linen-ig.js
new file mode 100644
index 0000000..0befa9f
--- /dev/null
+++ b/scripts/post-linen-ig.js
@@ -0,0 +1,50 @@
+#!/usr/bin/env node
+// Post a genuine-linen product to @linenwallpaper (Norma fleet account) via IG Graph API.
+// Target confirmed from Norma accounts.json: linenwallpaper -> ig_user_id 17841408700186822.
+// Steve-gated: run this yourself (e.g. `! node ~/Projects/linenwallpaper/scripts/post-linen-ig.js`).
+// Cost: $0 — Instagram Graph publishing is free.
+const fs = require('fs'), https = require('https');
+
+const NORMA_ENV = '/Users/macstudio3/Projects/Norma/agents/instagram-agent/.env';
+const IG_USER_ID = '17841408700186822'; // @linenwallpaper ("Linen Wallpaper")
+const IMAGE_URL = 'https://cdn.shopify.com/s/files/1/0015/4117/7456/files/kUWjSj2qTCxP5fGLpr0NC1e1SiFmyET61eBcLxBB.jpg?v=1776190104'; // Sag Harbor - Danish Linen
+const CAPTION = [
+ 'The quiet luxury of true linen.',
+ '',
+ 'Sag Harbor in Danish Linen — a warm greige weave that turns a wall into calm. Pure linen, woven texture, quiet rooms.',
+ '',
+ 'Shop the linen edit → linenwallpaper.com',
+ '',
+ '#linenwallpaper #linen #woventexture #naturaltexture #quietluxury #interiordesign #wallcovering #neutralinteriors #texturedwalls #linenwalls',
+].join('\n');
+
+const env = fs.readFileSync(NORMA_ENV, 'utf8');
+const TOK = (env.match(/^IG_ACCESS_TOKEN=(.+)$/m) || [])[1]?.trim();
+if (!TOK) { console.error('No IG_ACCESS_TOKEN in Norma .env'); process.exit(1); }
+
+function post(path, params) {
+ return new Promise((res, rej) => {
+ const body = new URLSearchParams({ ...params, access_token: TOK }).toString();
+ const r = https.request(`https://graph.facebook.com/v21.0/${path}`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(body) },
+ }, resp => { let d = ''; resp.on('data', c => d += c); resp.on('end', () => res({ status: resp.statusCode, body: d })); });
+ r.on('error', rej); r.write(body); r.end();
+ });
+}
+
+(async () => {
+ const c = await post(`${IG_USER_ID}/media`, { image_url: IMAGE_URL, caption: CAPTION });
+ console.log('container:', c.status, c.body.slice(0, 300));
+ const cid = JSON.parse(c.body || '{}').id;
+ if (!cid) { console.error('No creation id — stopping.'); process.exit(1); }
+ await new Promise(r => setTimeout(r, 5000)); // let the container finish
+ const pub = await post(`${IG_USER_ID}/media_publish`, { creation_id: cid });
+ console.log('publish:', pub.status, pub.body.slice(0, 300));
+ const mid = JSON.parse(pub.body || '{}').id;
+ if (mid) {
+ https.get(`https://graph.facebook.com/v21.0/${mid}?fields=permalink&access_token=${TOK}`, r => {
+ let d = ''; r.on('data', c => d += c); r.on('end', () => console.log('PERMALINK:', d));
+ });
+ }
+})();
← c3c76d8 linenwallpaper: tighten linen filter — require linen/flax in
·
back to Linenwallpaper
·
chore: version bump v0.1.1 (session close — niche-filter fix 589d0fb →