Skip to content
  • AI Agents
  • Gemini
  • n8n
  • Automation
  • Zod
  • Node.js

How to Build an AI Content Agent That Writes Daily Social Posts

By Published 4 min read (or skim, I won't know)

An AI content agent is a scheduled pipeline, not a chatbot: a trigger fires, the agent gathers context, an LLM such as Gemini drafts posts for each platform as structured JSON, a schema validates them, and a human approves them before publishing.

Why build one

At Garage Collective I built and deployed an AI content-generation agent that produces daily Instagram, LinkedIn and blog content. It reduced manual content-creation effort by roughly 40%. This post walks through the architecture pattern behind that kind of agent, so you can build your own.

The pipeline

StageJobTool options
1. TriggerRun every morningn8n Schedule node, node-cron
2. ContextTopic, brand voice, recent postsDatabase, Google Sheet, CMS
3. DraftOne post per platformGemini or Groq
4. ValidateLengths, fields, banned wordsZod
5. ReviewApprove, edit or rejectSlack, email, dashboard
6. PublishPost or schedulePlatform APIs, scheduler

Step 1: Describe the output before the prompt

Each platform has different rules, so define them as a schema. This is the same idea I used for reliable Gemini JSON in HireMate:

import { z } from "zod";

export const DailyContent = z.object({
  topic: z.string(),
  linkedin: z.object({ post: z.string().min(200).max(2800) }),
  instagram: z.object({ caption: z.string().max(2200), hashtags: z.array(z.string()).min(3).max(15) }),
  blog: z.object({ title: z.string().max(70), outline: z.array(z.string()).min(3), draft: z.string().min(600) }),
});
export type DailyContent = z.infer<typeof DailyContent>;

Step 2: Give the model the context a writer would need

Generic prompts give generic posts. Feed the model what a human writer would ask for:

const prompt = `
You write social content for ${brand.name}.
Audience: ${brand.audience}
Voice: ${brand.voice}
Never use: ${brand.bannedPhrases.join(", ")}
Today's topic: ${topic}
Avoid repeating these recent posts: ${recent.map((p) => p.summary).join(" | ")}

Return JSON with keys linkedin, instagram and blog, following the rules for each platform.
`;

The "recent posts" line matters more than it looks. Without it, a daily agent repeats itself within a week.

Step 3: Generate, validate, retry

import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

export async function draftDailyContent(prompt: string, attempts = 2): Promise<DailyContent> {
  const res = await ai.models.generateContent({
    model: "gemini-2.5-flash",
    contents: prompt,
    config: { responseMimeType: "application/json" },
  });
  const parsed = DailyContent.safeParse(JSON.parse(res.text ?? "{}"));
  if (parsed.success) return parsed.data;
  if (attempts > 0) return draftDailyContent(prompt, attempts - 1);
  throw new Error(`Draft failed validation: ${parsed.error.message}`);
}

Step 4: Schedule it

Option A: plain Node.js with node-cron.

import cron from "node-cron";

cron.schedule("0 7 * * 1-5", async () => {
  const context = await loadContext();
  const draft = await draftDailyContent(buildPrompt(context));
  await saveForReview(draft);
  await notifyReviewers(draft.topic);
}, { timezone: "Asia/Kolkata" });

Option B: n8n. A Schedule Trigger node, a node that reads the topic list, an HTTP Request node that calls a small /draft endpoint wrapping the function above, then Slack or email for review. Non-developers can change the schedule, the topic source or the reviewers without touching code.

Both work. n8n wins on visibility and easy changes; code wins on testing and prompt versioning. Using n8n for orchestration and a Node.js endpoint for the LLM step gets you both.

Step 5: Keep a human in the loop

Store each draft with a status (pending, approved, rejected) and send reviewers a link. Track how often drafts are approved without edits. That number tells you whether the prompt is improving, and when a low-risk format is ready to publish automatically.

What goes wrong (and the fix)

  • Same post, new day. Pass recent post summaries into the prompt.
  • Invalid JSON or overlong captions. Validate with Zod and retry once or twice.
  • Off-brand tone. Add one or two real example posts to the prompt.
  • Silent failures. Alert someone when a run fails, so a missing post is never discovered at 6 p.m.
  • API keys in the workflow. Keep them in environment variables or n8n credentials, never in node parameters.

Key takeaways

  • An AI agent is a scheduled pipeline with an LLM step, not a chat window.
  • Define the output schema per platform before writing the prompt.
  • Validate every draft, retry on failure, and alert on errors.
  • Keep human review, and measure how often drafts ship unedited.

Want an agent like this for your team? I build them as an AI automation developer.

Frequently asked questions

What is an AI content agent?

An AI content agent is an automated workflow that gathers inputs such as topics, product updates or brand guidelines, uses a large language model to draft platform-specific posts, validates the output, and queues it for review or publishing on a schedule.

Should AI-generated social posts be published automatically?

Start with a human review step. Let the agent draft and queue posts, and have a person approve them. Remove the review step only for low-risk formats once the output has been consistently good.

n8n or custom code for an AI content workflow?

n8n is faster for wiring triggers, APIs and approvals visually, and is easy for non-developers to adjust. Custom Node.js code with node-cron gives more control over prompts, validation and testing. Many teams use n8n for orchestration and call a small Node.js service for the LLM step.

How do you keep AI content on brand?

Put the brand voice, audience, banned phrases and one or two example posts in the prompt, ask for structured JSON per platform, validate length and required fields with a schema, and keep a human approval step.