[object Object]

← 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

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 →