Systems Library / Marketing Automation / How to Automate Content Calendar Planning with AI
Marketing Automation content marketing

How to Automate Content Calendar Planning with AI

Let AI analyze trends and plan your content calendar months in advance.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

Every month I used to spend three hours planning what content to produce. I'd look at keyword tools, check what competitors were publishing, think through what questions clients were asking, and try to build a coherent schedule. Now that same three hours produces a 90-day content calendar. The ai content calendar planning automation system I built pulls from keyword trends, competitor analysis, and your existing content library to generate a structured, prioritized calendar in about 20 minutes.

The bigger gain is strategic consistency. Manual planning produces content that reacts to what happened last month. AI-assisted planning looks 90 days out and builds topical clusters that compound in search authority over time.

What You Need Before Starting

Step 1: Define Your Content Strategy Parameters

The AI needs strategic context before it can plan. Without this, you get generic suggestions.

# content_strategy.py

CONTENT_STRATEGY = {
    "brand": "Jay Banlasan / AI Systems Guy",
    "audience": "Business owners and marketing managers running paid ads and AI workflows",
    "primary_goal": "Generate leads for AI systems consulting engagements",
    
    "content_pillars": [
        {
            "pillar": "AI Model Operations",
            "description": "How to run AI APIs efficiently, reliably, and cost-effectively",
            "target_intent": "informational, how-to",
            "examples": ["rate limiting", "cost tracking", "failover", "caching"]
        },
        {
            "pillar": "Paid Advertising Automation",
            "description": "Using AI to automate Meta and Google Ads workflows",
            "target_intent": "how-to, tutorial",
            "examples": ["ad copy generation", "CPA tracking", "reporting automation"]
        },
        {
            "pillar": "Business AI Systems",
            "description": "Practical AI integrations for business operations",
            "target_intent": "informational, case study",
            "examples": ["lead enrichment", "CRM automation", "reporting"]
        }
    ],
    
    "publish_cadence": "2x per week",
    "preferred_formats": ["tutorial", "case-study", "how-to"],
    "avoid_formats": ["listicle", "opinion-only"],
    
    "existing_content_gaps": [
        "Advanced Meta Ads automation",
        "AI cost optimization case studies",
        "Content marketing with AI"
    ]
}

Step 2: Build the Trend Analysis Input

Feed in current trend signals for the AI to factor into planning.

import anthropic
import json
from datetime import date, timedelta

_client = anthropic.Anthropic()

def analyze_content_trends(pillar: str, period: str = "Q4 2024") -> list[str]:
    """
    Ask AI to identify current trends in a content pillar area.
    Returns a list of trending topics/questions.
    """
    prompt = f"""You are a content strategist specializing in B2B tech content.

Identify the top 8-10 trending topics and questions that business owners and 
marketing managers are currently searching for in this area:

Pillar: {pillar}
Period: {period}

Focus on:
- Questions they're actively searching for
- Problems they're trying to solve right now
- Emerging techniques or tools they want to learn
- Pain points that have grown in the past 6 months

Return a JSON list of strings: ["topic 1", "topic 2", ...]
Be specific. No generic topics."""

    response = _client.messages.create(
        model="claude-sonnet-4-5", max_tokens=500,
        messages=[{"role": "user", "content": prompt}]
    )
    
    try:
        return json.loads(response.content[0].text.strip())
    except Exception:
        return []

def build_topic_pool(strategy: dict) -> dict[str, list[str]]:
    """Build a pool of potential topics per pillar."""
    pool = {}
    for pillar_info in strategy["content_pillars"]:
        pillar = pillar_info["pillar"]
        trends = analyze_content_trends(pillar)
        pool[pillar] = trends
        print(f"Got {len(trends)} topics for: {pillar}")
    return pool

Step 3: Build the Content Calendar Generator

Take the topic pool and strategy parameters, and generate a structured calendar.

