reddit-cultivate

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Reddit Cultivation Skill (AppleScript Chrome Control)

Reddit账号运营技能(AppleScript Chrome控制)

Build and maintain Reddit presence by controlling the user's real Chrome browser 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
  • AppleScript executes JavaScript in Chrome's active tab
  • Chrome is already logged into Reddit → cookies sent automatically
  • Same-origin fetch → no CORS, no detection, no IP blocks
  • Reddit cannot distinguish this from human browsing

Claude Code → osascript → Chrome(已登录的真实浏览器)→ Reddit
  • AppleScript在Chrome的活动标签页中执行JavaScript
  • Chrome已登录Reddit → Cookie自动发送
  • 同源请求 → 无CORS问题、无检测、无IP封禁
  • Reddit无法将此与人工浏览区分开

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)

方法检测(先运行)

Chrome multi-profile can cause AppleScript to not see windows. Always detect first:
bash
WINDOWS=$(osascript -e 'tell application "Google Chrome" to return count of windows' 2>/dev/null)
if [ "$WINDOWS" = "0" ] || [ -z "$WINDOWS" ]; then
    echo "Use Method 2 (System Events + Console)"
else
    echo "Use Method 1 (execute javascript)"
fi

Chrome多配置文件可能导致AppleScript无法识别窗口。请先执行检测:
bash
WINDOWS=$(osascript -e 'tell application "Google Chrome" to return count of windows' 2>/dev/null)
if [ "$WINDOWS" = "0" ] || [ -z "$WINDOWS" ]; then
    echo "Use Method 2 (System Events + Console)"
else
    echo "Use Method 1 (execute javascript)"
fi

Method 1: AppleScript Execute JavaScript (Preferred)

方法1:AppleScript执行JavaScript(推荐)

Works when
count of windows > 0
.
count of windows > 0
时适用。

Navigate

导航

bash
osascript -e 'tell application "Google Chrome" to tell active tab of first window to set URL to "https://www.reddit.com/r/SideProject/rising/"'
bash
osascript -e 'tell application "Google Chrome" to tell active tab of first window to set URL to "https://www.reddit.com/r/SideProject/rising/"'

Execute JS & Read Result (document.title trick)

执行JS并读取结果(document.title技巧)

bash
undefined
bash
undefined

Run JS that writes result to document.title

运行将结果写入document.title的JS

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="R:"+JSON.stringify({name:d.data.name,karma:d.data.total_karma})})"'
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="R:"+JSON.stringify({name:d.data.name,karma:d.data.total_karma})})"'

Wait, then read title

等待后读取标题

sleep 2 osascript -e 'tell application "Google Chrome" to return title of active tab of first window'
undefined
sleep 2 osascript -e 'tell application "Google Chrome" to return title of active tab of first window'
undefined

JXA for Complex JS (avoids escaping hell)

使用JXA处理复杂JS(避免转义问题)

bash
osascript -l JavaScript -e '
var chrome = Application("Google Chrome");
var tab = chrome.windows[0].activeTab;
tab.execute({javascript: "(" + function() {
    // Complex JS here — no escaping needed
    fetch("/r/SideProject/rising.json?limit=10", {credentials: "include"})
        .then(r => r.json())
        .then(d => {
            var posts = d.data.children.map(p => ({
                title: p.data.title.substring(0, 60),
                score: p.data.score,
                comments: p.data.num_comments,
                id: p.data.name,
                url: "https://reddit.com" + p.data.permalink
            }));
            document.title = "POSTS:" + JSON.stringify(posts);
        });
} + ")();"});
'

bash
osascript -l JavaScript -e '
var chrome = Application("Google Chrome");
var tab = chrome.windows[0].activeTab;
tab.execute({javascript: "(" + function() {
    // 此处放置复杂JS — 无需转义
    fetch("/r/SideProject/rising.json?limit=10", {credentials: "include"})
        .then(r => r.json())
        .then(d => {
            var posts = d.data.children.map(p => ({
                title: p.data.title.substring(0, 60),
                score: p.data.score,
                comments: p.data.num_comments,
                id: p.data.name,
                url: "https://reddit.com" + p.data.permalink
            }));
            document.title = "POSTS:" + JSON.stringify(posts);
        });
} + ")();"});
'

Method 2: System Events + Console (Multi-Profile Fallback)

方法2:系统事件+控制台(多配置文件 fallback)

When AppleScript can't see Chrome windows (multi-profile bug), use keyboard automation.
当AppleScript无法识别Chrome窗口时(多配置文件bug),使用键盘自动化。

Step 1: Copy JS to Clipboard

步骤1:将JS复制到剪贴板

