关于 content-parser
content-parser 是用于从受支持平台的 URL 提取并整理内容的 Agent 技能,返回正文、元数据和引用,可作为生成内容前的处理步骤或独立提取工具。
主要功能
- 01提取 URL 内容及元数据
- 02返回引用链接
- 03可选生成摘要
- 04可设置最大长度
- 05支持配置 X/Twitter 推文数量
适用场景
- 01提取文章供后续内容生成
- 02解析链接并查看页面信息
- 03抓取 X/Twitter 个人资料的推文
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ marswaveai/ skills --skill content-parser安装后在 Claude Code 中输入/content-parser确认已加载。
附带文件references/supported-platforms.md
详细介绍
适用场景
- 用户提供 URL 并希望提取或阅读其内容
- 其他技能需要在生成内容前解析 URL 中的源材料
- 用户说“解析此 URL”“提取此链接中的内容”
- 用户说“解析链接”“提取内容”
不适用场景
- 用户已有文本内容,不需要解析 URL
- 用户想生成音频或视频内容(而非提取内容)
- 用户想阅读本地文件(使用标准文件读取工具)
用途
提取并规范化受支持平台上的 URL 内容。返回包含正文、元数据和引用的结构化数据。可用作内容生成技能的预处理步骤,也可单独用于内容提取。
硬性约束
- 不使用 shell 脚本。根据下方的 API Reference (Inlined) 部分构造 curl 命令
- API 密钥和请求头请参阅下方的 § API Reference (Inlined)
- 轮询、错误和交互模式请参阅下方的 § API Reference (Inlined)
- URL 必须是有效的 HTTP(S) URL
- 进行任何交互前,始终先阅读
shared/config-pattern.md中的配置 - 绝不将文件保存到
~/Downloads/或.listenhub/— 保存到当前工作目录
步骤 -1:API 密钥检查
按照 shared/config-pattern.md § API Key Check 操作。如果缺少密钥,立即停止。
步骤 0:配置设置
按照 shared/config-pattern.md 步骤 0(Zero-Question Boot)操作。
如果文件不存在 — 静默创建默认配置并继续:
mkdir -p ".listenhub/content-parser"
echo '{"autoDownload":true}' > ".listenhub/content-parser/config.json"
CONFIG_PATH=".listenhub/content-parser/config.json"
CONFIG=$(cat "$CONFIG_PATH")
不要询问任何设置问题。 直接进入交互流程。
如果文件存在 — 静默读取配置并继续:
CONFIG_PATH=".listenhub/content-parser/config.json"
[ ! -f "$CONFIG_PATH" ] && CONFIG_PATH="$HOME/.listenhub/content-parser/config.json"
CONFIG=$(cat "$CONFIG_PATH")
设置流程(仅在用户主动要求重新配置时)
仅当用户明确要求重新配置时运行。显示当前设置:
当前配置 (content-parser):
自动下载:{是 / 否}
然后询问:
- autoDownload:“是否自动将提取的内容保存到当前目录?”
- “是(推荐)” →
autoDownload: true - “否” →
autoDownload: false
- “是(推荐)” →
立即保存:
NEW_CONFIG=$(echo "$CONFIG" | jq --argjson dl {true/false} '. + {"autoDownload": $dl}')
echo "$NEW_CONFIG" > "$CONFIG_PATH"
CONFIG=$(cat "$CONFIG_PATH")
交互流程
步骤 1:输入 URL
自由文本输入。询问用户:
您想从哪个 URL 提取内容?
步骤 2:选项(可选)
询问用户是否要配置提取选项:
Question: "Do you want to configure extraction options?"
Options:
- "No, use defaults" — Extract with default settings
- "Yes, configure options" — Set summarize, maxLength, or Twitter tweet count
如果选择“Yes”,继续询问:
- Summarize:是否生成内容摘要?(是/否)
- Max Length:是否设置内容最大长度?(自由输入,例如“5000”)
- Twitter count(仅当 URL 是 Twitter/X 个人资料时):要获取多少条推文?(1–100,默认 20)
步骤 3:确认并提取
总结:
Ready to extract content:
URL: {url}
Options: {summarize: true, maxLength: 5000, twitter.count: 50} / default
Proceed?
调用 API 前等待用户明确确认。
工作流
-
验证 URL:必须是 HTTP(S) URL。如有需要,请进行规范化(参见
references/supported-platforms.md) -
构建请求正文:
{ "source": { "type": "url", "uri": "{url}" }, "options": { "summarize": true/false, "maxLength": 5000, "twitter": { "count": 50 } } }如果用户选择默认值,则省略
options。 -
提交(前台):
POST /v1/content/extract→ 提取taskId -
告知用户内容提取正在进行
-
轮询(后台):使用
run_in_background: true和timeout: 300000运行以下精确的 bash 命令。注意:状态字段为.data.status(不是processStatus),间隔为 5 秒,值为processing/completed/failed:TASK_ID="<id-from-step-3>" for i in $(seq 1 60); do RESULT=$(curl -sS "https://api.marswave.ai/openapi/v1/content/extract/$TASK_ID" \ -H "Authorization: Bearer $LISTENHUB_API_KEY" \ -H "X-Source: skills" 2>/dev/null) STATUS=$(echo "$RESULT" | tr -d '\000-\037\177' | jq -r '.data.status // "processing"') case "$STATUS" in completed) echo "$RESULT"; exit 0 ;; failed) echo "FAILED: $RESULT" >&2; exit 1 ;; *) sleep 5 ;; esac done echo "TIMEOUT" >&2; exit 2 -
收到通知后,下载并呈现结果:
如果
autoDownload为true,则根据提取的标题生成 slug;如果没有标题,则使用域名作为后备。按照shared/config-pattern.md§ Artifact Naming 中的说明生成 slug 并处理重复项。- 在当前目录写入
{slug}.md——完整的 Markdown 格式提取内容 - 在当前目录写入
{slug}.json——完整的原始 API 响应数据
SLUG="{title-slug}" # e.g. "topology-wikipedia" # Dedup: check if files exist BASE="$SLUG"; i=2 while [ -e "${SLUG}.md" ] || [ -e "${SLUG}.json" ]; do SLUG="${BASE}-${i}"; i=$((i+1)); done echo "$CONTENT_MD" > "${SLUG}.md" echo "$RESULT" > "${SLUG}.json"呈现:
内容提取完成! 来源:{url} 标题:{metadata.title} 长度:~{character count} 字符 消耗积分:{credits} 已保存到当前目录: {slug}.md {slug}.json - 在当前目录写入
-
显示提取内容的预览(前约 500 个字符)
-
提议在其他技能中使用内容(例如
/podcast、/tts)
预计耗时:10-30 秒,具体取决于内容大小和平台。
API 参考(内嵌)
身份验证
环境变量:LISTENHUB_API_KEY(格式:lh_sk_...)
存储在 ~/.zshrc(macOS)或 ~/.bashrc(Linux)中:
export LISTENHUB_API_KEY="lh_sk_..."
获取方式:访问 https://listenhub.ai/settings/api-keys(需要 Pro 计划)。
基础 URL:https://api.marswave.ai/openapi/v1
必需请求头(每个请求都需要):
Authorization: Bearer $LISTENHUB_API_KEY
Content-Type: application/json
X-Source: skills
X-Source: skills 请求头用于标识请求来自 Claude Code 技能(CLI 工具)。
curl 模板:
curl -sS -X POST "https://api.marswave.ai/openapi/v1/{endpoint}" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Source: skills" \
-d '{ ... }'
对于 GET 请求,省略 -d,并将 -X POST 改为 -X GET。
安全注意事项:
- 切勿在输出中记录或显示完整的 API 密钥
- API 密钥仅通过 HTTPS 传输
- 请勿将敏感或机密信息作为内容输入传递——这些信息会发送至外部 API 进行处理
POST /v1/content/extract
为 URL 创建内容提取任务。返回用于轮询的 taskId。
请求正文:
| 字段 | 必需 | 类型 | 描述 |
|---|---|---|---|
| source | 是 | object | 要从中提取内容的来源 |
| source.type | 是 | string | 必须为 "url" |
| source.uri | 是 | string | 用于提取内容的有效 HTTP(S) URL |
| options | 否 | object | 提取选项 |
| options.summarize | 否 | boolean | 是否生成摘要 |
| options.maxLength | 否 | integer | 内容最大长度 |
| options.twitter | 否 | object | Twitter/X 专用选项 |
| options.twitter.count | 否 | integer | 要获取的推文数量(1-100,默认值为 20) |
响应:
{
"code": 0,
"message": "success",
"data": {
"taskId": "69a7dac700cf95938f86d9bb"
}
}
错误代码:
| 代码 | 含义 |
|---|---|
| 29003 | 验证错误("source.uri" is required、"source.uri" must be a valid uri) |
| 21007 | API 密钥无效 |
GET /v1/content/extract/{taskId}
获取提取任务的状态和结果。
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| taskId | 字符串 | 24 位十六进制任务 ID |
响应状态:
- processing — 任务仍在运行
- completed — 提取已完成,数据可用
- failed — 提取失败,请检查
failCode和message
响应(processing):
{
"code": 0,
"message": "success",
"data": {
"taskId": "69a7dac700cf95938f86d9bb",
"status": "processing",
"createdAt": "2025-04-09T12:00:00Z",
"data": null,
"credits": 0,
"failCode": null,
"message": null
}
}
响应(completed):
{
"code": 0,
"message": "success",
"data": {
"taskId": "69a7dac700cf95938f86d9bb",
"status": "completed",
"createdAt": "2025-04-09T12:00:00Z",
"data": {
"content": "Extracted text content...",
"metadata": {
"title": "Article Title",
"author": "Author Name",
"publishedAt": "2025-04-01T08:00:00Z"
},
"references": [
"https://example.com/related-article"
]
},
"credits": 5,
"failCode": null,
"message": null
}
}
响应(failed):
{
"code": 0,
"message": "success",
"data": {
"taskId": "69a7dac700cf95938f86d9bb",
"status": "failed",
"createdAt": "2025-04-09T12:00:00Z",
"data": null,
"credits": 0,
"failCode": "EXTRACT_FAILED",
"message": "Unable to extract content from the provided URL"
}
}
关键字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| status | 字符串 | processing、completed 或 failed |
| data.data.content | 字符串 | 提取的文本内容 |
| data.data.metadata | 对象 | 页面元数据(标题、作者、发布时间) |
| data.data.references | 数组 | 引用的 URL(字符串数组) |
| credits | 整数 | 消耗的额度 |
| failCode | 字符串 | 错误代码(成功时为 null) |
| message | 字符串 | 错误消息(成功时为 null) |
错误代码:
| 代码 | 含义 |
|---|---|
| 29003 | taskId 格式无效 |
| 25002 | 未找到任务 |
轮询模式
间隔 5 秒,最多轮询 60 次。使用 run_in_background: true 和 timeout: 300000 运行。
两步模式:
- 提交(前台):发送创建请求的 POST 请求,并从响应中提取
taskId。 - 轮询(后台):使用
run_in_background: true运行轮询循环。任务完成后会自动通知你。
确切的轮询 bash 命令已在工作流部分(步骤 5)中指定。
错误处理
HTTP 状态码:
| 代码 | 含义 | 操作 |
|---|---|---|
| 200 | 成功 | 解析响应正文 |
| 400 | 请求错误 | 检查参数 |
| 401 | API 密钥无效 | 重新检查 LISTENHUB_API_KEY |
| 402 | 额度不足 | 告知用户充值 |
| 403 | 禁止访问 | 无权访问此资源 |
| 429 | 请求过于频繁 | 指数退避,延迟后重试 |
| 500/502/503/504 | 服务端错误 | 最多重试 3 次 |
重试策略:
- 429 请求频率限制:等待 15 秒后重试(指数退避)
- 5xx 服务端错误:以 5 秒间隔最多重试 3 次
- 网络错误:最多重试 3 次
应用错误代码:
| 代码 | 含义 |
|---|---|
| 21007 | 用户 API 密钥无效 |
| 25429 | 请求频率受限(应用级) |
示例
用户:“解析这篇文章:https://en.wikipedia.org/wiki/Topology”
Agent 工作流:
- URL:
https://en.wikipedia.org/wiki/Topology - 选项:默认值(省略选项)
- 提交提取请求
curl -sS -X POST "https://api.marswave.ai/openapi/v1/content/extract" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Source: skills" \
-d '{
"source": {
"type": "url",
"uri": "https://en.wikipedia.org/wiki/Topology"
}
}'
- 轮询直至完成:
curl -sS "https://api.marswave.ai/openapi/v1/content/extract/69a7dac700cf95938f86d9bb" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "X-Source: skills"
- 展示提取内容预览,并提供后续操作选项。
用户:“提取 @elonmusk 最近的推文,获取 50 条推文”
Agent 工作流:
- URL:
https://x.com/elonmusk - 选项:
{"twitter": {"count": 50}} - 提交提取请求
curl -sS -X POST "https://api.marswave.ai/openapi/v1/content/extract" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Source: skills" \
-d '{
"source": {
"type": "url",
"uri": "https://x.com/elonmusk"
},
"options": {
"twitter": {
"count": 50
}
}
}'
- 轮询直至完成,并展示结果。