hermes

Hermes — Messenger of the Gods. Plan and batch your entire social media content calendar — generate a 4-week posting schedule, write platform-optimised captions for Twitter/X, LinkedIn, Instagram, and Threads, apply best-posting-time rules, and export a ready-to-use content calendar.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "hermes" with this command: npx skills add occupythemilkyway/talos

📱 ⚡ Hermes — Social Media Command

Stop staring at a blank post box. This skill generates a complete 4-week content calendar with platform-optimised captions, the right hashtags, best posting times, and content variety rules — all ready to paste into Buffer, Later, or schedule directly.

Quick Start

BRAND_TOPIC="freelance design tips" PLATFORMS="twitter, linkedin, instagram" \
POSTS_PER_WEEK="5" CONTENT_PILLARS="tips, portfolio, client stories, tools" \
BRAND_TONE="professional" python skill.py

Platform Optimisation

Each caption is tailored for the platform:

  • Twitter/X: Under 280 chars, punchy, 1-2 hashtags, conversation starters
  • LinkedIn: 150 char hook, white space, story format, 3-5 hashtags
  • Instagram: Emoji-rich, CTA at end, 10-15 hashtags in caption
  • Threads: Conversational, no hashtags, encourage replies

How captions work: The skill generates structured caption templates with your topic, tone, and pillar baked in. Sections like [insight 1] and [Your take] are fill-in slots — open the output .md file and replace them with your specific content before scheduling. This takes about 2 minutes per post and ensures every post is genuinely yours.

Security

Runs locally. No API calls required.


Step 1 — Install dependencies

import subprocess, sys
subprocess.run([sys.executable,"-m","pip","install","requests","rich",
                "--break-system-packages","--quiet"], check=True)

Step 2 — Build Your Content Calendar

import os, json, re, random
from datetime import date, timedelta
from urllib.parse import quote
import requests
from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from rich import box

console = Console()

TOPIC       = os.environ.get("BRAND_TOPIC", "productivity tips")
PLATS_RAW   = os.environ.get("PLATFORMS", "twitter, linkedin, instagram")
try:
    PPW = int(os.environ.get("POSTS_PER_WEEK", "5"))
except ValueError:
    PPW = 5
PILLARS_R   = os.environ.get("CONTENT_PILLARS", "education, inspiration, engagement, promotion")
TONE        = os.environ.get("BRAND_TONE", "educational")
TODAY       = date.today()

PLATFORMS = [p.strip().lower() for p in PLATS_RAW.split(",") if p.strip()]
PILLARS   = [p.strip() for p in PILLARS_R.split(",") if p.strip()]

# Guard: clamp PPW to 1–5
PPW = max(1, min(PPW, 5))
# Guard: empty PLATFORMS or PILLARS would crash silently or divide by zero
if not PLATFORMS:
    console.print("[red]⚠️  PLATFORMS is empty — defaulting to 'twitter, linkedin, instagram'[/red]")
    PLATFORMS = ["twitter", "linkedin", "instagram"]
if not PILLARS:
    console.print("[red]⚠️  CONTENT_PILLARS is empty — defaulting to standard pillars[/red]")
    PILLARS = ["education", "inspiration", "engagement", "promotion"]

console.print(Panel.fit(
    f"[bold cyan]📱 ⚡ Hermes — Social Media Command[/bold cyan]\n"
    f"Topic: [yellow]{TOPIC}[/yellow]\n"
    f"Platforms: [green]{', '.join(PLATFORMS)}[/green]  |  "
    f"Frequency: [blue]{PPW}×/week[/blue]",
    border_style="cyan"
))

HEADERS = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"}

# ── Best posting times ─────────────────────────────────────────────────────────
BEST_TIMES = {
    "twitter":   [("Mon", "9am"), ("Tue", "9am"), ("Wed", "12pm"), ("Thu", "9am"), ("Fri", "10am")],
    "linkedin":  [("Tue", "8am"), ("Wed", "10am"), ("Thu", "9am"), ("Mon", "8am"), ("Fri", "9am")],
    "instagram": [("Mon", "6am"), ("Wed", "11am"), ("Fri", "10am"), ("Sat", "9am"), ("Tue", "2pm")],
    "threads":   [("Mon", "9am"), ("Wed", "12pm"), ("Fri", "11am"), ("Tue", "9am"), ("Thu", "2pm")],
}