bash
python3 -c "
import subprocess
js = '''(async()=>{
    let resp = await fetch('/api/me.json', {credentials: 'include'});
    let data = await resp.json();
    document.title = 'R:' + JSON.stringify({name: data.data.name, karma: data.data.total_karma});
})()'''
subprocess.run(['pbcopy'], input=js.encode(), check=True)
"
bash
python3 -c "
import subprocess
js = '''(async()=>{
    let resp = await fetch('/api/me.json', {credentials: 'include'});
    let data = await resp.json();
    document.title = 'R:' + JSON.stringify({name: data.data.name, karma: data.data.total_karma});
})()'''
subprocess.run(['pbcopy'], input=js.encode(), check=True)
"

Step 2: Execute via Chrome Console Keyboard Shortcuts

步骤2:通过Chrome控制台快捷键执行

bash
osascript -e '
tell application "System Events"
    tell process "Google Chrome"
        set frontmost to true
        delay 0.3
        -- Cmd+Option+J = open/close Console
        key code 38 using {command down, option down}
        delay 1
        -- Select all + Paste + Enter
        keystroke "a" using {command down}
        delay 0.2
        keystroke "v" using {command down}
        delay 0.5
        key code 36
        delay 0.3
        -- Close Console
        key code 38 using {command down, option down}
    end tell
end tell'
bash
osascript -e '
tell application "System Events"
    tell process "Google Chrome"
        set frontmost to true
        delay 0.3
        -- Cmd+Option+J = 打开/关闭控制台
        key code 38 using {command down, option down}
        delay 1
        -- 全选 + 粘贴 + 回车
        keystroke "a" using {command down}
        delay 0.2
        keystroke "v" using {command down}
        delay 0.5
        key code 36
        delay 0.3
        -- 关闭控制台
        key code 38 using {command down, option down}
    end tell
end tell'

Step 3: Read Title via System Events

步骤3:通过系统事件读取标题

bash
sleep 3
osascript -e '
tell application "System Events"
    tell process "Google Chrome"
        return name of window 1
    end tell
end tell'

bash
sleep 3
osascript -e '
tell application "System Events"
    tell process "Google Chrome"
        return name of window 1
    end tell
end tell'

Workflow

工作流程

Step 1: Check Account Status

步骤1:检查账号状态

Get username, karma, verify login using
/api/me.json
.
通过
/api/me.json
获取用户名、Karma值,验证登录状态。

Step 2: Scan Rising Posts

步骤2:扫描热度上升的帖子

For each target subreddit, fetch rising posts:
/r/{subreddit}/rising.json?limit=10
Look for:
  • Rising posts with < 15 comments (early = more visibility)
  • Score > 2 (some traction)
  • Questions you can answer or discussions with genuine insight
针对每个目标子版块,获取热度上升的帖子:
/r/{subreddit}/rising.json?limit=10
寻找:
  • 评论数<15的上升帖子(早期参与曝光度更高)
  • 得分>2(已有一定关注度)
  • 你能解答的问题或有真知灼见的讨论

Step 3: Draft Comments

步骤3:撰写评论

Rules:
  • 2-4 sentences, natural tone
  • Add genuine value (insights, experience, helpful info)
  • No self-promotion, no links, no emojis
  • Match the subreddit's culture
  • Each comment must be unique
规则:
  • 2-4句话,语气自然
  • 提供真正的价值(见解、经验、有用信息)
  • 不自我推广、不发链接、不用表情符号
  • 契合子版块的文化
  • 每条评论必须独一无二

Step 4: Post All Comments

步骤4:发布所有评论

Get modhash, then post each comment with 4s delay between posts.
javascript
// Get modhash first
let me = await fetch("/api/me.json", {credentials: "include"}).then(r=>r.json());
let uh = me.data.modhash;