def generate_content_calendar(
    strategy: dict,
    topic_pool: dict,
    weeks: int = 12,
    existing_posts: list[str] = []
) -> list[dict]:
    
    existing_summary = "\n".join(existing_posts[:20]) if existing_posts else "None provided"
    
    topics_formatted = json.dumps(topic_pool, indent=2)
    
    prompt = f"""You are a content strategist. Create a {weeks}-week content calendar.

Brand: {strategy['brand']}
Audience: {strategy['audience']}
Business goal: {strategy['primary_goal']}
Cadence: {strategy['publish_cadence']}
Preferred formats: {', '.join(strategy['preferred_formats'])}

Available topics by pillar:
{topics_formatted}

Existing posts (avoid duplicating):
{existing_summary}

Strategy rules:
1. Alternate between pillars for topic diversity
2. Build topical clusters: group 2-3 related posts in consecutive weeks
3. Start with highest-traffic-potential topics first
4. Mix tutorial and case-study formats
5. Each post should link naturally to 1-2 others in the calendar

Return a JSON list of {weeks * 2} posts:
[{{
  "week": 1,
  "publish_date": "YYYY-MM-DD",
  "title": "exact proposed title",
  "pillar": "pillar name",
  "format": "tutorial|case-study|how-to",
  "target_keyword": "primary keyword phrase",
  "hook": "first sentence idea",
  "why_now": "why this topic is timely",
  "links_to": ["title of related post in calendar"]
}}]

Start dates from: {(date.today() + timedelta(days=7)).isoformat()}"""
    
    response = _client.messages.create(
        model="claude-sonnet-4-5", max_tokens=3000,
        messages=[{"role": "user", "content": prompt}]
    )
    
    try:
        return json.loads(response.content[0].text.strip())
    except json.JSONDecodeError:
        # Try to extract JSON from response
        text = response.content[0].text
        start = text.find("[")
        end = text.rfind("]") + 1
        if start >= 0 and end > start:
            return json.loads(text[start:end])
        raise

Step 4: Score and Prioritize the Calendar

Not all topics are equally valuable. Score each post by potential impact.

def score_content_piece(piece: dict, strategy: dict) -> float:
    """Score 0-1 based on strategic value."""
    score = 0.5  # baseline
    
    # Bonus for matching content gaps
    keyword = piece.get("target_keyword", "").lower()
    for gap in strategy.get("existing_content_gaps", []):
        if any(word in keyword for word in gap.lower().split()):
            score += 0.15
            break
    
    # Bonus for linking to other calendar posts (compound value)
    if piece.get("links_to"):
        score += 0.1
    
    # Penalty for duplicate-adjacent pillars in the same week
    # (handled by generator prompt, this is a safety check)
    
    return min(1.0, score)

def prioritize_calendar(calendar: list[dict], strategy: dict) -> list[dict]:
    scored = [(piece, score_content_piece(piece, strategy)) for piece in calendar]
    
    # Sort by week first, then by score within each week's batch
    from itertools import groupby
    result = []
    
    for week, items in groupby(sorted(scored, key=lambda x: x[0]["week"]),
                                 key=lambda x: x[0]["week"]):
        week_items = sorted(items, key=lambda x: x[1], reverse=True)
        for piece, score in week_items:
            piece["priority_score"] = round(score, 2)
            result.append(piece)
    
    return result

Step 5: Export to a Usable Format

Generate a Markdown calendar document and a CSV for your project management tool.

import csv

def export_calendar_markdown(calendar: list[dict], output_path: str = "content_calendar.md"):
    lines = [f"# Content Calendar\n\nGenerated: {date.today().isoformat()}\n"]
    
    current_week = None
    for item in calendar:
        if item["week"] != current_week:
            current_week = item["week"]
            lines.append(f"\n## Week {current_week}")
        
        lines.append(
            f"\n**{item['publish_date']}** | {item['format'].title()}\n"
            f"- Title: {item['title']}\n"
            f"- Keyword: `{item['target_keyword']}`\n"
            f"- Pillar: {item['pillar']}\n"
            f"- Hook: {item['hook']}\n"
        )
        if item.get("links_to"):
            links = ", ".join(item["links_to"])
            lines.append(f"- Links to: {links}\n")
    
    with open(output_path, "w") as f:
        f.write("\n".join(lines))
    print(f"Calendar saved to {output_path}")

def export_calendar_csv(calendar: list[dict], output_path: str = "content_calendar.csv"):
    fields = ["week", "publish_date", "title", "pillar", "format",
              "target_keyword", "hook", "why_now", "priority_score"]
    
    with open(output_path, "w", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=fields, extrasaction="ignore")
        writer.writeheader()
        writer.writerows(calendar)
    print(f"CSV saved to {output_path}")

Step 6: Run the Full Pipeline

def generate_90_day_calendar():
    print("Building topic pool from trends...")
    topic_pool = build_topic_pool(CONTENT_STRATEGY)
    
    print("\nGenerating 12-week calendar...")
    calendar = generate_content_calendar(
        strategy=CONTENT_STRATEGY,
        topic_pool=topic_pool,
        weeks=12,
        existing_posts=[
            "How to Build a Multi-Model AI Router",
            "How to Implement AI Request Prioritization",
        ]
    )
    
    print(f"Generated {len(calendar)} content pieces")
    
    prioritized = prioritize_calendar(calendar, CONTENT_STRATEGY)
    
    export_calendar_markdown(prioritized)
    export_calendar_csv(prioritized)
    
    print("\nTop 5 Priority Posts:")
    top5 = sorted(prioritized, key=lambda x: x["priority_score"], reverse=True)[:5]
    for p in top5:
        print(f"  Week {p['week']}: {p['title']} (score: {p['priority_score']})")

if __name__ == "__main__":
    generate_90_day_calendar()

What to Build Next

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems