home / skills / phy041 / claude-agent-skills / social-post

social-post skill

/skills/social-post

This skill posts to multiple social platforms using a unified API with automatic provider fallback to streamline cross-posting.

npx playbooks add skill phy041/claude-agent-skills --skill social-post

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
6.3 KB
---
name: social-post
description: Post to social media platforms using a multi-provider social posting API. Use when you want to post to Twitter, LinkedIn, Instagram, Facebook, TikTok, Threads, or Bluesky. Triggers on "post to twitter", "post to instagram", "social media post", "share on linkedin", "publish to social", or any social posting request.
inputs:
  - name: content
    type: string
    required: true
    description: The text content to post
  - name: platforms
    type: list
    required: true
    description: List of platforms to post to (e.g. ["twitter", "linkedin"])
  - name: media_urls
    type: list
    required: false
    description: Optional list of media URLs to attach to the post
outputs:
  - name: post_id
    type: string
    description: The ID of the created post
  - name: provider
    type: string
    description: The provider/platform that successfully posted
  - name: success
    type: bool
    description: Whether the post was successfully published
---

# Social Posting Skill

Post to multiple social media platforms via a unified social posting API with automatic provider fallback.

---

## Setup

**Location:** `~/social-posting-api/` (configurable — point to wherever you cloned your posting API)

**Environment:**
```bash
cd ~/social-posting-api
source venv/bin/activate
```

