全部技能 / 内容创作 / twitter-reader
内容创作 · daymade/claude-code-skills

twitter-reader

Fetch Twitter/X post content including long-form Articles with full images and metadata. Use when Claude needs to retrieve tweet/article content, author info, engagement metrics, and embedded media. Supports individual posts and X Articles (long-form content). Automatically downloads all images to local attachments folder and generates complete Markdown with proper image references. Preferred over Jina for X Articles with images.

风险提醒:橙色 · 评估后使用AI 侦查报告
作者 daymadeGitHub daymade/claude-code-skills ↗Stars 1378许可 MITcommit 63a65c1fcc
agent 宿主通常会约束 skill 执行权限;风险提醒为 AI 侦查观点,不构成质量或安全保证。第三方 skill 仅作拆解与展示,安装使用风险自负,版权归原作者。

1实现原理 · 为什么它能做到

单帖纯文本首选路径是免登录、免 key 直接 curl fxtwitter 镜像 API,全文取自 tweet.text(文档注明 full_text 键不存在)——这一路径零凭证、零配置,2026-08-30 起取代 Jina 成为默认

twitter-reader/SKILL.md
works direct, and returns the **full note_tweet body in `tweet.text`** (the `full_text` key does not exist; a 2,324-char long-form announcement came back complete):
注:文档内联给出 `curl -sS --max-time 20 "https://api.fxtwitter.com/<user>/status/<id>" | python3 -c ...` 配方,由 agent 直接执行(无脚本封装),镜像 API 返回结构化 JSON 后只取 created_at 与 text 两字段。这是本 skill 对『读单帖』问题的真实答案:不抓页面、不调官方 API,靠第三方镜像。

X Articles(长文带图)主路径由 fetch_article.py 承接:先用 `uv run --with twitter-cli` 现场安装并执行 PyPI 包 twitter-cli 的 `twitter article` 子命令,拿到含 author/metrics/articleText 的结构化 YAML

twitter-reader/scripts/fetch_article.py
def run_twitter_cli(url: str) -> dict: """Fetch article data using twitter-cli via uv run.""" cmd = ["uv", "run", "--with", "twitter-cli", "twitter", "article", url]
注:每次运行由 uv 临时解析安装 twitter-cli(版本未 pin),输出经 parse_yaml_output 用 yaml.safe_load 解析后取 data 字段。元数据(createdAtLocal/author/metrics{likes,retweets,bookmarks}/articleTitle/articleText)全靠这个第三方 CLI 的私有输出格式,本仓不实现任何 Twitter API 直连。

正文(含图)经 Jina Reader(r.jina.ai)抓取:有 JINA_API_KEY 就带 Bearer,没有就匿名;随后按 'Markdown Content:' 标记切出正文,若 Jina 失败则回退用 twitter-cli 返回的 articleText

twitter-reader/scripts/fetch_article.py
api_key = os.getenv("JINA_API_KEY", "") jina_url = f"https://r.jina.ai/{url}" cmd = ["curl", "-s", jina_url] if api_key: cmd.extend(["-H", f"Authorization: Bearer {api_key}"])
注:文档明确告知匿名 r.jina.ai 访问 x.com 会被第三方滥用拖累成间歇性全局 403 ban(2026-08-30 实测记录),因此 Jina 被定位为『可用但不可靠』的正文源;key 在此是可选优化而非必需。

图片本地化是脚本核心增值:从抓回的 Markdown 里用正则抽出 pbs.twimg.com/media 链接 → 去重并统一改为 ?format=jpg&name=large → curl 逐个下载到 attachments/日期-作者-标题/ → 再把正文中的远程图 URL 正则替换为本地相对路径

twitter-reader/scripts/fetch_article.py
pattern = r'https://pbs\.twimg\.com/media/[^\s\)"\']+'
注:extract_image_urls 只认 pbs.twimg.com/media 前缀,把下载面限制在 Twitter 图片 CDN;download_images 用 `curl -sL url -o filepath` 落盘(无超时、串行、文件名 01-image.jpg… 按序编号),replace_image_urls 再把远程 URL 全部改写为 attachments/... 本地相对引用,保证 Markdown 离线可看。

输出纪律:YYYY-MM-DD-标题.md(含 YAML frontmatter:source/author/date/likes/retweets/bookmarks)+ 同名附件目录;日期取 createdAtLocal 前 10 位,标题与作者经 sanitize_filename 消毒截断 60 字符

