Reddit Posting Skill (AppleScript Chrome Control)
Post to Reddit by controlling the user's real Chrome via AppleScript. No Playwright, no Selenium, no API tokens.
How It Works
Claude Code → osascript → Chrome (real browser, logged in) → Reddit /api/submit
- Same-origin fetch with cookies → undetectable
- Reddit's
/api/submitendpoint for text/link posts - Modhash from
/api/me.jsonfor CSRF protection
Prerequisites
- macOS only (AppleScript is a macOS technology)
- Chrome: View → Developer → Allow JavaScript from Apple Events (restart Chrome after enabling)
- User logged into Reddit in Chrome
Method Detection (Run First)
WINDOWS=$(osascript -e 'tell application "Google Chrome" to return count of windows' 2>/dev/null)
if [ "$WINDOWS" = "0" ] || [ -z "$WINDOWS" ]; then
echo "METHOD 2 (System Events + Console)"
else
echo "METHOD 1 (execute javascript)"
fi
See reddit-cultivate skill for full Method 1 vs Method 2 details.
Posting Workflow
Step 1: Get Modhash
osascript -e 'tell application "Google Chrome" to tell active tab of first window to execute javascript "fetch(\"/api/me.json\",{credentials:\"include\"}).then(r=>r.json()).then(d=>{document.title=\"UH:\"+d.data.modhash})"'
sleep 2
osascript -e 'tell application "Google Chrome" to return title of active tab of first window'
Step 2: Submit Post
Navigate Chrome to reddit.com first (same-origin requirement), then submit:
(async()=>{
try {
let body = new URLSearchParams({
sr: "SideProject", // subreddit name (no r/ prefix)
kind: "self", // "self" for text, "link" for URL
title: "Your post title",
text: "Your post body with **markdown** support",
uh: "MODHASH_HERE",
api_type: "json",
resubmit: "true"
});
let resp = await fetch("/api/submit", {
method: "POST",
credentials: "include",
headers: {"Content-Type": "application/x-www-form-urlencoded"},
body: body.toString()
});
let result = await resp.json();
document.title = "POSTED:" + JSON.stringify(result);
} catch(e) {
document.title = "ERR:" + e.message;
}
})()
For link posts, change:
kind: "link",
url: "https://github.com/your/repo", // instead of text
Step 3: Extract Post Link
The response contains result.json.data.url — the direct link to the new post.
Step 4: Add Flair (if required)
Some subreddits require flair. After posting, use:
(async()=>{
try {
// First get available flairs
let resp = await fetch("/r/SUBREDDIT/api/link_flair_v2", {credentials: "include"});
let flairs = await resp.json();
document.title = "FLAIRS:" + JSON.stringify(flairs.map(f => ({id: f.id, text: f.text})));
} catch(e) {
document.title = "ERR:" + e.message;
}
})()
Then apply flair:
(async()=>{
try {
let body = new URLSearchParams({
link: "t3_POST_ID",
flair_template_id: "FLAIR_ID",
uh: "MODHASH"
});
await fetch("/api/selectflair", {
method: "POST",
credentials: "include",
headers: {"Content-Type": "application/x-www-form-urlencoded"},
body: body.toString()
});
document.title = "FLAIR_SET";
} catch(e) {
document.title = "ERR:" + e.message;
}
})()
Step 5: Session Summary
Always end with the post link:
| Sub | Title | Post Link | |-----|-------|-----------| | r/SideProject | "Your title" | https://www.reddit.com/r/SideProject/comments/abc123/... |
Spam Filter Avoidance
Words to AVOID in titles/body
| Avoid | Use Instead | |-------|-------------| | crawl, crawled, crawling | compiled, cataloged, indexed, collected | | scrape, scraping | gathered, extracted, retrieved | | bot, automated | tool, script, program | | free (overused) | open source, MIT licensed | | hack, hacks | tips, techniques, methods |
Content Triggers to Avoid
- Multiple external links (max 1-2)
- URL shorteners (bit.ly, tinyurl)
- New account + promotional content
- Same content across multiple subreddits quickly
- Excessive self-promotion language
Best Subreddits for Open Source Projects
| Subreddit | Members | Best For | Notes | |-----------|---------|----------|-------| | r/coolgithubprojects | 60K | GitHub repos | Designed for this! | | r/SideProject | 453K | Side projects | Very welcoming | | r/opensource | 100K+ | Open source tools | Technical audience | | r/programming | 6M+ | Dev tools | High competition | | r/Python | 1.5M+ | Python tools | Active community | | r/webdev | 2M+ | Web tools | "Showoff Saturday" only | | r/selfhosted | 400K+ | Self-hosted tools | Great engagement |
Best Times to Post (US Eastern Time)
| Day | Best Time | |-----|-----------| | Monday | 6-8 AM | | Tuesday | 7-9 AM | | Wednesday | 8-10 AM | | Thursday | 7-9 AM | | Friday | 6-8 AM | | Saturday | 7-9 AM | | Sunday | 8-10 AM |
Post 30 minutes BEFORE peak times for momentum building.
Post Templates
Open Source Project Announcement
Title: I built [PROJECT_NAME] - [one-line description] (open source)
Body:
Hey everyone,
I created [PROJECT_NAME] to solve [PROBLEM].
**What it does:**
- Feature 1
- Feature 2
- Feature 3
**Tech stack:** [Languages/frameworks]
**Links:**
- GitHub: [single link]
Happy to answer any questions!
Tool/Resource Share
Title: [TOOL_NAME]: [what it does] - free and open source
Body:
Built this because [reason/pain point].
**Features:**
- [List 3-5 key features]
**How to use:**
[Brief code example or instructions]
GitHub: [link]
Feedback welcome!
Cross-Posting Strategy
Stagger posts across subreddits for maximum reach:
- Day 1: Primary subreddit (most relevant)
- Day 2-3: Secondary subreddit (different audience)
- Day 4-5: General subreddit (r/SideProject, etc.)
Never post to multiple subreddits on the same day — triggers spam detection.
Error Recovery
| Issue | Solution | |-------|----------| | "Post removed by filters" | Rewrite without trigger words, reduce links | | "You're doing that too much" | Wait 10-15 min, need more karma | | "This community requires flair" | Use /api/selectflair after posting | | "Title too long" | Keep under 300 characters | | Post not visible | Check if shadowbanned: profile in incognito | | Modhash expired | Re-fetch from /api/me.json |
Why AppleScript (Not Playwright)
| Tool | Problem | |------|---------| | Playwright | navigator.webdriver=true, detected by Reddit | | Selenium | Same detection issue | | curl + API | IP blocked after few requests | | AppleScript | Controls real Chrome, undetectable, cookies included |