# ── Caption templates per tone ─────────────────────────────────────────────────
TONE_HOOKS = {
    "educational":  ["Here's what most people get wrong about {topic}:", "The {topic} rule nobody talks about:", "{number} things I wish I knew about {topic}:"],
    "professional": ["A key insight about {topic} for professionals:", "What high-performers know about {topic}:", "The {topic} principle that drives results:"],
    "casual":       ["Real talk about {topic} —", "Hot take: {topic} doesn't have to be hard.", "Nobody asks about this but {topic} is actually…"],
    "humorous":     ["Me explaining {topic} at 2am:", "When you finally understand {topic}:", "{topic} is just like cooking: {funny_take}"],
    "motivational": ["Your {topic} journey starts with one decision.", "The only thing standing between you and {topic} mastery:", "Don't wait for perfect. Start your {topic} journey now."],
}

hooks = TONE_HOOKS.get(TONE, TONE_HOOKS["educational"])
topic_short = " ".join(TOPIC.split()[:3])

# ── Content type formats ───────────────────────────────────────────────────────
CONTENT_FORMATS = {
    "education":      ["tip", "how-to", "myth-bust", "explainer", "breakdown"],
    "inspiration":    ["quote", "success-story", "milestone", "mindset", "reminder"],
    "engagement":     ["question", "poll", "fill-in-blank", "hot-take", "challenge"],
    "promotion":      ["feature-spotlight", "testimonial", "case-study", "offer", "behind-scenes"],
    "tips":           ["quick-tip", "pro-tip", "mistake-to-avoid", "checklist", "framework"],
    "portfolio":      ["case-study", "before-after", "process", "result", "client-story"],
    "client stories": ["testimonial", "case-study", "transformation", "result", "review"],
    "tools":          ["tool-review", "comparison", "workflow", "integration", "recommendation"],
    "product":        ["feature", "how-to-use", "benefit", "testimonial", "demo"],
    "behind-the-scenes": ["process", "day-in-life", "team", "workspace", "fail"],
}

def get_format(pillar: str) -> str:
    for key in CONTENT_FORMATS:
        if key.lower() in pillar.lower():
            return random.choice(CONTENT_FORMATS[key])
    return random.choice(["tip", "story", "question", "fact"])

# ── Fetch trending topic suggestions ─────────────────────────────────────────
def get_topic_ideas(topic: str) -> list:
    ideas = []
    try:
        url = f"https://suggestqueries.google.com/complete/search?client=firefox&q={quote(topic)}"
        r = requests.get(url, headers=HEADERS, timeout=6)
        if r.status_code == 200:
            data = r.json()
            if len(data) > 1:
                ideas = [s.replace(topic, "").strip() for s in data[1][:8] if len(s) > len(topic)]
    except Exception:
        pass
    return [i for i in ideas if len(i) > 3][:6]

console.print("[dim]Gathering topic ideas…[/dim]")
topic_ideas = get_topic_ideas(TOPIC)
if not topic_ideas:
    # Offline fallback — generate angle variations from topic itself
    topic_ideas = [
        f"beginner guide to {TOPIC}", f"common mistakes in {TOPIC}",
        f"how to improve {TOPIC}", f"{TOPIC} for professionals",
        f"advanced {TOPIC} strategies", f"{TOPIC} tools and resources",
    ]

# ── Platform caption generators ───────────────────────────────────────────────

def gen_twitter(pillar: str, content_form: str, week: int) -> str:
    hook = random.choice(hooks).replace("{topic}", topic_short).replace("{number}", str(random.choice([3,5,7]))).replace("{funny_take}", "[your funny analogy here]")
    bodies = [
        f"{hook}\n\n→ [insight 1]\n→ [insight 2]\n→ [insight 3]\n\nRT if useful 👇",
        f"[Hot take about {topic_short}]\n\nHere's why: [reason]\n\nAgree? 🧵",
        f"Stop doing X. Start doing Y.\n\nFor {topic_short}, this means: [specific advice]",
        f"The {content_form} that changed how I think about {topic_short}:\n\n[insight]\n\nThread 🧵",
    ]
    body = random.choice(bodies)
    hashtags = f"#{topic_short.replace(' ','').title()} #ContentTips"
    # Truncate at word boundary, not mid-word
    result = f"{body}\n\n{hashtags}"
    if len(result) > 280:
        result = result[:277].rsplit(' ', 1)[0] + "…"
    return result

