reddit-post

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Reddit Posting Skill (AppleScript Chrome Control)

Reddit发帖技能(AppleScript Chrome控制)

Post to Reddit by controlling the user's real Chrome via AppleScript. No Playwright, no Selenium, no API tokens.

通过AppleScript控制用户的真实Chrome浏览器在Reddit发帖。无需使用Playwright、Selenium,也不需要API令牌。

How It Works

工作原理

Claude Code → osascript → Chrome (real browser, logged in) → Reddit /api/submit
  • Same-origin fetch with cookies → undetectable
  • Reddit's
    /api/submit
    endpoint for text/link posts
  • Modhash from
    /api/me.json
    for CSRF protection

Claude Code → osascript → Chrome (真实浏览器,已登录) → Reddit /api/submit
  • 携带Cookie的同源请求 → 无法被检测
  • 使用Reddit的
    /api/submit
    端点发布文字/链接帖
  • /api/me.json
    获取Modhash以实现CSRF防护

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

  • 仅支持macOS(AppleScript是macOS专属技术)
  • Chrome浏览器:依次点击「视图」→「开发者」→「允许来自Apple事件的JavaScript」(启用后需重启Chrome)
  • 用户已在Chrome中登录Reddit账号

Method Detection (Run First)

方法检测(先运行)

bash
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.

bash
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
查看
reddit-cultivate
技能以了解方法1与方法2的完整区别。

Posting Workflow

发帖流程

Step 1: Get Modhash

步骤1:获取Modhash

bash
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'
bash
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

步骤2:提交帖子

Navigate Chrome to reddit.com first (same-origin requirement), then submit:
javascript
(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:
javascript
kind: "link",
url: "https://github.com/your/repo",  // instead of text
先将Chrome导航至reddit.com(满足同源要求),再提交内容:
javascript
(async()=>{
  try {
    let body = new URLSearchParams({
      sr: "SideProject",           // subreddit名称(无需r/前缀)
      kind: "self",                // "self"表示文字帖,"link"表示链接帖
      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;
  }
})()
若发布链接帖,请修改:
javascript
kind: "link",
url: "https://github.com/your/repo",  // 替换text字段

Step 3: Extract Post Link

步骤3:提取帖子链接

The response contains
result.json.data.url
— the direct link to the new post.
响应结果中包含
result.json.data.url
——新帖子的直接链接。

Step 4: Add Flair (if required)

步骤4:添加标签(若需要)

Some subreddits require flair. After posting, use:
javascript
(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:
javascript
(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;
  }
})()
部分子版块要求添加标签。发帖后使用以下代码:
javascript
(async()=>{
  try {
    // 先获取可用标签
    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;
  }
})()
然后应用标签:
javascript
(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

步骤5:会话总结

Always end with the post link:
SubTitlePost Link
r/SideProject"Your title"https://www.reddit.com/r/SideProject/comments/abc123/...

务必以帖子链接结尾:
子版块标题帖子链接
r/SideProject"Your title"https://www.reddit.com/r/SideProject/comments/abc123/...

Spam Filter Avoidance

规避垃圾过滤器

Words to AVOID in titles/body

标题/正文中需避免的词汇

AvoidUse Instead
crawl, crawled, crawlingcompiled, cataloged, indexed, collected
scrape, scrapinggathered, extracted, retrieved
bot, automatedtool, script, program
free (overused)open source, MIT licensed
hack, hackstips, techniques, methods
需避免替代词汇
crawl, crawled, crawlingcompiled, cataloged, indexed, collected
scrape, scrapinggathered, extracted, retrieved
bot, automatedtool, script, program
free(滥用)open source, MIT licensed
hack, hackstips, 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

  • 多个外部链接(最多1-2个)
  • URL短链接(bit.ly、tinyurl等)
  • 新账号发布推广内容
  • 短时间内在多个子版块发布相同内容
  • 过度的自我推广话术

Best Subreddits for Open Source Projects

适合推广开源项目的子版块

SubredditMembersBest ForNotes
r/coolgithubprojects60KGitHub reposDesigned for this!
r/SideProject453KSide projectsVery welcoming
r/opensource100K+Open source toolsTechnical audience
r/programming6M+Dev toolsHigh competition
r/Python1.5M+Python toolsActive community
r/webdev2M+Web tools"Showoff Saturday" only
r/selfhosted400K+Self-hosted toolsGreat engagement

子版块成员数适用场景备注
r/coolgithubprojects6万GitHub仓库专为该场景设计!
r/SideProject45.3万副业项目社区氛围友好
r/opensource10万+开源工具受众技术水平较高
r/programming600万+开发工具竞争激烈
r/Python150万+Python工具社区活跃度高
r/webdev200万+Web工具仅在“Showoff Saturday”发布
r/selfhosted40万+自托管工具互动性强

Best Times to Post (US Eastern Time)

最佳发帖时间(美国东部时间)

DayBest Time
Monday6-8 AM
Tuesday7-9 AM
Wednesday8-10 AM
Thursday7-9 AM
Friday6-8 AM
Saturday7-9 AM
Sunday8-10 AM
Post 30 minutes BEFORE peak times for momentum building.

日期最佳时间
周一6-8点
周二7-9点
周三8-10点
周四7-9点
周五6-8点
周六7-9点
周日8-10点
建议在高峰时段前30分钟发帖,以积累热度。

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!
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!

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:
  1. Day 1: Primary subreddit (most relevant)
  2. Day 2-3: Secondary subreddit (different audience)
  3. Day 4-5: General subreddit (r/SideProject, etc.)
Never post to multiple subreddits on the same day — triggers spam detection.

错开时间在不同子版块发帖以扩大覆盖范围:
  1. 第1天:主帖子版块(最相关的)
  2. 第2-3天:次要子版块(受众不同)
  3. 第4-5天:综合子版块(如r/SideProject等)
切勿在同一天内多个子版块发布相同内容——会触发垃圾检测。

Error Recovery

错误排查

IssueSolution
"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 visibleCheck if shadowbanned: profile in incognito
Modhash expiredRe-fetch from /api/me.json

问题解决方案
“Post removed by filters”修改内容,移除触发词汇,减少链接数量
“You're doing that too much”等待10-15分钟,需要更多 karma(积分)
“This community requires flair”发帖后使用/api/selectflair接口添加标签
“Title too long”控制在300字符以内
帖子不可见检查是否被影子封禁:在隐身模式查看个人主页
Modhash过期重新从/api/me.json获取

Why AppleScript (Not Playwright)

为什么选择AppleScript(而非Playwright)

ToolProblem
Playwright
navigator.webdriver=true
, detected by Reddit
SeleniumSame detection issue
curl + APIIP blocked after few requests
AppleScriptControls real Chrome, undetectable, cookies included
工具问题
Playwright
navigator.webdriver=true
,会被Reddit检测到
Selenium存在相同的检测问题
curl + API几次请求后IP会被封禁
AppleScript控制真实Chrome浏览器,无法被检测,自动携带Cookie