diff --git a/blogwatcher-daily/SKILL.md b/blogwatcher-daily/SKILL.md index 12929ab..ca54112 100644 --- a/blogwatcher-daily/SKILL.md +++ b/blogwatcher-daily/SKILL.md @@ -6,7 +6,7 @@ category: custom tags: [rss, blog, monitoring, automation, export, category] metadata: author: Hermes Agent - last_updated: 2026-09-01 + last_updated: "2026-09-01" platform: macos, ubuntu custom_skill_path: /Users/weishen/.hermes/skills/custom/ installation_note: "blogwatcher-daily 脚本在 Mac mini 本地运行(依赖 feedparser)。需要 RSSHub 服务(http://192.168.3.45:1200)访问 YouTube/Bilibili 等被墙源。" diff --git a/blogwatcher-daily/blogwatcher.db b/blogwatcher-daily/blogwatcher.db index a2fb05c..a2bdfb3 100644 Binary files a/blogwatcher-daily/blogwatcher.db and b/blogwatcher-daily/blogwatcher.db differ diff --git a/blogwatcher-daily/references/agentmail-sending.md b/blogwatcher-daily/references/agentmail-sending.md new file mode 100644 index 0000000..0dd6f1b --- /dev/null +++ b/blogwatcher-daily/references/agentmail-sending.md @@ -0,0 +1,74 @@ +# AgentMail 发送邮件工作流(配合 blogwatcher-daily 等导出技能) + +> 从 blogwatcher-daily 的 SKILL.md 中拆出,因为「AgentMail 发信」是独立于「RSS 抓取导出」的能力。任何需要先导出再发邮件的场景都可复用。 + +## 前置条件 + +- `agentmail` CLI 已安装(`/opt/homebrew/bin/agentmail`) +- API key 在 `~/.zshrc` 的 `AGENTMAIL_API_KEY` 里(当前 Hermes shell 不会自动加载 .zshrc,需手动 source 或提取) +- **出站网络需要走代理**:`ALL_PROXY=socks5://127.0.0.1:10808`(否则 agentmail API 返回 403 被 CloudFront 拦截) + +## 标准发送流程 + +```bash +# 1) 提取 API key + 设置代理(每次新 shell 都要做) +export AGENTMAIL_API_KEY=$(grep '^export AGENTMAIL_API_KEY=' ~/.zshrc | sed 's/.*="\(.*\)"/\1/') +export ALL_PROXY=socks5://127.0.0.1:10808 +export HTTP_PROXY=http://127.0.0.1:10808 +export HTTPS_PROXY=http://127.0.0.1:10808 + +# 2) 列出 inbox 拿 inbox_id(首次;一般是 star-agent@agentmail.to) +agentmail inboxes list + +# 3) 发送(--html 直接读 HTML 内容字符串) +agentmail inboxes messages send \ + --inbox-id "star-agent@agentmail.to" \ + --to "billyshen@163.com" \ + --subject "主题" \ + --html "$(cat /tmp/file.html)" +``` + +返回 JSON: +```json +{ + "message_id": "<...>@email.amazonses.com", + "thread_id": "..." +} +``` + +## 常见陷阱 + +### 1. 403 "Request blocked" +- 没走代理。CloudFront 拦了直连 IP。 +- 修复:export 上面 3 个 PROXY 环境变量后重试。 + +### 2. 401 "credentials are missing" +- 当前 shell 没加载 .zshrc,`AGENTMAIL_API_KEY` 不在环境里。 +- 修复:用上面的 `export $(grep ...)` 提取。 + +### 3. HTML 太长 +- `--html "$(cat file)"` 把整个文件塞进命令行参数。对很大的 HTML(>500KB)可能撞到 ARG_MAX。 +- 应对:先压缩 HTML(去掉 base64 图片、压缩 CSS),或者改用 `--json @payload.json` 走 stdin。 + +## 与 blogwatcher-daily 配合的固定模式 + +```bash +# 导出 → 发邮件 +python3 ~/.hermes/skills/custom/blogwatcher-daily/scripts/blogwatcher-daily.py \ + --export html --date 2026-08-30 > /tmp/digest.html + +agentmail inboxes messages send \ + --inbox-id "star-agent@agentmail.to" \ + --to "billyshen@163.com" \ + --subject "Blogwatcher Daily Digest $(date +%Y-%m-%d)" \ + --html "$(cat /tmp/digest.html)" +``` + +## 当前用户的 inbox + +- `star-agent@agentmail.to`(默认发件箱) + +## 已发送示例 + +- Blogwatcher 每日摘要 → billyshen@163.com +- 单订阅文章打包(异次元软件世界、惫懒の欧阳川)→ billyshen@163.com diff --git a/blogwatcher-daily/subscriptions.txt b/blogwatcher-daily/subscriptions.txt index 3fdb976..931d5ea 100644 --- a/blogwatcher-daily/subscriptions.txt +++ b/blogwatcher-daily/subscriptions.txt @@ -37,3 +37,4 @@ AI技术|AI懒人报|http://192.168.3.45:1200/youtube/channel/UCNyBkFPz_IPWaincc 未分类|Dan Koe|http://192.168.3.45:1200/youtube/channel/UCWXYDYv5STLk-zoxMP2I1Lw 技术博客|技术爬爬虾 TechShrimp|http://192.168.3.45:1200/youtube/channel/UCa6D2k5qhpOI9I-WT8fpd6g AI技术|AI Foundations|http://192.168.3.45:1200/youtube/channel/UCWZwfV3ICOt3uEPpW6hYK4g +生活方式|马蜂窝游记|http://192.168.3.45:1200/mafengwo/note/hot diff --git a/llm-provider-billing/SKILL.md b/llm-provider-billing/SKILL.md index 20a61f9..34a0a17 100644 --- a/llm-provider-billing/SKILL.md +++ b/llm-provider-billing/SKILL.md @@ -52,6 +52,46 @@ curl -s https://api.deepseek.com/user/balance \ - **402 vs 401**:余额归零 → HTTP 402 Insufficient Balance(key 仍有效,充值即恢复);key 错误/缺失 → 401。遇到 402 是去充值,不是换 key - 充值/发票在 platform.deepseek.com 的 Billing 页面 +## 阿里云百炼 Token Plan(已验证 ✅) + +Token Plan 是订阅制(周配额),"余量" = 本周剩余 token 配额比例,语义区别于 DeepSeek 的余额。 + +### 一键查询 + +```bash +bash ~/.hermes/skills/custom/llm-provider-billing/scripts/bailian-token-plan.sh +# --summary 附加统一用量摘要(免费额度 freeTier + 近期用量) +bash ~/.hermes/skills/custom/llm-provider-billing/scripts/bailian-token-plan.sh --summary +``` + +### 鉴权要求(关键) + +- **Console 鉴权**:首次运行前需浏览器一次性授权 `bl auth login --console --console-site domestic`(国内站) +- **API Key 查不了配额**:`bl auth login --api-key ` / 环境变量里的 key(用户的是 `OPENAI_API_KEY`)只能调模型,不能查余量 +- 授权凭据落盘 `~/.bailian/config.json`,登录一次长期有效;回调走本机 `127.0.0.1` 端口,浏览器必须与 CLI 同机 + +### 返回结构(实测 2026-09-10) + +```json +{ + "per1WeekPercentage": 0.032949624, + "per1WeekResetTime": 1789624440000 +} +``` + +- `per1WeekPercentage`:**本周已用比例**(0.033 ≈ 3.3% 已用;实测随时间递增,确认是"已用"不是"剩余"),剩余 ≈ 1 - 该值 +- `per1WeekResetTime`:本周配额重置时间(epoch 毫秒,如 2026-09-17 13:54 CST,即 7 天滚动窗口) +- 原始 JSON 只有这两个字段,无绝对额度数值;脚本自动换算已用/剩余百分比 + 本地时区重置时间 + +### 相关命令 + +| 命令 | 用途 | 鉴权 | +|---|---|---| +| `bl usage token-plan --output json` | Token Plan 周配额用量 | Console | +| `bl usage summary --output json` | 统一摘要:freeTier 剩余额度 + 近期用量 | Console | +| `bl usage stats` / `bl usage free` | 用量统计 / 免费额度 | Console | +| `bl token-plan list-seats` | 订阅座位详情 | AK/SK(`ALIBABA_CLOUD_ACCESS_KEY_ID` 等环境变量) | + ## 其他提供商(待扩展) 每家端点不同。添加前先用 web_search 验证官方文档并实测一次,把端点 + 返回结构记录到 `references/`。 diff --git a/llm-provider-billing/scripts/bailian-token-plan.sh b/llm-provider-billing/scripts/bailian-token-plan.sh new file mode 100644 index 0000000..636a5e0 --- /dev/null +++ b/llm-provider-billing/scripts/bailian-token-plan.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# 阿里云百炼 Token Plan 余量/配额查询 — 依赖 bl CLI 的控制台登录(一次性授权) +# 用法: bash bailian-token-plan.sh [--summary] +# --summary 额外输出统一用量摘要(免费额度 + 近期用量) +set -euo pipefail + +if ! command -v bl >/dev/null 2>&1; then + echo "❌ 未找到 bl CLI,请先: npm install -g bailian-cli" >&2 + exit 1 +fi + +AUTH=$(bl auth status --output json 2>/dev/null || true) +if ! echo "$AUTH" | grep -q '"authenticated": *true'; then + echo "❌ 百炼控制台未登录(API Key 只能调模型,查不了配额)。请先执行一次性授权:" >&2 + echo " bl auth login --console --console-site domestic" >&2 + exit 1 +fi + +echo "🔍 查询百炼 Token Plan 配额 ..." >&2 +if ! bl usage token-plan --output json > /tmp/bailian-token-plan.json 2>/tmp/bailian-token-plan.err; then + echo "❌ bl usage token-plan 失败:" >&2 + cat /tmp/bailian-token-plan.err >&2 + exit 1 +fi +cat /tmp/bailian-token-plan.json +echo + +# 友好摘要:周配额已用/剩余比例 + 重置时间(本地时区) +if command -v python3 >/dev/null 2>&1; then + python3 - <<'PY' +import json, sys, datetime, time +try: + d = json.load(open('/tmp/bailian-token-plan.json')) +except Exception as e: + print(f"⚠️ 无法解析 JSON: {e}", file=sys.stderr) + sys.exit(0) +used = d.get('per1WeekPercentage') +reset = d.get('per1WeekResetTime') +if used is not None: + used_pct = used * 100 + print(f"📊 本周 Token Plan 已用: {used_pct:.2f}% | 剩余约为: {100 - used_pct:.2f}%") +else: + print("⚠️ 响应中没有 per1WeekPercentage 字段(结构可能已变化),请参考上方原始 JSON") +if reset: + dt = datetime.datetime.fromtimestamp(reset / 1000) + tzname = time.strftime('%Z') + print(f"🔄 本周配额重置时间: {dt.strftime('%Y-%m-%d %H:%M:%S')}(本地时区 {tzname or 'local'})") +PY +fi + +if [ "${1:-}" = "--summary" ]; then + echo "=== 统一用量摘要(免费额度等) ===" >&2 + bl usage summary --output json +fi \ No newline at end of file