twitter-reader/scripts/fetch_article.py
md = f"""--- source: {source_url} author: {author.get("name", "")} date: {date_str} likes: {metrics.get("likes", 0)}
注:generate_markdown 拼 frontmatter + 正文;正文若含本地化图片引用则先经 replace_image_urls 改写再拼接。整体是一个『网页/推文 → 干净 PKM 文件』的转换器,面向 Obsidian 式笔记库。

Jina 文本模式作为旁路:fetch_tweet.py(单条、硬性要求 JINA_API_KEY、仅 HTTPS)与 fetch_tweets.sh(bash 批量循环,正则允许 http/https)直接 curl r.jina.ai 并透传 Bearer

twitter-reader/scripts/fetch_tweets.sh
for url in "$@"; do if [[ ! "$url" =~ ^https?://(x\.com|twitter\.com)/ ]]; then
注:该旁路在 SKILL.md 中被明确定位为 fallback(文档承认共享 key 已 402 余额不足、批量脚本当前不可用),核心主张是『别依赖它』——这是少见的把自家备用通道风险写进文档的 skill。

2核心能力

01免登录单帖全文读取(fxtwitter 首选通道)
02X Article 长文内容抓取(含 note_tweet 级别的长正文)
03结构化元数据:作者、日期、likes/retweets/bookmarks 互动指标
04正文内嵌图片自动批量下载到本地 attachments 目录并改写为本地引用
05生成带 YAML frontmatter 的 Markdown 文件(source/author/date/likes/retweets/bookmarks),面向 PKM 系统
06Jina 文本模式单条/批量抓取(fetch_tweet.py / fetch_tweets.sh)与 URL 白名单校验
07内容源降级容错:Jina 失效时回退 twitter-cli articleText;对第三方通道不稳定做实测记录并文档化

3外部依赖

类型依赖
clicurl
cliuv (Python 包管理器)
clipython3(含内联 -c 解析)
packagetwitter-cli(PyPI,uv 现场安装并执行 twitter article 子命令,未 pin 版本)
packagepyyaml
apiJina Reader API
networkfxtwitter 镜像 API
networkTwitter 图片 CDN(图片下载目标)
networkx.com / twitter.com(被抓取目标,经 fxtwitter/Jina 代理访问)

4风险提醒 风险提醒:橙色 · 评估后使用

风险提醒:橙色 · 评估后使用
  • 运行时自动安装并执行未 pin 的第三方 PyPI 包 twitter-cli(uv run --with),代码在审计范围之外——供应链/可复现性面 — fetch_article.py: `cmd = ["uv", "run", "--with", "twitter-cli", "twitter", "article", url]`
  • JINA_API_KEY 环境变量凭证读取且被外发(fetch_tweet.py/fetch_tweets.sh 硬性要求) — 外发目的地唯一(r.jina.ai 本体)、无硬编码密钥,但 key 在宿主环境中存在被注入指令诱导滥用的可能(宿主权限约束面)
  • 抓取类技能固有:远程正文原样写入 .md,宿主随后让 Claude 读取时正文可携带 prompt-injection;对 x.com 高频抓取有平台风控与 ToS 灰区(文档自证第三方滥用已致匿名 Jina 被全局 ban) — SKILL.md: 'anonymous `r.jina.ai` access to x.com gets **403-globally-banned for hours** when *third-party* users abuse the domain'
  • 健壮性细节:脚本内 curl 无 --max-time、图片下载串行无上限、URL 仅前缀白名单(bash 版放行 http://) — 仅 SKILL.md fxtwitter 配方有 20s 超时;fetch_tweets.sh: `^https?://(x\.com|twitter\.com)/`
侦查意见,非认证。橙标依据范式表橙色行两个条件均字面命中:(a) 环境变量凭证读取——JINA_API_KEY 被两个脚本硬性读取并外发(去向唯一且可预期:r.jina.ai 本体,无 cookies/keychain/硬编码密钥,故未触及更高档);(b) 依赖第三方远程包——主路径每次运行经 uv 从 PyPI 现场安装并执行 twitter-cli(未 pin),执行代码不在本仓审计范围,与 .security-scan-passed(gitleaks 静态扫本目录文本)覆盖的边界之外。脚本本身无 shell=True/无混淆/无隐蔽外发、下载面被正则锁死在 pbs.twimg.com、免 key 的 fxtwitter 路径零凭证——这些使其低于红色档;但『远程包 + env 凭证』两者叠加使绿色/蓝色档不成立,黄色档的『仅公开 API/官方 CLI 且外发可预期』也不完全贴切,故定橙色:评估后使用。

5第二遍独立确认

  • [ok] fxtwitter API(api.fxtwitter.com)调用点真实存在 — SKILL.md fxtwitter 段内联 curl 配方原文命中;文档自述 2026-08-30 实测过 2,324 字符 note_tweet 完整返回。仅验证调用点,端点当前可达性未在线复核
  • [ok] Jina r.jina.ai 调用点真实存在 — 三个脚本各自命中:fetch_tweet.py `jina_api_url = f"https://r.jina.ai/{url}"`、fetch_tweets.sh `curl -s "https://r.jina.ai/${url}"`、fetch_article.py run_jina_api;Bearer 头与 JINA_API_KEY 读取逐处对上
  • [ok] twitter-cli 依赖真实存在(uv run --with) — fetch_article.py run_twitter_cli 的 argv 原文命中;SKILL.md Quick Start 另以 `uv run --with pyyaml` 启动脚本,与 parse_yaml_output 的 yaml 导入一致
  • [ok] pbs.twimg.com 图片下载路径真实存在且仅此 CDN — extract_image_urls 正则仅匹配 pbs\.twimg\.com/media/ 前缀;download_images 用 curl -sL 落盘。未发现其他图片域名
  • [ok] JINA_API_KEY 读取点全覆盖、无硬编码密钥 — grep JINA_|sk- 于 twitter-reader/ 命中仅 3 处 env 读取(无字面量);全仓库 CHANGELOG 记录 2026-01-05 前后『Removed hardcoded API keys』。SKILL.md 所述『shared key 402 余额尽』系作者侧市场共享 key,仓库内无对应字符串
  • [ok] URL 校验形态:前缀白名单而非权威解析 — fetch_tweet.py/fetch_article.py 用 startswith(("https://x.com/","https://twitter.com/"));fetch_tweets.sh 用正则 ^https?://(x\.com|twitter\.com)/。三处均要求主机后紧跟 /,可挡 https://x.com.evil.com 型主机混淆;bash 版放行 http:// 与文档『HTTPS only』表述存在出入(py 版严格)
  • [ok] 无隐藏脚本/无混淆/无隐蔽外发 — 目录仅 SKILL.md + 3 脚本 + .security-scan-passed 标记;脚本全部为列表式 subprocess,无 shell=True/eval/curl 之外的网络动词;.security-scan-passed 为纯文本记录,无执行作用
  • [ok] 功能声明与代码能力相符性 — 『长文带图 + 元数据 + 自动下载 + Markdown』在 fetch_article.py 中逐项落实;但核心卖点依赖第三方间歇服务:Jina 匿名被全局 ban 时正文只剩 twitter-cli 的 articleText 兜底(可能不含图),文档已如实标注『Preferred over Jina…』仅针对有图场景——无夸大但有外部依赖边界

6结论

  • 读单帖零成本通道:免登录免 key 的 fxtwitter 镜像优先,文档给出可直接执行的完整 curl 配方
  • 长文带图一键转本地 PKM 文件:元数据 + 图片自动下载 + URL 改写 + YAML frontmatter 全自动
  • 诚实文档:把自家主备用通道(Jina)的间歇性全局 ban、共享 key 欠费等失败经验写进 SKILL.md 并设计降级,避免 agent 把不可靠路径当主通道
  • 依赖面极窄:仅 curl + uv + 两个小脚本,无重型运行时,输出结构清晰(YYYY-MM-DD-标题.md + attachments/)
  • 适合:需要把 X 帖/长文(含图)转成干净本地 Markdown 供笔记/PKM/继续加工的个人或团队;Claude Code 类宿主;愿意自备 Jina key(可选)且接受第三方镜像与代理通道的场景。
    不适合:需要回复线程/评论列表(replies 只是计数)、需登录态数据、对供应链零容忍或断网环境(twitter-cli 每次经 uv 现场安装)、把抓 X 当主业务的规模化合规采集。
    安装 agent 直装可复制
    ① 本站镜像 更新 2026-09-06
    方式 A · 人下载镜像包下载 twitter-reader.tar.gz
    sha256: 6e441b1396143142…
    方式 B · JSON 格式安装指南,复制给 agent
    安装指南
    agent 读 JSON 指南后会自动从本站下载安装,无需更多说明。
    ② 上游 GitHub · 原始来源
    能访问 GitHub?直接去上游安装(实时版,可能已更新)GitHub 原始 ↗
    本页镜像锁定 commit 63a65c1fcc;上游为实时仓库。
    来源信息 GitHub 原始
    作者 / 仓库daymade / daymade/claude-code-skills
    Stars1378
    最近推送2026-09-06
    本 skill commit63a65c1fcc
    许可MIT
    本站信息
    收录日期2026-09-06
    分类内容创作
    侦查报告2026-09-06 · 2 遍
    本站镜像与 GitHub 原始是不同来源:本站锁定 commit 快照经 /r2 分发;GitHub 为实时上游,内容可能已更新。