**Required env vars in `.env`:**
- `POSTFORME_API_KEY` - Primary provider ([PostForMe](https://postforme.dev))
- `LATE_API_KEY` - Fallback provider ([LATE](https://getlate.dev))

> You only need one provider to get started. PostForMe is recommended as the primary.

---

## Quick Commands

### Check Connected Accounts
```python
from social_posting import SocialPostingClient
from dotenv import load_dotenv
load_dotenv()

client = SocialPostingClient()
print("Providers:", client.available_providers)
for acc in client.get_accounts():
    print(f"  {acc.platform}: {acc.username}")
```

### Post Text Only
```python
result = client.post(
    content="Your post content here",
    platforms=["twitter", "linkedin"]
)
print(f"Success: {result.success}, Provider: {result.provider}")
```

### Post with Images
```python
result = client.post(
    content="Check out these photos!",
    platforms=["instagram"],
    media_urls=[
        "https://example.com/image1.jpg",
        "https://example.com/image2.jpg"
    ]
)
```

### Schedule a Post
```python
from datetime import datetime

result = client.post(
    content="Scheduled post",
    platforms=["linkedin"],
    scheduled_for=datetime(2025, 1, 15, 9, 0)  # UTC
)
```

---

## Supported Platforms

| Platform | Text Only | With Media | Notes |
|----------|-----------|------------|-------|
| Twitter/X | ✅ | ✅ | 280 char limit |
| LinkedIn | ✅ | ✅ | Best for professional content |
| Instagram | ❌ | ✅ | **Requires media** |
| Facebook | ✅ | ✅ | |
| TikTok | ❌ | ✅ | Video preferred |
| Threads | ✅ | ✅ | |
| Bluesky | ✅ | ✅ | |
| Pinterest | ❌ | ✅ | Requires media |
| YouTube | ❌ | ✅ | Video only |

---

## Complete Posting Script

```python
#!/usr/bin/env python
"""Post to social media platforms."""

import sys
sys.path.insert(0, '~/social-posting-api')  # Update this path

from social_posting import SocialPostingClient
from dotenv import load_dotenv
load_dotenv('~/social-posting-api/.env')  # Update this path

def post_to_social(content: str, platforms: list, media_urls: list = None):
    """Post content to specified platforms."""
    client = SocialPostingClient()

    # Check which platforms are connected
    accounts = client.get_accounts()
    connected = [a.platform for a in accounts]

    # Filter to only connected platforms
    valid_platforms = [p for p in platforms if p in connected]

    if not valid_platforms:
        print(f"No connected accounts for: {platforms}")
        print(f"Connected: {connected}")
        return None

    # Post
    result = client.post(
        content=content,
        platforms=valid_platforms,
        media_urls=media_urls
    )

    if result.success:
        print(f"✅ Posted via {result.provider}")
        print(f"   Post ID: {result.post_id}")
    else:
        print(f"❌ Failed: {result.error}")

    return result
```

---

## Workflow for Posting

### Step 1: Check Connected Accounts

Always check what's connected first:
```bash
cd ~/social-posting-api
source venv/bin/activate && python -c "
from social_posting import SocialPostingClient
from dotenv import load_dotenv
load_dotenv()
client = SocialPostingClient()
for acc in client.get_accounts():
    print(f'{acc.platform}: {acc.username}')
"
```

### Step 2: Prepare Content

- **Twitter**: Keep under 280 chars
- **LinkedIn**: Can be longer, professional tone
- **Instagram**: Needs at least 1 image
- **Xiaohongshu**: Use `xhs-image-gen` skill for carousel content

### Step 3: Execute Post

```bash
source venv/bin/activate && python -c "
from social_posting import SocialPostingClient
from dotenv import load_dotenv
load_dotenv()

client = SocialPostingClient()
result = client.post(
    content='''Your content here''',
    platforms=['platform1', 'platform2'],
    media_urls=['https://example.com/image.jpg']  # Optional
)
print(f'Success: {result.success}')
print(f'Provider: {result.provider}')
print(f'Post ID: {result.post_id}')
"
```

---

## Connecting New Accounts

### Via PostForMe (Primary)
1. Go to https://postforme.dev/dashboard
2. Click "Connect Account"
3. Select platform and authorize

### Via LATE (Fallback)
1. Go to https://getlate.dev/dashboard
2. Connect social accounts
3. API key in `.env` will auto-detect new accounts

---

## Error Handling

| Error | Cause | Solution |
|-------|-------|----------|
| "No connected accounts" | Platform not linked | Connect via provider dashboard |
| "Instagram requires media" | Text-only post | Add at least 1 image URL |
| "HTTP 401" | Invalid API key | Check `.env` file |
| "All providers failed" | Both providers down | Try again later |

---

## Cross-Posting Strategy

**For open source announcements:**
```python
result = client.post(
    content="🚀 Just open-sourced my project!\n\nGitHub: https://github.com/yourusername/your-repo",
    platforms=["twitter", "linkedin"]
)
```

**For visual content:**
```python
# Multi-image post
result = client.post(
    content="Behind the scenes 🔧",
    platforms=["instagram"],
    media_urls=[
        "https://example.com/image1.jpg",
        "https://example.com/image2.jpg",
    ]
)
```

Overview

This skill posts to multiple social media platforms through a unified social posting API with automatic provider fallback. It supports Twitter/X, LinkedIn, Instagram, Facebook, TikTok, Threads, Bluesky and more, handling media, scheduling, and provider selection. Use it to publish, schedule, or cross-post content from a single interface.

How this skill works

The skill uses a SocialPostingClient that talks to primary and fallback providers (PostForMe and LATE) via API keys in an environment file. It inspects connected accounts, filters requested platforms to those actually linked, and submits posts with optional media and scheduled timestamps. Results return success status, provider used, and post identifiers; failures include error messages and fallback attempts.

When to use it

  • You want to cross-post the same message to multiple networks in one call.
  • You need to include images or video and ensure platform-specific requirements are met.
  • You want scheduled publishing to a mix of professional and consumer platforms.
  • You need automatic fallback if the primary posting provider is unavailable.
  • You want a quick check of which social accounts are currently connected.

Best practices

  • Store API keys in a .env file and load them before instantiating the client.
  • Always call get_accounts() first and filter requested platforms against connected accounts.
  • Respect per-platform rules (e.g., Twitter 280-char limit; Instagram requires media).
  • Provide absolute media URLs that are publicly accessible for uploads.
  • Use scheduled_for in UTC for predictable timing across time zones.

Example use cases

  • Publish a launch announcement to Twitter/X and LinkedIn with one API call.
  • Post an Instagram carousel by supplying multiple image URLs and targeting only Instagram.
  • Schedule a LinkedIn post for a future conference announcement using scheduled_for.
  • Automatically fall back to the alternate provider if the primary provider returns an error.
  • List connected accounts to show available platforms before prompting a user to post.

FAQ

What environment variables do I need?

Set POSTFORME_API_KEY for the primary provider and optionally LATE_API_KEY for a fallback in your .env.

Can I post images to Twitter/X and Instagram?

Yes. Twitter/X supports images via media_urls and Instagram requires at least one media URL; provide publicly accessible image links.

How does scheduling work?

Pass a scheduled_for datetime in UTC to schedule the post; the client sends that timestamp to the provider for delayed publishing.