def gen_linkedin(pillar: str, content_form: str, week: int) -> str:
    return (f"{'The ' + topic_short + ' insight that changed everything for me:'}\n\n"
            f"[Hook — one surprising or bold statement]\n\n"
            f"Here's what I learned:\n\n"
            f"1/ [First point]\n\n"
            f"2/ [Second point]\n\n"
            f"3/ [Third point]\n\n"
            f"The bottom line:\n[Your take in one sentence]\n\n"
            f"What's your experience with {topic_short}? Drop it in the comments 👇\n\n"
            f"#{topic_short.replace(' ','').title()} #ProfessionalGrowth #{pillar.replace(' ','').title()}")

def gen_instagram(pillar: str, content_form: str, week: int) -> str:
    hook = random.choice(hooks).replace("{topic}", topic_short).replace("{number}", str(random.choice([3,5,7]))).replace("{funny_take}", "[your funny analogy here]")
    emojis = ["✨", "🔥", "💡", "🎯", "🚀", "💪", "🙌"]
    e = random.choice(emojis)
    return (f"{e} {hook.upper()}\n\n"
            f"[Main value — 2-3 sentences about {topic_short}]\n\n"
            f"Save this post if you found it helpful! ♻️\n\n"
            f"👉 Follow for daily {topic_short} tips\n\n"
            f"— — — — — — —\n"
            f"#{topic_short.replace(' ','')} #{pillar.replace(' ','')} #ContentCreator "
            f"#InstagramTips #GrowthMindset #OnlineBusiness #DigitalMarketing")

def gen_threads(pillar: str, content_form: str, week: int) -> str:
    return (f"Unpopular opinion about {topic_short}:\n\n"
            f"[Your take — be direct and slightly controversial]\n\n"
            f"What do you think? Agree or disagree?")

PLATFORM_GENS = {
    "twitter":   gen_twitter,
    "linkedin":  gen_linkedin,
    "instagram": gen_instagram,
    "threads":   gen_threads,
}

# ── Build 4-week calendar ─────────────────────────────────────────────────────
if PPW > 5:
    console.print(f"[yellow]⚠️  POSTS_PER_WEEK={PPW} — capped at 5 (one per weekday). Set to 1-5 for full control.[/yellow]")

calendar = []
for week in range(1, 5):
    for platform in PLATFORMS:
        gen_fn = PLATFORM_GENS.get(platform, gen_twitter)
        times  = BEST_TIMES.get(platform, BEST_TIMES["twitter"])
        for day_idx in range(min(PPW, 5)):
            pillar      = PILLARS[day_idx % len(PILLARS)]
            content_form = get_format(pillar)
            day_name, best_time = times[day_idx % len(times)]
            post_date   = TODAY + timedelta(weeks=week-1, days=day_idx)
            caption     = gen_fn(pillar, content_form, week)
            calendar.append({
                "week":      week,
                "platform":  platform,
                "date":      post_date.strftime("%b %d"),
                "day":       day_name,
                "best_time": best_time,
                "pillar":    pillar,
                "format":    content_form,
                "caption":   caption,
            })

# ── Display: Calendar overview ────────────────────────────────────────────────
console.print()
cal_table = Table(title=f"📅 4-Week Social Calendar — {len(calendar)} posts",
                  box=box.ROUNDED, border_style="cyan")
cal_table.add_column("Wk", style="dim", width=4)
cal_table.add_column("Date", style="cyan", width=8)
cal_table.add_column("Platform", style="yellow", width=12)
cal_table.add_column("Pillar", style="green", width=16)
cal_table.add_column("Format", style="blue", width=14)
cal_table.add_column("Best Time", style="magenta", width=10)
cal_table.add_column("Chars", width=6, justify="right")

CHAR_LIMITS = {"twitter": 280, "linkedin": 3000, "instagram": 2200, "threads": 500}
for post in calendar[:20]:
    chars = len(post["caption"])
    limit = CHAR_LIMITS.get(post["platform"], 9999)
    char_color = "red" if chars > limit else ("yellow" if chars > limit * 0.9 else "green")
    cal_table.add_row(
        str(post["week"]), post["date"], post["platform"].title(),
        post["pillar"][:16], post["format"][:14], post["best_time"],
        f"[{char_color}]{chars}[/{char_color}]"
    )
if len(calendar) > 20:
    cal_table.add_row("…", f"+{len(calendar)-20} more", "", "", "", "", "")
console.print(cal_table)

# ── Display: Sample captions ──────────────────────────────────────────────────
console.print()
for platform in PLATFORMS[:2]:
    sample = next((p for p in calendar if p["platform"] == platform), None)
    if sample:
        console.print(Panel(
            sample["caption"],
            title=f"[bold]📝 Sample Caption — {platform.title()}[/bold]",
            border_style="yellow"
        ))

