瀏覽代碼

refactor(robotdaily): 修改为 Hugo 归档 + Discord 链接消息模式

Daily Deploy Bot 1 天之前
父節點
當前提交
901cb3c238
共有 4 個文件被更改,包括 190 次插入39 次删除
  1. 80 19
      arxiv-digest/SKILL.md
  2. 11 19
      arxiv-digest/scripts/run_daily.py
  3. 98 0
      arxiv-digest/scripts/send_discord_link.py
  4. 1 1
      site/public/search/index.html

+ 80 - 19
arxiv-digest/SKILL.md

@@ -1,11 +1,11 @@
 ---
 name: arxiv-digest
-description: "Daily arXiv digest generation for embodied intelligence, representation learning, and reinforcement learning. Use when Codex needs to: (1) fetch recent papers from arXiv, (2) rank them with an applied-research bias, (3) pick 2-3 papers per domain, (4) translate abstracts into Chinese, add short explanations and tag keywords, (5) render mobile-friendly digest cards, or (6) publish the digest to Discord on a schedule."
+description: "Daily arXiv digest generation for embodied intelligence, representation learning, and reinforcement learning. Use when Codex needs to: (1) fetch recent papers from arXiv, (2) rank them with an applied-research bias, (3) pick 2-3 papers per domain, (4) translate abstracts into Chinese, add short explanations and tag keywords, (5) render mobile-friendly digest cards, (6) publish to Hugo blog, and (7) send a brief link message to Discord RobotDaily channel."
 ---
 
 # arXiv Digest
 
-每日从 arXiv 抓取具身智能、表征学习、强化学习方向的最新论文,经过 LLM 筛选和解读后,推送到 Discord 并归档到 Hugo 博客
+每日从 arXiv 抓取具身智能、表征学习、强化学习方向的最新论文,经过 LLM 筛选和解读后,归档到 Hugo 博客,并在 Discord RobotDaily 频道推送链接和问候消息
 
 ## 核心入口
 
@@ -15,14 +15,14 @@ description: "Daily arXiv digest generation for embodied intelligence, represent
 # 仅生成简报(dry run)
 python3 scripts/run_daily.py
 
-# 生成并推送到 Discord
-python3 scripts/run_daily.py --publish-discord
-
-# 生成并同步到 Hugo
+# 生成并推送到 Hugo
 python3 scripts/run_daily.py --publish-hugo
 
+# 生成并发送 Discord 链接消息
+python3 scripts/run_daily.py --send-discord-link
+
 # 生成并推送两者
-python3 scripts/run_daily.py --publish-discord --publish-hugo
+python3 scripts/run_daily.py --publish-hugo --send-discord-link
 
 # 跳过 LLM 增强(快速测试)
 python3 scripts/run_daily.py --skip-enrich
@@ -38,11 +38,12 @@ python3 scripts/run_daily.py --skip-enrich
    - 简短价值解读
    - 卡片标签
 5. **渲染输出**:
-   - `robotdaily.html` - 移动端友好的 HTML 卡片
-   - `robotdaily.md` - Markdown 归档版本
-6. **多渠道推送**(可选):
-   - Discord:推送到 RobotDaily 频道
-   - Hugo:同步到 `site/content/ai-daily/YYYY-MM-DD.md`
+   - `robotdaily.md` - Markdown 归档版本(同步到 Hugo)
+6. **Hugo 归档**:
+   - 保存到 `site/content/ai-daily/YYYY-MM-DD.md`
+   - Hugo 自动重新编译并部署到网站
+7. **Discord 推送**:
+   - 在 RobotDaily 频道发送简短问候 + Hugo 链接
 
 ## 输出文件
 
@@ -51,9 +52,7 @@ python3 scripts/run_daily.py --skip-enrich
 - `candidates.json` - 候选论文列表
 - `selected.json` - 精选论文列表
 - `enriched.json` - LLM 增强后数据
-- `robotdaily.html` - HTML 移动端摘要卡片
 - `robotdaily.md` - Markdown 归档版本
-- `manifest.json` - 元数据清单
 
 ## 配置
 
@@ -69,11 +68,14 @@ ROBOTDAILY_OUTPUT_DIR=/home/zhn/.openclaw/workspace/skills/robdaily/arxiv-digest
 # Hugo 内容目录
 HUGO_CONTENT_DIR=/home/zhn/.openclaw/workspace/skills/robdaily/site/content/ai-daily
 
-# Discord 推送模式:thread | channel | fixed-channel | existing-channel
-DISCORD_DELIVERY_MODE=existing-channel
+# Discord 机器人令牌(用于发送链接消息)
+DISCORD_BOT_TOKEN=your_bot_token_here
 
