feat(reddit): honest tiering — OpenCLI / rdt-cli, no zero-config path
- live-verified 2026-06: anonymous .json endpoints are 403-blocked (all variants) and the official API closed self-service registration in 2025-11 — so the channel now says plainly: every Reddit backend needs a logged-in session, mainland China needs a proxy - backends = [OpenCLI, rdt-cli]: OpenCLI rides the browser session (desktop preferred); rdt-cli stays for servers and existing installs (upstream unmaintained since 2026-03, noted in the ok message) - install: desktop routes to OpenCLI, server installs rdt-cli from the pinned git source (split out as _install_rdt_cli) - skill/references/social.md: Reddit section rewritten as two backend command groups + a PRAW note scoped to users who already hold pre-2025-11 credentials (explicitly not recommended for new users) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Reddit — search and read via rdt-cli (public-clis/rdt-cli).
|
||||
"""Reddit — multi-backend: OpenCLI / rdt-cli. Login is mandatory.
|
||||
|
||||
NOTE: Reddit requires authentication since 2024. All API requests
|
||||
(including public subreddit reads) return HTTP 403 without a valid
|
||||
session cookie. Run `rdt login` after installation to authenticate.
|
||||
Honest tiering (live-verified 2026-06): there is NO zero-config path.
|
||||
Anonymous .json endpoints are blocked (403 anti-bot, all variants), and
|
||||
the official API closed self-service registration in 2025-11 (manual
|
||||
approval, individual scripts rarely granted — PRAW is only an option for
|
||||
users who already hold credentials). Every working backend rides a
|
||||
logged-in session: OpenCLI reuses the browser's, rdt-cli imports cookies.
|
||||
"""
|
||||
|
||||
import json
|
||||
@@ -32,8 +35,8 @@ _RDT_BROKEN_HINT = (
|
||||
class RedditChannel(Channel):
|
||||
name = "reddit"
|
||||
description = "Reddit 帖子和评论"
|
||||
backends = ["rdt-cli"]
|
||||
tier = 1 # Reddit requires login since 2024 (rdt login) — not zero-config
|
||||
backends = ["OpenCLI", "rdt-cli"]
|
||||
tier = 1 # no zero-config path exists — see module docstring
|
||||
|
||||
def can_handle(self, url: str) -> bool:
|
||||
from urllib.parse import urlparse
|
||||
@@ -42,19 +45,59 @@ class RedditChannel(Channel):
|
||||
return "reddit.com" in d or "redd.it" in d
|
||||
|
||||
def check(self, config=None):
|
||||
"""Probe candidates in order; first fully-usable backend wins."""
|
||||
self.active_backend = None
|
||||
findings = []
|
||||
|
||||
for backend in self.ordered_backends(config):
|
||||
if backend == "OpenCLI":
|
||||
result = self._check_opencli()
|
||||
else:
|
||||
result = self._check_rdt()
|
||||
if result is None:
|
||||
continue
|
||||
findings.append((backend, *result))
|
||||
|
||||
for wanted in ("ok", "warn"):
|
||||
for backend, status, message in findings:
|
||||
if status == wanted:
|
||||
self.active_backend = backend
|
||||
return status, message
|
||||
|
||||
if findings:
|
||||
return "error", "\n".join(m for _, _, m in findings)
|
||||
|
||||
return "off", (
|
||||
"未安装任何 Reddit 后端。注意:Reddit 没有零配置路径"
|
||||
"(匿名 .json 已被封,官方 API 需人工审批),必须用登录态。推荐:\n"
|
||||
" 桌面:agent-reach install --channels opencli\n"
|
||||
" (复用 Chrome 登录态,登录过 reddit.com 即可用)\n"
|
||||
f" 服务器/存量:pipx install '{_RDT_GIT_SOURCE}'\n"
|
||||
" 然后 `rdt login` 或手动写入 Cookie(见 doctor 提示)\n"
|
||||
"中国大陆访问 Reddit 需要代理"
|
||||
)
|
||||
|
||||
def _check_opencli(self):
|
||||
"""OpenCLI candidate. None = not installed."""
|
||||
from agent_reach.backends import opencli_status
|
||||
|
||||
st = opencli_status()
|
||||
if not st.installed:
|
||||
return None
|
||||
if st.broken:
|
||||
return "error", st.hint
|
||||
if st.ready:
|
||||
return "ok", (
|
||||
"OpenCLI 可用(复用浏览器登录态)。用法:"
|
||||
"opencli reddit search/read/subreddit/hot -f yaml"
|
||||
)
|
||||
return "warn", st.hint
|
||||
|
||||
def _check_rdt(self):
|
||||
"""rdt-cli candidate. None = not installed."""
|
||||
rdt = shutil.which("rdt")
|
||||
if not rdt:
|
||||
return "off", (
|
||||
"需要安装 rdt-cli。PyPI 版本可能暂时落后,推荐直接从 GitHub 安装:\n"
|
||||
f" pipx install '{_RDT_GIT_SOURCE}'\n"
|
||||
"如已确认 PyPI 版本已更新,也可使用:\n"
|
||||
" pipx install rdt-cli\n"
|
||||
" uv tool install rdt-cli\n"
|
||||
"最新源码:https://github.com/public-clis/rdt-cli\n"
|
||||
"安装后运行 `rdt login` 登录(需先在浏览器登录 reddit.com)"
|
||||
)
|
||||
return None
|
||||
|
||||
# 不走 probe_command:实测 `rdt status --json` 成功时(rc=0)也会向 stderr
|
||||
# 打网络重试日志,probe 把 stdout+stderr 合并后 JSON 解析必炸。
|
||||
@@ -83,9 +126,7 @@ class RedditChannel(Channel):
|
||||
tail = detail[-1] if detail else "无输出"
|
||||
return "error", f"rdt 异常退出(exit {r.returncode}):{tail}。运行 `rdt status` 查看详情"
|
||||
|
||||
# 进程正常退出 → rdt 本身是活的(无论登录与否),后端即为可用
|
||||
self.active_backend = "rdt-cli"
|
||||
|
||||
# 进程正常退出 → rdt 本身是活的(无论登录与否)
|
||||
try:
|
||||
data = json.loads(r.stdout or "")
|
||||
except json.JSONDecodeError:
|
||||
@@ -101,7 +142,10 @@ class RedditChannel(Channel):
|
||||
|
||||
if authenticated:
|
||||
suffix = f"(已登录:{username})" if username else ""
|
||||
return "ok", (f"rdt-cli 可用{suffix}(搜索帖子、阅读全文、查看评论)")
|
||||
return "ok", (
|
||||
f"rdt-cli 可用{suffix}(搜索帖子、阅读全文、查看评论;"
|
||||
"上游 2026-03 起停更,桌面用户建议迁移到 OpenCLI)"
|
||||
)
|
||||
|
||||
return "warn", (
|
||||
"rdt-cli 已安装但未登录。Reddit 自 2024 年起要求认证,"
|
||||
|
||||
+18
-1
@@ -774,7 +774,24 @@ def _install_opencli_deps():
|
||||
|
||||
|
||||
def _install_reddit_deps():
|
||||
"""Install rdt-cli for Reddit search + reading."""
|
||||
"""Set up Reddit — desktop prefers OpenCLI, rdt-cli for servers/legacy.
|
||||
|
||||
No zero-config path exists (anonymous .json blocked, official API
|
||||
approval-gated since 2025-11) — every backend needs a logged-in session.
|
||||
"""
|
||||
if _detect_environment() != "server":
|
||||
_install_opencli_deps()
|
||||
print(" Reddit 走 OpenCLI(浏览器里登录过 reddit.com 即可用)")
|
||||
import shutil
|
||||
if shutil.which("rdt"):
|
||||
print(" ✅ 检测到存量 rdt-cli,将作为备选后端继续可用")
|
||||
return
|
||||
|
||||
_install_rdt_cli()
|
||||
|
||||
|
||||
def _install_rdt_cli():
|
||||
"""Install rdt-cli (pinned git source — PyPI lags upstream)."""
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
|
||||
@@ -180,25 +180,43 @@ user = ch.get_user("Livid")
|
||||
|
||||
> **节点列表**: https://www.v2ex.com/planes
|
||||
|
||||
## Reddit (rdt-cli)
|
||||
## Reddit(多后端,必须登录态)
|
||||
|
||||
**Reddit 没有零配置路径**:匿名 `.json` 端点已被封(403),官方 API 自 2025-11 起人工审批基本不批。两个后端都靠登录态,先跑 `agent-reach doctor --json` 看 reddit 的 `active_backend`。中国大陆访问需代理。
|
||||
|
||||
### 后端 A:OpenCLI(桌面首选,复用浏览器登录态)
|
||||
|
||||
```bash
|
||||
# 搜索帖子
|
||||
rdt search "query" --limit 10
|
||||
opencli reddit search "query" -f yaml
|
||||
|
||||
# 读帖子全文 + 评论
|
||||
rdt read POST_ID
|
||||
opencli reddit read POST_ID -f yaml
|
||||
|
||||
# 浏览 subreddit
|
||||
rdt sub python --limit 20
|
||||
# 浏览 subreddit / 热门 / Popular
|
||||
opencli reddit subreddit LocalLLaMA -f yaml
|
||||
opencli reddit hot -f yaml
|
||||
opencli reddit popular -f yaml
|
||||
|
||||
# 浏览热门
|
||||
rdt popular --limit 10
|
||||
|
||||
# 浏览 /r/all
|
||||
rdt all --limit 10
|
||||
# subreddit 元信息(订阅数、简介)
|
||||
opencli reddit subreddit-info LocalLLaMA -f yaml
|
||||
```
|
||||
|
||||
> **安装**: `pipx install 'git+https://github.com/public-clis/rdt-cli.git'`(PyPI 版本暂时落后,需从 GitHub 装 v0.4.2+)。需要先登录(`rdt login`)才能搜索和阅读。
|
||||
> 需要登录的功能:`rdt feed --subs-only`(订阅列表)、`rdt saved`(收藏)。
|
||||
> 要求 Chrome 打开且浏览器里登录过 reddit.com。
|
||||
|
||||
### 后端 B:rdt-cli(存量/服务器备选,上游 2026-03 起停更)
|
||||
|
||||
```bash
|
||||
rdt search "query" --limit 10 # 搜索帖子
|
||||
rdt read POST_ID # 读帖子全文 + 评论
|
||||
rdt sub python --limit 20 # 浏览 subreddit
|
||||
rdt popular --limit 10 # 浏览热门
|
||||
rdt all --limit 10 # 浏览 /r/all
|
||||
```
|
||||
|
||||
> **安装**: `pipx install 'git+https://github.com/public-clis/rdt-cli.git'`(PyPI 版本落后,需从 GitHub 装 v0.4.2+)。先 `rdt login` 才能搜索和阅读(服务器无浏览器时手动写 Cookie,见 doctor 提示)。
|
||||
> 建议使用 `--yaml` 输出,对 AI agent 更友好。
|
||||
|
||||
### 高级选项:官方 API + PRAW(仅限已有凭证的用户)
|
||||
|
||||
2025-11 前注册过 Reddit script app(持有 client_id/client_secret)的用户可以用 PRAW 走官方 API(100 QPM 免费)。新申请需人工审批且个人项目基本不批,**不要推荐新用户走这条路**。
|
||||
|
||||
Reference in New Issue
Block a user