diff --git a/.github/workflows/crawler.yml b/.github/workflows/crawler.yml
index e7d4450..5714814 100644
--- a/.github/workflows/crawler.yml
+++ b/.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
diff --git a/README-EN.md b/README-EN.md
index 265f043..1c56aab 100644
--- a/README-EN.md
+++ b/README-EN.md
@@ -8,12 +8,13 @@
-
+
+
[](https://github.com/sansan0/TrendRadar/stargazers)
[](https://github.com/sansan0/TrendRadar/network/members)
[](LICENSE)
-[](https://github.com/sansan0/TrendRadar)
+[](https://github.com/sansan0/TrendRadar)
[](https://github.com/sansan0/TrendRadar)
[](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
-
+[](https://share.302.ai/mEOUzG)
-
+
-### 💰 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
-
-[](https://share.302.ai/mEOUzG)
-
+
+> 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 👇
+
+
+
+[](https://shandianshuo.cn) [](https://shandianshuo.cn)
+
+
+
+
+
+
---
diff --git a/README.md b/README.md
index ef605d1..489986d 100644
--- a/README.md
+++ b/README.md
@@ -1,19 +1,20 @@
-
+
🚀 最快
30秒部署的热点助手 —— 告别无效刷屏,只看真正关心的新闻资讯

-

+

+

[](https://github.com/sansan0/TrendRadar/stargazers)
[](https://github.com/sansan0/TrendRadar/network/members)
[](LICENSE)
-[](https://github.com/sansan0/TrendRadar)
+[](https://github.com/sansan0/TrendRadar)
[](https://github.com/sansan0/TrendRadar)
[](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`
+
+
+
+👉 点击展开:历史更新
+
+
### 2025/11/23 - v3.2.0
**🎯 新增高级定制功能**
@@ -351,10 +379,6 @@ GitHub 一键 Fork 即可使用,无需编程基础。
- 优化查询今日新闻却可能错误返回过去日期的情况
-
-👉 点击展开:历史更新
-
-
### 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 文件增加了一个【必须词】功能,使用 + 号
+
+ 👉 点击展开:Bark 推送(iOS 专属,简洁高效)
+
+
+ **GitHub Secret 配置(⚠️ Name 名称必须严格一致):**
+ - **Name(名称)**:`BARK_URL`(请复制粘贴此名称,不要手打)
+ - **Secret(值)**:你的 Bark 推送 URL
+
+
+
+ **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)
+
+
+
3. **手动测试新闻推送**:
> 💡 **完成第1-2步后,请立即测试!** 测试成功后再根据需要调整配置(第4步)。
@@ -2206,21 +2290,19 @@ MCP Inspector 是官方调试工具,用于测试 MCP 连接:
+[](https://share.302.ai/mEOUzG)
-
+
-### 💰 302.AI 新用户福利
-
-> 领取的 1 美元可用于调用各种 AI 大模型(如 Claude、GPT 等)
-> 本项目 AI 分析功能需配置大模型使用,配置教程详见 [AI 智能分析](#-ai-智能分析)
-
-[](https://share.302.ai/mEOUzG)
----
-
+> 每天追踪这么多热点,写报告、回复消息是否让手腕疲惫?
+> 试试「闪电说」AI 语音输入法 —— 用说的,比打字快 4 倍 ⚡ 。从看热点到输出内容,让效率翻倍 👇
+
+
+
+[](https://shandianshuo.cn) [](https://shandianshuo.cn)
+
+
+
+
+
+
+
+---
### 项目相关
@@ -2342,4 +2436,4 @@ GPL-3.0 License
[🔝 回到顶部](#trendradar)
-
+
\ No newline at end of file
diff --git a/_image/ai3.png b/_image/ai3.png
index ee77a6b..728c1bd 100644
Binary files a/_image/ai3.png and b/_image/ai3.png differ
diff --git a/_image/banner-shandianshuo.png b/_image/banner-shandianshuo.png
new file mode 100644
index 0000000..94ad566
Binary files /dev/null and b/_image/banner-shandianshuo.png differ
diff --git a/_image/shandianshuo.png b/_image/shandianshuo.png
new file mode 100644
index 0000000..3c1039f
Binary files /dev/null and b/_image/shandianshuo.png differ
diff --git a/config/config.yaml b/config/config.yaml
index c53fde6..8441807 100644
--- a/config/config.yaml
+++ b/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:
diff --git a/docker/docker-compose-build.yml b/docker/docker-compose-build.yml
index bff1995..c241068 100644
--- a/docker/docker-compose-build.yml
+++ b/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}
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index 4ba55e1..6124cfc 100644
--- a/docker/docker-compose.yml
+++ b/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}
diff --git a/main.py b/main.py
index c722454..62d12dd 100644
--- a/main.py
+++ b/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"],
]
)
diff --git a/version b/version
index a4f52a5..0fa4ae4 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-3.2.0
\ No newline at end of file
+3.3.0
\ No newline at end of file