diff --git a/docker/.env b/docker/.env index e290670..9662b7b 100644 --- a/docker/.env +++ b/docker/.env @@ -1,3 +1,33 @@ +# ============================================ +# 核心配置(环境变量优先级 > config.yaml) +# ============================================ + +# 是否启用爬虫 (true/false) +ENABLE_CRAWLER= +# 是否启用通知 (true/false) +ENABLE_NOTIFICATION= +# 报告模式 (all/filtered) +REPORT_MODE= + +# ============================================ +# 推送时间窗口配置 +# ============================================ + +# 是否启用推送时间窗口 (true/false) +PUSH_WINDOW_ENABLED= +# 推送开始时间 (HH:MM 格式,如 08:00) +PUSH_WINDOW_START= +# 推送结束时间 (HH:MM 格式,如 22:00) +PUSH_WINDOW_END= +# 每天只推送一次 (true/false) +PUSH_WINDOW_ONCE_PER_DAY= +# 推送记录保留天数 (数字,如 7) +PUSH_WINDOW_RETENTION_DAYS= + +# ============================================ +# 通知渠道配置 +# ============================================ + # 推送配置 FEISHU_WEBHOOK_URL= TELEGRAM_BOT_TOKEN= @@ -18,7 +48,13 @@ NTFY_TOPIC= # 可选:访问令牌(用于私有主题) NTFY_TOKEN= +# ============================================ # 运行配置 -CRON_SCHEDULE=*/30 * * * * # 定时任务表达式,每 30 分钟执行一次(比如 8点,8点半,9点,9点半这种时间规律执行) -RUN_MODE=cron # 运行模式:cron/once -IMMEDIATE_RUN=true # 启动时立即执行一次 \ No newline at end of file +# ============================================ + +# 定时任务表达式,每 30 分钟执行一次(比如 8点,8点半,9点,9点半这种时间规律执行) +CRON_SCHEDULE=*/30 * * * * +# 运行模式:cron/once +RUN_MODE=cron +# 启动时立即执行一次 +IMMEDIATE_RUN=true \ No newline at end of file diff --git a/docker/docker-compose-build.yml b/docker/docker-compose-build.yml index d818661..5dc69d8 100644 --- a/docker/docker-compose-build.yml +++ b/docker/docker-compose-build.yml @@ -12,19 +12,33 @@ services: environment: - TZ=Asia/Shanghai + # 核心配置 + - ENABLE_CRAWLER=${ENABLE_CRAWLER:-} + - ENABLE_NOTIFICATION=${ENABLE_NOTIFICATION:-} + - REPORT_MODE=${REPORT_MODE:-} + # 推送时间窗口 + - PUSH_WINDOW_ENABLED=${PUSH_WINDOW_ENABLED:-} + - PUSH_WINDOW_START=${PUSH_WINDOW_START:-} + - PUSH_WINDOW_END=${PUSH_WINDOW_END:-} + - PUSH_WINDOW_ONCE_PER_DAY=${PUSH_WINDOW_ONCE_PER_DAY:-} + - PUSH_WINDOW_RETENTION_DAYS=${PUSH_WINDOW_RETENTION_DAYS:-} + # 通知渠道 - FEISHU_WEBHOOK_URL=${FEISHU_WEBHOOK_URL:-} - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN:-} - TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID:-} - DINGTALK_WEBHOOK_URL=${DINGTALK_WEBHOOK_URL:-} - WEWORK_WEBHOOK_URL=${WEWORK_WEBHOOK_URL:-} + # 邮件配置 - EMAIL_FROM=${EMAIL_FROM:-} - EMAIL_PASSWORD=${EMAIL_PASSWORD:-} - EMAIL_TO=${EMAIL_TO:-} - EMAIL_SMTP_SERVER=${EMAIL_SMTP_SERVER:-} - EMAIL_SMTP_PORT=${EMAIL_SMTP_PORT:-} + # ntfy配置 - NTFY_SERVER_URL=${NTFY_SERVER_URL:-https://ntfy.sh} - NTFY_TOPIC=${NTFY_TOPIC:-} - NTFY_TOKEN=${NTFY_TOKEN:-} + # 运行模式 - CRON_SCHEDULE=${CRON_SCHEDULE:-*/5 * * * *} - RUN_MODE=${RUN_MODE:-cron} - IMMEDIATE_RUN=${IMMEDIATE_RUN:-true} diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index c390916..94f47fb 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -10,19 +10,33 @@ services: environment: - TZ=Asia/Shanghai + # 核心配置 + - ENABLE_CRAWLER=${ENABLE_CRAWLER:-} + - ENABLE_NOTIFICATION=${ENABLE_NOTIFICATION:-} + - REPORT_MODE=${REPORT_MODE:-} + # 推送时间窗口 + - PUSH_WINDOW_ENABLED=${PUSH_WINDOW_ENABLED:-} + - PUSH_WINDOW_START=${PUSH_WINDOW_START:-} + - PUSH_WINDOW_END=${PUSH_WINDOW_END:-} + - PUSH_WINDOW_ONCE_PER_DAY=${PUSH_WINDOW_ONCE_PER_DAY:-} + - PUSH_WINDOW_RETENTION_DAYS=${PUSH_WINDOW_RETENTION_DAYS:-} + # 通知渠道 - FEISHU_WEBHOOK_URL=${FEISHU_WEBHOOK_URL:-} - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN:-} - TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID:-} - DINGTALK_WEBHOOK_URL=${DINGTALK_WEBHOOK_URL:-} - WEWORK_WEBHOOK_URL=${WEWORK_WEBHOOK_URL:-} + # 邮件配置 - EMAIL_FROM=${EMAIL_FROM:-} - EMAIL_PASSWORD=${EMAIL_PASSWORD:-} - EMAIL_TO=${EMAIL_TO:-} - EMAIL_SMTP_SERVER=${EMAIL_SMTP_SERVER:-} - EMAIL_SMTP_PORT=${EMAIL_SMTP_PORT:-} + # ntfy配置 - NTFY_SERVER_URL=${NTFY_SERVER_URL:-https://ntfy.sh} - NTFY_TOPIC=${NTFY_TOPIC:-} - NTFY_TOKEN=${NTFY_TOKEN:-} + # 运行模式 - CRON_SCHEDULE=${CRON_SCHEDULE:-*/5 * * * *} - RUN_MODE=${RUN_MODE:-cron} - IMMEDIATE_RUN=${IMMEDIATE_RUN:-true} diff --git a/main.py b/main.py index 6bbb0bd..be42c8a 100644 --- a/main.py +++ b/main.py @@ -20,16 +20,16 @@ import requests import yaml -VERSION = "3.0.4" +VERSION = "3.0.5" # === SMTP邮件配置 === SMTP_CONFIGS = { - # Gmail + # Gmail(使用 STARTTLS) "gmail.com": {"server": "smtp.gmail.com", "port": 587, "encryption": "TLS"}, - # QQ邮箱 - "qq.com": {"server": "smtp.qq.com", "port": 587, "encryption": "TLS"}, - # Outlook + # QQ邮箱(使用 SSL,更稳定) + "qq.com": {"server": "smtp.qq.com", "port": 465, "encryption": "SSL"}, + # Outlook(使用 STARTTLS) "outlook.com": { "server": "smtp-mail.outlook.com", "port": 587, @@ -41,13 +41,13 @@ SMTP_CONFIGS = { "encryption": "TLS", }, "live.com": {"server": "smtp-mail.outlook.com", "port": 587, "encryption": "TLS"}, - # 网易邮箱 - "163.com": {"server": "smtp.163.com", "port": 587, "encryption": "TLS"}, - "126.com": {"server": "smtp.126.com", "port": 587, "encryption": "TLS"}, - # 新浪邮箱 - "sina.com": {"server": "smtp.sina.com", "port": 587, "encryption": "TLS"}, - # 搜狐邮箱 - "sohu.com": {"server": "smtp.sohu.com", "port": 587, "encryption": "TLS"}, + # 网易邮箱(使用 SSL,更稳定) + "163.com": {"server": "smtp.163.com", "port": 465, "encryption": "SSL"}, + "126.com": {"server": "smtp.126.com", "port": 465, "encryption": "SSL"}, + # 新浪邮箱(使用 SSL) + "sina.com": {"server": "smtp.sina.com", "port": 465, "encryption": "SSL"}, + # 搜狐邮箱(使用 SSL) + "sohu.com": {"server": "smtp.sohu.com", "port": 465, "encryption": "SSL"}, } @@ -69,12 +69,19 @@ def load_config(): "VERSION_CHECK_URL": config_data["app"]["version_check_url"], "SHOW_VERSION_UPDATE": config_data["app"]["show_version_update"], "REQUEST_INTERVAL": config_data["crawler"]["request_interval"], - "REPORT_MODE": config_data["report"]["mode"], + "REPORT_MODE": os.environ.get("REPORT_MODE", "").strip() + or config_data["report"]["mode"], "RANK_THRESHOLD": config_data["report"]["rank_threshold"], "USE_PROXY": config_data["crawler"]["use_proxy"], "DEFAULT_PROXY": config_data["crawler"]["default_proxy"], - "ENABLE_CRAWLER": config_data["crawler"]["enable_crawler"], - "ENABLE_NOTIFICATION": config_data["notification"]["enable_notification"], + "ENABLE_CRAWLER": os.environ.get("ENABLE_CRAWLER", "").strip().lower() + in ("true", "1") + if os.environ.get("ENABLE_CRAWLER", "").strip() + else config_data["crawler"]["enable_crawler"], + "ENABLE_NOTIFICATION": os.environ.get("ENABLE_NOTIFICATION", "").strip().lower() + in ("true", "1") + if os.environ.get("ENABLE_NOTIFICATION", "").strip() + else config_data["notification"]["enable_notification"], "MESSAGE_BATCH_SIZE": config_data["notification"]["message_batch_size"], "DINGTALK_BATCH_SIZE": config_data["notification"].get( "dingtalk_batch_size", 20000 @@ -85,23 +92,32 @@ def load_config(): "feishu_message_separator" ], "PUSH_WINDOW": { - "ENABLED": config_data["notification"] + "ENABLED": os.environ.get("PUSH_WINDOW_ENABLED", "").strip().lower() + in ("true", "1") + if os.environ.get("PUSH_WINDOW_ENABLED", "").strip() + else config_data["notification"] .get("push_window", {}) .get("enabled", False), "TIME_RANGE": { - "START": config_data["notification"] + "START": os.environ.get("PUSH_WINDOW_START", "").strip() + or config_data["notification"] .get("push_window", {}) .get("time_range", {}) .get("start", "08:00"), - "END": config_data["notification"] + "END": os.environ.get("PUSH_WINDOW_END", "").strip() + or config_data["notification"] .get("push_window", {}) .get("time_range", {}) .get("end", "22:00"), }, - "ONCE_PER_DAY": config_data["notification"] + "ONCE_PER_DAY": os.environ.get("PUSH_WINDOW_ONCE_PER_DAY", "").strip().lower() + in ("true", "1") + if os.environ.get("PUSH_WINDOW_ONCE_PER_DAY", "").strip() + else config_data["notification"] .get("push_window", {}) .get("once_per_day", True), - "RECORD_RETENTION_DAYS": config_data["notification"] + "RECORD_RETENTION_DAYS": int(os.environ.get("PUSH_WINDOW_RETENTION_DAYS", "0")) + or config_data["notification"] .get("push_window", {}) .get("push_record_retention_days", 7), }, @@ -3724,7 +3740,14 @@ def send_to_email( # 使用自定义 SMTP 配置 smtp_server = custom_smtp_server smtp_port = int(custom_smtp_port) - use_tls = smtp_port == 587 + # 根据端口判断加密方式:465=SSL, 587=TLS + if smtp_port == 465: + use_tls = False # SSL 模式(SMTP_SSL) + elif smtp_port == 587: + use_tls = True # TLS 模式(STARTTLS) + else: + # 其他端口优先尝试 TLS(更安全,更广泛支持) + use_tls = True elif domain in SMTP_CONFIGS: # 使用预设配置 config = SMTP_CONFIGS[domain] diff --git a/readme.md b/readme.md index 2e11bb5..4c1f73e 100644 --- a/readme.md +++ b/readme.md @@ -11,7 +11,7 @@ [![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.0.4-blue.svg)](https://github.com/sansan0/TrendRadar) +[![Version](https://img.shields.io/badge/version-v3.0.5-blue.svg)](https://github.com/sansan0/TrendRadar) [![MCP](https://img.shields.io/badge/MCP-v1.0.1-green.svg)](https://github.com/sansan0/TrendRadar) [![企业微信通知](https://img.shields.io/badge/企业微信-通知-00D4AA?style=flat-square)](https://work.weixin.qq.com/) @@ -47,7 +47,7 @@ - 感谢**关注[公众号](#问题答疑与1元点赞)** 的读者们,你们的留言、点赞、分享和推荐等积极互动让内容更有温度😎。
-👉 点击查看致谢名单 (当前 🔥49🔥 位) +👉 点击查看致谢名单 (当前 🔥53🔥 位) ### 数据支持 @@ -67,6 +67,10 @@ | 点赞人 | 金额 | 日期 | 备注 | | :-------------------------: | :----: | :----: | :-----------------------: | +| c*r | 6 | 2025.11.12 | | +| a*n | 5 | 2025.11.12 | | +| 。*c | 1 | 2025.11.12 | 感谢开源分享 | +| *记 | 1 | 2025.11.11 | | | *主 | 1 | 2025.11.10 | | | *了 | 10 | 2025.11.09 | | | *杰 | 5 | 2025.11.08 | | @@ -521,6 +525,14 @@ GitHub 一键 Fork 即可使用,无需编程基础。 - **大版本升级**:从 v1.x 升级到 v2.y, 建议删除现有 fork 后重新 fork,这样更省力且避免配置冲突 +### 2025/11/12 - v3.0.5 + +- 修复邮件发送 SSL/TLS 端口配置逻辑错误 +- 优化邮箱服务商(QQ/163/126)默认使用 465 端口(SSL) +- **新增 Docker 环境变量支持**:核心配置项(`enable_crawler`、`report_mode`、`push_window` 等)支持通过环境变量覆盖,解决 NAS 用户修改配置文件不生效的问题(详见 [🐳 Docker 部署](#-docker-部署) 章节) + + + ### 2025/10/26 - mcp-v1.0.1 **MCP 模块更新:** @@ -528,14 +540,15 @@ GitHub 一键 Fork 即可使用,无需编程基础。 - 统一所有工具的时间参数格式 +
+👉 历史更新 + + ### 2025/10/31 - v3.0.4 - 解决飞书因推送内容过长而产生的错误,实现了分批推送 -
-👉 历史更新 - ### 2025/10/23 - v3.0.3 - 扩大 ntfy 错误信息显示范围 @@ -1231,6 +1244,38 @@ docker run -d --name trend-radar \ - `config/frequency_words.txt` - 关键词配置(设置你关心的热点词汇) - `.env` - 环境变量配置(webhook URLs 和定时任务) + **⚙️ 环境变量覆盖机制(v3.0.5+)** + + 如果你在 NAS 或其他 Docker 环境中遇到**修改 `config.yaml` 后配置不生效**的问题,可以通过环境变量直接覆盖配置: + + | 环境变量 | 对应配置 | 示例值 | 说明 | + |---------|---------|-------|------| + | `ENABLE_CRAWLER` | `crawler.enable_crawler` | `true` / `false` | 是否启用爬虫 | + | `ENABLE_NOTIFICATION` | `notification.enable_notification` | `true` / `false` | 是否启用通知 | + | `REPORT_MODE` | `report.mode` | `all` / `filtered` | 报告模式 | + | `PUSH_WINDOW_ENABLED` | `notification.push_window.enabled` | `true` / `false` | 推送时间窗口开关 | + | `PUSH_WINDOW_START` | `notification.push_window.time_range.start` | `08:00` | 推送开始时间 | + | `PUSH_WINDOW_END` | `notification.push_window.time_range.end` | `22:00` | 推送结束时间 | + | `FEISHU_WEBHOOK_URL` | `notification.webhooks.feishu_url` | `https://...` | 飞书 Webhook | + + **配置优先级**:环境变量 > config.yaml + + **使用方法**: + - 修改 `.env` 文件,取消注释并填写需要的配置 + - 或在 NAS/群晖 Docker 管理界面的"环境变量"中直接添加 + - 重启容器后生效:`docker-compose restart` + + **验证配置**: + ```bash + docker logs trend-radar | grep "配置来源\|来源:" + ``` + 输出示例: + ``` + 爬虫状态: 已启用 (来源: 环境变量) + 报告模式: filtered (来源: 环境变量) + 通知渠道配置来源: 飞书(环境变量), 邮件(配置文件) + ``` + 3. **启动服务**: ```bash # 拉取最新镜像并启动 @@ -1653,7 +1698,7 @@ MCP Inspector 是官方调试工具,用于测试 MCP 连接: ## ☕问题答疑与1元点赞 > 心意到就行,收到的**点赞**用于提高开发者开源的积极性。**点赞**已收录于**致谢名单** -> 我发现大家都很善于靠自己解决问题,这种尝试值得鼓励,但如果被问题卡住太久,建议提问或者留言。这样我既能帮到**你**,也能帮到**更多探索中的小伙伴**~~ +> 提问或者留言前,建议先搜索已有的 issues 列表,或者浏览微信公众号文章留言区(找评论超过 10 的与本项目有关的文章)。 - **GitHub Issues**:适合针对性强的解答。提问时请提供完整信息(截图、错误日志、系统环境等)。 - **公众号交流**:适合快速咨询。建议优先在相关文章下的公共留言区交流,如私信,请文明礼貌用语😉 diff --git a/version b/version index b38ebbf..7da3c16 100644 --- a/version +++ b/version @@ -1 +1 @@ -3.0.4 \ No newline at end of file +3.0.5 \ No newline at end of file