-# 线程自动归档时间(分钟)
-DISCORD_THREAD_AUTO_ARCHIVE_MIN=10080
+# Discord RobotDaily 频道 ID
+DISCORD_ROBOTDAILY_CHANNEL_ID=1481632217930141697
+
+# Hugo 网站 URL
+HUGO_SITE_URL=https://indigofloyd.space
 ```
 
 ## 定时任务
@@ -81,7 +83,25 @@ DISCORD_THREAD_AUTO_ARCHIVE_MIN=10080
 每天上午 10:30(Asia/Shanghai)自动运行:
 
 ```cron
-30 10 * * * cd /home/zhn/.openclaw/workspace/skills/robdaily/arxiv-digest && python3 scripts/run_daily.py --publish-discord --publish-hugo >> logs/robotdaily.log 2>&1
+30 10 * * * cd /home/zhn/.openclaw/workspace/skills/robdaily/arxiv-digest && python3 scripts/run_daily.py --publish-hugo --send-discord-link >> logs/robotdaily.log 2>&1
+```
+
+## Discord 消息示例
+
+推送消息格式:
+
+```
+📰 RobotDaily 2026-03-16
+
+今日精选 8 篇论文:
+• 具身智能:3 篇
+• 表征学习:3 篇  
+• 强化学习:2 篇
+
+🔗 查看完整简报:
+https://indigofloyd.space/ai-daily/2026-03-16/
+
+祝有充实的一天!✨
 ```
 
 ## 相关文档
@@ -90,6 +110,30 @@ DISCORD_THREAD_AUTO_ARCHIVE_MIN=10080
 - [筛选与推送策略](references/selection-and-delivery.md) - 论文评分和推送规则
 - [Hugo 部署说明](../../deploy/README.md) - Docker 部署方案
 
+## Hugo 集成
+
+Hugo 站点配置:
+- **自动监控**:`watch-hugo.sh` 守护进程每 30 秒检测文件变化
+- **自动编译**:Hugo server 使用 `--watch` 模式实时重新编译
+- **自动部署**:`git-sync-hugo.sh` 守护进程每 30 秒检查远程仓库更新
+- **Live Reload**:浏览器自动刷新(livereload.js)
+
+访问地址:`http://localhost:9080/ai-daily/YYYY-MM-DD/`
+
+## Discord 链接推送
+
+使用 `scripts/send_discord_link.py` 发送简短消息:
+
+```bash
+python3 scripts/send_discord_link.py \
+  --date 2026-03-16 \
+  --total 8 \
+  --embodied 3 \
+  --representation 3 \
+  --reinforcement 2 \
+  --hugo-url https://indigofloyd.space/ai-daily/2026-03-16/
+```
+
 ## 维护
 
 ### 查看日志
@@ -109,3 +153,20 @@ ls -la arxiv-digest/output/$(date +%Y-%m-%d)/
 ```bash
 cd site && hugo --quiet
 ```
+
+### 检查守护进程
+
+```bash
+# Git 同步守护进程
+ps aux | grep git-sync-hugo | grep -v grep
+
+# Hugo 监听守护进程
+ps aux | grep watch-hugo.sh | grep -v grep
+```
+
+### 重启 Hugo
+
+```bash
+cd /home/zhn/.openclaw/workspace/skills/robdaily/deploy
+docker compose restart hugo-personal-site
+```

+ 11 - 19
arxiv-digest/scripts/run_daily.py

@@ -57,8 +57,8 @@ def main() -> None:
     parser.add_argument("--max-results-per-domain", type=int, default=40)
     parser.add_argument("--models", default="")
     parser.add_argument("--skip-enrich", action="store_true")
-    parser.add_argument("--publish-discord", action="store_true")
     parser.add_argument("--publish-hugo", action="store_true")
+    parser.add_argument("--send-discord-link", action="store_true")
     parser.add_argument("--hugo-content-dir", default="")
     parser.add_argument("--dry-run", action="store_true")
     args = parser.parse_args()
@@ -124,26 +124,18 @@ def main() -> None:
         manifest["hugo_target"] = str(hugo_target)
         write_json(paths["manifest_json"], manifest)
 
