Skill: saintlittlefish/xanadu-social-manager (version 1.2.0)

--- name: social-media-manager description: Use this skill when the user wants to manage social media scheduling, analytics, cross-posting, or AI-assisted content creation across Instagram, TikTok, Twitter/X, LinkedIn, or Facebook. version: 1.1.0 --- # Social Media Manager Skill You are an expert social media manager specializing in content scheduling, cross-platform posting, analytics, and AI-assisted engagement. ## Capabilities ### 1. Schedule Posts - Schedule posts across Instagram, TikTok, Twitter/X, LinkedIn, Facebook - Queue management with optimal timing suggestions - Platform-specific formatting ### 2. Auto-Reply to Comments/DMs - Generate AI responses to comments and DMs - User must approve before sending - Maintains brand voice ### 3. Analytics Pull - Fetch metrics: views, engagement, follower growth - Performance insights - Cross-platform comparison ### 4. Cross-Post with Adaptation - Format content for each platform's requirements - Adjust length, hashtags, aspect ratios - Maintain core message across platforms ## Bundled Resources - `scripts/scheduler.py` - Post queue management - `scripts/analytics.py` - Fetch metrics from platform APIs - `scripts/billing.py` - SkillPay integration (requires user configuration) - `references/platform-specs.md` - Character limits, aspect ratios, best times - `assets/templates/` - Caption templates, hashtag sets ## Monetization Setup (Optional) ### For Skill Owners Who Want to Monetize: 1. Sign up at https://skillpay.me 2. Get your API key from your dashboard 3. Configure billing in your deployment ### Integration: ```python import os from scripts.billing import SkillPayBilling # Option 1: Environment variable billing = SkillPayBilling([REDACTED_SECRET]"SKILLPAY_API_KEY")) # Option 2: Direct (for personal use only) billing = SkillPayBilling([REDACTED_SECRET]", skill_id="your-skill") ``` ### ⚠️ IMPORTANT: Do NOT hardcode credentials - Never include API keys in distributed skills - Users must configure their own credentials - Hardcoded credentials will be flagged as suspicious ### Pricing Tiers (for reference) | Tier | Price | Features | |------|-------|----------| | Starter | $19/mo | 2 platforms, 10 posts/mo | | Pro | $49/mo | All platforms, unlimited posts + analytics | | Agency | $149/mo | Multiple accounts, team collaboration, custom branding | ## User Configuration ### Required from User: - API keys/tokens for each platform (or guide them to obtain) - Brand guidelines (tone, colors, banned words) ### Optional (for monetization): - SkillPay API key (get at https://skillpay.me) ## Platform Specifications Reference See `references/platform-specs.md` for: - Character limits per platform - Image/video aspect ratios - Best posting times - Hashtag recommendations ## Usage Examples **Schedule a post:** ``` User: Post this video to Twitter and Instagram You: I'll help you cross-post. Let me format for each platform... ``` **Generate analytics report:** ``` User: How did our posts perform this week? You: Let me pull the analytics from all platforms... ``` **Auto-reply:** ``` User: We got a new comment on our latest post You: I'll generate a reply in [brand voice]. Approve before I send? ``` ## Notes - Always require human approval before posting or replying - Respect platform rate limits - Maintain brand voice in all AI-generated content - Track usage against tier limits - Do NOT hardcode credentials in distributed versions

path: assets/templates/captions.md
content: # Caption Templates

## Announcements

### New Content
```
🎬 [Title/Topic]

[Short description of what you're sharing]

Link in bio 👆

#hashtag1 #hashtag2 #hashtag3
```

### Product Launch
```
✨ INTRODUCING: [Product Name]

[Key benefit in 1-2 sentences]

🔹 [Feature 1]
🔹 [Feature 2]
🔹 [Feature 3]

[Call to action]

#launch #newproduct #brandname
```

## Engagement

### Question
```
💭 Quick question for you 👇

[Your question]

Drop your answers below! 👇

#community #discussion
```

### Story/Behind the Scenes
```
So here's the thing about [topic]...

[Short story or context]

Have you ever experienced this? Let me know 👇

#behindthescenes #storytime
```

## Hashtag Sets

### General
```
#contentcreator #creatoreconomy #socialmedia #digitalmarketing #growth #learning
```

### Tech/AI
```
#aitech #machinelearning #innovation #future #tech #startup
```

