coreyhaines31/social-fetch
When you or another skill needs to fetch the content of a social media post by URL — tweet, X thread, LinkedIn post, Instagram post, TikTok video, Bluesky post, Reddit thread, Mastodon status, Threads post, Hacker News thread. Returns normalized structured data (author, posted_at, text, engagement counts, media URLs, replies if requested) regardless of platform. Tries strategies in order: direct API (Bluesky, Mastodon, HN, Reddit), agent-browser with modal dismissal (LinkedIn, X preview), Wayback Machine (older posts), paid APIs (ScrapeCreators / Apify — only if env keys present). Triggers on \"/social-fetch <url>,\" \"fetch this tweet,\" \"fetch this post,\" \"what does this LinkedIn say,\" \"read this thread,\" \"pull this post.\" Used by deep-research (citing specific posts), jab-hook (inspiration account analysis), business-brainstorm (competitor / operator commentary).
npx skills add https://github.com/coreyhaines31/makerskills --skill social-fetch
Normalized fetcher for social posts across platforms. Detects platform from URL, tries strategies in order, returns the same JSON shape regardless of source.
| URL pattern | Platform |
|---|---|
| x.com/<user>/status/<id> or twitter.com/<user>/status/<id> | x (Twitter) |
| linkedin.com/posts/<slug> or linkedin.com/feed/update/urn:li:activity:<id> | linkedin |
| linkedin.com/in/<handle> (profile, recent activity) | linkedin-profile |
| instagram.com/p/<id> or instagram.com/reel/<id> | instagram |
| tiktok.com/@<user>/video/<id> | tiktok |
| bsky.app/profile/<handle>/post/<rkey> | bluesky |
| reddit.com/r/<sub>/comments/<id>/... | reddit |
| <mastodon-instance>/@<user>/<id> (e.g. mastodon.social, hachyderm.io) | mastodon |
| threads.net/@<user>/post/<id> | threads |
| news.ycombinator.com/item?id=<id> | hn |
| youtube.com/watch?v=<id> or youtu.be/<id> | → defer to watch-video |
If the URL doesn't match any pattern, ask the user what platform it is.
Read references/strategies.md for the per-platform strategy chain. Each platform has 2–5 strategies tried in order.
Key principles:
For each strategy in the chain:
After exhausting the chain, return a clear error: which strategies were tried, why each failed, and what's needed to unlock (e.g., "Add $SCRAPECREATORS_API_KEY for X — see references/auth-keys.md").
Return this shape regardless of platform (see references/output-schema.md for the full spec + platform-specific examples):
{
"platform": "x",
"url": "https://x.com/example/status/1234567890",
"fetched_at": "2026-06-17T14:35:00Z",
"raw_source": "scrapecreators",
"author": {
"handle": "@example",
"name": "the user Ganim",
"verified": true
},
"posted_at": "2026-06-17T16:53:00Z",
"text": "The 80/20 of a useful AI second brain: ...",
"media": [],
"engagement": {
"likes": 51,
"reposts": 13,
"replies": 9,
"bookmarks": 7,
"views": 32700
},
"is_thread": true,
"thread": [],
"replies": []
}
Fields with no equivalent on a platform (e.g., bookmarks on Mastodon) get null, not 0. Missing data is different from zero data.
Based on flags / asks:
| Flag | Behavior |
|---|---|
| --with-replies | Fetch top-level replies (1 hop). Costs extra API quota. |
| --thread | If the post is part of a thread by the same author, fetch the whole thread. |
| --raw | Include the raw API/scrape response in the output (for debugging) |
| --media | Download media files (images/videos) to ~/Documents/social-fetches/<platform>-<id>/ |
Default: just the post itself, no replies, no media download (just URLs).
If ~/Documents/social-fetches/_cache/ exists, cache successful fetches there by {platform}-{id}.json for 24h. Saves API quota when the same post is referenced repeatedly across skills.
Skip cache if --no-cache flag is set or for --with-replies / --thread (likely-stale).
deep-research — cite specific posts in research briefs. When research surfaces a relevant tweet/post URL, fetch and include in the brief.jab-hook — pull recent posts from inspiration accounts for deeper format analysis (currently uses agent-browser inline; should call this skill instead).business-brainstorm — pull competitor / operator commentary as evidence during scoring.second-brain — capture a post into raw/ with the tweet- / bookmark- prefix; the structured output makes for cleaner raw files than a screenshot or copy-paste.watch-video — for YouTube URLs (or any video — Loom, Vimeo, Riverside, MP4), route there instead.$SCRAPECREATORS_API_KEY or $APIFY_API_TOKEN.linkedin.com/posts/...) often need paid fallback.If a platform consistently fails on free strategies and the user uses it often, prompt to set up the paid key (see references/auth-keys.md).
~/Documents/social-fetches/_cache/ prevents API burn when the same post is referenced across multiple skills in a session. --with-replies / --thread skip cache because replies age fast.--media downloads images/videos. Silent media downloads eat disk quickly.Take coreyhaines31/social-fetch from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.