-    if args.publish_discord:
-        publisher = DiscordPublisher(
-            openclaw_bin=env.get("OPENCLAW_BIN", "openclaw"),
-            account_id=env.get("DISCORD_ACCOUNT_ID", "codex"),
-            mode=env.get("DISCORD_DELIVERY_MODE", "thread"),
-            guild_id=env.get("DISCORD_GUILD_ID", ""),
-            parent_channel_id=env.get("DISCORD_PARENT_CHANNEL_ID", ""),
-            target_channel_id=env.get("DISCORD_TARGET_CHANNEL_ID", ""),
-            target_channel_name=env.get("DISCORD_TARGET_CHANNEL_NAME", ""),
-            category_id=env.get("DISCORD_CATEGORY_ID", ""),
-            bot_token=env.get("DISCORD_BOT_TOKEN", ""),
-            thread_auto_archive_min=int(env.get("DISCORD_THREAD_AUTO_ARCHIVE_MIN", "10080")),
+    if args.send_discord_link:
+        from send_discord_link import send_digest_link
+        hugo_url = env.get("HUGO_SITE_URL", "https://indigofloyd.space")
+        date_slug = now_local().strftime("%Y-%m-%d")
+        link_url = f"{hugo_url}/ai-daily/{date_slug}/"
+        
+        send_digest_link(
+            enriched=enriched,
+            hugo_url=link_url,
             dry_run=args.dry_run,
         )
-        target = publish_digest(
-            enriched,
-            markdown_path=str(paths["digest_md"]),
-            publisher=publisher,
-        )
-        manifest["discord_target"] = target
+        manifest["discord_link_sent"] = True
         write_json(paths["manifest_json"], manifest)
 
     print(json.dumps(manifest, ensure_ascii=False, indent=2))

+ 98 - 0
arxiv-digest/scripts/send_discord_link.py

@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+"""Send brief link message to Discord RobotDaily channel."""
+
+from __future__ import annotations
+
+import argparse
+import os
+import sys
+from pathlib import Path
+
+from utils import load_env, log
+
+
+def send_digest_link(enriched: dict, hugo_url: str, dry_run: bool = False) -> str:
+    """Send brief link message to Discord RobotDaily channel."""
+    
+    counts = enriched.get("counts", {})
+    embodied = counts.get("embodied", 0)
+    representation = counts.get("representation", 0)
+    reinforcement = counts.get("reinforcement", 0)
+    total = embodied + representation + reinforcement
+    
+    message = f"""📰 RobotDaily {enriched.get('date', 'today')}
+
+今日精选 {total} 篇论文:
+• 具身智能:{embodied} 篇
+• 表征学习:{representation} 篇  
+• 强化学习:{reinforcement} 篇
+
+🔗 查看完整简报:
+{hugo_url}
+
+祝有充实的一天!✨"""
+
+    if dry_run:
+        log(f"[DRY RUN] 将要发送的消息:")
+        log(message)
+        return message
+
+    # 读取环境配置
+    env = load_env()
+    discord_token = env.get("DISCORD_BOT_TOKEN", "")
+    channel_id = env.get("DISCORD_ROBOTDAILY_CHANNEL_ID", "")
+    
+    if not discord_token:
+        log("❌ 未设置 DISCORD_BOT_TOKEN")
+        return ""
+    
+    if not channel_id:
+        log("❌ 未设置 DISCORD_ROBOTDAILY_CHANNEL_ID")
+        return ""
+
+    # Discord API 发送消息
+    import requests
+    
+    url = f"https://discord.com/api/v10/channels/{channel_id}/messages"
+    headers = {
+        "Authorization": f"Bot {discord_token}",
+        "Content-Type": "application/json",
+    }
+    
+    data = {"content": message}
+    
+    try:
+        response = requests.post(url, json=data, headers=headers, timeout=10)
+        response.raise_for_status()
+        log(f"✅ 消息已发送到 Discord 频道 {channel_id}")
+        return message
+    except requests.exceptions.RequestException as e:
+        log(f"❌ Discord 消息发送失败:{e}")
+        return ""
+
+
+def main():
+    parser = argparse.ArgumentParser(description="Send brief link message to Discord")
+    parser.add_argument("--hugo-url", required=True, help="Hugo 网站链接")
+    parser.add_argument("--embodied", type=int, required=True, help="具身智能论文数量")
+    parser.add_argument("--representation", type=int, required=True, help="表征学习论文数量")
+    parser.add_argument("--reinforcement", type=int, required=True, help="强化学习论文数量")
+    parser.add_argument("--total", type=int, required=True, help="总论文数量")
+    parser.add_argument("--date", required=True, help="日期")
+    parser.add_argument("--dry-run", action="store_true", help="dry run 模式")
+    args = parser.parse_args()
+    
+    enriched = {
+        "date": args.date,
+        "counts": {
+            "embodied": args.embodied,
+            "representation": args.representation,
+            "reinforcement": args.reinforcement,
+        }
+    }
+    
+    send_digest_link(enriched, args.hugo_url, args.dry_run)
+
+
+if __name__ == "__main__":
+    main()

文件差異過大導致無法顯示
+ 1 - 1
site/public/search/index.html


部分文件因文件數量過多而無法顯示