首页龙虾技能列表 › Castreader Openclaw Skill — Castreader — URL转语音播客

Castreader Openclaw Skill — Castreader — URL转语音播客

v3.2.14

URL转语音工具:提取任意网页并转换为自然AI语音(Kokoro TTS)。唯一能将URL转换为播客品质MP3的技能——无需API密钥。还能朗读微信读书/Kindle同步的书籍。

1· 491·1 当前·1 累计
by @vinxu·MIT-0
下载技能包
License
MIT-0
最后更新
2026/4/14
安全扫描
VirusTotal
无害
查看报告
OpenClaw
安全
medium confidence
技能的文件、脚本和指令与其声明的目的(通过CastReader提取URL或本地书籍并生成TTS)一致,但需要运行npm(Puppeteer/Chromium),会将提取的文本发送到外部TTS API,并存在一些小的元数据不匹配问题需要注意。
评估建议
安装前需考虑的事项: - 网络与隐私:技能会提取网页文本和书籍文件,并将其发送到外部TTS API(默认https://api.castreader.ai)。如果页面或书籍包含敏感数据,请勿使用在线TTS模式。API密钥是可选的;如果设置CASTREADER_API_KEY,它将包含在API请求中。 - 安装占用:必须在技能文件夹中运行npm install,这将安装Puppeteer和许多npm包,并下载Chromium二进制文件——需要大量下载和额外磁盘空间。如果谨慎行事,建议在沙箱、容器或VM中运行。 - 本地文件访问:技能将从~/castreader-library/books/读取同步的书籍。使用书籍功能前,请确保只存放预期文件。 - 代码审查与测试:如果想更安全,可以检查附带的脚本(它们存在)并测试仅提取模式(运行node scripts/read-url.js <url> 0)离线验证提取行为,而不生成TTS。也可以在隔离环境中运行npm install --no-audit并监控网络流量。 - 元数据不匹配:注册表元数据未声明脚本使用的环境变量——请注意并有意设置或省略...
详细分析 ▾
用途与能力
技能是URL/书籍转音频工具,其代码(提取器包、基于Puppeteer的提取和TTS调用)匹配该目的。它还读取本地库目录(~/castreader-library/books/)用于同步书籍——这与“阅读书籍”能力一致。小的的不匹配:SKILL元数据未列出环境变量(CASTREADER_API_URL/VOICE/API_KEY),尽管脚本使用它们;README中有记录。
指令范围
SKILL.md指示代理运行npm install,然后仅使用提供的node脚本。这些脚本(extract/read-url/sync-books/generate-text)通过Puppeteer执行网页浏览,将extractor-bundle.js注入目标页面,读写/tmp和用户主目录castreader-library下的文件,并将提取的文本POST到外部TTS端点(默认https://api.castreader.ai)。所有这些操作都在声明的范围内,但确实涉及将提取的网页/书籍文本发送到主机外(隐私考虑)。
安装机制
注册表中没有自动安装规范,但SKILL.md坚持在技能目录中运行npm install。package.json依赖puppeteer,这将在安装期间获取许多npm包并下载Chromium二进制文件——一个中等风险、高占用的操作。这些包来自npm注册表(没有奇怪的URL),但您应该期待大量下载和本地资源使用。
凭证需求
技能未在注册表元数据中声明所需的环境变量,但代码读取可选的环境变量:CASTREADER_API_URL、CASTREADER_API_KEY、CASTREADER_VOICE、CASTREADER_SPEED。使用API_KEY(如果提供)会在请求中将该密钥发送到TTS API。脚本还在用户主目录(~/castreader-library/books/)下读取文件——适合读取同步书籍,但可能敏感。总体而言,请求/使用的环境和文件系统访问对于功能集是合理的,但注册表元数据遗漏和提取的文本被发布到外部API是值得注意的问题。
持久化与权限
技能不请求“always:true”,不修改其他技能或系统设置,不持久化代理范围的配置。它按调用方式运行(node脚本),除了当前用户的正常文件系统和网络访问外,不请求提升的权限。
scripts/read-url.js:133
检测到Shell命令执行(child_process)。
scripts/generate-text.js:16
环境变量访问结合网络发送。
scripts/read-url.js:29
环境变量访问结合网络发送。
scripts/sync-books.js:38
环境变量访问结合网络发送。
scripts/generate-text.js:103
文件读取结合网络发送(可能存在数据泄露)。
scripts/read-url.js:130
文件读取结合网络发送(可能存在数据泄露)。
scripts/sync-books.js:130
文件读取结合网络发送(可能存在数据泄露)。
安全有层次,运行前请审查代码。

License

MIT-0

可自由使用、修改和再分发,无需署名。

运行时依赖

🖥️ OSmacOS · Linux · Windows

版本

latestv3.2.142026/3/13

改进README:更清晰的价值主张,删除已失效的脚本,修复链接,优化SKILL.md以便于搜索

● 无害

安装命令 点击复制

官方npx clawhub@latest install castreader
镜像加速npx clawhub@latest install castreader --registry https://cn.clawhub-mirror.com

技能文档

Setup (once per session)

cd  && npm install

How to find target (chatId)

User messages look like: [Telegram username id:8716240840 ...] The number after id: is the target. You MUST use this number in every message tool call. Example: target is "8716240840".


Mode A: When user sends a URL

Step 1: Extract article

node scripts/read-url.js "" 0

Returns: { title, language, totalParagraphs, totalCharacters, paragraphs[] }

Step 2: Show info + ask user to choose

Reply with this text:

📖 {title}
🌐 {language} · 📝 {totalParagraphs} paragraphs · 📊 {totalCharacters} chars

📋 Summary: {write 2-3 sentence summary from paragraphs}

Reply a number to choose: 1️⃣ Listen to full article (~{totalCharacters} chars, ~{Math.ceil(totalCharacters / 200)} sec to generate) 2️⃣ Listen to summary only (~{summary_char_count} chars, ~{Math.ceil(summary_char_count / 200)} sec to generate)

STOP. Wait for user to reply 1 or 2.

Step 3a: User chose 1 (full article)

Reply: 🎙️ Generating full audio (~{totalCharacters} chars, ~{Math.ceil(totalCharacters / 200)} seconds)...

node scripts/read-url.js "" all

Then send the audio file using the message tool:

{"action":"send", "target":"", "channel":"telegram", "filePath":"", "caption":"🔊 {title}"}

Reply: ✅ Done!

Step 3b: User chose 2 (summary only)

Reply: 🎙️ Generating summary audio...

Save the SAME summary text you showed in Step 2 to a file and generate:

echo "" > /tmp/castreader-summary.txt
node scripts/generate-text.js /tmp/castreader-summary.txt 

Then send the audio file using the message tool:

{"action":"send", "target":"", "channel":"telegram", "filePath":"/tmp/castreader-summary.mp3", "caption":"📋 Summary: {title}"}

Reply: ✅ Done!


Mode B: When user asks to read a book (微信读书 / Kindle)

Books are synced from WeChat Reading or Kindle to ~/castreader-library/books/. Each book is stored in a folder like 书名-hashid (e.g. 儒林外史-dc532c705c6d3edc5503acc).

⚠️ CRITICAL: You MUST use sync-books.js --list to get the exact book folder ID. NEVER guess or construct the folder path yourself. The folder name includes a title prefix that you cannot predict.

Step 1: List available books

node scripts/sync-books.js --list

Returns: { books: [{ id, title, author, language, totalChapters, totalCharacters, source, syncedAt }] }

The id field is the exact folder name you must use in all subsequent commands. Example: "儒林外史-dc532c705c6d3edc5503acc".

Step 2: Show book list and let user choose

Reply with the book list:

📚 Your synced books:
  • 📖 {title} — {author}
🌐 {language} · 📑 {totalChapters} chapters · 📊 {totalCharacters} chars · 📱 {source}
  • ...

Reply the number of the book you want to read.

STOP. Wait for user to choose a book.

Step 3: Show chapter list and let user choose

node scripts/sync-books.js --book ""

Use the exact id from Step 1 output.

Returns the book content with chapter list.

Reply:

📖 {title} — {author}
📑 {totalChapters} chapters · 📊 {totalCharacters} chars

📋 Chapters:

  • {chapter 1 title}
  • {chapter 2 title}
...

Reply a number to listen to a chapter, or "all" to listen to the full book.

STOP. Wait for user to choose.

Step 4a: User chose a chapter number

node scripts/sync-books.js --book "" --chapter  --audio

Returns: { title, audioFile, fileSizeBytes }

Send the audio:

{"action":"send", "target":"", "channel":"telegram", "filePath":"", "caption":"🔊 {bookTitle} — Chapter {num}"}

Step 4b: User chose "all" (full book)

node scripts/sync-books.js --book "" --audio

Returns: { title, audioFile, fileSizeBytes }

Send the audio:

{"action":"send", "target":"", "channel":"telegram", "filePath":"", "caption":"🔊 {bookTitle} (full)"}

Reading a chapter as text (no audio)

If the user wants to read (not listen), use without --audio:

node scripts/sync-books.js --book "" --chapter 

Returns: { title, author, language, chapter: { number, title, text }, totalChapters }


Rules

  • ALWAYS extract first (index=0 for URLs, --list for books), show info, wait for user choice. Never skip.
  • ALWAYS send audio files using the message tool with target (numeric chatId) and channel ("telegram"). Never just print the file path.
  • For books: ALWAYS run --list first and use the exact id from the output. NEVER construct book paths manually or use partial IDs.
  • Do NOT use built-in TTS tools. ONLY use read-url.js, generate-text.js, and sync-books.js.
  • Do NOT use web_fetch. ONLY use read-url.js.
  • Do NOT use the read tool to directly access files in ~/castreader-library/. ONLY use sync-books.js.
数据来源:ClawHub ↗ · 中文优化:龙虾技能库
OpenClaw 技能定制 / 插件定制 / 私有工作流定制

免费技能或插件可能存在安全风险,如需更匹配、更安全的方案,建议联系付费定制

了解定制服务