← back to Linenwallpaper
scripts/post-linen-ig.js
51 lines
#!/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));
});
}
})();