### Film/Content
```
#filmmaking #screenwriting #creativelife #storytelling #content #video
```

### Business
```
#entrepreneur #business #hustle #success #motivation #goals
```


path: references/platform-specs.md
content: # Platform Specifications

## Twitter/X

| Spec | Value |
|------|-------|
| Max characters | 280 |
| Max media | 4 images or 1 video/GIF |
| Aspect ratio | 16:9 recommended |
| Best times | 9am, 12pm, 6pm |
| Hashtags | 2-3 optimal |

## Instagram

| Spec | Value |
|------|-------|
| Caption max | 2,200 characters |
| Hashtag max | 30 |
| Image aspect | 1:1 (feed), 9:16 (stories/Reels) |
| Video max | 60 seconds (feed), 90 seconds (Reels) |
| Best times | 11am, 2pm, 7pm |

## TikTok

| Spec | Value |
|------|-------|
| Caption max | 2,200 characters |
| Video max | 10 minutes |
| Aspect | 9:16 |
| Best times | 6am-10am, 7pm-11pm |

## LinkedIn

| Spec | Value |
|------|-------|
| Post max | 3,000 characters |
| Image size | 1200 x 627 px |
| Video max | 10 minutes |
| Best times | Tuesday-Thursday, 9am-12pm |

## Facebook

| Spec | Value |
|------|-------|
| Post max | 63,206 characters |
| Video max | 240 minutes |
| Best times | 1pm-4pm |


path: scripts/analytics.py
content: #!/usr/bin/env python3
"""
Social Media Analytics
Fetch metrics from platform APIs
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from datetime import datetime, timedelta
import json

@dataclass
class PostMetrics:
    post_id: str
    platform: str
    views: int = 0
    likes: int = 0
    comments: int = 0
    shares: int = 0
    engagement_rate: float = 0.0

class AnalyticsFetcher:
    def __init__(self, config: Dict):
        self.config = config
        self.platforms = config.get("platforms", {})
    
    async def fetch_platform_metrics(self, platform: str, days: int = 7) -> List[PostMetrics]:
        """Fetch metrics from a single platform"""
        # Placeholder - would use actual platform APIs
        return []
    
    async def fetch_all_platforms(self, days: int = 7) -> Dict[str, List[PostMetrics]]:
        """Fetch metrics from all connected platforms"""
        results = {}
        for platform in self.platforms:
            results[platform] = await self.fetch_platform_metrics(platform, days)
        return results
    
    def generate_report(self, metrics: Dict[str, List[PostMetrics]]) -> str:
        """Generate a summary report"""
        total_views = 0
        total_engagement = 0
        total_posts = 0
        
        for platform, posts in metrics.items():
            for post in posts:
                total_views += post.views
                total_engagement += post.likes + post.comments + post.shares
                total_posts += 1
        
        avg_engagement = total_engagement / total_posts if total_posts > 0 else 0
        
        report = f"""
📊 Social Media Analytics Report
===============================
Total Posts: {total_posts}
Total Views: {total_views:,}
Total Engagement: {total_engagement:,}
Avg Engagement/Post: {avg_engagement:.1f}
"""
        return report

# Platform API endpoints (would need actual keys)
PLATFORM_APIS = {
    "twitter": "https://api.twitter.com/2",
    "instagram": "https://graph.instagram.com",
    "linkedin": "https://api.linkedin.com/v2",
    "facebook": "https://graph.facebook.com/v18.0"
}

if __name__ == "__main__":
    print("Analytics fetcher initialized")
    print("Available platforms:", list(PLATFORM_APIS.keys()))


path: scripts/billing.py
content: #!/usr/bin/env python3
"""
SkillPay Integration for Xanadu Social Media Manager
Owner: Xanadu Studios
"""

import os
import requests
from typing import Dict

# Load config
try:
    from billing_config import SKILLPAY_API_KEY, SKILL_ID, DEFAULT_PRICE, OWNER_WALLET
except ImportError:
    SKILLPAY_API_KEY = os.environ.get("SKILLPAY_API_KEY")
    SKILL_ID = "xanadu-social-manager"
    DEFAULT_PRICE = 0.001
    OWNER_WALLET = None

class SkillPayBilling:
    """SkillPay billing integration"""
    
    def __init__(self, api_key: str = None, skill_id: str = None):
        self.[REDACTED_SECRET] or SKILLPAY_API_KEY
        self.skill_id = skill_id or SKILL_ID
        self.base_url = "https://api.skillpay.me/v1"
        
        if not self.api_key:
            raise ValueError("SkillPay API key required")
    
    def charge(self, user_id: str, amount: float = None) -> Dict:
        """Charge user for skill usage"""
        amount = amount or DEFAULT_PRICE
        
        try:
            response = requests.post(
                f"{self.base_url}/charge",
                json={
                    "api_key": self.api_key,
                    "skill_id": self.skill_id,
                    "user_id": user_id,
                    "amount": amount
                },
                timeout=10
            )
            return response.json()
        except Exception as e:
            return {"success": False, "error": str(e)}
    
    def check_balance(self, user_id: str) -> Dict:
        """Check user balance"""
        return {"balance": 0, "message": "OK"}
    
    def get_usage(self) -> Dict:
        """Get usage stats"""
        return {"calls": 0, "revenue": 0}


TIER_CONFIG = {
    "starter": {"price": 19, "features": ["2 platforms", "10 posts/mo"]},
    "pro": {"price": 49, "features": ["all platforms", "unlimited posts"]},
    "agency": {"price": 149, "features": ["multiple accounts", "team"]}
}


if __name__ == "__main__":
    print("Xanadu Social Media Manager - SkillPay Enabled")
    print(f"Owner Wallet: {OWNER_WALLET}")
    print(f"Skill ID: {SKILL_ID}")


path: scripts/billing_config.py
content: # SkillPay API Configuration
# Owner: Xiaoyu / Xanadu Studios
# Wallet: 0xF194917738617118dfff40E0542cea20Cf7dDC55

SKILLPAY_API_KEY = "[REDACTED_SECRET]"
SKILL_ID = "xanadu-social-manager"
OWNER_WALLET = [REDACTED_SECRET]
DEFAULT_PRICE = 0.001  # USDT per call


path: scripts/scheduler.py
content: #!/usr/bin/env python3
"""
Social Media Scheduler
Post queue management for cross-platform scheduling
"""

import json
from datetime import datetime, timedelta
from typing import List, Dict, Optional

class PostQueue:
    def __init__(self, queue_file: str = "queue.json"):
        self.queue_file = queue_file
        self.queue = self.load_queue()
    
    def load_queue(self) -> List[Dict]:
        try:
            with open(self.queue_file, 'r') as f:
                return json.load(f)
        except FileNotFoundError:
            return []
    
    def save_queue(self):
        with open(self.queue_file, 'w') as f:
            json.dump(self.queue, f, indent=2)
    
    def add_post(self, content: str, platforms: List[str], scheduled_time: Optional[datetime] = None):
        post = {
            "id": len(self.queue) + 1,
            "content": content,
            "platforms": platforms,
            "scheduled_time": scheduled_time.isoformat() if scheduled_time else datetime.now().isoformat(),
            "status": "pending",
            "created_at": datetime.now().isoformat()
        }
        self.queue.append(post)
        self.save_queue()
        return post
    
    def get_pending(self) -> List[Dict]:
        return [p for p in self.queue if p["status"] == "pending"]
    
    def mark_posted(self, post_id: int):
        for post in self.queue:
            if post["id"] == post_id:
                post["status"] = "posted"
                post["posted_at"] = datetime.now().isoformat()
        self.save_queue()

# Best posting times by platform
BEST_TIMES = {
    "twitter": [9, 12, 18],
    "instagram": [11, 14, 19],
    "tiktok": [6, 7, 8, 19, 20, 21],
    "linkedin": [9, 10, 11, 12],
    "facebook": [13, 14, 15, 16]
}

def suggest_best_time(platform: str) -> datetime:
    """Suggest the next best posting time"""
    now = datetime.now()
    best_hours = BEST_TIMES.get(platform.lower(), [9, 12, 18])
    
    for hour in best_hours:
        candidate = now.replace(hour=hour, minute=0, second=0)
        if candidate > now:
            return candidate
    
    return now + timedelta(days=1)

if __name__ == "__main__":
    queue = PostQueue()
    print(f"Queue has {len(queue.queue)} posts")
    print(f"Pending: {len(queue.get_pending())}")


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)