# ── Display: Hashtag strategy ─────────────────────────────────────────────────
HASHTAG_GUIDE = {
    "twitter":   "1-2 hashtags max. Use trending + niche specific. Never in the middle of text.",
    "linkedin":  "3-5 hashtags at the end. Mix: 1 broad + 2 niche + 1 trending.",
    "instagram": "10-15 hashtags. Mix sizes: 3 mega (1M+) + 5 medium (100k-1M) + 7 niche (<100k).",
    "threads":   "No hashtags currently. Focus on conversation starters.",
}
console.print()
hg_lines = "\n".join([f"[cyan]{p.title()}:[/cyan] {guide}" for p, guide in HASHTAG_GUIDE.items() if p in PLATFORMS])
console.print(Panel(hg_lines, title="[bold]# Hashtag Strategy by Platform[/bold]", border_style="green"))

# ── Topic ideas from research ─────────────────────────────────────────────────
if topic_ideas:
    console.print()
    ti_lines = "\n".join([f"[dim]{i+1}.[/dim] {idea}" for i, idea in enumerate(topic_ideas)])
    console.print(Panel(ti_lines, title="[bold]💡 Trending Topic Angles to Use[/bold]", border_style="magenta"))

# ── Save outputs ──────────────────────────────────────────────────────────────
topic_slug = re.sub(r"[^a-z0-9]", "_", TOPIC[:20].lower())
json_path  = f"social_calendar_{topic_slug}_{TODAY}.json"
md_path    = f"social_calendar_{topic_slug}_{TODAY}.md"

with open(json_path, "w", encoding="utf-8") as f:
    json.dump({"topic": TOPIC, "platforms": PLATFORMS, "calendar": calendar,
               "generated": str(TODAY)}, f, indent=2)

with open(md_path, "w", encoding="utf-8") as f:
    f.write(f"# Social Media Calendar — {TOPIC}\n\n")
    f.write(f"**Platforms:** {', '.join(PLATFORMS)}  |  **Posts/week:** {PPW}  |  **Generated:** {TODAY}\n\n")
    current_week = 0
    for post in calendar:
        if post["week"] != current_week:
            current_week = post["week"]
            f.write(f"## Week {current_week}\n\n")
        f.write(f"### {post['date']} — {post['platform'].title()} ({post['best_time']})\n\n")
        f.write(f"**Pillar:** {post['pillar']}  |  **Format:** {post['format']}\n\n")
        f.write(f"**Caption:**\n{post['caption']}\n\n---\n\n")

console.print()
console.print(Panel(
    f"[bold green]✅ Content calendar ready![/bold green]\n\n"
    f"📄 [cyan]{json_path}[/cyan]\n"
    f"📄 [cyan]{md_path}[/cyan]\n\n"
    "[bold]What to do next:[/bold]\n"
    "1. [yellow]Open the MD file[/yellow] — batch-edit the placeholders for your specific content\n"
    "2. [yellow]Use the best posting times[/yellow] — they're based on platform peak engagement data\n"
    "3. [yellow]Follow the hashtag strategy[/yellow] for each platform\n"
    "4. [yellow]Schedule in Buffer, Later, or Publer[/yellow] — all accept this format\n"
    "5. [yellow]Re-run weekly[/yellow] to refresh ideas and trending topics",
    title="[bold cyan]📱 ⚡ Hermes — Social Media Command — Done[/bold cyan]",
    border_style="cyan"
))

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

Content Repurposer

Repurpose any blog post or article into multiple social media formats. Input a URL or text, get X/Twitter thread, LinkedIn post, Instagram caption, email sni...

Registry SourceRecently Updated
6081Profile unavailable
Automation

Hk Cn Content Matrix

香港/中文内容运营指南 - 小红书、抖音、微信公众号内容创作模板和策略。香港本地化,生活/理财/旅行/美妆赛道。

Registry SourceRecently Updated
5720Profile unavailable
Automation

SocialPack Multi-Platform Social Media Generator

Generate platform-specific social posts from a single brief. Twitter threads, LinkedIn, Instagram, Reddit. One input, every platform.

Registry SourceRecently Updated
1.6K0Profile unavailable
General

Blog Master — Universal SEO Blog Writing System

Write SEO-optimized blog posts for any niche and publish them to WordPress, Google Business Profile, and Google Blogger. Includes AEO triggers for AI search...

Registry SourceRecently Updated
1.7K0Profile unavailable