// Post comment
let body = new URLSearchParams({
    thing_id: "t3_xxxxx",  // post fullname
    text: "Your comment here",
    uh: uh,
    api_type: "json"
});
let resp = await fetch("/api/comment", {
    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);
Extract the comment ID from the response HTML: look for
id-t1_XXXXXXX
in the result.
获取modhash,然后每条评论间隔4秒发布。
javascript
// 先获取modhash
let me = await fetch("/api/me.json", {credentials: "include"}).then(r=>r.json());
let uh = me.data.modhash;

// 发布评论
let body = new URLSearchParams({
    thing_id: "t3_xxxxx",  // 帖子全名
    text: "Your comment here",
    uh: uh,
    api_type: "json"
});
let resp = await fetch("/api/comment", {
    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);
从响应HTML中提取评论ID:在结果中查找
id-t1_XXXXXXX

Step 5: Session Summary with Links

步骤5:带链接的会话总结

ALWAYS end with a summary table containing direct links to every comment posted.
The comment link format is:
https://www.reddit.com/r/{subreddit}/comments/{post_id}/comment/{comment_id}/
Where:
  • {subreddit}
    = the subreddit name
  • {post_id}
    = the post ID (from
    thing_id
    minus the
    t3_
    prefix)
  • {comment_id}
    = extracted from the POST response (the
    t1_XXXXXXX
    value, minus
    t1_
    prefix)
Example summary table:
This lets the user bookmark, follow up on replies, and track which comments got traction.

务必以包含每条已发布评论直接链接的总结表格结束。
评论链接格式:
https://www.reddit.com/r/{subreddit}/comments/{post_id}/comment/{comment_id}/
其中:
  • {subreddit}
    = 子版块名称
  • {post_id}
    = 帖子ID(
    thing_id
    去掉
    t3_
    前缀)
  • {comment_id}
    = 从POST响应中提取的ID(
    t1_XXXXXXX
    去掉
    t1_
    前缀)
示例总结表格:
这方便用户收藏、跟进回复,并跟踪哪些评论获得了关注度。

Recommended Target Subreddits

推荐目标子版块

PrioritySubredditWhy
Highr/SideProjectProject launches, very welcoming
Highr/indiehackersRevenue/growth discussions
Mediumr/ClaudeAIAI tooling audience
Mediumr/coolgithubprojectsOpen source visibility
Mediumr/startupsStartup discussions
Mediumr/entrepreneurBusiness insights
Mediumr/opensourceTechnical audience

优先级子版块理由
r/SideProject项目发布版块,氛围友好
r/indiehackers收益/增长讨论
r/ClaudeAIAI工具受众
r/coolgithubprojects开源项目曝光
r/startups创业讨论
r/entrepreneur商业见解
r/opensource技术受众

Comment Guidelines

评论指南

  • Add genuine value (insights, experience, helpful info)
  • No self-promotion in comments
  • Match the subreddit's tone
  • Be specific, not generic
  • 2-4 sentences, natural voice

  • 提供真正的价值(见解、经验、有用信息)
  • 评论中不自我推广
  • 契合子版块的语气
  • 内容具体,不泛泛而谈
  • 2-4句话,语气自然

Rate Limiting

速率限制

ActionLimit
Between API calls2+ seconds
Between posts4+ seconds
Per sessionMax 5 comments
Daily10-15 comments max

操作限制
API调用间隔2秒以上
帖子发布间隔4秒以上
每会话最多5条评论
每日最多10-15条评论

Karma Milestones

Karma值里程碑

KarmaUnlocks
100+Can post in most subreddits
500+Reduced spam filter triggers
1000+Trusted contributor status
5000+Community recognition

Karma值解锁权限
100+可在大多数子版块发帖
500+减少垃圾邮件过滤器触发
1000+可信贡献者身份
5000+社区认可

Algorithm Insights

算法洞察

  • First 30 minutes determine if post reaches Hot page
  • Early upvotes weighted 10x more than later ones
  • 2 early comments > 20 passive upvotes
  • Best posting time: Sunday 6-8 AM ET
  • Upvote ratio matters: 100↑/10↓ (90%) beats 150↑/50↓ (75%)

  • 前30分钟决定帖子能否登上热门页面
  • 早期点赞的权重是后期的10倍以上
  • 2条早期评论 > 20个被动点赞
  • 最佳发帖时间:美国东部时间周日6-8点
  • 点赞率很重要:100赞/10踩(90%)优于150赞/50踩(75%)

Troubleshooting

故障排除

ProblemSolution
count of windows
= 0
Chrome multi-profile bug → use Method 2
"Allow JavaScript" not workingRestart Chrome after enabling
Modhash expiredRe-fetch from
/api/me.json
403 responseRate limited, wait 5+ minutes
Comment not appearingCheck for shadowban: visit profile in incognito

问题解决方案
count of windows
= 0
Chrome多配置文件bug → 使用方法2
"允许JavaScript"不生效启用后重启Chrome
Modhash过期
/api/me.json
重新获取
403响应触发速率限制,等待5分钟以上
评论未显示检查是否被影子封禁:在隐身模式下访问个人资料

Why AppleScript (Not Playwright/Selenium)

为什么选择AppleScript(而非Playwright/Selenium)

ToolProblem
PlaywrightSets
navigator.webdriver=true
, detected instantly
SeleniumSame detection issue
PuppeteerSame detection issue
curl + APIIP blocked by Reddit after few requests
AppleScriptControls real Chrome, undetectable, cookies included
工具问题
Playwright设置
navigator.webdriver=true
,立即被检测到
Selenium同样的检测问题
Puppeteer同样的检测问题
curl + API几次请求后IP被Reddit封禁
AppleScript控制真实Chrome,无法被检测,自动包含Cookie