If you searched for “OpenClaw social media content pipeline LinkedIn X and Instagram”, you probably have the same headache I had: drafting posts in five different tabs, pasting the same screenshot three times, then forgetting to hit Publish on one of them. Below is the exact pipeline I now run in production. It uses OpenClaw v1.8.3 on Node 22, one agent per platform, and ships everything from the first idea to the engagement report without me touching a browser.
Why bother: the hidden cost of tab-swapping
A quick audit of my own routine was grim. Crafting a single post (and remembering the right hashtags, image sizes, and character limits) took ~22 minutes. That adds up to half a workday per week. Worse, each platform’s UI distracted me with a feed engineered for doom-scrolling. OpenClaw already runs my inbox assistant, so extending it felt natural. The goal: capture an idea in chat once, then let specialized agents handle drafting, formatting, scheduling, and analytics.
Architecture: three specialized agents and one orchestrator
OpenClaw encourages the multi-agent pattern: each agent focuses on a narrow responsibility, all orchestrated through the gateway. For this pipeline we use:
- claw-orchestrator – receives the raw idea, kicks off the workflow, aggregates results.
- claw-linkedin – formats long-form posts (max 3,000 chars), inserts line breaks, tracks
#opencorestyle hashtags. - claw-x – trims to 280 chars or splits threads, converts inline links to t.co, appends alt-text for images.
- claw-insta – enforces 2,200 char limit, strips external links, moves CTAs to link-in-bio, picks 30 max hashtags.
All agents share a Redis memory, so engagement stats inform future drafts.
Repo layout
content-pipeline/
├─ .env # tokens & keys
├─ package.json # scripts below
├─ agents/
│ ├─ orchestrator.js
│ ├─ linkedin.js
│ ├─ x.js
│ └─ instagram.js
└─ templates/
├─ linkedin.md
├─ x.md
└─ instagram.md
Bootstrapping OpenClaw locally (or on ClawCloud)
Skip if you already run an agent. Otherwise:
$ nvm install 22
$ npm create openclaw@latest # scaffolds gateway + first agent
$ cd openclaw
$ npm install openclaw@1.8.3 redis@5.3.2 axios@1.7.2
On ClawCloud the same happens in the UI; you just name the workspace and push your repo.
Environment variables
# .env (never commit this)
OPENAI_API_KEY=sk-...
LINKEDIN_ACCESS_TOKEN=...
X_BEARER_TOKEN=...
INSTAGRAM_USER_ID=...
REDIS_URL=redis://127.0.0.1:6379
TIMEZONE=Europe/Berlin
Capturing ideas: chat gateway + persistent memory
I spend most of my day in Slack, so the gateway connects there. A simple slash command /idea pipes the message into the orchestrator. The agent stores the raw idea plus metadata (who, channel, timestamp) in Redis. The point: ideas survive weekend reboots and can be searched later.
// orchestrator.js (snippet)
module.exports = async ({ text, user }) => {
await memory.push('ideas', { text, user, status: 'new', ts: Date.now() });
return `Captured! I’ll draft versions for LinkedIn, X and Instagram.`;
};
A CRON task scans for status:new every hour and triggers the drafting stage. Why hourly? It batches ideas but stays snappy enough for same-day posts.
Draft generation: templates + OpenAI
Each platform agent watches for a draft job. The heavy lifting is an OpenAI chat.completions call with a platform-specific system prompt plus a Markdown template.
// linkedin.js (core)
const prompt = [
{
role: 'system',
content: `You are a B2B storyteller writing for LinkedIn. Keep it conversational, 1st person, use line breaks every 2–3 sentences. End with a question.`
},
{ role: 'user', content: idea.text }
];
const { choices } = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: prompt,
temperature: 0.7,
max_tokens: 500
});
We then do two deterministic post-process steps:
- Inject UTM-tagged links pointing to our blog. LinkedIn preserves link previews; Instagram does not.
- Run text through
dblql(Dead-Blank-Line-Quality-Lint) to ensure no double spaces or “…” ellipses.
Similar logic lives in x.js (but with a hard 268-char limit to leave space for the tracking link) and instagram.js (moves links to linktree).
Human-in-the-loop editing
I tried a fully automated pipeline; it still produced the occasional clunker. Now every draft opens as a PR in a private GitHub repo. The orchestrator commits three Markdown files (idea-123-linkedin.md, etc.) and pings me for review.
- Pros: normal code review workflow, full history, inline suggestions.
- Cons: adds ~5 minutes per post; requires discipline to merge promptly.
The PR template highlights character counts and flag words (OpenClaw’s @nlp.moderation tool).
Characters: {{CHAR_COUNT}}
Violent language flagged: {{FLAG_WORDS}}
Schedule after merge? [ ] yes
When I click Merge, GitHub Actions hits the orchestrator webhook to flip status:draft to status:approved.
Scheduling & publishing via platform APIs
Each agent owns its platform’s API tokens. Using separate apps keeps the blast radius small if a key leaks. Publishing happens in two steps:
- Schedule – call the platform’s “draft” or “scheduled post” endpoint with a future
publish_at; fall back to immediate publish if scheduling is unavailable (X Basic API tier removed scheduling in 2023). - Confirm – agent listens for webhook (LinkedIn) or polls (X, Instagram) until the post is live, then writes
status:live.
Timezone headaches: everything goes through luxon. The TIMEZONE env var converts user-friendly “tomorrow 09:00” to platform-specific UTC.
Rate limits & retries
LinkedIn V2 REST: 100 calls/30 seconds. X API v2: 300 posts/24 h. Instagram Graph: 25 calls/user/hour. The agents keep a simple token bucket in Redis. On HTTP 429 the job requeues with exponential backoff (2^retries * 30s capped at 10 min).
Formatting quirks & hashtag strategy
Automation is only useful if the output feels native. The agents enforce the following rules:
- LinkedIn: first line blank → avoids auto-collapse. Max 5 hashtags. Emoji pass-through okay.
- X: no more than 2 hashtags; they burn characters. Use alt-text for images; API field
alt_text. - Instagram: add line break
(zero-width space) between paragraphs to avoid the dreaded wall of text. Move hashtags to the end. Up to 30.
Hashtags come from a shared YAML curated weekly:
# hashtags.yaml
linkedin:
- BuildingInPublic
- SaaS
x:
- DevLife
- IndieHackers
instagram:
- CodingLife
- CoffeeAndCode
The orchestrator picks two random items per post so the feed doesn’t look copy-pasted.
Engagement monitoring & feedback loop
The final piece: measure what resonates and feed it back. Each agent streams basic metrics into Redis:
- LinkedIn:
impressions,reactions,comments - X:
views,likes,retweets - Instagram:
reach,likes,saves
A nightly batch job calculates engagement per 1 k reach and stores a moving average. When a new idea comes in, the drafting prompt includes the top three posts by engagement so the model can mimic tone and structure.
// prompts/add_context.js
const topPosts = await analytics.getTopPosts(3);
messages.unshift({
role: 'system',
content: `Reference successful tone:
1. ${topPosts[0].text}
2. ${topPosts[1].text}
3. ${topPosts[2].text}`
});
This alone increased average likes on LinkedIn by 27 % in two weeks, according to my simple A/B test (n ≈ 30 posts).
Putting it all together: one command
The final developer experience matters. My package.json exposes:
"scripts": {
"dev": "openclaw dev ‑-agents ./agents",
"cron": "node scripts/batch.js",
"post": "npx ts-node scripts/manual_post.ts"
}
Typical day:
- Type
/idea “GitHub Actions caching gotcha …”in Slack. - Next top-of-the-hour, three PRs pop up. I skim, tweak wording, merge.
- The pipeline schedules for 10:02, 10:07, 10:10 based on historical engagement windows.
- At 15:00 a Slack DM posts the engagement delta chart. I reply “double down on this angle” and the orchestrator stores that instruction for the next draft.
The whole loop costs me ~6 minutes instead of 22, and I never open platform UIs.
Next step
Clone the repo template at openclaw/examples, drop in your tokens, and run npm run dev. You’ll have a working LinkedIn/X/Instagram pipeline before coffee goes cold.