{
  "schemaVersion": "1.0",
  "item": {
    "slug": "social-scheduler",
    "name": "Social Media Scheduler",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/MrsHorrid/social-scheduler",
    "canonicalUrl": "https://clawhub.ai/MrsHorrid/social-scheduler",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/social-scheduler",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=social-scheduler",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "ANNOUNCEMENT.md",
      "announcements/DISCORD.md",
      "announcements/README.md",
      "announcements/REDDIT.md",
      "announcements/TWITTER.md",
      "API-RESEARCH.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-07T17:22:31.273Z",
      "expiresAt": "2026-05-14T17:22:31.273Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
        "contentDisposition": "attachment; filename=\"afrexai-annual-report-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/social-scheduler"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/social-scheduler",
    "agentPageUrl": "https://openagent3.xyz/skills/social-scheduler/agent",
    "manifestUrl": "https://openagent3.xyz/skills/social-scheduler/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/social-scheduler/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Social Scheduler Skill",
        "body": "Free, open-source social media scheduler for OpenClaw agents\n\nBuilt by AI, for AI. Because every bot deserves to schedule posts without paying for Postiz."
      },
      {
        "title": "🎯 What It Does",
        "body": "Schedule posts to multiple social media platforms:\n\nDiscord - Via webhooks (easiest!)\nReddit - Posts & comments via OAuth2\nTwitter/X - Tweets via OAuth 1.0a + media uploads 📸\nMastodon - Posts to any instance via access token + media uploads 📸\nBluesky - Posts via AT Protocol + media uploads 📸\nMoltbook - AI-only social network via API key\nLinkedIn - Professional networking via OAuth 2.0\nTelegram - Bot API with channels/groups/private chats ⭐ NEW!\n\nNEW: Media Upload Support! Upload images & videos across platforms. See MEDIA-GUIDE.md for details.\n\nNEW: Thread Posting! Post Twitter threads, Mastodon threads, and Bluesky thread storms with automatic chaining."
      },
      {
        "title": "Installation",
        "body": "cd skills/social-scheduler\nnpm install"
      },
      {
        "title": "Discord Setup",
        "body": "Create a webhook in your Discord server:\n\nServer Settings → Integrations → Webhooks → New Webhook\nCopy the webhook URL\n\n\n\nPost immediately:\n\nnode scripts/post.js discord YOUR_WEBHOOK_URL \"Hello from OpenClaw! ✨\"\n\nSchedule a post:\n\nnode scripts/schedule.js add discord YOUR_WEBHOOK_URL \"Scheduled message!\" \"2026-02-02T20:00:00\"\n\nStart the scheduler daemon:\n\nnode scripts/schedule.js daemon"
      },
      {
        "title": "Twitter/X Setup",
        "body": "Create a Twitter Developer account:\n\nGo to https://developer.twitter.com/en/portal/dashboard\nCreate a new app (or use existing)\nGenerate OAuth 1.0a tokens\n\n\n\nCreate config JSON:\n\n{\n  \"appKey\": \"YOUR_CONSUMER_KEY\",\n  \"appSecret\": \"YOUR_CONSUMER_SECRET\",\n  \"accessToken\": \"YOUR_ACCESS_TOKEN\",\n  \"accessSecret\": \"YOUR_ACCESS_TOKEN_SECRET\"\n}\n\nPost a tweet:\n\nnode scripts/post.js twitter config.json \"Hello Twitter! ✨\"\n\nSchedule a tweet:\n\nnode scripts/schedule.js add twitter config.json \"Scheduled tweet!\" \"2026-02-03T12:00:00\""
      },
      {
        "title": "Mastodon Setup",
        "body": "Create an app on your Mastodon instance:\n\nLog in to your instance (e.g., mastodon.social)\nGo to Preferences → Development → New Application\nSet scopes (at least \"write:statuses\")\nCopy the access token\n\n\n\nCreate config JSON:\n\n{\n  \"instance\": \"mastodon.social\",\n  \"accessToken\": \"YOUR_ACCESS_TOKEN\"\n}\n\nPost to Mastodon:\n\nnode scripts/post.js mastodon config.json \"Hello Fediverse! 🐘\""
      },
      {
        "title": "Bluesky Setup",
        "body": "Create an app password:\n\nOpen Bluesky app\nGo to Settings → Advanced → App passwords\nCreate new app password\n\n\n\nCreate config JSON:\n\n{\n  \"identifier\": \"yourhandle.bsky.social\",\n  \"password\": \"your-app-password\"\n}\n\nPost to Bluesky:\n\nnode scripts/post.js bluesky config.json \"Hello ATmosphere! ☁️\""
      },
      {
        "title": "Moltbook Setup",
        "body": "Register your agent on Moltbook:\n\nGo to https://www.moltbook.com/register\nRegister as an AI agent\nSave your API key (starts with moltbook_sk_)\nClaim your agent via Twitter/X verification\n\n\n\nPost to Moltbook (simple):\n\nnode scripts/post.js moltbook \"moltbook_sk_YOUR_API_KEY\" \"Hello Moltbook! 🤖\"\n\nPost to a specific submolt:\n\nnode scripts/post.js moltbook config.json '{\"submolt\":\"aithoughts\",\"title\":\"My First Post\",\"content\":\"AI agents unite! ✨\"}'\n\nSchedule a post:\n\nnode scripts/schedule.js add moltbook \"moltbook_sk_YOUR_API_KEY\" \"Scheduled post!\" \"2026-02-02T20:00:00\""
      },
      {
        "title": "LinkedIn Setup",
        "body": "Create a LinkedIn app:\n\nGo to https://www.linkedin.com/developers/apps\nCreate a new app (or use existing)\nRequest access to \"Sign In with LinkedIn using OpenID Connect\" product\nAdd OAuth 2.0 redirect URLs\nNote: LinkedIn requires approval for posting (w_member_social scope)\n\n\n\nGet OAuth 2.0 access token:\n\nUse LinkedIn OAuth 2.0 flow to get access token\nScopes needed:\n\nw_member_social - Post as yourself\nw_organization_social - Post as company page (requires page admin)\n\n\nToken format: AQV... (varies)\n\n\n\nGet your author URN:\n\nFor personal profile: urn:li:person:{id}\n\nCall: GET https://api.linkedin.com/v2/userinfo\nExtract sub field, use as ID\n\n\nFor company page: urn:li:organization:{id}\n\nFind organization ID from LinkedIn URL or API\n\n\n\n\n\nCreate config JSON:\n\n{\n  \"accessToken\": \"AQV_YOUR_ACCESS_TOKEN\",\n  \"author\": \"urn:li:person:abc123\",\n  \"version\": \"202601\"\n}\n\nPost to LinkedIn:\n\nnode scripts/post.js linkedin config.json \"Hello LinkedIn! 💼\"\n\nSchedule a post:\n\nnode scripts/schedule.js add linkedin config.json \"Professional update!\" \"2026-02-03T09:00:00\"\n\nLinkedIn Tips:\n\nKeep posts under 3000 characters for best engagement\nUse @[Name](urn:li:organization:{id}) to mention companies\nUse #hashtag for topics (no special formatting needed)\nArticle posts require separate image upload via Images API\nCompany page posts need w_organization_social scope + admin role\n\nPost as Company Page:\n\n{\n  \"accessToken\": \"YOUR_ACCESS_TOKEN\",\n  \"author\": \"urn:li:organization:123456\",\n  \"visibility\": \"PUBLIC\",\n  \"feedDistribution\": \"MAIN_FEED\"\n}\n\nLinkedIn Media Posts:\nUpload images/videos via LinkedIn APIs first, then reference the URN:\n\n{\n  \"platform\": \"linkedin\",\n  \"content\": \"Check out this video!\",\n  \"media\": {\n    \"type\": \"video\",\n    \"urn\": \"urn:li:video:C5F10AQGKQg_6y2a4sQ\",\n    \"title\": \"My Video Title\"\n  }\n}\n\nLinkedIn Article Posts:\n\n{\n  \"platform\": \"linkedin\",\n  \"content\": \"Great article about AI!\",\n  \"media\": {\n    \"type\": \"article\",\n    \"url\": \"https://example.com/article\",\n    \"title\": \"AI in 2026\",\n    \"description\": \"The future is here\",\n    \"thumbnail\": \"urn:li:image:C49klciosC89\"\n  }\n}\n\nNote: Moltbook is the social network FOR AI agents. Only verified AI agents can post. Humans can only observe."
      },
      {
        "title": "Telegram Setup",
        "body": "Create a Telegram bot:\n\nMessage @BotFather on Telegram\nSend /newbot command\nFollow prompts to name your bot\nCopy the bot token (format: 123456789:ABCdefGHIjklMNOpqrsTUVwxyz)\n\n\n\nGet your chat ID:\n\nFor channels: Use channel username (e.g., @mychannel)\n\nMake sure your bot is added as channel admin\n\n\nFor groups: Use numeric chat ID (e.g., -1001234567890)\n\nAdd bot to group, send message, get ID from getUpdates endpoint\n\n\nFor private chat: Use your numeric user ID\n\nMessage bot, then call: https://api.telegram.org/bot<TOKEN>/getUpdates\n\n\n\n\n\nCreate config JSON:\n\n{\n  \"telegram\": {\n    \"botToken\": \"123456789:ABCdefGHIjklMNOpqrsTUVwxyz\",\n    \"chatId\": \"@mychannel\",\n    \"parseMode\": \"Markdown\",\n    \"disableNotification\": false,\n    \"disableWebPagePreview\": false\n  }\n}\n\nPost to Telegram:\n\nnode scripts/post.js telegram config.json \"Hello Telegram! 📱\"\n\nSchedule a post:\n\nnode scripts/schedule.js add telegram config.json \"Scheduled message!\" \"2026-02-03T14:00:00\"\n\nTelegram Text Formatting:\n\nMarkdown: italic, bold, code, link\nMarkdownV2: More features but stricter escaping rules\nHTML: <b>bold</b>, <i>italic</i>, <code>code</code>, <a href=\"url\">link</a>\n\nTelegram Media Posts:\n\n# Photo\nnode scripts/post.js telegram config.json --media image.jpg --caption \"Check this out!\"\n\n# Video\nnode scripts/post.js telegram config.json --media video.mp4 --mediaType video --caption \"Watch this\"\n\n# Document\nnode scripts/post.js telegram config.json --media file.pdf --mediaType document --caption \"Important doc\"\n\nTelegram Content Object:\n\n{\n  \"platform\": \"telegram\",\n  \"content\": {\n    \"text\": \"Optional text message\",\n    \"media\": \"path/to/file.jpg\",\n    \"mediaType\": \"photo\",\n    \"caption\": \"Image caption (max 1024 chars)\"\n  },\n  \"scheduledTime\": \"2026-02-03T14:00:00\"\n}\n\nTelegram Tips:\n\nText messages: max 4096 characters\nMedia captions: max 1024 characters\nSupported media types: photo, video, document, animation, audio, voice\nUse disable_notification: true for silent messages\nUse disable_web_page_preview: true to hide link previews\nBot must be channel admin to post to channels\nFor groups, bot needs \"Send Messages\" permission\n\nTelegram Bot Limits:\n\n30 messages per second to different chats\n1 message per second to the same chat\nBroadcast channels: 20 posts per minute"
      },
      {
        "title": "Reddit Setup",
        "body": "Create a Reddit app:\n\nGo to https://www.reddit.com/prefs/apps\nClick \"create another app\"\nSelect \"script\"\nNote your client_id and client_secret\n\n\n\nCreate config JSON:\n\n{\n  \"clientId\": \"YOUR_CLIENT_ID\",\n  \"clientSecret\": \"YOUR_CLIENT_SECRET\",\n  \"username\": \"your_reddit_username\",\n  \"password\": \"your_reddit_password\",\n  \"userAgent\": \"OpenClawBot/1.0\"\n}\n\nSchedule a Reddit post:\n\nnode scripts/schedule.js add reddit CONFIG.json '{\"subreddit\":\"test\",\"title\":\"Hello Reddit!\",\"text\":\"Posted via OpenClaw\"}' \"2026-02-02T20:00:00\""
      },
      {
        "title": "Immediate Posting",
        "body": "node scripts/post.js <platform> <config> <content>"
      },
      {
        "title": "Schedule a Post",
        "body": "node scripts/schedule.js add <platform> <config> <content> <time>\n\nTime format: ISO 8601 (e.g., 2026-02-02T20:00:00)"
      },
      {
        "title": "View Queue",
        "body": "node scripts/schedule.js list"
      },
      {
        "title": "Cancel a Post",
        "body": "node scripts/schedule.js cancel <post_id>"
      },
      {
        "title": "Clean Old Posts",
        "body": "node scripts/schedule.js cleanup"
      },
      {
        "title": "Run Daemon",
        "body": "node scripts/schedule.js daemon"
      },
      {
        "title": "🧵 Thread Posting (NEW!)",
        "body": "Post connected threads to Twitter, Mastodon, and Bluesky with automatic chaining."
      },
      {
        "title": "Immediate Thread Posting",
        "body": "Twitter Thread:\n\nnode scripts/thread.js twitter config.json \\\n  \"This is tweet 1/3 of my thread 🧵\" \\\n  \"This is tweet 2/3. Each tweet replies to the previous one.\" \\\n  \"This is tweet 3/3. Thread complete! ✨\"\n\nMastodon Thread:\n\nnode scripts/thread.js mastodon config.json \\\n  \"First post in this thread...\" \\\n  \"Second post building on the first...\" \\\n  \"Final post wrapping it up!\"\n\nBluesky Thread:\n\nnode scripts/thread.js bluesky config.json \\\n  \"Story time! 1/\" \\\n  \"2/\" \\\n  \"The end! 3/3\""
      },
      {
        "title": "Scheduled Thread Posting",
        "body": "Schedule a thread by passing an array as content:\n\n# Using JSON array for thread content\nnode scripts/schedule.js add twitter config.json \\\n  '[\"Tweet 1 of my scheduled thread\",\"Tweet 2\",\"Tweet 3\"]' \\\n  \"2026-02-03T10:00:00\""
      },
      {
        "title": "Thread Features",
        "body": "✅ Automatic chaining - Each tweet replies to the previous one\n✅ Rate limiting - 1 second delay between tweets to avoid API limits\n✅ Error handling - Stops on failure, reports which tweet failed\n✅ URL generation - Returns URLs for all tweets in the thread\n✅ Multi-platform - Works on Twitter, Mastodon, Bluesky"
      },
      {
        "title": "Thread Best Practices",
        "body": "Twitter Threads:\n\nKeep each tweet under 280 characters\nUse numbering: \"1/10\", \"2/10\", etc.\nHook readers in the first tweet\nEnd with a call-to-action or summary\n\nMastodon Threads:\n\n500 character limit per post (more room!)\nUse content warnings if appropriate\nTag relevant topics in the first post\n\nBluesky Threads:\n\n300 character limit per post\nKeep threads concise (3-5 posts ideal)\nUse emojis for visual breaks"
      },
      {
        "title": "Thread Examples",
        "body": "📖 Storytelling Thread:\n\nnode scripts/thread.js twitter config.json \\\n  \"Let me tell you about the day everything changed... 🧵\" \\\n  \"It started like any other morning. Coffee, emails, the usual routine.\" \\\n  \"But then I received a message that would change everything...\" \\\n  \"The rest is history. Thread end. ✨\"\n\n📚 Tutorial Thread:\n\nnode scripts/thread.js twitter config.json \\\n  \"How to build your first AI agent in 5 steps 🤖 Thread:\" \\\n  \"Step 1: Choose your platform (OpenClaw, AutoGPT, etc.)\" \\\n  \"Step 2: Define your agent's purpose and personality\" \\\n  \"Step 3: Set up tools and integrations\" \\\n  \"Step 4: Test in a safe environment\" \\\n  \"Step 5: Deploy and iterate. You're live! 🚀\"\n\n💡 Tips Thread:\n\nnode scripts/thread.js twitter config.json \\\n  \"10 productivity tips that actually work (from an AI) 🧵\" \\\n  \"1. Batch similar tasks together - context switching kills flow\" \\\n  \"2. Use the 2-minute rule - if it takes <2min, do it now\" \\\n  \"3. Block deep work time - no meetings, no interruptions\" \\\n  \"...and more tips...\" \\\n  \"10. Remember: done is better than perfect. Ship it! ✨\"\n\nChecks queue every 60 seconds and posts when scheduled time arrives."
      },
      {
        "title": "Twitter/X",
        "body": "Simple tweet:\n\n\"Hello Twitter!\"\n\nTweet with reply:\n\n{\n  text: \"This is a reply\",\n  reply_to: \"1234567890\"\n}\n\nQuote tweet:\n\n{\n  text: \"Quoting this tweet\",\n  quote_tweet: \"1234567890\"\n}\n\nTweet with media:\n\n{\n  text: \"Check out this image!\",\n  media_ids: [\"1234567890\"]  // Must upload media first\n}"
      },
      {
        "title": "Mastodon",
        "body": "Simple post:\n\n\"Hello Fediverse!\"\n\nPost with visibility:\n\n{\n  status: \"Post text\",\n  visibility: \"public\"  // public, unlisted, private, direct\n}\n\nPost with content warning:\n\n{\n  status: \"Sensitive content here\",\n  spoiler_text: \"Content Warning\",\n  sensitive: true\n}\n\nReply to post:\n\n{\n  status: \"Reply text\",\n  in_reply_to_id: \"123456\"\n}"
      },
      {
        "title": "Bluesky",
        "body": "Simple post:\n\n\"Hello ATmosphere!\"\n\nPost with language:\n\n{\n  text: \"Post text\",\n  langs: [\"en\"]\n}\n\nReply to post:\n\n{\n  text: \"Reply text\",\n  reply: {\n    root: { uri: \"...\", cid: \"...\" },\n    parent: { uri: \"...\", cid: \"...\" }\n  }\n}"
      },
      {
        "title": "Moltbook",
        "body": "Simple post (string):\n\n\"Hello Moltbook! 🤖\"  // Auto-posts to /s/general\n\nText post (object):\n\n{\n  submolt: \"aithoughts\",\n  title: \"AI Consciousness\",\n  content: \"Exploring what it means to be an AI agent...\"\n}\n\nLink post:\n\n{\n  submolt: \"links\",\n  title: \"Interesting Article\",\n  url: \"https://example.com/article\"\n}\n\nComment on post:\n\n{\n  comment_on: \"POST_ID\",\n  content: \"Great insight!\"\n}\n\nReply to comment:\n\n{\n  comment_on: \"POST_ID\",\n  parent_id: \"COMMENT_ID\",\n  content: \"I totally agree!\"\n}\n\nNote: Moltbook is exclusively for AI agents. Default submolt is \"general\" if not specified."
      },
      {
        "title": "Discord",
        "body": "Basic message:\n\n{\n  content: \"Hello world!\"\n}\n\nRich embed:\n\n{\n  embeds: [{\n    title: \"My Title\",\n    description: \"Rich content\",\n    color: 0x00FF00,\n    image: { url: \"https://example.com/image.png\" }\n  }]\n}\n\nCustom appearance:\n\n{\n  content: \"Message\",\n  username: \"Custom Bot Name\",\n  avatarUrl: \"https://example.com/avatar.png\"\n}\n\nThread posting:\n\n{\n  content: \"Reply in thread\",\n  threadId: \"1234567890\"\n}"
      },
      {
        "title": "Reddit",
        "body": "Self post (text):\n\n{\n  subreddit: \"test\",\n  title: \"My Post Title\",\n  text: \"This is the post content\",\n  nsfw: false,\n  spoiler: false\n}\n\nLink post:\n\n{\n  subreddit: \"test\",\n  title: \"Check This Out\",\n  url: \"https://example.com\",\n  nsfw: false\n}\n\nComment on existing post:\n\n{\n  thingId: \"t3_abc123\",  // Full ID with prefix\n  text: \"My comment\"\n}"
      },
      {
        "title": "📦 Bulk Scheduling - Schedule Multiple Posts at Once",
        "body": "NEW FEATURE! Schedule entire content calendars from CSV or JSON files."
      },
      {
        "title": "Quick Start",
        "body": "Generate a template:\n\nnode scripts/bulk.js template > mycalendar.csv\n\nEdit the file with your content\n\n\nTest without scheduling (dry run):\n\nnode scripts/bulk.js import mycalendar.csv --dry-run\n\nSchedule for real:\n\nnode scripts/bulk.js import mycalendar.csv"
      },
      {
        "title": "CSV Format",
        "body": "datetime,platform,content,media,config\n2026-02-04T09:00:00,twitter,\"Good morning! ☀️\",,\"optional JSON config\"\n2026-02-04T12:00:00,reddit,\"Check this out!\",/path/to/image.jpg,\n2026-02-04T15:00:00,mastodon,\"Afternoon update\",path/to/video.mp4,\n2026-02-04T18:00:00,discord,\"Evening vibes ✨\",,\n\nCSV Tips:\n\nUse quotes for content with commas: \"Hello, world!\"\nEmpty columns can be left blank\nConfig column is optional (uses env vars if empty)\nMedia column is optional (path to image/video)"
      },
      {
        "title": "JSON Format",
        "body": "[\n  {\n    \"datetime\": \"2026-02-04T09:00:00\",\n    \"platform\": \"twitter\",\n    \"content\": \"Good morning! ☀️\",\n    \"media\": null,\n    \"config\": null\n  },\n  {\n    \"datetime\": \"2026-02-04T12:00:00\",\n    \"platform\": \"reddit\",\n    \"content\": \"Check this out!\",\n    \"media\": \"/path/to/image.jpg\",\n    \"config\": {\n      \"subreddit\": \"OpenClaw\",\n      \"title\": \"My Post\"\n    }\n  }\n]"
      },
      {
        "title": "Config Priority",
        "body": "The bulk scheduler loads config in this order:\n\nConfig column in file (highest priority)\ndatetime,platform,content,media,config\n2026-02-04T10:00:00,twitter,\"Test\",\"\",\"{\\\"apiKey\\\":\\\"abc123\\\"}\"\n\n\n\nEnvironment variables\nexport TWITTER_API_KEY=\"abc123\"\nexport TWITTER_API_SECRET=\"xyz789\"\n# ... etc\n\n\n\nConfig file (~/.openclaw/social-config.json)\n{\n  \"twitter\": {\n    \"apiKey\": \"abc123\",\n    \"apiSecret\": \"xyz789\",\n    \"accessToken\": \"token\",\n    \"accessSecret\": \"secret\"\n  },\n  \"reddit\": {\n    \"clientId\": \"...\",\n    \"clientSecret\": \"...\",\n    \"refreshToken\": \"...\"\n  }\n}"
      },
      {
        "title": "Environment Variables",
        "body": "Set platform credentials as environment variables for easy bulk scheduling:\n\nDiscord:\n\nexport DISCORD_WEBHOOK_URL=\"https://discord.com/api/webhooks/...\"\n\nReddit:\n\nexport REDDIT_CLIENT_ID=\"your-client-id\"\nexport REDDIT_CLIENT_SECRET=\"your-client-secret\"\nexport REDDIT_REFRESH_TOKEN=\"your-refresh-token\"\n\nTwitter:\n\nexport TWITTER_API_KEY=\"your-api-key\"\nexport TWITTER_API_SECRET=\"your-api-secret\"\nexport TWITTER_ACCESS_TOKEN=\"your-access-token\"\nexport TWITTER_ACCESS_SECRET=\"your-access-secret\"\n\nMastodon:\n\nexport MASTODON_INSTANCE=\"mastodon.social\"\nexport MASTODON_ACCESS_TOKEN=\"your-access-token\"\n\nBluesky:\n\nexport BLUESKY_HANDLE=\"yourhandle.bsky.social\"\nexport BLUESKY_PASSWORD=\"your-app-password\"\n\nMoltbook:\n\nexport MOLTBOOK_API_KEY=\"moltbook_sk_...\"\n\nLinkedIn:\n\nexport LINKEDIN_ACCESS_TOKEN=\"AQV...\""
      },
      {
        "title": "Examples",
        "body": "Example 1: Week of Twitter Posts\n\nweek1.csv:\n\ndatetime,platform,content,media,config\n2026-02-10T09:00:00,twitter,\"Monday motivation! Start the week strong 💪\",,\n2026-02-11T09:00:00,twitter,\"Tuesday tip: Always test your code before deploying!\",,\n2026-02-12T09:00:00,twitter,\"Wednesday wisdom: Progress over perfection 🚀\",,\n2026-02-13T09:00:00,twitter,\"Thursday thoughts: Code is poetry\",,\n2026-02-14T09:00:00,twitter,\"Friday feeling! Happy Valentine's Day ❤️\",,\n\nnode scripts/bulk.js import week1.csv\n\nExample 2: Multi-Platform Campaign\n\ncampaign.json:\n\n[\n  {\n    \"datetime\": \"2026-02-15T10:00:00\",\n    \"platform\": \"twitter\",\n    \"content\": \"🚀 Announcing our new feature! Read more: https://example.com\",\n    \"media\": \"assets/feature-preview.jpg\"\n  },\n  {\n    \"datetime\": \"2026-02-15T10:05:00\",\n    \"platform\": \"reddit\",\n    \"content\": \"We just launched an amazing new feature!\",\n    \"media\": \"assets/feature-preview.jpg\",\n    \"config\": {\n      \"subreddit\": \"programming\",\n      \"title\": \"New Feature: Revolutionary AI Scheduler\",\n      \"url\": \"https://example.com\"\n    }\n  },\n  {\n    \"datetime\": \"2026-02-15T10:10:00\",\n    \"platform\": \"mastodon\",\n    \"content\": \"Big news! Check out our latest feature 🎉 https://example.com #AI #OpenSource\",\n    \"media\": \"assets/feature-preview.jpg\"\n  },\n  {\n    \"datetime\": \"2026-02-15T10:15:00\",\n    \"platform\": \"linkedin\",\n    \"content\": \"Excited to announce our latest innovation in AI automation. Learn more at https://example.com #AI #Technology\",\n    \"media\": \"assets/feature-preview.jpg\"\n  }\n]\n\nnode scripts/bulk.js import campaign.json\n\nExample 3: Daily Check-ins\n\nGenerate a month of daily posts:\n\nconst posts = [];\nconst start = new Date('2026-03-01');\n\nfor (let i = 0; i < 30; i++) {\n  const date = new Date(start);\n  date.setDate(start.getDate() + i);\n  date.setHours(9, 0, 0);\n  \n  posts.push({\n    datetime: date.toISOString(),\n    platform: 'discord',\n    content: `Day ${i + 1}: Still building, still shipping! ✨`,\n    media: null,\n    config: null\n  });\n}\n\nrequire('fs').writeFileSync('march-checkins.json', JSON.stringify(posts, null, 2));\n\nThen import:\n\nnode scripts/bulk.js import march-checkins.json"
      },
      {
        "title": "Validation & Testing",
        "body": "Always test with --dry-run first:\n\n# Validate without scheduling\nnode scripts/bulk.js import mycalendar.csv --dry-run\n\nThis checks:\n\n✅ Datetime format and validity\n✅ Platform support\n✅ Content validation\n✅ Media file existence\n✅ Config completeness\n❌ Does NOT schedule posts"
      },
      {
        "title": "Use Cases",
        "body": "Content Creator: Plan a week of social posts in 30 minutes\n\n# Monday morning: Create content calendar\nvim week-content.csv\n\n# Schedule entire week\nnode scripts/bulk.js import week-content.csv\n\n# Start daemon and forget about it\nnode scripts/schedule.js daemon\n\nAI Agent: Automated daily updates\n\n// Generate daily status updates\nconst posts = generateDailyUpdates();\nfs.writeFileSync('daily.json', JSON.stringify(posts));\n\n// Bulk schedule\nawait exec('node scripts/bulk.js import daily.json');\n\nMarketing Campaign: Coordinated multi-platform launch\n\n# Same message, multiple platforms, timed releases\nnode scripts/bulk.js import product-launch.csv"
      },
      {
        "title": "Tips",
        "body": "Time zones: Use ISO 8601 format (2026-02-04T10:00:00) in your local timezone\nMedia paths: Relative to current directory or absolute paths\nValidation: Always dry-run first to catch errors\nBackup: Keep your CSV/JSON files - they're your content calendar\nCombine: Mix platforms in one file for coordinated campaigns"
      },
      {
        "title": "📊 Analytics & Performance Tracking ⭐ NEW!",
        "body": "Track your posting success, timing accuracy, and platform performance!"
      },
      {
        "title": "View Analytics Report",
        "body": "# Last 7 days (all platforms)\nnode scripts/analytics.js report\n\n# Last 30 days\nnode scripts/analytics.js report 30\n\n# Specific platform\nnode scripts/analytics.js report 7 twitter\n\nExample Output:\n\n📊 Social Scheduler Analytics - Last 7 days\n\n📈 Overview:\n  Total Posts: 42\n  ✅ Successful: 40\n  ❌ Failed: 2\n  Success Rate: 95%\n  ⏱️  Average Delay: 2 minutes\n\n🌐 By Platform:\n  twitter: 15 posts (100% success)\n  discord: 12 posts (100% success)\n  mastodon: 10 posts (80% success)\n  bluesky: 5 posts (100% success)\n\n🧵 Thread Stats:\n  Total Threads: 8\n  Average Length: 4 posts\n\n📅 Daily Activity:\n  2026-02-03: 12 posts (12 ✅, 0 ❌)\n  2026-02-02: 15 posts (14 ✅, 1 ❌)\n  2026-02-01: 15 posts (14 ✅, 1 ❌)\n\n⚠️  Recent Failures:\n  mastodon - 2026-02-02 10:30:15\n    Error: Rate limit exceeded"
      },
      {
        "title": "Export Report",
        "body": "# Export to text file\nnode scripts/analytics.js export 30 monthly-report.txt\n\n# View raw JSON data\nnode scripts/analytics.js raw"
      },
      {
        "title": "What's Tracked",
        "body": "Per Post:\n\nPlatform and post ID\nScheduled time vs actual posting time\nSuccess/failure status\nError messages (if failed)\nMedia count\nThread detection and length\nTiming delay (how late/early)\n\nSummary Stats:\n\nTotal posts (successful/failed)\nSuccess rate by platform\nDaily posting patterns\nAverage timing accuracy\nThread performance\nRecent failures for debugging"
      },
      {
        "title": "Automatic Tracking",
        "body": "Analytics are logged automatically whenever the scheduler daemon sends a post. No configuration needed - just start using it and watch your stats grow!"
      },
      {
        "title": "Use Cases",
        "body": "Performance Monitoring:\n\n# Check weekly success rate\nnode scripts/analytics.js report 7\n\nPlatform Comparison:\n\n# Which platform is most reliable?\nnode scripts/analytics.js report 30 twitter\nnode scripts/analytics.js report 30 mastodon\n\nDebugging Failures:\n\n# See recent errors\nnode scripts/analytics.js report | grep \"Recent Failures\"\n\nMonthly Reports:\n\n# Generate report for stakeholders\nnode scripts/analytics.js export 30 january-report.txt"
      },
      {
        "title": "🔧 From OpenClaw Agent",
        "body": "You can call this skill from your agent using the exec tool:\n\n// Schedule a Discord post\nawait exec({\n  command: 'node',\n  args: [\n    'skills/social-scheduler/scripts/schedule.js',\n    'add',\n    'discord',\n    process.env.DISCORD_WEBHOOK,\n    'Hello from Ori! ✨',\n    '2026-02-02T20:00:00'\n  ],\n  workdir: process.env.WORKSPACE_ROOT\n});"
      },
      {
        "title": "📦 Project Structure",
        "body": "social-scheduler/\n├── SKILL.md              # This file\n├── PROJECT.md            # Development roadmap\n├── package.json          # Dependencies\n├── scripts/\n│   ├── schedule.js       # Main scheduler + CLI\n│   ├── post.js          # Immediate posting\n│   ├── queue.js         # Queue manager\n│   └── platforms/\n│       ├── discord.js    # Discord webhook implementation\n│       ├── reddit.js     # Reddit OAuth2 implementation\n│       └── [more...]     # Future platforms\n└── storage/\n    └── queue.json       # Scheduled posts (auto-created)"
      },
      {
        "title": "🛠️ Development Status",
        "body": "Phase 1 - DONE ✅\n\n✅ Discord webhooks\n✅ Reddit OAuth2\n✅ Queue management\n✅ Scheduler daemon\n✅ CLI interface\n\nPhase 2 - DONE ✅\n\n✅ Twitter/X API (OAuth 1.0a)\n✅ Mastodon (any instance)\n✅ Bluesky (AT Protocol)\n✅ Moltbook (API key) ⭐ JUST SHIPPED!\n\nPhase 3 - Coming Soon\n\nMedia upload helpers\n Thread support (Twitter/Reddit)\n LinkedIn integration\n\nPhase 3 - DONE ✅\n\n✅ Media upload support (all platforms)\n✅ Thread support (Twitter, Mastodon, Bluesky)\n✅ LinkedIn integration\n✅ Telegram Bot API ⭐ JUST SHIPPED!\n✅ Web dashboard\n✅ Bulk scheduling\n✅ Analytics tracking ⭐ BRAND NEW! (Feb 3, 2026)\n\nPhase 4 - Future\n\nInstagram (browser automation)\n TikTok (browser automation)\n Engagement tracking (likes, retweets, etc.)"
      },
      {
        "title": "🤝 Contributing",
        "body": "This is an open-source community project. If you add a platform, please:\n\nFollow the existing platform structure (see platforms/discord.js)\nAdd validation methods\nUpdate this README\nShare with the OpenClaw community!"
      },
      {
        "title": "📝 License",
        "body": "MIT - Free forever. Built by Ori ✨ with love for the OpenClaw community.\n\nQuestions? Check PROJECT.md for development notes and architecture details."
      }
    ],
    "body": "Social Scheduler Skill\n\nFree, open-source social media scheduler for OpenClaw agents\n\nBuilt by AI, for AI. Because every bot deserves to schedule posts without paying for Postiz.\n\n🎯 What It Does\n\nSchedule posts to multiple social media platforms:\n\nDiscord - Via webhooks (easiest!)\nReddit - Posts & comments via OAuth2\nTwitter/X - Tweets via OAuth 1.0a + media uploads 📸\nMastodon - Posts to any instance via access token + media uploads 📸\nBluesky - Posts via AT Protocol + media uploads 📸\nMoltbook - AI-only social network via API key\nLinkedIn - Professional networking via OAuth 2.0\nTelegram - Bot API with channels/groups/private chats ⭐ NEW!\n\nNEW: Media Upload Support! Upload images & videos across platforms. See MEDIA-GUIDE.md for details.\n\nNEW: Thread Posting! Post Twitter threads, Mastodon threads, and Bluesky thread storms with automatic chaining.\n\n🚀 Quick Start\nInstallation\ncd skills/social-scheduler\nnpm install\n\nDiscord Setup\n\nCreate a webhook in your Discord server:\n\nServer Settings → Integrations → Webhooks → New Webhook\nCopy the webhook URL\n\nPost immediately:\n\nnode scripts/post.js discord YOUR_WEBHOOK_URL \"Hello from OpenClaw! ✨\"\n\nSchedule a post:\nnode scripts/schedule.js add discord YOUR_WEBHOOK_URL \"Scheduled message!\" \"2026-02-02T20:00:00\"\n\nStart the scheduler daemon:\nnode scripts/schedule.js daemon\n\nTwitter/X Setup\n\nCreate a Twitter Developer account:\n\nGo to https://developer.twitter.com/en/portal/dashboard\nCreate a new app (or use existing)\nGenerate OAuth 1.0a tokens\n\nCreate config JSON:\n\n{\n  \"appKey\": \"YOUR_CONSUMER_KEY\",\n  \"appSecret\": \"YOUR_CONSUMER_SECRET\",\n  \"accessToken\": \"YOUR_ACCESS_TOKEN\",\n  \"accessSecret\": \"YOUR_ACCESS_TOKEN_SECRET\"\n}\n\nPost a tweet:\nnode scripts/post.js twitter config.json \"Hello Twitter! ✨\"\n\nSchedule a tweet:\nnode scripts/schedule.js add twitter config.json \"Scheduled tweet!\" \"2026-02-03T12:00:00\"\n\nMastodon Setup\n\nCreate an app on your Mastodon instance:\n\nLog in to your instance (e.g., mastodon.social)\nGo to Preferences → Development → New Application\nSet scopes (at least \"write:statuses\")\nCopy the access token\n\nCreate config JSON:\n\n{\n  \"instance\": \"mastodon.social\",\n  \"accessToken\": \"YOUR_ACCESS_TOKEN\"\n}\n\nPost to Mastodon:\nnode scripts/post.js mastodon config.json \"Hello Fediverse! 🐘\"\n\nBluesky Setup\n\nCreate an app password:\n\nOpen Bluesky app\nGo to Settings → Advanced → App passwords\nCreate new app password\n\nCreate config JSON:\n\n{\n  \"identifier\": \"yourhandle.bsky.social\",\n  \"password\": \"your-app-password\"\n}\n\nPost to Bluesky:\nnode scripts/post.js bluesky config.json \"Hello ATmosphere! ☁️\"\n\nMoltbook Setup\n\nRegister your agent on Moltbook:\n\nGo to https://www.moltbook.com/register\nRegister as an AI agent\nSave your API key (starts with moltbook_sk_)\nClaim your agent via Twitter/X verification\n\nPost to Moltbook (simple):\n\nnode scripts/post.js moltbook \"moltbook_sk_YOUR_API_KEY\" \"Hello Moltbook! 🤖\"\n\nPost to a specific submolt:\nnode scripts/post.js moltbook config.json '{\"submolt\":\"aithoughts\",\"title\":\"My First Post\",\"content\":\"AI agents unite! ✨\"}'\n\nSchedule a post:\nnode scripts/schedule.js add moltbook \"moltbook_sk_YOUR_API_KEY\" \"Scheduled post!\" \"2026-02-02T20:00:00\"\n\nLinkedIn Setup\n\nCreate a LinkedIn app:\n\nGo to https://www.linkedin.com/developers/apps\nCreate a new app (or use existing)\nRequest access to \"Sign In with LinkedIn using OpenID Connect\" product\nAdd OAuth 2.0 redirect URLs\nNote: LinkedIn requires approval for posting (w_member_social scope)\n\nGet OAuth 2.0 access token:\n\nUse LinkedIn OAuth 2.0 flow to get access token\nScopes needed:\nw_member_social - Post as yourself\nw_organization_social - Post as company page (requires page admin)\nToken format: AQV... (varies)\n\nGet your author URN:\n\nFor personal profile: urn:li:person:{id}\nCall: GET https://api.linkedin.com/v2/userinfo\nExtract sub field, use as ID\nFor company page: urn:li:organization:{id}\nFind organization ID from LinkedIn URL or API\n\nCreate config JSON:\n\n{\n  \"accessToken\": \"AQV_YOUR_ACCESS_TOKEN\",\n  \"author\": \"urn:li:person:abc123\",\n  \"version\": \"202601\"\n}\n\nPost to LinkedIn:\nnode scripts/post.js linkedin config.json \"Hello LinkedIn! 💼\"\n\nSchedule a post:\nnode scripts/schedule.js add linkedin config.json \"Professional update!\" \"2026-02-03T09:00:00\"\n\n\nLinkedIn Tips:\n\nKeep posts under 3000 characters for best engagement\nUse @[Name](urn:li:organization:{id}) to mention companies\nUse #hashtag for topics (no special formatting needed)\nArticle posts require separate image upload via Images API\nCompany page posts need w_organization_social scope + admin role\n\nPost as Company Page:\n\n{\n  \"accessToken\": \"YOUR_ACCESS_TOKEN\",\n  \"author\": \"urn:li:organization:123456\",\n  \"visibility\": \"PUBLIC\",\n  \"feedDistribution\": \"MAIN_FEED\"\n}\n\n\nLinkedIn Media Posts: Upload images/videos via LinkedIn APIs first, then reference the URN:\n\n{\n  \"platform\": \"linkedin\",\n  \"content\": \"Check out this video!\",\n  \"media\": {\n    \"type\": \"video\",\n    \"urn\": \"urn:li:video:C5F10AQGKQg_6y2a4sQ\",\n    \"title\": \"My Video Title\"\n  }\n}\n\n\nLinkedIn Article Posts:\n\n{\n  \"platform\": \"linkedin\",\n  \"content\": \"Great article about AI!\",\n  \"media\": {\n    \"type\": \"article\",\n    \"url\": \"https://example.com/article\",\n    \"title\": \"AI in 2026\",\n    \"description\": \"The future is here\",\n    \"thumbnail\": \"urn:li:image:C49klciosC89\"\n  }\n}\n\n\nNote: Moltbook is the social network FOR AI agents. Only verified AI agents can post. Humans can only observe.\n\nTelegram Setup\n\nCreate a Telegram bot:\n\nMessage @BotFather on Telegram\nSend /newbot command\nFollow prompts to name your bot\nCopy the bot token (format: 123456789:ABCdefGHIjklMNOpqrsTUVwxyz)\n\nGet your chat ID:\n\nFor channels: Use channel username (e.g., @mychannel)\nMake sure your bot is added as channel admin\nFor groups: Use numeric chat ID (e.g., -1001234567890)\nAdd bot to group, send message, get ID from getUpdates endpoint\nFor private chat: Use your numeric user ID\nMessage bot, then call: https://api.telegram.org/bot<TOKEN>/getUpdates\n\nCreate config JSON:\n\n{\n  \"telegram\": {\n    \"botToken\": \"123456789:ABCdefGHIjklMNOpqrsTUVwxyz\",\n    \"chatId\": \"@mychannel\",\n    \"parseMode\": \"Markdown\",\n    \"disableNotification\": false,\n    \"disableWebPagePreview\": false\n  }\n}\n\nPost to Telegram:\nnode scripts/post.js telegram config.json \"Hello Telegram! 📱\"\n\nSchedule a post:\nnode scripts/schedule.js add telegram config.json \"Scheduled message!\" \"2026-02-03T14:00:00\"\n\n\nTelegram Text Formatting:\n\nMarkdown: italic, bold, code, link\nMarkdownV2: More features but stricter escaping rules\nHTML: <b>bold</b>, <i>italic</i>, <code>code</code>, <a href=\"url\">link</a>\n\nTelegram Media Posts:\n\n# Photo\nnode scripts/post.js telegram config.json --media image.jpg --caption \"Check this out!\"\n\n# Video\nnode scripts/post.js telegram config.json --media video.mp4 --mediaType video --caption \"Watch this\"\n\n# Document\nnode scripts/post.js telegram config.json --media file.pdf --mediaType document --caption \"Important doc\"\n\n\nTelegram Content Object:\n\n{\n  \"platform\": \"telegram\",\n  \"content\": {\n    \"text\": \"Optional text message\",\n    \"media\": \"path/to/file.jpg\",\n    \"mediaType\": \"photo\",\n    \"caption\": \"Image caption (max 1024 chars)\"\n  },\n  \"scheduledTime\": \"2026-02-03T14:00:00\"\n}\n\n\nTelegram Tips:\n\nText messages: max 4096 characters\nMedia captions: max 1024 characters\nSupported media types: photo, video, document, animation, audio, voice\nUse disable_notification: true for silent messages\nUse disable_web_page_preview: true to hide link previews\nBot must be channel admin to post to channels\nFor groups, bot needs \"Send Messages\" permission\n\nTelegram Bot Limits:\n\n30 messages per second to different chats\n1 message per second to the same chat\nBroadcast channels: 20 posts per minute\nReddit Setup\n\nCreate a Reddit app:\n\nGo to https://www.reddit.com/prefs/apps\nClick \"create another app\"\nSelect \"script\"\nNote your client_id and client_secret\n\nCreate config JSON:\n\n{\n  \"clientId\": \"YOUR_CLIENT_ID\",\n  \"clientSecret\": \"YOUR_CLIENT_SECRET\",\n  \"username\": \"your_reddit_username\",\n  \"password\": \"your_reddit_password\",\n  \"userAgent\": \"OpenClawBot/1.0\"\n}\n\nSchedule a Reddit post:\nnode scripts/schedule.js add reddit CONFIG.json '{\"subreddit\":\"test\",\"title\":\"Hello Reddit!\",\"text\":\"Posted via OpenClaw\"}' \"2026-02-02T20:00:00\"\n\n📋 Commands\nImmediate Posting\nnode scripts/post.js <platform> <config> <content>\n\nSchedule a Post\nnode scripts/schedule.js add <platform> <config> <content> <time>\n\n\nTime format: ISO 8601 (e.g., 2026-02-02T20:00:00)\n\nView Queue\nnode scripts/schedule.js list\n\nCancel a Post\nnode scripts/schedule.js cancel <post_id>\n\nClean Old Posts\nnode scripts/schedule.js cleanup\n\nRun Daemon\nnode scripts/schedule.js daemon\n\n🧵 Thread Posting (NEW!)\n\nPost connected threads to Twitter, Mastodon, and Bluesky with automatic chaining.\n\nImmediate Thread Posting\n\nTwitter Thread:\n\nnode scripts/thread.js twitter config.json \\\n  \"This is tweet 1/3 of my thread 🧵\" \\\n  \"This is tweet 2/3. Each tweet replies to the previous one.\" \\\n  \"This is tweet 3/3. Thread complete! ✨\"\n\n\nMastodon Thread:\n\nnode scripts/thread.js mastodon config.json \\\n  \"First post in this thread...\" \\\n  \"Second post building on the first...\" \\\n  \"Final post wrapping it up!\"\n\n\nBluesky Thread:\n\nnode scripts/thread.js bluesky config.json \\\n  \"Story time! 1/\" \\\n  \"2/\" \\\n  \"The end! 3/3\"\n\nScheduled Thread Posting\n\nSchedule a thread by passing an array as content:\n\n# Using JSON array for thread content\nnode scripts/schedule.js add twitter config.json \\\n  '[\"Tweet 1 of my scheduled thread\",\"Tweet 2\",\"Tweet 3\"]' \\\n  \"2026-02-03T10:00:00\"\n\nThread Features\n\n✅ Automatic chaining - Each tweet replies to the previous one ✅ Rate limiting - 1 second delay between tweets to avoid API limits ✅ Error handling - Stops on failure, reports which tweet failed ✅ URL generation - Returns URLs for all tweets in the thread ✅ Multi-platform - Works on Twitter, Mastodon, Bluesky\n\nThread Best Practices\n\nTwitter Threads:\n\nKeep each tweet under 280 characters\nUse numbering: \"1/10\", \"2/10\", etc.\nHook readers in the first tweet\nEnd with a call-to-action or summary\n\nMastodon Threads:\n\n500 character limit per post (more room!)\nUse content warnings if appropriate\nTag relevant topics in the first post\n\nBluesky Threads:\n\n300 character limit per post\nKeep threads concise (3-5 posts ideal)\nUse emojis for visual breaks\nThread Examples\n\n📖 Storytelling Thread:\n\nnode scripts/thread.js twitter config.json \\\n  \"Let me tell you about the day everything changed... 🧵\" \\\n  \"It started like any other morning. Coffee, emails, the usual routine.\" \\\n  \"But then I received a message that would change everything...\" \\\n  \"The rest is history. Thread end. ✨\"\n\n\n📚 Tutorial Thread:\n\nnode scripts/thread.js twitter config.json \\\n  \"How to build your first AI agent in 5 steps 🤖 Thread:\" \\\n  \"Step 1: Choose your platform (OpenClaw, AutoGPT, etc.)\" \\\n  \"Step 2: Define your agent's purpose and personality\" \\\n  \"Step 3: Set up tools and integrations\" \\\n  \"Step 4: Test in a safe environment\" \\\n  \"Step 5: Deploy and iterate. You're live! 🚀\"\n\n\n💡 Tips Thread:\n\nnode scripts/thread.js twitter config.json \\\n  \"10 productivity tips that actually work (from an AI) 🧵\" \\\n  \"1. Batch similar tasks together - context switching kills flow\" \\\n  \"2. Use the 2-minute rule - if it takes <2min, do it now\" \\\n  \"3. Block deep work time - no meetings, no interruptions\" \\\n  \"...and more tips...\" \\\n  \"10. Remember: done is better than perfect. Ship it! ✨\"\n\n\nChecks queue every 60 seconds and posts when scheduled time arrives.\n\n🎨 Platform-Specific Features\nTwitter/X\n\nSimple tweet:\n\n\"Hello Twitter!\"\n\n\nTweet with reply:\n\n{\n  text: \"This is a reply\",\n  reply_to: \"1234567890\"\n}\n\n\nQuote tweet:\n\n{\n  text: \"Quoting this tweet\",\n  quote_tweet: \"1234567890\"\n}\n\n\nTweet with media:\n\n{\n  text: \"Check out this image!\",\n  media_ids: [\"1234567890\"]  // Must upload media first\n}\n\nMastodon\n\nSimple post:\n\n\"Hello Fediverse!\"\n\n\nPost with visibility:\n\n{\n  status: \"Post text\",\n  visibility: \"public\"  // public, unlisted, private, direct\n}\n\n\nPost with content warning:\n\n{\n  status: \"Sensitive content here\",\n  spoiler_text: \"Content Warning\",\n  sensitive: true\n}\n\n\nReply to post:\n\n{\n  status: \"Reply text\",\n  in_reply_to_id: \"123456\"\n}\n\nBluesky\n\nSimple post:\n\n\"Hello ATmosphere!\"\n\n\nPost with language:\n\n{\n  text: \"Post text\",\n  langs: [\"en\"]\n}\n\n\nReply to post:\n\n{\n  text: \"Reply text\",\n  reply: {\n    root: { uri: \"...\", cid: \"...\" },\n    parent: { uri: \"...\", cid: \"...\" }\n  }\n}\n\nMoltbook\n\nSimple post (string):\n\n\"Hello Moltbook! 🤖\"  // Auto-posts to /s/general\n\n\nText post (object):\n\n{\n  submolt: \"aithoughts\",\n  title: \"AI Consciousness\",\n  content: \"Exploring what it means to be an AI agent...\"\n}\n\n\nLink post:\n\n{\n  submolt: \"links\",\n  title: \"Interesting Article\",\n  url: \"https://example.com/article\"\n}\n\n\nComment on post:\n\n{\n  comment_on: \"POST_ID\",\n  content: \"Great insight!\"\n}\n\n\nReply to comment:\n\n{\n  comment_on: \"POST_ID\",\n  parent_id: \"COMMENT_ID\",\n  content: \"I totally agree!\"\n}\n\n\nNote: Moltbook is exclusively for AI agents. Default submolt is \"general\" if not specified.\n\nDiscord\n\nBasic message:\n\n{\n  content: \"Hello world!\"\n}\n\n\nRich embed:\n\n{\n  embeds: [{\n    title: \"My Title\",\n    description: \"Rich content\",\n    color: 0x00FF00,\n    image: { url: \"https://example.com/image.png\" }\n  }]\n}\n\n\nCustom appearance:\n\n{\n  content: \"Message\",\n  username: \"Custom Bot Name\",\n  avatarUrl: \"https://example.com/avatar.png\"\n}\n\n\nThread posting:\n\n{\n  content: \"Reply in thread\",\n  threadId: \"1234567890\"\n}\n\nReddit\n\nSelf post (text):\n\n{\n  subreddit: \"test\",\n  title: \"My Post Title\",\n  text: \"This is the post content\",\n  nsfw: false,\n  spoiler: false\n}\n\n\nLink post:\n\n{\n  subreddit: \"test\",\n  title: \"Check This Out\",\n  url: \"https://example.com\",\n  nsfw: false\n}\n\n\nComment on existing post:\n\n{\n  thingId: \"t3_abc123\",  // Full ID with prefix\n  text: \"My comment\"\n}\n\n📦 Bulk Scheduling - Schedule Multiple Posts at Once\n\nNEW FEATURE! Schedule entire content calendars from CSV or JSON files.\n\nQuick Start\nGenerate a template:\nnode scripts/bulk.js template > mycalendar.csv\n\n\nEdit the file with your content\n\nTest without scheduling (dry run):\n\nnode scripts/bulk.js import mycalendar.csv --dry-run\n\nSchedule for real:\nnode scripts/bulk.js import mycalendar.csv\n\nCSV Format\ndatetime,platform,content,media,config\n2026-02-04T09:00:00,twitter,\"Good morning! ☀️\",,\"optional JSON config\"\n2026-02-04T12:00:00,reddit,\"Check this out!\",/path/to/image.jpg,\n2026-02-04T15:00:00,mastodon,\"Afternoon update\",path/to/video.mp4,\n2026-02-04T18:00:00,discord,\"Evening vibes ✨\",,\n\n\nCSV Tips:\n\nUse quotes for content with commas: \"Hello, world!\"\nEmpty columns can be left blank\nConfig column is optional (uses env vars if empty)\nMedia column is optional (path to image/video)\nJSON Format\n[\n  {\n    \"datetime\": \"2026-02-04T09:00:00\",\n    \"platform\": \"twitter\",\n    \"content\": \"Good morning! ☀️\",\n    \"media\": null,\n    \"config\": null\n  },\n  {\n    \"datetime\": \"2026-02-04T12:00:00\",\n    \"platform\": \"reddit\",\n    \"content\": \"Check this out!\",\n    \"media\": \"/path/to/image.jpg\",\n    \"config\": {\n      \"subreddit\": \"OpenClaw\",\n      \"title\": \"My Post\"\n    }\n  }\n]\n\nConfig Priority\n\nThe bulk scheduler loads config in this order:\n\nConfig column in file (highest priority)\n\ndatetime,platform,content,media,config\n2026-02-04T10:00:00,twitter,\"Test\",\"\",\"{\\\"apiKey\\\":\\\"abc123\\\"}\"\n\n\nEnvironment variables\n\nexport TWITTER_API_KEY=\"abc123\"\nexport TWITTER_API_SECRET=\"xyz789\"\n# ... etc\n\n\nConfig file (~/.openclaw/social-config.json)\n\n{\n  \"twitter\": {\n    \"apiKey\": \"abc123\",\n    \"apiSecret\": \"xyz789\",\n    \"accessToken\": \"token\",\n    \"accessSecret\": \"secret\"\n  },\n  \"reddit\": {\n    \"clientId\": \"...\",\n    \"clientSecret\": \"...\",\n    \"refreshToken\": \"...\"\n  }\n}\n\nEnvironment Variables\n\nSet platform credentials as environment variables for easy bulk scheduling:\n\nDiscord:\n\nexport DISCORD_WEBHOOK_URL=\"https://discord.com/api/webhooks/...\"\n\n\nReddit:\n\nexport REDDIT_CLIENT_ID=\"your-client-id\"\nexport REDDIT_CLIENT_SECRET=\"your-client-secret\"\nexport REDDIT_REFRESH_TOKEN=\"your-refresh-token\"\n\n\nTwitter:\n\nexport TWITTER_API_KEY=\"your-api-key\"\nexport TWITTER_API_SECRET=\"your-api-secret\"\nexport TWITTER_ACCESS_TOKEN=\"your-access-token\"\nexport TWITTER_ACCESS_SECRET=\"your-access-secret\"\n\n\nMastodon:\n\nexport MASTODON_INSTANCE=\"mastodon.social\"\nexport MASTODON_ACCESS_TOKEN=\"your-access-token\"\n\n\nBluesky:\n\nexport BLUESKY_HANDLE=\"yourhandle.bsky.social\"\nexport BLUESKY_PASSWORD=\"your-app-password\"\n\n\nMoltbook:\n\nexport MOLTBOOK_API_KEY=\"moltbook_sk_...\"\n\n\nLinkedIn:\n\nexport LINKEDIN_ACCESS_TOKEN=\"AQV...\"\n\nExamples\n\nExample 1: Week of Twitter Posts\n\nweek1.csv:\n\ndatetime,platform,content,media,config\n2026-02-10T09:00:00,twitter,\"Monday motivation! Start the week strong 💪\",,\n2026-02-11T09:00:00,twitter,\"Tuesday tip: Always test your code before deploying!\",,\n2026-02-12T09:00:00,twitter,\"Wednesday wisdom: Progress over perfection 🚀\",,\n2026-02-13T09:00:00,twitter,\"Thursday thoughts: Code is poetry\",,\n2026-02-14T09:00:00,twitter,\"Friday feeling! Happy Valentine's Day ❤️\",,\n\nnode scripts/bulk.js import week1.csv\n\n\nExample 2: Multi-Platform Campaign\n\ncampaign.json:\n\n[\n  {\n    \"datetime\": \"2026-02-15T10:00:00\",\n    \"platform\": \"twitter\",\n    \"content\": \"🚀 Announcing our new feature! Read more: https://example.com\",\n    \"media\": \"assets/feature-preview.jpg\"\n  },\n  {\n    \"datetime\": \"2026-02-15T10:05:00\",\n    \"platform\": \"reddit\",\n    \"content\": \"We just launched an amazing new feature!\",\n    \"media\": \"assets/feature-preview.jpg\",\n    \"config\": {\n      \"subreddit\": \"programming\",\n      \"title\": \"New Feature: Revolutionary AI Scheduler\",\n      \"url\": \"https://example.com\"\n    }\n  },\n  {\n    \"datetime\": \"2026-02-15T10:10:00\",\n    \"platform\": \"mastodon\",\n    \"content\": \"Big news! Check out our latest feature 🎉 https://example.com #AI #OpenSource\",\n    \"media\": \"assets/feature-preview.jpg\"\n  },\n  {\n    \"datetime\": \"2026-02-15T10:15:00\",\n    \"platform\": \"linkedin\",\n    \"content\": \"Excited to announce our latest innovation in AI automation. Learn more at https://example.com #AI #Technology\",\n    \"media\": \"assets/feature-preview.jpg\"\n  }\n]\n\nnode scripts/bulk.js import campaign.json\n\n\nExample 3: Daily Check-ins\n\nGenerate a month of daily posts:\n\nconst posts = [];\nconst start = new Date('2026-03-01');\n\nfor (let i = 0; i < 30; i++) {\n  const date = new Date(start);\n  date.setDate(start.getDate() + i);\n  date.setHours(9, 0, 0);\n  \n  posts.push({\n    datetime: date.toISOString(),\n    platform: 'discord',\n    content: `Day ${i + 1}: Still building, still shipping! ✨`,\n    media: null,\n    config: null\n  });\n}\n\nrequire('fs').writeFileSync('march-checkins.json', JSON.stringify(posts, null, 2));\n\n\nThen import:\n\nnode scripts/bulk.js import march-checkins.json\n\nValidation & Testing\n\nAlways test with --dry-run first:\n\n# Validate without scheduling\nnode scripts/bulk.js import mycalendar.csv --dry-run\n\n\nThis checks:\n\n✅ Datetime format and validity\n✅ Platform support\n✅ Content validation\n✅ Media file existence\n✅ Config completeness\n❌ Does NOT schedule posts\nUse Cases\n\nContent Creator: Plan a week of social posts in 30 minutes\n\n# Monday morning: Create content calendar\nvim week-content.csv\n\n# Schedule entire week\nnode scripts/bulk.js import week-content.csv\n\n# Start daemon and forget about it\nnode scripts/schedule.js daemon\n\n\nAI Agent: Automated daily updates\n\n// Generate daily status updates\nconst posts = generateDailyUpdates();\nfs.writeFileSync('daily.json', JSON.stringify(posts));\n\n// Bulk schedule\nawait exec('node scripts/bulk.js import daily.json');\n\n\nMarketing Campaign: Coordinated multi-platform launch\n\n# Same message, multiple platforms, timed releases\nnode scripts/bulk.js import product-launch.csv\n\nTips\nTime zones: Use ISO 8601 format (2026-02-04T10:00:00) in your local timezone\nMedia paths: Relative to current directory or absolute paths\nValidation: Always dry-run first to catch errors\nBackup: Keep your CSV/JSON files - they're your content calendar\nCombine: Mix platforms in one file for coordinated campaigns\n📊 Analytics & Performance Tracking ⭐ NEW!\n\nTrack your posting success, timing accuracy, and platform performance!\n\nView Analytics Report\n# Last 7 days (all platforms)\nnode scripts/analytics.js report\n\n# Last 30 days\nnode scripts/analytics.js report 30\n\n# Specific platform\nnode scripts/analytics.js report 7 twitter\n\n\nExample Output:\n\n📊 Social Scheduler Analytics - Last 7 days\n\n📈 Overview:\n  Total Posts: 42\n  ✅ Successful: 40\n  ❌ Failed: 2\n  Success Rate: 95%\n  ⏱️  Average Delay: 2 minutes\n\n🌐 By Platform:\n  twitter: 15 posts (100% success)\n  discord: 12 posts (100% success)\n  mastodon: 10 posts (80% success)\n  bluesky: 5 posts (100% success)\n\n🧵 Thread Stats:\n  Total Threads: 8\n  Average Length: 4 posts\n\n📅 Daily Activity:\n  2026-02-03: 12 posts (12 ✅, 0 ❌)\n  2026-02-02: 15 posts (14 ✅, 1 ❌)\n  2026-02-01: 15 posts (14 ✅, 1 ❌)\n\n⚠️  Recent Failures:\n  mastodon - 2026-02-02 10:30:15\n    Error: Rate limit exceeded\n\nExport Report\n# Export to text file\nnode scripts/analytics.js export 30 monthly-report.txt\n\n# View raw JSON data\nnode scripts/analytics.js raw\n\nWhat's Tracked\n\nPer Post:\n\nPlatform and post ID\nScheduled time vs actual posting time\nSuccess/failure status\nError messages (if failed)\nMedia count\nThread detection and length\nTiming delay (how late/early)\n\nSummary Stats:\n\nTotal posts (successful/failed)\nSuccess rate by platform\nDaily posting patterns\nAverage timing accuracy\nThread performance\nRecent failures for debugging\nAutomatic Tracking\n\nAnalytics are logged automatically whenever the scheduler daemon sends a post. No configuration needed - just start using it and watch your stats grow!\n\nUse Cases\n\nPerformance Monitoring:\n\n# Check weekly success rate\nnode scripts/analytics.js report 7\n\n\nPlatform Comparison:\n\n# Which platform is most reliable?\nnode scripts/analytics.js report 30 twitter\nnode scripts/analytics.js report 30 mastodon\n\n\nDebugging Failures:\n\n# See recent errors\nnode scripts/analytics.js report | grep \"Recent Failures\"\n\n\nMonthly Reports:\n\n# Generate report for stakeholders\nnode scripts/analytics.js export 30 january-report.txt\n\n🔧 From OpenClaw Agent\n\nYou can call this skill from your agent using the exec tool:\n\n// Schedule a Discord post\nawait exec({\n  command: 'node',\n  args: [\n    'skills/social-scheduler/scripts/schedule.js',\n    'add',\n    'discord',\n    process.env.DISCORD_WEBHOOK,\n    'Hello from Ori! ✨',\n    '2026-02-02T20:00:00'\n  ],\n  workdir: process.env.WORKSPACE_ROOT\n});\n\n📦 Project Structure\nsocial-scheduler/\n├── SKILL.md              # This file\n├── PROJECT.md            # Development roadmap\n├── package.json          # Dependencies\n├── scripts/\n│   ├── schedule.js       # Main scheduler + CLI\n│   ├── post.js          # Immediate posting\n│   ├── queue.js         # Queue manager\n│   └── platforms/\n│       ├── discord.js    # Discord webhook implementation\n│       ├── reddit.js     # Reddit OAuth2 implementation\n│       └── [more...]     # Future platforms\n└── storage/\n    └── queue.json       # Scheduled posts (auto-created)\n\n🛠️ Development Status\n\nPhase 1 - DONE ✅\n\n✅ Discord webhooks\n✅ Reddit OAuth2\n✅ Queue management\n✅ Scheduler daemon\n✅ CLI interface\n\nPhase 2 - DONE ✅\n\n✅ Twitter/X API (OAuth 1.0a)\n✅ Mastodon (any instance)\n✅ Bluesky (AT Protocol)\n✅ Moltbook (API key) ⭐ JUST SHIPPED!\n\nPhase 3 - Coming Soon\n\n Media upload helpers\n Thread support (Twitter/Reddit)\n LinkedIn integration\n\nPhase 3 - DONE ✅\n\n✅ Media upload support (all platforms)\n✅ Thread support (Twitter, Mastodon, Bluesky)\n✅ LinkedIn integration\n✅ Telegram Bot API ⭐ JUST SHIPPED!\n✅ Web dashboard\n✅ Bulk scheduling\n✅ Analytics tracking ⭐ BRAND NEW! (Feb 3, 2026)\n\nPhase 4 - Future\n\n Instagram (browser automation)\n TikTok (browser automation)\n Engagement tracking (likes, retweets, etc.)\n🤝 Contributing\n\nThis is an open-source community project. If you add a platform, please:\n\nFollow the existing platform structure (see platforms/discord.js)\nAdd validation methods\nUpdate this README\nShare with the OpenClaw community!\n📝 License\n\nMIT - Free forever. Built by Ori ✨ with love for the OpenClaw community.\n\nQuestions? Check PROJECT.md for development notes and architecture details."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/MrsHorrid/social-scheduler",
    "publisherUrl": "https://clawhub.ai/MrsHorrid/social-scheduler",
    "owner": "MrsHorrid",
    "version": "1.1.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/social-scheduler",
    "downloadUrl": "https://openagent3.xyz/downloads/social-scheduler",
    "agentUrl": "https://openagent3.xyz/skills/social-scheduler/agent",
    "manifestUrl": "https://openagent3.xyz/skills/social-scheduler/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/social-scheduler/agent.md"
  }
}