Bläddra i källkod

v3.3.0: 新增 iOS 平台的 bark 推送,修复 ntfy 配置问题

sansan 5 månader sedan
förälder
incheckning
bf6a3d760e

+ 1 - 0
.github/workflows/crawler.yml

@@ -62,6 +62,7 @@ jobs:
           NTFY_TOPIC: ${{ secrets.NTFY_TOPIC }}
           NTFY_SERVER_URL: ${{ secrets.NTFY_SERVER_URL }}
           NTFY_TOKEN: ${{ secrets.NTFY_TOKEN }}
+          BARK_URL: ${{ secrets.BARK_URL }}
           GITHUB_ACTIONS: true
         run: python main.py
 

+ 50 - 12
README-EN.md

@@ -8,12 +8,13 @@
 
 <a href="https://trendshift.io/repositories/14726" target="_blank"><img src="https://trendshift.io/api/badge/repositories/14726" alt="sansan0%2FTrendRadar | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
 
-<a href="https://share.302.ai/mEOUzG" target="_blank"><img src="_image/302ai.png" alt="302.AI logo" height="60"/></a>
+<a href="https://share.302.ai/mEOUzG" target="_blank"><img src="_image/302ai.png" alt="302.AI logo" height="52"/></a>
+<a href="https://shandianshuo.cn" target="_blank"><img src="_image/shandianshuo.png" alt="FlashSpeak logo" height="55"/></a>
 
 [![GitHub Stars](https://img.shields.io/github/stars/sansan0/TrendRadar?style=flat-square&logo=github&color=yellow)](https://github.com/sansan0/TrendRadar/stargazers)
 [![GitHub Forks](https://img.shields.io/github/forks/sansan0/TrendRadar?style=flat-square&logo=github&color=blue)](https://github.com/sansan0/TrendRadar/network/members)
 [![License](https://img.shields.io/badge/license-GPL--3.0-blue.svg?style=flat-square)](LICENSE)
-[![Version](https://img.shields.io/badge/version-v3.2.0-blue.svg)](https://github.com/sansan0/TrendRadar)
+[![Version](https://img.shields.io/badge/version-v3.3.0-blue.svg)](https://github.com/sansan0/TrendRadar)
 [![MCP](https://img.shields.io/badge/MCP-v1.0.2-green.svg)](https://github.com/sansan0/TrendRadar)
 
 [![WeWork](https://img.shields.io/badge/WeWork-Notification-00D4AA?style=flat-square)](https://work.weixin.qq.com/)
@@ -258,11 +259,35 @@ Transform from "algorithm recommendation captivity" to "actively getting the inf
 ## 📝 Changelog
 
 >**Upgrade Instructions**:
-- **Tip**: Do NOT update this project via **Sync fork**. Check [Changelog](#changelog) to understand specific [Upgrade Methods] and [Features]
+- **📌 Check Latest Updates**: **[Original Repository Changelog](https://github.com/sansan0/TrendRadar?tab=readme-ov-file#-changelog)**
+- **Tip**: Do NOT update this project via **Sync fork**. Check [Changelog] to understand specific [Upgrade Methods] and [Features]
 - **Minor Version Update**: Upgrading from v2.x to v2.y, replace `main.py` in your forked repo with the latest version
 - **Major Version Upgrade**: Upgrading from v1.x to v2.y, recommend deleting existing fork and re-forking to save effort and avoid config conflicts
 
 
+### 2025/11/24 - v3.3.0
+
+**🎉 Added Bark Push Support**
+
+1. **iOS Exclusive Push Channel**
+   - Supports Bark push (based on APNs, iOS platform)
+   - Free, open-source, clean, efficient, ad-free
+   - Supports both official server and self-hosted server
+
+2. **Multiple Deployment Methods**
+   - GitHub Actions: Configure `BARK_URL` Secret
+   - Docker: Environment variable `BARK_URL`
+   - Local: `config/config.yaml` configuration file
+
+> 📖 **Detailed Configuration Tutorial**: [Quick Start - Bark Push](#-quick-start)
+
+**🐛 Bug Fix**
+- Fixed issue where `ntfy_server_url` in `config.yaml` was ignored ([#345](https://github.com/sansan0/TrendRadar/issues/345))
+
+**🔧 Upgrade Instructions**:
+- **GitHub Fork Users**: Update `main.py`, `config/config.yaml`, `.github/workflows/crawler.yml`
+
+
 ### 2025/11/23 - v3.2.0
 
 **🎯 New Advanced Customization Features**
@@ -2078,23 +2103,19 @@ Any client supporting Model Context Protocol can connect to TrendRadar:
 
 ## 🪄 Sponsors
 
+### 🤖 302.AI - Enterprise AI Resource Platform
+
 > **302.AI** is a pay-as-you-go enterprise-level AI resource platform
 > Providing the latest and most comprehensive **AI models** and **APIs** on the market, plus various ready-to-use online AI applications
 
-
 <div align="center">
 
+[![Register & Claim](https://img.shields.io/badge/Register_302.AI-Claim_$1_Credit-8B5CF6?style=for-the-badge&logo=openai&logoColor=white)](https://share.302.ai/mEOUzG)
 <a href="https://share.302.ai/mEOUzG" target="_blank">
-  <img src="_image/banner-302ai-en.jpg" alt="302.AI" width="800"/>
+  <img src="_image/banner-302ai-en.jpg" alt="302.AI" width="700"/>
 </a>
 </div>
 
-### 💰 302.AI New User Benefits
-
-> The $1 credit can be used to call various AI models (such as Claude, GPT, etc.)   
-> This project's AI analysis features require AI model integration. See [AI Analysis Deployment](#-ai-analysis-deployment) for configuration tutorial
-
-[![Register & Claim](https://img.shields.io/badge/Register_302.AI-Claim_$1_Free_Credit-FF6B6B?style=for-the-badge&logo=openai&logoColor=white)](https://share.302.ai/mEOUzG)
 
 <details id="sponsor-tutorial">
 <summary><b>👉 Click to expand: 302.AI Usage Tutorial</b></summary>
@@ -2126,7 +2147,24 @@ A: You can top up as needed, pay-as-you-go. Major AI model prices are now relati
 
 </details>
 
-<br>
+
+> Tracking so many trending topics daily, writing reports, replying messages making your wrists tired?
+>
+> Try「FlashSpeak」AI Voice Input - Speak instead of type, 4x faster ⚡
+>
+> On-device Model • Lightning Fast • Absolute Privacy • Mac/Win Support
+>
+> From reading trends to content output, double your efficiency 👇
+
+<div align="center">
+
+[![Mac Download](https://img.shields.io/badge/Mac-Free_Download-FF6B6B?style=for-the-badge&logo=apple&logoColor=white)](https://shandianshuo.cn) [![Windows Download](https://img.shields.io/badge/Windows-Free_Download-FF6B6B?style=for-the-badge&logo=lightning&logoColor=white)](https://shandianshuo.cn)
+<a href="https://shandianshuo.cn" target="_blank">
+  <img src="_image/banner-shandianshuo.png" alt="FlashSpeak" width="700"/>
+</a>
+</div>
+
+
 
 ---
 

+ 113 - 19
README.md

@@ -1,19 +1,20 @@
 <div align="center" id="trendradar">
 
 <a href="https://github.com/sansan0/TrendRadar" title="TrendRadar">
-  <img src="/_image/banner.webp" alt="TrendRadar Banner" width="90%">
+  <img src="/_image/banner.webp" alt="TrendRadar Banner" width="80%">
 </a>
 
 🚀 最快<strong>30秒</strong>部署的热点助手 —— 告别无效刷屏,只看真正关心的新闻资讯
 
 <a href="https://trendshift.io/repositories/14726" target="_blank"><img src="https://trendshift.io/api/badge/repositories/14726" alt="sansan0%2FTrendRadar | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
 
-<a href="https://share.302.ai/mEOUzG" target="_blank"><img src="_image/302ai.png" alt="302.AI logo" height="60"/></a>
+<a href="https://share.302.ai/mEOUzG" target="_blank"><img src="_image/302ai.png" alt="302.AI logo" height="52"/></a>
+<a href="https://shandianshuo.cn" target="_blank"><img src="_image/shandianshuo.png" alt="闪电说 logo" height="55"/></a>
 
 [![GitHub Stars](https://img.shields.io/github/stars/sansan0/TrendRadar?style=flat-square&logo=github&color=yellow)](https://github.com/sansan0/TrendRadar/stargazers)
 [![GitHub Forks](https://img.shields.io/github/forks/sansan0/TrendRadar?style=flat-square&logo=github&color=blue)](https://github.com/sansan0/TrendRadar/network/members)
 [![License](https://img.shields.io/badge/license-GPL--3.0-blue.svg?style=flat-square)](LICENSE)
-[![Version](https://img.shields.io/badge/version-v3.2.0-blue.svg)](https://github.com/sansan0/TrendRadar)
+[![Version](https://img.shields.io/badge/version-v3.3.0-blue.svg)](https://github.com/sansan0/TrendRadar)
 [![MCP](https://img.shields.io/badge/MCP-v1.0.2-green.svg)](https://github.com/sansan0/TrendRadar)
 
 [![企业微信通知](https://img.shields.io/badge/企业微信-通知-00D4AA?style=flat-square)](https://work.weixin.qq.com/)
@@ -327,6 +328,33 @@ GitHub 一键 Fork 即可使用,无需编程基础。
 - **大版本升级**:从 v1.x 升级到 v2.y,建议删除现有 fork 后重新 fork,这样更省力且避免配置冲突
 
 
+### 2025/11/24 - v3.3.0
+
+**🎉 新增 Bark 推送支持**
+
+1. **iOS 专属推送渠道**
+   - 支持 Bark 推送(基于 APNs,iOS 平台)
+   - 免费开源,简洁高效,无广告干扰
+   - 支持官方服务器和自建服务器两种方式
+
+2. **多种部署方式**
+   - GitHub Actions:配置 `BARK_URL` Secret
+   - Docker:环境变量 `BARK_URL`
+   - 本地运行:`config/config.yaml` 配置文件
+
+> 📖 **详细配置教程**:[快速开始 - Bark 推送](#-快速开始)
+
+**🐛 Bug 修复**
+- 修复 `config.yaml` 中 `ntfy_server_url` 配置不生效的问题 ([#345](https://github.com/sansan0/TrendRadar/issues/345))
+
+**🔧 升级说明**:
+- **GitHub Fork 用户**:更新 `main.py`、`config/config.yaml`、`.github/workflows/crawler.yml`
+
+
+<details>
+<summary>👉 点击展开:<strong>历史更新</strong></summary>
+
+
 ### 2025/11/23 - v3.2.0
 
 **🎯 新增高级定制功能**
@@ -351,10 +379,6 @@ GitHub 一键 Fork 即可使用,无需编程基础。
   - 优化查询今日新闻却可能错误返回过去日期的情况
 
 
-<details>
-<summary>👉 点击展开:<strong>历史更新</strong></summary>
-
-
 ### 2025/11/22 - v3.1.1
 
 - **修复数据异常导致的崩溃问题**:解决部分用户在 GitHub Actions 环境中遇到的 `'float' object has no attribute 'lower'` 错误
@@ -938,6 +962,7 @@ frequency_words.txt 文件增加了一个【必须词】功能,使用 + 号
    | **新浪邮箱** | sina.com | smtp.sina.com | 465 | SSL |
    | **搜狐邮箱** | sohu.com | smtp.sohu.com | 465 | SSL |
    | **天翼邮箱** | 189.cn | smtp.189.cn | 465 | SSL |
+   | **阿里云邮箱** | aliyun.com | smtp.aliyun.com | 465 | TLS |
 
    > **自动识别**:使用以上邮箱时,无需手动配置 `EMAIL_SMTP_SERVER` 和 `EMAIL_SMTP_PORT`,系统会自动识别。
    >
@@ -947,6 +972,7 @@ frequency_words.txt 文件增加了一个【必须词】功能,使用 + 号
    >
    > **特别感谢**:
    > - 感谢 [@DYZYD](https://github.com/DYZYD) 贡献天翼邮箱(189.cn)配置并完成自发自收测试 ([#291](https://github.com/sansan0/TrendRadar/issues/291))
+   > - 感谢 [@longzhenren](https://github.com/longzhenren) 贡献阿里云邮箱(aliyun.com)配置并完成测试 ([#344](https://github.com/sansan0/TrendRadar/issues/344))
 
    **常见邮箱设置:**
 
@@ -1098,6 +1124,64 @@ frequency_words.txt 文件增加了一个【必须词】功能,使用 + 号
 
    </details>
 
+   <details>
+   <summary>👉 点击展开:<strong>Bark 推送</strong>(iOS 专属,简洁高效)</summary>
+   <br>
+
+   **GitHub Secret 配置(⚠️ Name 名称必须严格一致):**
+   - **Name(名称)**:`BARK_URL`(请复制粘贴此名称,不要手打)
+   - **Secret(值)**:你的 Bark 推送 URL
+
+   <br>
+
+   **Bark 简介:**
+
+   Bark 是一款 iOS 平台的免费开源推送工具,特点是简单、快速、无广告。
+
+   **使用方式:**
+
+   ### 方式一:使用官方服务器(推荐新手) 🆓
+
+   1. **下载 Bark App**:
+      - iOS:[App Store](https://apps.apple.com/cn/app/bark-给你的手机发推送/id1403753865)
+
+   2. **获取推送 URL**:
+      - 打开 Bark App
+      - 复制首页显示的推送 URL(格式如:`https://api.day.app/your_device_key`)
+      - 将 URL 配置到 GitHub Secrets 中的 `BARK_URL`
+
+   ### 方式二:自建服务器(完全隐私控制) 🔒
+
+   **适合人群**:有服务器、追求完全隐私、技术能力强
+
+   **Docker 一键部署**:
+   ```bash
+   docker run -d \
+     --name bark-server \
+     -p 8080:8080 \
+     finab/bark-server
+   ```
+
+   **配置 TrendRadar**:
+   ```yaml
+   BARK_URL: http://your-server-ip:8080/your_device_key
+   ```
+
+   ---
+
+   **注意事项:**
+   - ✅ Bark 使用 APNs 推送,单条消息最大 4KB
+   - ✅ 支持自动分批推送,无需担心消息过长
+   - ✅ 推送格式为纯文本(自动去除 Markdown 语法)
+   - ⚠️ 仅支持 iOS 平台
+
+   **相关链接:**
+   - [Bark 官方网站](https://bark.day.app/)
+   - [Bark GitHub 仓库](https://github.com/Finb/Bark)
+   - [Bark Server 自建教程](https://github.com/Finb/bark-server)
+
+   </details>
+
 3. **手动测试新闻推送**:
 
    > 💡 **完成第1-2步后,请立即测试!** 测试成功后再根据需要调整配置(第4步)。
@@ -2206,21 +2290,19 @@ MCP Inspector 是官方调试工具,用于测试 MCP 连接:
 
 <div align="center">
 
+[![注册领取](https://img.shields.io/badge/注册_302.AI-领取_1_美元免费测试额度-8B5CF6?style=for-the-badge&logo=openai&logoColor=white)](https://share.302.ai/mEOUzG)
 <a href="https://share.302.ai/mEOUzG" target="_blank">
-  <img src="_image/banner-302ai-zh.jpg" alt="302.AI" width="800"/>
+  <img src="_image/banner-302ai-zh.jpg" alt="302.AI" width="700"/>
 </a>
 </div>
 
-### 💰 302.AI 新用户福利
-
-> 领取的 1 美元可用于调用各种 AI 大模型(如 Claude、GPT 等)      
-> 本项目 AI 分析功能需配置大模型使用,配置教程详见 [AI 智能分析](#-ai-智能分析)
-
-[![注册领取](https://img.shields.io/badge/注册_302.AI-领取_1_美元免费测试额度-FF6B6B?style=for-the-badge&logo=openai&logoColor=white)](https://share.302.ai/mEOUzG)
 
 <details id="sponsor-tutorial">
 <summary>👉 点击展开:<b>302.AI 使用教程</b></summary>
+<br>
 
+> 领取的 1 美元可用于调用各种 AI 大模型(如 Claude、GPT 等)
+> 本项目 AI 分析功能需配置大模型使用,配置教程详见 [AI 智能分析](#-ai-智能分析)
 
 ### 第 1 步:获取 API Key
 
@@ -2240,17 +2322,29 @@ MCP Inspector 是官方调试工具,用于测试 MCP 连接:
 **提示:** Cherry Studio 已原生集成 302.AI,配置后即可看到完整模型列表。
 
 
-**Q: 1 美元免费额度能用多久?**    
+**Q: 1 美元免费额度能用多久?**
 A: 取决于使用频率和模型选择,可以进行多次测试体验。
 
-**Q: 免费额度用完后怎么办?**    
+**Q: 免费额度用完后怎么办?**
 A: 可以按需充值,按量付费。目前大厂模型价格已相对亲民。
 
 </details>
 
----
 
-<br>
+> 每天追踪这么多热点,写报告、回复消息是否让手腕疲惫?        
+> 试试「闪电说」AI 语音输入法 —— 用说的,比打字快 4 倍 ⚡ 。从看热点到输出内容,让效率翻倍 👇
+
+<div align="center">
+
+[![Mac下载](https://img.shields.io/badge/Mac-免费下载-FF6B6B?style=for-the-badge&logo=apple&logoColor=white)](https://shandianshuo.cn) [![Windows下载](https://img.shields.io/badge/Windows-免费下载-FF6B6B?style=for-the-badge&logo=lightning&logoColor=white)](https://shandianshuo.cn)
+<a href="https://shandianshuo.cn" target="_blank">
+  <img src="_image/banner-shandianshuo.png" alt="闪电说" width="700"/>
+</a>
+</div>
+
+
+
+---
 
 ### 项目相关
 
@@ -2342,4 +2436,4 @@ GPL-3.0 License
 
 [🔝 回到顶部](#trendradar)
 
-</div>
+</div>

BIN
_image/ai3.png


BIN
_image/banner-shandianshuo.png


BIN
_image/shandianshuo.png


+ 2 - 0
config/config.yaml

@@ -35,6 +35,7 @@ notification:
   message_batch_size: 4000 # 消息分批大小(字节)(这个配置别动)
   dingtalk_batch_size: 20000 # 钉钉消息分批大小(字节)(这个配置也别动)
   feishu_batch_size: 29000 # 飞书消息分批大小(字节)
+  bark_batch_size: 3600 # Bark消息分批大小(字节)
   batch_send_interval: 3 # 批次发送间隔(秒)
   feishu_message_separator: "━━━━━━━━━━━━━━━━━━━" # feishu 消息分割线
 
@@ -84,6 +85,7 @@ notification:
     ntfy_server_url: "https://ntfy.sh" # ntfy服务器地址,默认使用公共服务,可改为自托管地址
     ntfy_topic: "" # ntfy主题名称
     ntfy_token: "" # ntfy访问令牌(可选,用于私有主题)
+    bark_url: "" # Bark推送URL(格式:https://api.day.app/your_device_key 或自建服务器地址)
 
 # 用于让关注度更高的新闻在更前面显示,即用算法重新组合不同平台的热搜排序形成你侧重的热搜,合起来是 1 就行
 weight:

+ 2 - 0
docker/docker-compose-build.yml

@@ -41,6 +41,8 @@ services:
       - NTFY_SERVER_URL=${NTFY_SERVER_URL:-https://ntfy.sh}
       - NTFY_TOPIC=${NTFY_TOPIC:-}
       - NTFY_TOKEN=${NTFY_TOKEN:-}
+      # Bark配置
+      - BARK_URL=${BARK_URL:-}
       # 运行模式
       - CRON_SCHEDULE=${CRON_SCHEDULE:-*/5 * * * *}
       - RUN_MODE=${RUN_MODE:-cron}

+ 2 - 0
docker/docker-compose.yml

@@ -39,6 +39,8 @@ services:
       - NTFY_SERVER_URL=${NTFY_SERVER_URL:-https://ntfy.sh}
       - NTFY_TOPIC=${NTFY_TOPIC:-}
       - NTFY_TOKEN=${NTFY_TOKEN:-}
+      # Bark配置
+      - BARK_URL=${BARK_URL:-}
       # 运行模式
       - CRON_SCHEDULE=${CRON_SCHEDULE:-*/5 * * * *}
       - RUN_MODE=${RUN_MODE:-cron}

+ 141 - 4
main.py

@@ -20,7 +20,7 @@ import requests
 import yaml
 
 
-VERSION = "3.2.0"
+VERSION = "3.3.0"
 
 
 # === SMTP邮件配置 ===
@@ -50,6 +50,8 @@ SMTP_CONFIGS = {
     "sohu.com": {"server": "smtp.sohu.com", "port": 465, "encryption": "SSL"},
     # 天翼邮箱(使用 SSL)
     "189.cn": {"server": "smtp.189.cn", "port": 465, "encryption": "SSL"},
+    # 阿里云邮箱(使用 TLS)
+    "aliyun.com": {"server": "smtp.aliyun.com", "port": 465, "encryption": "TLS"},
 }
 
 
@@ -97,6 +99,7 @@ def load_config():
             "dingtalk_batch_size", 20000
         ),
         "FEISHU_BATCH_SIZE": config_data["notification"].get("feishu_batch_size", 29000),
+        "BARK_BATCH_SIZE": config_data["notification"].get("bark_batch_size", 3600),
         "BATCH_SEND_INTERVAL": config_data["notification"]["batch_send_interval"],
         "FEISHU_MESSAGE_SEPARATOR": config_data["notification"][
             "feishu_message_separator"
@@ -182,9 +185,11 @@ def load_config():
     ).strip() or webhooks.get("email_smtp_port", "")
 
     # ntfy配置
-    config["NTFY_SERVER_URL"] = os.environ.get(
-        "NTFY_SERVER_URL", "https://ntfy.sh"
-    ).strip() or webhooks.get("ntfy_server_url", "https://ntfy.sh")
+    config["NTFY_SERVER_URL"] = (
+        os.environ.get("NTFY_SERVER_URL", "").strip()
+        or webhooks.get("ntfy_server_url")
+        or "https://ntfy.sh"
+    )
     config["NTFY_TOPIC"] = os.environ.get("NTFY_TOPIC", "").strip() or webhooks.get(
         "ntfy_topic", ""
     )
@@ -192,6 +197,11 @@ def load_config():
         "ntfy_token", ""
     )
 
+    # Bark配置
+    config["BARK_URL"] = os.environ.get("BARK_URL", "").strip() or webhooks.get(
+        "bark_url", ""
+    )
+
     # 输出配置来源信息
     notification_sources = []
     if config["FEISHU_WEBHOOK_URL"]:
@@ -217,6 +227,10 @@ def load_config():
         server_source = "环境变量" if os.environ.get("NTFY_SERVER_URL") else "配置文件"
         notification_sources.append(f"ntfy({server_source})")
 
+    if config["BARK_URL"]:
+        bark_source = "环境变量" if os.environ.get("BARK_URL") else "配置文件"
+        notification_sources.append(f"Bark({bark_source})")
+
     if notification_sources:
         print(f"通知渠道配置来源: {', '.join(notification_sources)}")
     else:
@@ -3397,6 +3411,7 @@ def send_to_notifications(
     ntfy_server_url = CONFIG["NTFY_SERVER_URL"]
     ntfy_topic = CONFIG["NTFY_TOPIC"]
     ntfy_token = CONFIG.get("NTFY_TOKEN", "")
+    bark_url = CONFIG["BARK_URL"]
 
     update_info_to_send = update_info if CONFIG["SHOW_VERSION_UPDATE"] else None
 
@@ -3443,6 +3458,17 @@ def send_to_notifications(
             mode,
         )
 
+    # 发送到 Bark
+    if bark_url:
+        results["bark"] = send_to_bark(
+            bark_url,
+            report_data,
+            report_type,
+            update_info_to_send,
+            proxy_url,
+            mode,
+        )
+
     # 发送邮件
     if email_from and email_password and email_to:
         results["email"] = send_to_email(
@@ -4129,6 +4155,116 @@ def send_to_ntfy(
         return False
 
 
+def send_to_bark(
+    bark_url: str,
+    report_data: Dict,
+    report_type: str,
+    update_info: Optional[Dict] = None,
+    proxy_url: Optional[str] = None,
+    mode: str = "daily",
+) -> bool:
+    """发送到Bark(支持分批发送,使用纯文本格式)"""
+    proxies = None
+    if proxy_url:
+        proxies = {"http": proxy_url, "https": proxy_url}
+
+    # 获取分批内容(Bark 限制为 3600 字节以避免 413 错误)
+    batches = split_content_into_batches(
+        report_data, "wework", update_info, max_bytes=CONFIG["BARK_BATCH_SIZE"], mode=mode
+    )
+
+    total_batches = len(batches)
+    print(f"Bark消息分为 {total_batches} 批次发送 [{report_type}]")
+
+    # 反转批次顺序,使得在Bark客户端显示时顺序正确
+    # Bark显示最新消息在上面,所以我们从最后一批开始推送
+    reversed_batches = list(reversed(batches))
+
+    print(f"Bark将按反向顺序推送(最后批次先推送),确保客户端显示顺序正确")
+
+    # 逐批发送(反向顺序)
+    success_count = 0
+    for idx, batch_content in enumerate(reversed_batches, 1):
+        # 计算正确的批次编号(用户视角的编号)
+        actual_batch_num = total_batches - idx + 1
+
+        # 添加批次标识(使用正确的批次编号)
+        if total_batches > 1:
+            batch_header = f"[第 {actual_batch_num}/{total_batches} 批次]\n\n"
+            batch_content = batch_header + batch_content
+
+        # 清理 markdown 语法(Bark 不支持 markdown)
+        plain_content = strip_markdown(batch_content)
+
+        batch_size = len(plain_content.encode("utf-8"))
+        print(
+            f"发送Bark第 {actual_batch_num}/{total_batches} 批次(推送顺序: {idx}/{total_batches}),大小:{batch_size} 字节 [{report_type}]"
+        )
+
+        # 检查消息大小(Bark使用APNs,限制4KB)
+        if batch_size > 4096:
+            print(
+                f"警告:Bark第 {actual_batch_num}/{total_batches} 批次消息过大({batch_size} 字节),可能被拒绝"
+            )
+
+        # 构建JSON payload
+        payload = {
+            "title": report_type,
+            "body": plain_content,
+            "sound": "default",
+            "group": "TrendRadar",
+        }
+
+        try:
+            response = requests.post(
+                bark_url,
+                json=payload,
+                proxies=proxies,
+                timeout=30,
+            )
+
+            if response.status_code == 200:
+                result = response.json()
+                if result.get("code") == 200:
+                    print(f"Bark第 {actual_batch_num}/{total_batches} 批次发送成功 [{report_type}]")
+                    success_count += 1
+                    # 批次间间隔
+                    if idx < total_batches:
+                        time.sleep(CONFIG["BATCH_SEND_INTERVAL"])
+                else:
+                    print(
+                        f"Bark第 {actual_batch_num}/{total_batches} 批次发送失败 [{report_type}],错误:{result.get('message', '未知错误')}"
+                    )
+            else:
+                print(
+                    f"Bark第 {actual_batch_num}/{total_batches} 批次发送失败 [{report_type}],状态码:{response.status_code}"
+                )
+                try:
+                    print(f"错误详情:{response.text}")
+                except:
+                    pass
+
+        except requests.exceptions.ConnectTimeout:
+            print(f"Bark第 {actual_batch_num}/{total_batches} 批次连接超时 [{report_type}]")
+        except requests.exceptions.ReadTimeout:
+            print(f"Bark第 {actual_batch_num}/{total_batches} 批次读取超时 [{report_type}]")
+        except requests.exceptions.ConnectionError as e:
+            print(f"Bark第 {actual_batch_num}/{total_batches} 批次连接错误 [{report_type}]:{e}")
+        except Exception as e:
+            print(f"Bark第 {actual_batch_num}/{total_batches} 批次发送异常 [{report_type}]:{e}")
+
+    # 判断整体发送是否成功
+    if success_count == total_batches:
+        print(f"Bark所有 {total_batches} 批次发送完成 [{report_type}]")
+        return True
+    elif success_count > 0:
+        print(f"Bark部分发送成功:{success_count}/{total_batches} 批次 [{report_type}]")
+        return True  # 部分成功也视为成功
+    else:
+        print(f"Bark发送完全失败 [{report_type}]")
+        return False
+
+
 # === 主分析器 ===
 class NewsAnalyzer:
     """新闻分析器"""
@@ -4241,6 +4377,7 @@ class NewsAnalyzer:
                     and CONFIG["EMAIL_TO"]
                 ),
                 (CONFIG["NTFY_SERVER_URL"] and CONFIG["NTFY_TOPIC"]),
+                CONFIG["BARK_URL"],
             ]
         )
 

+ 1 - 1
version

@@ -1 +1 @@
-3.2.0
+3.3.0