Content
<div align="center" id="trendradar">
<a href="https://github.com/sansan0/TrendRadar" title="TrendRadar">
<img src="/_image/banner.webp" alt="TrendRadar Banner" width="80%">
</a>
The hotspot assistant that can be deployed in as fast as <strong>30 seconds</strong> — Say goodbye to ineffective scrolling and only see the news and information that truly matters to you.
<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://shandianshuo.cn" target="_blank" title="AI voice input, 4 times faster than typing ⚡"><img src="_image/shandianshuo.png" alt="闪电说 logo" height="50"/></a>
[](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/)
[](https://weixin.qq.com/)
[](https://telegram.org/)
[](#)
[](https://www.feishu.cn/)
[](#)
[](https://github.com/binwiederhier/ntfy)
[](https://github.com/Finb/Bark)
[](https://slack.com/)
[](https://github.com/sansan0/TrendRadar)
[](https://sansan0.github.io/TrendRadar)
[](https://hub.docker.com/r/wantcat/trendradar)
[](https://modelcontextprotocol.io/)
</div>
<div align="center">
**中文** | **[English](README-EN.md)**
</div>
> This project aims for lightweight and easy deployment.
<br>
## 📑 Quick Navigation
> 💡 **Click the links below** to quickly jump to the corresponding sections. It is recommended to start deployment from "**Quick Start**", and for detailed customization, please refer to "**Configuration Details**".
<div align="center">
| | | |
|:---:|:---:|:---:|
| [🚀 **Quick Start**](#-quick-start) | [AI Intelligent Analysis](#-ai-intelligent-analysis) | [⚙️ **Configuration Details**](#configuration-details) |
| [Docker Deployment](#6-docker-deployment) | [MCP Client](#-mcp-client) | [Project Related](#-project-related) |
| | [❓ **Q&A and Communication**](#q-a-and-communication) | |
</div>
<br>
- Thanks to the contributors who **patiently reported bugs**; every piece of feedback makes the project better 😉;
- Thanks to the audience who **starred the project**; **fork** what you desire, **star** what I desire, having both is the best support for the open-source spirit 😍;
- Thanks to the readers who **followed the [public account](#q-a-and-communication)**; your comments, likes, shares, and recommendations create a warmer interaction with the content 😎.
<details>
<summary>👉 Click to expand: <strong>Acknowledgment List</strong> (Currently <strong>🔥73🔥</strong> people)</summary>
### Infrastructure Support
Thanks to the infrastructure provided for free by **GitHub**, this project can be conveniently run with a **one-click fork**.
### Data Support
This project uses the API of the [newsnow](https://github.com/ourongxing/newsnow) project to obtain multi-platform data. Special thanks to the author for providing this service.
After contacting the author, he stated that there is no need to worry about server pressure, but this is based on his goodwill and trust. Please everyone:
- **Go to the [newsnow project](https://github.com/ourongxing/newsnow) and give it a star to show your support**
- When deploying with Docker, please control the push frequency reasonably and avoid over-exploitation.
### Promotion Support
> Thanks to the following platforms and individuals for their recommendations (in chronological order)
- [Small Software](https://mp.weixin.qq.com/s/fvutkJ_NPUelSW9OGK39aA) - Open source software recommendation platform
- [LinuxDo Community](https://linux.do/) - A gathering place for tech enthusiasts
- [Ruan Yifeng Weekly](https://github.com/ruanyf/weekly) - An influential weekly in the tech circle
### Audience Support
> Thanks to the friends who **provided financial support**, your generosity has transformed into snacks and drinks by the keyboard, accompanying every iteration of the project.
>
> **"One Yuan Like" has been paused**. If you still wish to support the author, you can go to the bottom of the [public account](#问题答疑与交流) article and click "Like the Author".
>
> To the friend with the cute cat avatar, I don't know which corner you found my payment code from, but I received your 1.8 in three consecutive donations. Thank you for your kindness!
| Liker | Amount | Date | Remarks |
| :-------------------------: | :------: | :--------: | :-----------------------: |
| D*5 | 1.8 * 3 | 2025.11.24 | |
| *Gui | 1 | 2025.11.17 | |
| *Chao | 10 | 2025.11.17 | |
| R*w | 10 | 2025.11.17 | This agent is amazing, bro |
| J*o | 1 | 2025.11.17 | Thanks for the open source, wish you success |
| *Chen | 8.88 | 2025.11.16 | The project is good, studying it |
| *Hai | 1 | 2025.11.15 | |
| *De | 1.99 | 2025.11.15 | |
| *Shu | 8.8 | 2025.11.14 | Thanks for the open source, the project is great, supporting it |
| M*e | 10 | 2025.11.14 | Open source is not easy, thank you for your hard work |
| **Ke | 1 | 2025.11.14 | |
| *Yun | 88 | 2025.11.13 | Good project, thanks for the open source |
| *W | 6 | 2025.11.13 | |
| *Kai | 1 | 2025.11.13 | |
| Dui*. | 1 | 2025.11.13 | Thanks for your TrendRadar |
| s*y | 1 | 2025.11.13 | |
| **Xiang | 10 | 2025.11.13 | Good project, wish I had found it sooner, thanks for the open source! |
| *Wei | 9.9 | 2025.11.13 | TrendRadar is awesome, treat the teacher to coffee~ |
| h*p | 5 | 2025.11.12 | Support Chinese open source, keep it up! |
| c*r | 6 | 2025.11.12 | |
| a*n | 5 | 2025.11.12 | |
| . *c | 1 | 2025.11.12 | Thanks for the open source sharing |
| *Ji | 1 | 2025.11.11 | |
| *Zhu | 1 | 2025.11.10 | |
| *Le | 10 | 2025.11.09 | |
| *Jie | 5 | 2025.11.08 | |
| *Dian | 8.80 | 2025.11.07 | Development is not easy, supporting it. |
| Q*Q | 6.66 | 2025.11.07 | Thanks for the open source! |
| C*e | 1 | 2025.11.05 | |
| Peter Fan | 20 | 2025.10.29 | |
| M*n | 1 | 2025.10.27 | Thanks for the open source |
| *Xu | 8.88 | 2025.10.23 | Teacher, I'm a newbie, I've been trying for a few days but haven't figured it out, seeking advice |
| Eason | 1 | 2025.10.22 | Still haven't figured it out, but you're doing a good thing |
| P*n | 1 | 2025.10.20 | |
| *Jie | 1 | 2025.10.19 | |
| *Xu | 1 | 2025.10.18 | |
| *Zhi | 1 | 2025.10.17 | |
| *😀 | 10 | 2025.10.16 | Like |
| **Jie | 10 | 2025.10.16 | |
| *Xiao | 10 | 2025.10.16 | |
| *Ji | 5 | 2025.10.14 | TrendRadar |
| J*d | 1 | 2025.10.14 | Thanks for your tool, it's fun... |
| *H | 1 | 2025.10.14 | |
| Na*O | 10 | 2025.10.13 | |
| *Yuan | 1 | 2025.10.13 | |
| P*g | 6 | 2025.10.13 | |
| Ocean | 20 | 2025.10.12 | ...really amazing!!! Even a newbie can use it directly... |
| **Pei | 5.2 | 2025.10.2 | github-yzyf1312: Long live open source |
| *Chun | 3 | 2025.9.23 | Keep it up, very good |
| *🍍 | 10 | 2025.9.21 | |
| E*f | 1 | 2025.9.20 | |
| *Ji | 1 | 2025.9.20 | |
| z*u | 2 | 2025.9.19 | |
| **Hao | 5 | 2025.9.17 | |
| *Hao | 1 | 2025.9.15 | |
| T*T | 2 | 2025.9.15 | Like |
| *Jia | 10 | 2025.9.10 | |
| *X | 1.11 | 2025.9.3 | |
| *Biao | 20 | 2025.8.31 | Thanks from the old friend |
| *Xia | 1 | 2025.8.30 | |
| 2*D | 88 | 2025.8.13 PM | |
| 2*D | 1 | 2025.8.13 AM | |
| S*o | 1 | 2025.8.05 | Support |
| *侠 | 10 | 2025.8.04 | |
| x*x | 2 | 2025.8.03 | trendRadar Good project, like |
| *远 | 1 | 2025.8.01 | |
| *邪 | 5 | 2025.8.01 | |
| *梦 | 0.1 | 2025.7.30 | |
| **龙 | 10 | 2025.7.29 | Support |
</details>
<br>
## 🪄 Sponsors
> Does writing reports and replying to messages every day make your wrist tired? Try "Shandian Shuo" AI voice input method — speaking is 4 times faster than typing ⚡
<div align="center">
[](https://shandianshuo.cn) [](https://shandianshuo.cn)
<a href="https://shandianshuo.cn" target="_blank">
<img src="_image/banner-shandianshuo.png" alt="Shandian Shuo" width="600"/>
</a>
</div>
<br>
## 📝 Changelog
> **📌 View Latest Updates**: **[Original Repository Changelog](https://github.com/sansan0/TrendRadar?tab=readme-ov-file#-changelog)** :
- **Note**: It is recommended to check the 【历史更新】 (historical updates) for specific 【功能内容】 (feature details).
### 2026/01/02 - v4.7.0
- **Fix RSS HTML Display**: Fixed rendering issues caused by mismatched RSS data formats, now displayed correctly grouped by keywords.
- **New Regular Expression Syntax**: Keyword configuration now supports `/pattern/` regular expression syntax, resolving issues with incorrect matches of English substrings (e.g., `ai` matching `training`) [📖 View Syntax Details](#关键词基础语法).
- **New Display Name Syntax**: Use `=> Note` to give complex regular expressions a memorable name, making push message displays clearer (e.g., `/\bai\b/ => AI-related`).
- **Don't Know How to Write Regular Expressions?** The README now includes guidance on generating regular expressions with AI. Tell ChatGPT/Claude/DeepSeek what you want to match, and let the AI help you write it.
### 2025/12/30 - mcp-v2.0.0
- **Architecture Adjustment**: Removed TXT support, unified the use of SQLite database
- **RSS Query**: Added `get_latest_rss`, `search_rss`, `get_rss_feeds_status`
- **Unified Search**: `search_news` supports `include_rss` parameter to search both hot lists and RSS simultaneously
<details>
<summary>👉 Click to expand: <strong>Historical Updates</strong></summary>
### 2026/01/01 - v4.6.0
- **Fix RSS HTML display**: Merged RSS content into the hot list HTML page, displayed grouped by source.
- **New display_mode configuration**: Supports two display modes: `keyword` (grouped by keyword) and `platform` (grouped by platform).
### 2025/12/30 - v4.5.0
- **RSS Feed Support**: Added RSS/Atom fetching, grouped statistics by keywords (consistent with hot list format)
- **Storage Structure Refactoring**: Flattened directory structure `output/{type}/{date}.db`
- **Unified Sorting Configuration**: `sort_by_position_first` now affects both hot list and RSS
- **Configuration Structure Refactoring**: `config.yaml` reorganized into 7 logical groups (app, report, notification, storage, platforms, rss, advanced), making configuration paths clearer
### 2025/12/26 - mcp-v1.2.0
**MCP Module Update - Optimized toolkit, added aggregation comparison feature, merged redundant tools:**
- Added `aggregate_news` tool - Cross-platform news deduplication and aggregation
- Added `compare_periods` tool - Period comparison analysis (week-on-week/month-on-month)
- Merged `find_similar_news` + `search_related_news_history` → `find_related_news`
- Enhanced `get_trending_topics` - Added `auto_extract` mode for automatic hot topic extraction
- Fixed several bugs
- Synchronized updates to the README-MCP-FAQ.md document in both Chinese and English versions (Q1-Q18)
### 2025/12/20 - v4.0.3
- Added URL normalization feature to address the issue of duplicate pushes caused by dynamic parameters (such as `band_rank`) on platforms like Weibo.
- Fixed the incremental mode detection logic to correctly identify historical titles.
### 2025/12/17 - v4.0.1
- StorageManager adds a method for pushing record agents
- S3 client switches to virtual-hosted style to enhance compatibility (supports more services such as Tencent Cloud COS)
### 2025/12/13 - mcp-v1.1.0
**MCP Module Updates:**
- Adapted to v4.0.0, while also compatible with v3.x data
- Added storage synchronization tools: `sync_from_remote`, `get_storage_status`, `list_available_dates`
### 2025/12/13 - v4.0.0
**🎉 Major Update: Comprehensive Refactoring of Storage and Core Architecture**
- **Multi-Storage Backend Support**: Introduced a new storage module that supports local SQLite and remote cloud storage (S3 compatible protocol, recommended free Cloudflare R2), adaptable to GitHub Actions, Docker, and local environments.
- **Database Structure Optimization**: Refactored the SQLite database table structure to enhance data efficiency and query capabilities.
- **Core Code Modularization**: Split the main program logic into multiple modules within the trendradar package, significantly improving code maintainability.
- **Enhanced Features**: Implemented date format standardization, data retention policies, timezone configuration support, time display optimization, and fixed remote storage data persistence issues to ensure the accuracy of data merging.
- **Cleanup and Compatibility**: Removed most historical compatibility code and unified data storage and retrieval methods.
### 2025/12/03 - v3.5.0
**🎉 Core Feature Enhancements**
1. **Multi-account Push Support**
- All push channels (Feishu, DingTalk, WeChat Work, Telegram, ntfy, Bark, Slack) support multi-account configuration
- Use a semicolon `;` to separate multiple accounts, for example: `FEISHU_WEBHOOK_URL=url1;url2`
- Automatically verify the consistency of paired configurations (such as Telegram's token and chat_id) in quantity
2. **Configurable Push Content Order**
- Added `reverse_content_order` configuration item
- Supports custom display order for hot word statistics and newly added hot news
3. **Global Filter Keywords**
- Added `[GLOBAL_FILTER]` area marker to support global filtering of unwanted content
- Applicable scenarios: filtering advertisements, marketing, low-quality content, etc.
**🐳 Docker Dual-path HTML Generation Optimization**
- **Bug Fixes**: Resolved the issue of `index.html` not syncing to the host machine in the Docker environment
- **Dual-path Generation**: Daily summary HTML is generated in two locations simultaneously
- `index.html` (project root directory): for GitHub Pages access
- `output/index.html`: accessible directly from the host machine via Docker Volume mount
- **Compatibility**: Ensured that Docker, GitHub Actions, and local runtime environments can all access the web version of the report normally
**🐳 Docker MCP Image Support**
- Added a standalone MCP service image `wantcat/trendradar-mcp`
- Supports Docker deployment of AI analysis features, providing services through HTTP interface (port 3333)
- Dual-container architecture: news push service and MCP service run independently, allowing for separate scaling and restarting
- See [Docker Deployment - MCP Service](#6-docker-部署) for details
**🌐 Web Server Support**
- Added a built-in web server to support accessing generated reports via a browser
- Control start/stop through the `manage.py` command: `docker exec -it trendradar python manage.py start_webserver`
- Access address: `http://localhost:8080` (port configurable)
- Security features: static file service, directory restrictions, local access
- Supports both automatic startup and manual control modes
**📖 Documentation Optimization**
- Added [Report Configuration](#7-报告配置) section: detailed explanation of report-related parameters
- Added [Push Time Window Configuration](#8-推送时间窗口配置) section: push_window configuration tutorial
- Added [Execution Frequency Configuration](#9-执行频率配置) section: Cron expression explanation and common examples
- Added [Multi-account Push Configuration](#10-多账号推送配置) section: detailed explanation of multi-account push configuration
- Optimized each configuration section: unified addition of "configuration location" explanations
- Simplified quick start configuration instructions: three core files are clear at a glance
- Optimized [Docker Deployment](#6-docker-部署) section: added image description, recommended git clone deployment, reorganized deployment methods
**🔧 Upgrade Instructions**:
- **GitHub Fork Users**: Update `main.py`, `config/config.yaml` (added multi-account push support, no need to modify existing configurations)
- **Multi-account Push**: New feature, disabled by default, existing single-account configurations remain unaffected
### 2025/11/26 - mcp-v1.0.3
**MCP Module Updates:**
- Added date parsing tool resolve_date_range to address the issue of inconsistent date calculations in AI models
- Supports parsing of natural language date expressions (this week, last 7 days, last month, etc.)
- Total number of tools increased from 13 to 14
### 2025/11/28 - v3.4.1
**🔧 Format Optimization**
1. **Bark Push Enhancement**
- Bark now supports Markdown rendering
- Enables native Markdown format: bold, links, lists, code blocks, etc.
- Removed plain text conversion to fully utilize Bark's native rendering capabilities
2. **Slack Format Precision**
- Uses dedicated mrkdwn format to handle batched content
- Improves byte size estimation accuracy (avoiding message overflow)
- Optimizes link format: `<url|text>` and bold syntax: `*text*`
3. **Performance Improvement**
- Format conversion is completed during batching, avoiding secondary processing
- Accurately estimates message size, reducing failure rate in sending
**🔧 Upgrade Instructions**:
- **GitHub Fork Users**: Update `main.py`, `config.yaml`
### 2025/11/25 - v3.4.0
**🎉 New Slack Push Support**
1. **Team Collaboration Push Channel**
- Supports Slack Incoming Webhooks (a globally popular team collaboration tool)
- Centralized message management, suitable for team sharing of hot news
- Supports mrkdwn format (bold, links, etc.)
2. **Multiple Deployment Methods**
- GitHub Actions: Configure `SLACK_WEBHOOK_URL` Secret
- Docker: Environment variable `SLACK_WEBHOOK_URL`
- Local Run: `config/config.yaml` configuration file
> 📖 **Detailed Configuration Tutorial**: [Quick Start - Slack Push](#-quick-start)
- Optimized the experience of one-click installation of MCP with setup-windows.bat and setup-windows-en.bat
**🔧 Upgrade Notes**:
- **GitHub Fork Users**: Update `main.py`, `config/config.yaml`, `.github/workflows/crawler.yml`
### 2025/11/24 - v3.3.0
**🎉 New Bark Push Support**
1. **iOS Exclusive Push Channel**
- Supports Bark push (based on APNs, iOS platform)
- Free and open-source, simple and efficient, no ad interference
- Supports both official server and self-hosted server options
2. **Multiple Deployment Methods**
- GitHub Actions: Configure `BARK_URL` Secret
- Docker: Environment variable `BARK_URL`
- Local Run: `config/config.yaml` configuration file
> 📖 **Detailed Configuration Tutorial**: [Quick Start - Bark Push](#-quick-start)
**🐛 Bug Fixes**
- Fixed the issue where `ntfy_server_url` configuration in `config.yaml` was not effective ([#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**
1. **Keyword Sorting Priority Configuration**
- Supports two sorting strategies: Popularity First vs Configuration Order First
- Meets different usage scenarios: Hotspot Tracking or Personalized Attention
2. **Precise Control of Display Quantity**
- Global Configuration: Uniformly limit the display quantity of all keywords
- Individual Configuration: Use `@number` syntax to set limits for specific keywords
- Effectively control push length, highlighting key content
> 📖 **Detailed Configuration Tutorial**: [Keyword Configuration - Advanced Configuration](#关键词高级配置)
**🔧 Upgrade Notes**:
- **GitHub Fork Users**: Update `main.py`, `config/config.yaml`
### 2025/11/18 - mcp-v1.0.2
**MCP Module Updates:**
- Optimized the situation where querying today's news might incorrectly return past dates.
### 2025/11/22 - v3.1.1
- **Fixed crash issue caused by data anomalies**: Resolved the `'float' object has no attribute 'lower'` error encountered by some users in the GitHub Actions environment.
- Added dual protection mechanism: Filter out invalid titles (None, float, empty strings) during the data retrieval phase, and added type checks at the function call sites.
- Improved system stability to ensure normal operation even when the data source returns an abnormal format.
**Upgrade Instructions** (for GitHub Fork users):
- Mandatory update: `main.py`
- It is recommended to use a minor version upgrade method: copy and replace the above file.
### 2025/11/20 - v3.1.0
- **Added support for personal WeChat push**: Corporate WeChat applications can push to personal WeChat without the need to install the Corporate WeChat APP.
- Supports two message formats: `markdown` (Corporate WeChat group bot) and `text` (personal WeChat application).
- Added `WEWORK_MSG_TYPE` environment variable configuration, supporting various deployment methods such as GitHub Actions, Docker, docker compose, etc.
- The `text` mode automatically removes Markdown syntax, providing a pure text push effect.
- For details, see the configuration instructions for "Personal WeChat Push" in the quick start section.
**Upgrade Instructions** (for GitHub Fork users):
- Mandatory updates: `main.py`, `config/config.yaml`
- Optional updates: `.github/workflows/crawler.yml` (if using GitHub Actions for deployment)
- It is recommended to use a minor version upgrade method: copy and replace the above files.
### 2025/11/12 - v3.0.5
- Fixed the logical error in the SSL/TLS port configuration for email sending
- Optimized the default use of port 465 (SSL) for email service providers (QQ/163/126)
- **Added support for Docker environment variables**: Core configuration items (`enable_crawler`, `report_mode`, `push_window`, etc.) can now be overridden by environment variables, resolving the issue where NAS users' modifications to the configuration file do not take effect (see the [🐳 Docker Deployment](#-docker-部署) section for details)
### 2025/10/26 - mcp-v1.0.1
**MCP Module Updates:**
- Fixed the error in passing date query parameters
- Unified the time parameter format across all tools
### 2025/10/31 - v3.0.4
- Fixed an error caused by the long content of the push in Feishu (飞书), implementing batch push.
### 2025/10/23 - v3.0.3
- Expanded the display range of ntfy error messages
### 2025/10/21 - v3.0.2
- Fix ntfy push encoding issue
### 2025/10/20 - v3.0.0
**Major Update - AI Analysis Feature Launched** 🤖
- **Core Features**:
- New AI analysis server based on MCP (Model Context Protocol)
- Supports 17 intelligent analysis tools: basic queries, intelligent retrieval, advanced analysis, RSS queries, system management
- Natural language interaction: query and analyze news data through conversational methods
- Multi-client support: Claude Desktop, Cherry Studio, Cursor, Cline, etc.
- **Analysis Capabilities**:
- Topic trend analysis (popularity tracking, lifecycle, viral detection, trend prediction)
- Data insights (platform comparison, activity statistics, keyword co-occurrence)
- Sentiment analysis, similar news finding, intelligent summary generation
- Historical news retrieval, multi-modal search
- **Update Notes**:
- This is an independent AI analysis feature that does not affect existing push functionalities
- Optional usage, no need to upgrade existing deployments
### 2025/10/15 - v2.4.4
- **Update Content**:
- Fix ntfy push encoding issue + 1
- Fix push time window judgment issue
- **Update Reminder**:
- Recommended for [minor version upgrade]
### 2025/10/10 - v2.4.3
> Thanks to [nidaye996](https://github.com/sansan0/TrendRadar/issues/98) for identifying the experience issue
- **Update Content**:
- Refactored "静默推送模式" (Silent Push Mode) to "推送时间窗口控制" (Push Time Window Control) to enhance functionality understanding
- Clarified that the push time window is an optional additional feature that can be used with three push modes
- Improved comments and documentation descriptions for clearer functionality positioning
- **Update Reminder**:
- This is merely a refactor, and upgrading is not necessary
### 2025/10/8 - v2.4.2
- **Update Content**:
- Fixed ntfy push encoding issue
- Fixed missing configuration file issue
- Optimized ntfy push effect
- Added segmented image export feature for GitHub Pages
- **Update Reminder**:
- It is recommended to use the [Major Version Update]
### 2025/10/2 - v2.4.0
**New ntfy Push Notifications**
- **Core Features**:
- Supports ntfy.sh public service and self-hosted servers
- **Use Cases**:
- Suitable for privacy-conscious users (supports self-hosting)
- Cross-platform push (iOS, Android, Desktop, Web)
- No account registration required (public server)
- Open source and free (MIT License)
- **Update Notice**:
- It is recommended to use the [major version update]
### 2025/09/26 - v2.3.2
- Fixed the issue where email notification configuration checks were overlooked ([#88](https://github.com/sansan0/TrendRadar/issues/88))
**Fix Description**:
- Resolved the problem where the system still prompted "No webhook configured" even when email notifications were correctly configured.
### 2025/09/22 - v2.3.1
- **New Email Push Feature**: Supports sending hot news reports to your email
- **Intelligent SMTP Recognition**: Automatically recognizes configurations for over 10 email service providers, including Gmail, QQ Mail, Outlook, and NetEase Mail
- **Beautiful HTML Format**: Email content uses the same HTML format as the web version, with exquisite layout and mobile adaptation
- **Batch Sending Support**: Supports multiple recipients, simply separate them with commas to send to multiple people at once
- **Custom SMTP**: Allows customization of SMTP server and port
- Fixed Docker build network connection issues
**Usage Instructions**:
- Applicable Scenarios: Suitable for users who need email archiving, team sharing, and scheduled reports
- Supported Email Providers: Gmail, QQ Mail, Outlook/Hotmail, 163/126 Mail, Sina Mail, Sohu Mail, etc.
**Update Reminder**:
- This update includes a lot of content; if you wish to upgrade, it is recommended to use the 【Major Version Upgrade】.
### 2025/09/17 - v2.2.0
- Added a one-click save news image feature, allowing you to easily share trending topics you care about.
**Usage Instructions**:
- Applicable Scenario: After you have enabled the web version feature following the tutorial (GitHub Pages)
- How to Use: Open the webpage link on your mobile phone or computer, and click the "Save as Image" button at the top of the page
- Actual Effect: The system will automatically create a beautiful image of the current news report and save it to your mobile photo album or computer desktop
- Sharing Convenience: You can directly send this image to friends, post it on your social circle, or share it in work groups, allowing others to see the important information you discovered.
### 2025/09/13 - v2.1.2
- Fixed the issue of news push failure caused by DingTalk's (钉钉) push capacity limit (using batch push).
### 2025/09/04 - v2.1.1
- Fixed the issue where Docker could not run properly on certain architectures
- Officially released the official Docker image wantcat/trendradar, supporting multiple architectures
- Optimized the Docker deployment process for quick usage without local builds
### 2025/08/30 - v2.1.0
**Core Improvements**:
- **Push Logic Optimization**: Changed from "push every execution" to "controllable push within a time window"
- **Time Window Control**: Allows setting a push time range to avoid disturbances during non-working hours
- **Selectable Push Frequency**: Supports single or multiple pushes within the specified time period
**Update Notes**:
- This feature is disabled by default and needs to be manually enabled in config.yaml for time window control
- Upgrading requires updating both main.py and config.yaml files
### 2025/08/27 - v2.0.4
- This version is not a feature fix, but an important reminder.
- Please make sure to keep your webhooks secure; do not expose them, do not expose them, do not expose them.
- If you have deployed this project on GitHub via forking, please enter the webhooks into GitHub Secrets, not config.yaml.
- If you have already exposed the webhooks or entered them into config.yaml, it is recommended to delete them and regenerate.
### 2025/08/06 - v2.0.3
- Optimized the web version of the github page for better usability on mobile devices.
### 2025/07/28 - v2.0.2
- Refactored the code
- Resolved the issue of version number being easily overlooked for modification
### 2025/07/27 - v2.0.1
**Bug Fixes**:
1. Fixed an execution issue caused by CRLF line endings in the Docker shell script.
2. Resolved a logic issue where sending news would be empty when frequency_words.txt is empty.
- After the fix, when you select frequency_words.txt as empty, it will **push all news**, but due to message push size limitations, please make the following adjustments:
- Option 1: Disable mobile push and only select GitHub Pages deployment (this is the most comprehensive information option, which will reorder hot topics across all platforms according to your **custom hot search algorithm**).
- Option 2: Reduce the push platforms, prioritizing **WeChat Work** or **Telegram**. I have implemented batch push functionality for these two platforms (due to batch pushing affecting the push experience, and since these two platforms only allow a limited push capacity, batch push functionality was reluctantly implemented, but it at least ensures the completeness of the information received).
- Option 3: This can be combined with Option 2, where selecting the current or incremental mode can effectively reduce the content pushed at one time.
### 2025/07/17 - v2.0.0
**Major Refactor**:
- Configuration management refactor: All configurations are now managed through the `config/config.yaml` file (I haven't split main.py for your convenience in copying the upgrade)
- Runtime mode upgrade: Supports three modes - `daily` (daily summary), `current` (current leaderboard), `incremental` (incremental monitoring)
- Docker support: Complete Docker deployment solution, supports containerized operation
**Configuration File Description**:
- `config/config.yaml` - Main configuration file (application settings, crawler configuration, notification configuration, platform configuration, etc.)
- `config/frequency_words.txt` - Keyword configuration (monitoring vocabulary settings)
### 2025/07/09 - v1.4.1
**New Features**: Added incremental push (configure FOCUS_NEW_ONLY at the top of main.py), this switch only cares about new topics rather than ongoing popularity, and will only send notifications when there is new content.
**Bug Fixes**: Fixed occasional layout issues caused by special characters in the news itself in certain cases.
### 2025/06/23 - v1.3.0
There are length limits for push messages in 企业微信 (WeChat Work) and Telegram. To address this, I adopted a method of splitting the messages for pushing. For detailed development documentation, please refer to [企业微信](https://developer.work.weixin.qq.com/document/path/91770) and [Telegram](https://core.telegram.org/bots/api).
### 2025/06/21 - v1.2.1
In the previous versions before this release, not only does main.py need to be copied and replaced, but crawler.yml also needs to be copied and replaced.
https://github.com/sansan0/TrendRadar/blob/master/.github/workflows/crawler.yml
### 2025/06/19 - v1.2.0
> Thanks to the API整理 (API organization) by claude research across various platforms, I was able to quickly complete the adaptation for each platform (although the code has become more redundant~)
1. Support for Telegram, WeChat Work (企业微信), and DingTalk (钉钉) push channels, with support for multi-channel configuration and simultaneous push.
### 2025/06/18 - v1.1.0
> **200 star⭐** achieved, let's keep the excitement going~ Recently, under my "encouragement," quite a few people have liked, shared, and recommended my public account, and I've seen the encouraging data from specific accounts in the backend. Many have become loyal fans since the angel round (I've only been running the public account for a little over a month, although I registered it seven or eight years ago, haha, so I got on early but started late). However, since you haven't left comments or messaged me, I can't respond to each of you individually to express my gratitude for your support, so thank you all here!
1. Important update: I've added weighting, so the news you see now is the hottest and most followed, appearing at the top.
2. Updated usage documentation: Many features have been updated recently, and the previous usage documentation was written a bit too simply (see the complete tutorial for ⚙️ frequency_words.txt configuration below).
### 2025/06/16 - v1.0.0
1. Added a new version update prompt for the project, which is enabled by default. To disable it, you can change "FEISHU_SHOW_VERSION_UPDATE": True to False in main.py.
### 2025/06/13+14
1. Removed compatibility code. Students who forked earlier may experience anomalies when directly copying the code on that day (it will return to normal the next day).
2. Added a new news display at the bottom of feishu and html.
### 2025/06/09
**100 stars⭐** achieved, let's add a small feature to excite everyone.
The frequency_words.txt file has added a "must-have words" feature, using the + sign.
1. The must-have word syntax is as follows:
Both 唐僧 (Tang Seng) and 猪八戒 (Zhu Bajie) must appear in the title to be included in the push news.
```
+唐僧
+猪八戒
```
2. The priority of filter words is higher:
If a filter word matches 唐僧念经 (Tang Seng chanting), then even if 唐僧 is in the must-have words, it will not be displayed.
```
+唐僧
!唐僧念经
```
### 2025/06/02
1. **Webpage** and **Feishu message** support direct mobile jump to detailed news
2. Optimized display effect + 1
### 2025/05/26
1. Feishu message display effect optimization
<table>
<tr>
<td align="center">
Before Optimization<br>
<img src="_image/before.jpg" alt="Feishu message interface - Before Optimization" width="400"/>
</td>
<td align="center">
After Optimization<br>
<img src="_image/after.jpg" alt="Feishu message interface - After Optimization" width="400"/>
</td>
</tr>
</table>
</details>
<br>
## ✨ Core Features
### **Global Hotspot Aggregation**
- Zhihu
- Douyin
- Bilibili Hot Search
- Wall Street News
- Tieba
- Baidu Hot Search
- Caixin Hot Topics
- The Paper
- Phoenix Network
- Toutiao
- Weibo
By default, 11 mainstream platforms are monitored, and additional platforms can be added as needed.
> 💡 For detailed configuration instructions, see [Configuration Details - Platform Configuration](#1-平台配置)
### **RSS Feed Support** (Added in v4.5.0)
Support for fetching RSS/Atom feeds, with keyword grouping statistics (consistent with the hot list format):
- **Unified Format**: RSS and hot list use the same keyword matching and display format
- **Simple Configuration**: Directly add RSS sources in `config.yaml`
- **Merged Push**: Hot list and RSS are merged into a single message push
> 💡 RSS uses the same `frequency_words.txt` for keyword filtering as the hot list
### **Smart Push Strategy**
**Three Push Modes**:
| Mode | Applicable Scenarios | Push Characteristics |
|------|---------------------|---------------------|
| **Daily Summary** (当日汇总) | Enterprise managers/regular users | Pushes all matching news of the day on time (will include previously pushed news) |
| **Current List** (当前榜单) | Self-media individuals/content creators | Pushes current list matching news on time (appears every time it remains on the list) |
| **Incremental Monitoring** (增量监控) | Investors/traders | Only pushes new content, zero duplicates |
> 💡 **Quick Selection Guide:**
> - Don't want to see duplicate news → Use `incremental` (增量监控)
> - Want to see the complete list trend → Use `current` (当前榜单)
> - Need a daily summary report → Use `daily` (当日汇总)
>
> For detailed comparisons and configuration tutorials, see [Configuration Details - Push Mode Explanation](#3-推送模式详解)
**Additional Features** (Optional):
| Feature | Description | Default |
|---------|-------------|---------|
| **Push Time Window Control** | Set the push time range (e.g., 09:00-18:00) to avoid disturbances during non-working hours | Off |
| **Content Order Configuration** | Adjust the display order of "Hot Keyword Statistics" and "New Hot News" (added in v3.5.0) | Statistics first |
| **Display Mode Switch** | `keyword`=grouped by keywords, `platform`=grouped by platform (added in v4.6.0) | keyword |
> 💡 For detailed configuration tutorials, see [Configuration Details - Report Configuration](#7-报告配置) and [Configuration Details - Push Time Window](#8-推送时间窗口配置)
### **Precise Content Filtering**
Set personal keywords (e.g., AI, BYD, education policy) to only push relevant hot topics and filter out unrelated information.
> 💡 **Basic Configuration Tutorial**: [Keyword Configuration - Basic Syntax](#关键词基础语法)
>
> 💡 **Advanced Configuration Tutorial**: [Keyword Configuration - Advanced Configuration](#关键词高级配置)
>
> 💡 You can also choose not to filter and push all hot topics completely (leave frequency_words.txt empty).
### **Hot Trend Analysis**
Real-time tracking of news popularity changes allows you to not only know "what is trending," but also understand "how trends evolve."
- **Timeline Tracking**: Records the complete time span from the first appearance to the last appearance of each news item.
- **Popularity Changes**: Statistics on the ranking changes and frequency of news appearances over different time periods.
- **New Detection**: Real-time identification of newly emerging hot topics, marked with 🆕 for immediate alerts.
- **Sustainability Analysis**: Distinguishes between one-time hot topics and in-depth news that continues to ferment.
- **Cross-Platform Comparison**: Analyzes the ranking performance of the same news across different platforms to reveal differences in media attention.
> 💡 For push format details, see [Configuration Details - Push Format Reference](#5-推送格式参考)
### **Personalized Hotspot Algorithm**
No longer being led by the algorithms of various platforms, TrendRadar will reorganize the trending searches across the internet.
> 💡 Three ratios can be adjusted, see [Configuration Details - Hotspot Weight Adjustment](#4-热点权重调整) for more information.
### **Multi-Channel Multi-Account Push**
Supports **WeChat Work** (+ WeChat push solution), **Feishu**, **DingTalk**, **Telegram**, **Email**, **ntfy**, **Bark**, **Slack**, with messages delivered directly to mobile phones and email.
> 💡 For detailed configuration tutorials, see [Configuration Details - Multi-Account Push Configuration](#10-多账号推送配置)
### **Flexible Storage Architecture** (v4.0.0 Major Update)
**Multi-Storage Backend Support**:
- **Remote Cloud Storage**: Default in GitHub Actions environment, supports S3 compatible protocols (R2/OSS/COS, etc.), data stored in the cloud, does not pollute the repository
- **Local SQLite Database**: Default in Docker/local environment, data is fully controllable
- **Automatic Backend Selection**: Smart switching of storage methods based on the running environment
> 💡 For detailed explanation, see [Configuration Details - Storage Configuration](#11-存储配置)
### **Multi-Platform Deployment**
- **GitHub Actions**: Scheduled automatic crawling + remote cloud storage (requires sign-in for renewal)
- **Docker Deployment**: Supports multi-architecture containerized operation, local data storage
- **Local Running**: Directly run on Windows/Mac/Linux
### **AI Intelligent Analysis (New in v3.0.0)**
The AI dialogue analysis system based on the MCP (Model Context Protocol) allows you to deeply mine news data using natural language.
> **💡 Usage Tips**: The AI features require local news data support.
> - The project comes with test data for immediate feature experience.
> - It is recommended to deploy and run the project yourself to obtain more real-time data.
>
> For more details, see [AI Intelligent Analysis](#-ai-智能分析)
### **Zero Technical Barrier Deployment**
You can use it with one-click Fork on GitHub, no programming background required.
> 30 seconds deployment: GitHub Pages (web browsing) supports one-click saving as an image, ready to share with others at any time.
>
> 1 minute deployment: WeChat Work (mobile notification)
**💡 Tip:** Want a **real-time updated** web version? After forking, go to your repository Settings → Pages, and enable GitHub Pages. [Preview](https://sansan0.github.io/TrendRadar/).
### **Reduce APP Dependency**
From "being kidnapped by algorithm recommendations" to "actively obtaining the information you want"
**Target Audience:** Investors, self-media individuals, corporate public relations, ordinary users concerned about current events
**Typical Scenarios:** Stock market investment monitoring, brand public opinion tracking, industry trend observation, obtaining life information
| Github Pages Effect (mobile adaptation, email push effect) | Feishu Push Effect |
|:---:|:---:|
|  |  |
<br>
## 🚀 Quick Start
> **Reminder**: It is recommended to **[check the latest official documentation](https://github.com/sansan0/TrendRadar?tab=readme-ov-file)** to ensure that the configuration steps are up to date.
### Please choose the deployment method that suits you
#### 🅰️ Solution One: Docker Deployment (Recommended 🔥)
* **Features**: More stable than GitHub Actions
* **Applicable to**: Those with their own servers, NAS, or computers running long-term
👉 **[Jump to Docker Deployment Tutorial](#6-docker-部署)**
#### 🅱️ Solution Two: GitHub Actions Deployment (Content of this section ⬇️)
* **Features**: Data is stored in **remote cloud storage** (no longer written to the Git repository)
* **Recommendation**: Configure cloud storage services (Cloudflare R2 free tier is sufficient, Alibaba Cloud OSS, Tencent Cloud COS, etc.)
* **Note**: Regular check-ins are required for renewal (every 7 days)
1️⃣ **Obtain Project Code**
Click the green **[Use this template]** button in the upper right corner of this repository page → Select "Create a new repository".
> ⚠️ Reminder:
> - The term "Fork" mentioned in the subsequent documents can be understood as "Use this template"
> - Using Fork may lead to runtime exceptions, see [Issue #606](https://github.com/sansan0/TrendRadar/issues/606)
<br>
2️⃣ **Set Up GitHub Secrets**:
In your forked repository, go to `Settings` > `Secrets and variables` > `Actions` > `New repository secret`
**📌 Important Note (Please read carefully):**
- **One Name corresponds to one Secret**: For each configuration item added, click the "New repository secret" button once, and fill in a pair of "Name" and "Secret"
- **It is normal not to see the value after saving**: For security reasons, when editing again after saving, only the Name will be visible (the value of Secret will not be shown)
- **Do not create your own names**: The Name of the Secret must **strictly use** the names listed below (such as `WEWORK_WEBHOOK_URL`, `FEISHU_WEBHOOK_URL`, etc.), and cannot be modified or created arbitrarily, otherwise the system will not recognize it
- **Multiple platforms can be configured simultaneously**: The system will send notifications to all configured platforms
**Configuration Example:**
<img src="_image/secrets.png" alt="GitHub Secrets Configuration Example"/>
As shown in the image above, each line is a configuration item:
- **Name**: Must use the fixed names listed in the expanded content below (such as `WEWORK_WEBHOOK_URL`)
- **Secret**: Fill in the actual content obtained from the corresponding platform (such as Webhook address, Token, etc.)
<br>
<details>
<summary>👉 Click to expand: <strong>WeChat Work Bot</strong> (Configuration is the simplest and quickest)</summary>
<br>
**GitHub Secret Configuration (⚠️ Name must be strictly consistent):**
- **Name**: `WEWORK_WEBHOOK_URL` (please copy and paste this name, do not type it manually to avoid errors)
- **Secret**: Your WeChat Work Bot Webhook address
<br>
**Bot Setup Steps:**
#### Mobile Setup:
1. Open the WeChat Work App → Enter the target internal group chat
2. Click the "…" button in the upper right corner → Select "Message Push"
3. Click "Add" → Enter the name "TrendRadar"
4. Copy the Webhook address, click save, and configure the copied content into the GitHub Secret above
#### The PC setup process is similar
</details>
<details>
<summary>👉 Click to expand: <strong>Personal WeChat Push</strong> (Based on WeChat Work application, pushes to personal WeChat)</summary>
<br>
> Since this solution is based on the plugin mechanism of WeChat Work, the push style is plain text (no markdown format), but it can be directly pushed to personal WeChat without installing the WeChat Work App.
**GitHub Secret Configuration (⚠️ Name must be strictly consistent):**
- **Name**: `WEWORK_WEBHOOK_URL` (please copy and paste this name, do not type it manually)
- **Secret**: Your WeChat Work application Webhook address
- **Name**: `WEWORK_MSG_TYPE` (please copy and paste this name, do not type it manually)
- **Secret**: `text`
<br>
**Setup Steps:**
1. Complete the WeChat Work Bot Webhook setup above
2. Add `WEWORK_MSG_TYPE` Secret, set the value to `text`
3. Follow the instructions in the image below to link to personal WeChat
4. After configuration, the WeChat Work App on your phone can be deleted
<img src="_image/wework.png" title="Personal WeChat Push Configuration"/>
**Note**:
- Use the same Webhook address as the WeChat Work Bot
- The difference lies in the message format: `text` is plain text, `markdown` is rich text (default)
- The plain text format will automatically remove all markdown syntax (bold, links, etc.)
</details>
<details>
<summary>👉 Click to expand: <strong>Feishu Bot</strong> (Messages display the friendliest)</summary>
<br>
**GitHub Secret Configuration (⚠️ Name must be strictly consistent):**
- **Name**: `FEISHU_WEBHOOK_URL` (please copy and paste this name, do not type it manually)
- **Secret**: Your Feishu Bot Webhook address (this link starts with something like https://www.feishu.cn/flow/api/trigger-webhook/********)
<br>
There are two solutions, **Solution One** is simple to configure, **Solution Two** is complex (but stable for pushing)
Solution One was discovered and suggested by **ziventian**, thanks to him here, the default is personal push, but group push operations can also be configured [#97](https://github.com/sansan0/TrendRadar/issues/97).
**Solution One:**
> Some users may encounter additional operations, otherwise it will report "system error". You need to search for the bot on the mobile side and then enable the Feishu Bot application (this suggestion comes from a user, please refer to it)
1. Open https://botbuilder.feishu.cn/home/my-command in your computer browser
2. Click "Create New Bot Command"
3. Click "Select Trigger", scroll down, and click "Webhook Trigger"
4. At this point, you will see the "Webhook Address", copy this link to a local notepad for temporary storage, and continue with the next steps
5. Place the following content in "Parameters", then click "Finish"
```json
{
"message_type": "text",
"content": {
"total_titles": "{{内容}}",
"timestamp": "{{内容}}",
"report_type": "{{内容}}",
"text": "{{内容}}"
}
}
```
6. Click "Select Action" > "Send Message via Official Bot"
7. Fill in the message title as "TrendRadar Hotspot Monitoring"
8. The most critical part comes, click the + button, select "Webhook Trigger", and arrange it according to the image below

9. After configuration is complete, configure the Webhook address copied in step 4 into the GitHub Secrets under `FEISHU_WEBHOOK_URL`
<br>
**Solution Two:**
1. Open https://botbuilder.feishu.cn/home/my-app in your computer browser
2. Click "Create New Bot Application"
3. After entering the created application, click "Process Involved" > "Create Process" > "Select Trigger"
4. Scroll down and click "Webhook Trigger"
5. At this point, you will see the "Webhook Address", copy this link to a local notepad for temporary storage, and continue with the next steps
6. Place the following content in "Parameters", then click "Finish"
```json
{
"message_type": "text",
"content": {
"total_titles": "{{内容}}",
"timestamp": "{{内容}}",
"report_type": "{{内容}}",
"text": "{{内容}}"
}
}
```
7. Click "Select Action" > "Send Feishu Message", check "Group Message", then click the input box below, and select "My Managed Groups" (if you don't have a group, you can create one in the Feishu app)
8. Fill in the message title as "TrendRadar Hotspot Monitoring"
9. The most critical part is here. Click the + button, select "Webhook Trigger," and arrange it according to the image below.

10. After the configuration is complete, copy the Webhook URL from step 5 and configure it in GitHub Secrets as `FEISHU_WEBHOOK_URL`.
</details>
<details>
<summary>👉 Click to expand: <strong>DingTalk Bot</strong></summary>
<br>
**GitHub Secret Configuration (⚠️ Name must match exactly):**
- **Name**: `DINGTALK_WEBHOOK_URL` (please copy and paste this name, do not type it manually)
- **Secret**: Your DingTalk Bot Webhook URL
<br>
**Bot Setup Steps:**
1. **Create a Bot (PC only)**:
- Open the DingTalk PC client and enter the target group chat.
- Click the group settings icon (⚙️) → scroll down to find "Bot" and click it.
- Select "Add Bot" → "Custom."
2. **Configure the Bot**:
- Set the bot name.
- **Security Settings**:
- **Custom Keywords**: Set to "Hotspot."
3. **Complete the Setup**:
- Check the service terms agreement → click "Finish."
- Copy the obtained Webhook URL.
- Configure the URL in GitHub Secrets as `DINGTALK_WEBHOOK_URL`.
**Note**: The mobile version can only receive messages and cannot create new bots.
</details>
<details>
<summary>👉 Click to expand: <strong>Telegram Bot</strong></summary>
<br>
**GitHub Secret Configuration (⚠️ Name must match exactly):**
- **Name**: `TELEGRAM_BOT_TOKEN` (please copy and paste this name, do not type it manually)
- **Secret**: Your Telegram Bot Token
- **Name**: `TELEGRAM_CHAT_ID` (please copy and paste this name, do not type it manually)
- **Secret**: Your Telegram Chat ID
**Note**: Telegram requires the configuration of **two** Secrets. Please click the "New repository secret" button twice to add them separately.
<br>
**Bot Setup Steps:**
1. **Create a Bot**:
- Search for `@BotFather` in Telegram (pay attention to case, it has a blue badge, and shows something like 37849827 monthly users; this is the official one, be cautious of similar unofficial accounts).
- Send the command `/newbot` to create a new bot.
- Set the bot name (it must end with "bot," and you may encounter duplicate names, so think hard for a unique name).
- Obtain the Bot Token (format: `123456789:AAHfiqksKZ8WmR2zSjiQ7_v4TMAKdiHm9T0`).
2. **Get the Chat ID**:
**Method 1: Obtain via Official API**
- First, send a message to your bot.
- Access: `https://api.telegram.org/bot<Your Bot Token>/getUpdates`
- Find the number in the returned JSON under `"chat":{"id":number}`.
**Method 2: Use a Third-Party Tool**
- Search for `@userinfobot` and send `/start`.
- Obtain your user ID as the Chat ID.
3. **Configure in GitHub**:
- `TELEGRAM_BOT_TOKEN`: Fill in the Bot Token obtained in step 1.
- `TELEGRAM_CHAT_ID`: Fill in the Chat ID obtained in step 2.
</details>
<details>
<summary>👉 Click to expand: <strong>Email Notifications</strong> (supports all major email providers)</summary>
<br>
- Important Note: To prevent abuse of the email mass sending feature, the current mass sending allows all recipients to see each other's email addresses.
- If you have no prior experience configuring email sending like below, it is not recommended to try.
> ⚠️ **Important Configuration Dependency**: Email notifications require an HTML report file. Please ensure that `config/config.yaml` has `storage.formats.html` set to `true`:
> ```yaml
> storage:
> formats:
> sqlite: true
> txt: false
> html: true # Must be enabled, otherwise email notifications will fail
> ```
> If set to `false`, an error will occur during email sending: `Error: HTML file does not exist or was not provided: None`.
<br>
**GitHub Secret Configuration (⚠️ Name must match exactly):**
- **Name**: `EMAIL_FROM` (please copy and paste this name, do not type it manually)
- **Secret**: Sender's email address.
- **Name**: `EMAIL_PASSWORD` (please copy and paste this name, do not type it manually)
- **Secret**: Email password or authorization code.
- **Name**: `EMAIL_TO` (please copy and paste this name, do not type it manually)
- **Secret**: Recipient's email address (multiple recipients can be separated by commas, or it can be the same as EMAIL_FROM to send to yourself).
- **Name**: `EMAIL_SMTP_SERVER` (optional configuration, please copy and paste this name)
- **Secret**: SMTP server address (can be left blank, the system will automatically recognize it).
- **Name**: `EMAIL_SMTP_PORT` (optional configuration, please copy and paste this name)
- **Secret**: SMTP port (can be left blank, the system will automatically recognize it).
**Note**: Email notifications require at least **3 mandatory** Secrets (EMAIL_FROM, EMAIL_PASSWORD, EMAIL_TO), while the last two are optional configurations.
<br>
**Supported Email Service Providers** (automatically recognizes SMTP configuration):
| Email Service Provider | Domain | SMTP Server | Port | Encryption |
|------------------------|-------------|---------------------------|------|------------|
| **Gmail** | gmail.com | smtp.gmail.com | 587 | TLS |
| **QQ Mail** | qq.com | smtp.qq.com | 465 | SSL |
| **Outlook** | outlook.com | smtp-mail.outlook.com | 587 | TLS |
| **Hotmail** | hotmail.com | smtp-mail.outlook.com | 587 | TLS |
| **Live** | live.com | smtp-mail.outlook.com | 587 | TLS |
| **163 Mail** | 163.com | smtp.163.com | 465 | SSL |
| **126 Mail** | 126.com | smtp.126.com | 465 | SSL |
| **Sina Mail** | sina.com | smtp.sina.com | 465 | SSL |
| **Sohu Mail** | sohu.com | smtp.sohu.com | 465 | SSL |
| **Tianyi Mail** | 189.cn | smtp.189.cn | 465 | SSL |
| **Aliyun Mail** | aliyun.com | smtp.aliyun.com | 465 | TLS |
| **Yandex Mail** | yandex.com | smtp.yandex.com | 465 | TLS |
| **iCloud Mail** | icloud.com | smtp.mail.me.com | 587 | SSL |
> **Automatic Identification**: When using the above email, there is no need to manually configure `EMAIL_SMTP_SERVER` and `EMAIL_SMTP_PORT`, as the system will automatically identify them.
>
> **Feedback Instructions**:
> - If you successfully test with **other emails**, feel free to open an [Issues](https://github.com/sansan0/TrendRadar/issues) to let me know, and I will add it to the support list.
> - If the above email configuration is incorrect or unusable, please also open an [Issues](https://github.com/sansan0/TrendRadar/issues) to provide feedback, helping to improve the project.
>
> **Special Thanks**:
> - Thanks to [@DYZYD](https://github.com/DYZYD) for contributing the configuration for Tianyi Email (189.cn) and completing the self-sent and received testing ([#291](https://github.com/sansan0/TrendRadar/issues/291)).
> - Thanks to [@longzhenren](https://github.com/longzhenren) for contributing the configuration for Alibaba Cloud Email (aliyun.com) and completing the testing ([#344](https://github.com/sansan0/TrendRadar/issues/344)).
> - Thanks to [@ACANX](https://github.com/ACANX) for contributing the configuration for Yandex Email (yandex.com) and completing the testing ([#663](https://github.com/sansan0/TrendRadar/issues/663)).
> - Thanks to [@Sleepy-Tianhao](https://github.com/Sleepy-Tianhao) for contributing the configuration for iCloud Email (icloud.com) and completing the testing ([#728](https://github.com/sansan0/TrendRadar/issues/728)).
**Common Email Settings:**
#### QQ Email:
1. Log in to the QQ Email web version → Settings → Account
2. Enable POP3/SMTP service
3. Generate an authorization code (16-character letters)
4. Fill in `EMAIL_PASSWORD` with the authorization code, not the QQ password.
#### Gmail:
1. Enable two-step verification
2. Generate an app-specific password
3. Fill in `EMAIL_PASSWORD` with the app-specific password.
#### 163/126 Email:
1. Log in to the web version → Settings → POP3/SMTP/IMAP
2. Enable SMTP service
3. Set the client authorization code
4. Fill in `EMAIL_PASSWORD` with the authorization code.
<br>
**Advanced Configuration**:
If automatic identification fails, you can manually configure SMTP:
- `EMAIL_SMTP_SERVER`: e.g., smtp.gmail.com
- `EMAIL_SMTP_PORT`: e.g., 587 (TLS) or 465 (SSL)
<br>
**If there are multiple recipients (note that they are separated by English commas)**:
- EMAIL_TO="user1@example.com,user2@example.com,user3@example.com"
</details>
<details>
<summary>👉 Click to expand: <strong>ntfy Push</strong> (Open source and free, supports self-hosting)</summary>
<br>
**Two Usage Methods:**
### Method 1: Free Use (Recommended for Beginners) 🆓
**Features**:
- ✅ No account registration required, use immediately
- ✅ 250 messages per day (sufficient for 90% of users)
- ✅ Topic name is the "password" (choose a name that is not easy to guess)
- ⚠️ Messages are not encrypted, not suitable for sensitive information, but suitable for non-sensitive information in our project.
**Quick Start**:
1. **Download the ntfy app**:
- Android: [Google Play](https://play.google.com/store/apps/details?id=io.heckel.ntfy) / [F-Droid](https://f-droid.org/en/packages/io.heckel.ntfy/)
- iOS: [App Store](https://apps.apple.com/us/app/ntfy/id1625396347)
- Desktop: Visit [ntfy.sh](https://ntfy.sh)
2. **Subscribe to a topic** (choose a hard-to-guess name):
```
Suggested format: trendradar-{your initials}-{random number}
Cannot use Chinese characters
✅ Good example: trendradar-zs-8492
❌ Bad example: news, alerts (too easy to guess)
```
3. **Configure GitHub Secret (⚠️ Name must match exactly)**:
- **Name**: `NTFY_TOPIC` (please copy and paste this name, do not type it manually)
- **Secret**: Fill in the topic name you just subscribed to.
- **Name**: `NTFY_SERVER_URL` (optional configuration, please copy and paste this name)
- **Secret**: Leave blank (default uses ntfy.sh)
- **Name**: `NTFY_TOKEN` (optional configuration, please copy and paste this name)
- **Secret**: Leave blank.
**Note**: ntfy requires at least 1 mandatory Secret (NTFY_TOPIC), the latter two are optional configurations.
4. **Test**:
```bash
curl -d "Test message" ntfy.sh/your_topic_name
```
---
### Method 2: Self-Hosting (Complete Privacy Control) 🔒
**Suitable for**: Those with servers, seeking complete privacy, and have strong technical skills.
**Advantages**:
- ✅ Fully open source (Apache 2.0 + GPLv2)
- ✅ Complete control over data
- ✅ No restrictions
- ✅ Zero cost
**One-click Docker Deployment**:
```bash
docker run -d \
--name ntfy \
-p 80:80 \
-v /var/cache/ntfy:/var/cache/ntfy \
binwiederhier/ntfy \
serve --cache-file /var/cache/ntfy/cache.db
```
**Configure TrendRadar**:
```yaml
NTFY_SERVER_URL: https://ntfy.yourdomain.com
NTFY_TOPIC: trendradar-alerts # Simple name can be used for self-hosting
NTFY_TOKEN: tk_your_token # Optional: Enable access control
```
**Subscribe in the app**:
- Click "Use another server"
- Enter your server address
- Enter the topic name
- (Optional) Enter login credentials
---
**Frequently Asked Questions**:
<details>
<summary><strong>Q1: Is the free version sufficient?</strong></summary>
250 messages per day is enough for most users. Calculating with a fetch every 30 minutes, there are about 48 pushes per day, which is completely sufficient.
</details>
<details>
<summary><strong>Q2: Is the Topic name really secure?</strong></summary>
If you choose a random, sufficiently long name (like `trendradar-zs-8492-news`), brute-forcing is nearly impossible:
- ntfy has strict rate limits (1 request per second)
- 64 character choices (A-Z, a-z, 0-9, _, -)
- A 10-character random string has 64^10 possibilities (it would take years to crack).
</details>
---
**Recommended Choices**:
| User Type | Recommended Plan | Reason |
|-------------|------------------|----------------------------|
| Regular User| Method 1 (Free) | Simple and quick, sufficient|
| Technical User| Method 2 (Self-hosted)| Complete control, no limits|
| High-frequency User| Method 3 (Paid)| Check the official website for details.|
**Related Links**:
- [ntfy Official Documentation](https://docs.ntfy.sh/)
- [Self-hosting Tutorial](https://docs.ntfy.sh/install/)
- [GitHub Repository](https://github.com/binwiederhier/ntfy)
</details>
<details>
<summary>👉 Click to expand: <strong>Bark Push</strong> (iOS exclusive, simple and efficient)</summary>
<br>
**GitHub Secret Configuration (⚠️ Name must match exactly):**
- **Name**: `BARK_URL` (please copy and paste this name, do not type it manually)
- **Secret**: Your Bark push URL
<br>
**Introduction to Bark:**
Bark is a free and open-source push notification tool for the iOS platform, characterized by its simplicity, speed, and ad-free experience.
**Usage:**
### Method 1: Use the Official Server (Recommended for Beginners) 🆓
1. **Download the Bark App**:
- iOS: [App Store](https://apps.apple.com/cn/app/bark-给你的手机发推送/id1403753865)
2. **Obtain the Push URL**:
- Open the Bark App
- Copy the push URL displayed on the homepage (format: `https://api.day.app/your_device_key`)
- Configure the URL in GitHub Secrets under `BARK_URL`
### Method 2: Self-hosted Server (Complete Privacy Control) 🔒
**Suitable for**: Those with a server, seeking complete privacy, and possessing strong technical skills
**One-click Docker Deployment**:
```bash
docker run -d \
--name bark-server \
-p 8080:8080 \
finab/bark-server
```
**Configure TrendRadar**:
```yaml
BARK_URL: http://your-server-ip:8080/your_device_key
```
---
**Notes:**
- ✅ Bark uses APNs for push notifications, with a maximum message size of 4KB
- ✅ Supports automatic batch sending, no need to worry about overly long messages
- ✅ The push format is plain text (automatically removes Markdown syntax)
- ⚠️ Only supports iOS platform
**Related Links:**
- [Bark Official Website](https://bark.day.app/)
- [Bark GitHub Repository](https://github.com/Finb/Bark)
- [Bark Server Self-hosting Tutorial](https://github.com/Finb/bark-server)
</details>
<details>
<summary>👉 Click to expand: <strong>Slack Push</strong></summary>
<br>
**GitHub Secret Configuration (⚠️ Name must match exactly):**
- **Name**: `SLACK_WEBHOOK_URL` (please copy and paste this name, do not type it manually)
- **Secret**: Your Slack Incoming Webhook URL
<br>
**Introduction to Slack:**
Slack is a team collaboration tool, and Incoming Webhooks can push messages to Slack channels.
**Setup Steps:**
### Step 1: Create a Slack App
1. **Visit the Slack API Page**:
- Open https://api.slack.com/apps?new_app=1
- If not logged in, log into your Slack workspace first
2. **Choose Creation Method**:
- Click **"From scratch"**
3. **Fill in App Information**:
- **App Name**: Enter the application name (e.g., `TrendRadar` or `Hot News Monitoring`)
- **Workspace**: Select your workspace from the dropdown list
- Click the **"Create App"** button
### Step 2: Enable Incoming Webhooks
1. **Navigate to Incoming Webhooks**:
- Find and click **"Incoming Webhooks"** in the left menu
2. **Enable the Feature**:
- Find the **"Activate Incoming Webhooks"** switch
- Toggle the switch from `OFF` to `ON`
- The page will automatically refresh to show new configuration options
### Step 3: Generate Webhook URL
1. **Add a New Webhook**:
- Scroll to the bottom of the page
- Click the **"Add New Webhook to Workspace"** button
2. **Select Target Channel**:
- An authorization page will pop up
- Select the channel to receive messages from the dropdown list (e.g., `#Hot News`)
- ⚠️ If you want to select a private channel, you must first join that channel
3. **Authorize the App**:
- Click the **"Allow"** button to complete authorization
- The system will automatically redirect back to the configuration page
### Step 4: Copy and Save Webhook URL
1. **View the Generated URL**:
- In the "Webhook URLs for Your Workspace" area
- You will see the newly generated Webhook URL
- Format: `https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX`
2. **Copy the URL**:
- Click the **"Copy"** button to the right of the URL
- Or manually select the URL and copy it
3. **Configure in TrendRadar**:
- **GitHub Actions**: Add the URL to GitHub Secrets under `SLACK_WEBHOOK_URL`
- **Local Testing**: Fill in the `slack_webhook_url` field in `config/config.yaml` with the URL
- **Docker Deployment**: Add the URL to the `SLACK_WEBHOOK_URL` variable in the `docker/.env` file
---
**Notes:**
- ✅ Supports Markdown format (automatically converted to Slack mrkdwn)
- ✅ Supports automatic batch sending (4KB per batch)
- ✅ Suitable for team collaboration, centralized message management
- ⚠️ Webhook URL contains a key, do not expose it
**Message Format Preview:**
```
*[Batch 1/2]*
📊 *Hot Vocabulary Statistics*
🔥 *[1/3] AI ChatGPT* : 2 messages
1. [Baidu Hot Search] 🆕 ChatGPT-5 officially released *[1]* - 09:15 (1 time)
2. [Today's Headlines] AI chip concept stocks surge *[3]* - [08:30 ~ 10:45] (3 times)
```
**Related Links:**
- [Slack Incoming Webhooks Official Documentation](https://api.slack.com/messaging/webhooks)
- [Slack API App Management](https://api.slack.com/apps)
</details>
<br>
3️⃣ **Manual Testing of News Push**:
> ⚠️ Reminder:
> - After completing Steps 1-2, please test immediately! Adjust configurations as needed after successful testing (Step 4)
> - Please enter your own project, not this project!
**How to Find Your Actions Page**:
- **Method 1**: Open the homepage of your forked project and click the **Actions** tab at the top
- **Method 2**: Directly visit `https://github.com/your_username/TrendRadar/actions`
**Example Comparison**:
- ❌ Author's project: `https://github.com/sansan0/TrendRadar/actions`
- ✅ Your project: `https://github.com/your_username/TrendRadar/actions`
**Test Steps**:
1. Go to the Actions page of your project.
2. Find **"Get Hot News"** (it must be this exact wording), click on it, and then click the **"Run workflow"** button to run it.
- If you do not see this wording, refer to [#109](https://github.com/sansan0/TrendRadar/issues/109) for a solution.
3. In about 3 minutes, the messages will be pushed to the platform you configured.
<br>
> ⚠️ Reminder:
> - Do not perform manual tests too frequently to avoid triggering GitHub Actions limits.
> - After clicking Run workflow, you need to refresh the browser page to see the new run records.
<br>
4️⃣ **Configuration Instructions (Optional)**:
The default configuration is already functional. If you need personalized adjustments, understanding the following three files is sufficient:
| File | Purpose |
|------|---------|
| `config/config.yaml` | Main configuration file: push mode, time window, platform list, hot topic weights, etc. |
| `config/frequency_words.txt` | Keyword file: set the vocabulary you care about to filter push content. |
| `.github/workflows/crawler.yml` | Execution frequency: controls how often it runs (⚠️ Modify with caution). |
👉 **Detailed Configuration Tutorial**: [Configuration Details](#配置详解)
<br>
5️⃣ **GitHub Actions Check-in Renewal Mechanism & Remote Cloud Storage Configuration**:
**v4.0.0 Important Changes**: Introduced an "Activity Detection" mechanism, requiring GitHub Actions to check in regularly to maintain operation.
- **Running Period**: The validity period is **7 days**; after the countdown ends, the service will automatically suspend.
- **Renewal Method**: Manually trigger the "Check In" workflow on the Actions page to reset the 7-day validity period.
- **Operation Path**: `Actions` → `Check In` → `Run workflow`
- **Design Philosophy**:
- If you forget to check in for 7 days, perhaps this information is not essential for you. A timely pause can help you detach from the information flow and give your brain some breathing space.
- GitHub Actions is a valuable public computing resource. The introduction of the check-in mechanism aims to avoid ineffective resource usage and ensure that resources are allocated to truly active and needy users. Thank you for your understanding and support.
---
**You can also choose not to configure remote cloud storage**, but in this case, the project will be in **lightweight mode**, and some advanced features will be unavailable.
**Comparison of Two Deployment Modes**:
| Mode | Configuration Requirements | Functionality Scope |
|------|---------------------------|---------------------|
| **Lightweight Mode** | No storage configuration required | Real-time scraping + Keyword filtering + Multi-channel push |
| **Full Mode** | Configure remote cloud storage | Lightweight mode + New detection + Trend tracking + Incremental push + AI analysis |
**Lightweight Mode Description**:
- ✅ Available: Real-time news scraping, keyword filtering, hot topic weight sorting, current ranking push.
- ❌ Unavailable: New news detection (🆕), heat trend tracking, incremental mode, daily summary accumulation, MCP AI analysis.
**Full Mode Description**: After configuring remote cloud storage, all features will be unlocked. Continue with the steps below to configure.
<details>
<summary>👉 Click to expand: <strong>Remote Cloud Storage Configuration (Determines Functionality Completeness) (Optional)</strong></summary>
<br>
**⚠️ Configuration Prerequisites for Cloudflare R2 as an Example:**
According to Cloudflare platform rules, activating R2 requires binding a payment method.
* **Purpose**: For identity verification only (Verify Only), **no charges incurred**.
* **Payment**: Supports dual-currency credit cards or PayPal in the domestic region.
* **Usage**: The free quota of R2 (10GB storage/month) is sufficient to cover the daily operation of this project, so there is no need to worry about charges.
---
**GitHub Secret Configuration**:
**Required Configuration (4 items):**
| Name | Secret (Value) Description |
|------|---------------------------|
| `S3_BUCKET_NAME` | Bucket name (e.g., `trendradar-data`) |
| `S3_ACCESS_KEY_ID` | Access Key ID |
| `S3_SECRET_ACCESS_KEY` | Secret Access Key |
| `S3_ENDPOINT_URL` | S3 API endpoint (e.g., R2: `https://<account-id>.r2.cloudflarestorage.com`) |
**Optional Configuration:**
| Name | Secret (Value) Description |
|------|---------------------------|
| `S3_REGION` | Region (default `auto`, some service providers may require specification) |
> 💡 **More storage configuration options**: See [Storage Configuration Details](#11-存储配置)
<br>
**How to Obtain Credentials (Using Cloudflare R2 as an Example):**
1. **Access R2 Overview**:
- Log in to [Cloudflare Dashboard](https://dash.cloudflare.com/).
- Find and click on `R2 Object Storage` in the left sidebar.
2. **Create a Bucket**:
- Click `Overview`.
- Click the `Create Bucket` button in the upper right corner.
- Enter a name (e.g., `trendradar-data`), and click `Create Bucket`.
3. **Create an API Token**:
- Return to the **Overview** page.
- Click the **bottom right** `Account Details` to find and click `Manage` (Manage R2 API Tokens).
- You will also see `S3 API`: `https://<account-id>.r2.cloudflarestorage.com` (this is the S3_ENDPOINT_URL).
- Click `Create Account API Token`.
- **⚠️ Key Settings**:
- **Token Name**: Fill in as you like (e.g., `github-action-write`).
- **Permissions**: Select `Admin Read and Write`.
- **Specify Bucket**: For security, it is recommended to select `Only for specified buckets` and check your bucket (e.g., `trendradar-data`).
- Click `Create API Token`, and **immediately copy** the displayed `Access Key ID` and `Secret Access Key` (displayed only once!).
</details>
<br>
6️⃣ **🎉 Deployment Successful! Share Your Experience**
Congratulations on completing the configuration of TrendRadar! You can now start tracking hot news.
💬 Many others are sharing their experiences on the public account, and we look forward to your sharing~
- Want to learn more tricks and advanced techniques?
- Encountering issues that need quick answers?
- Have good ideas to discuss?
👉 Feel free to follow the public account "**[Silicon-based Tea Room](#问题答疑与交流)**", your likes and comments are the driving force for the project's continuous updates.
<br>
7️⃣ **Want Smarter Analysis? Try AI Enhanced Features** (Optional)
The basic configuration is sufficient for daily use, but if you want to:
- Let AI automatically analyze hot trends and data insights.
- Search and query news through natural language.
- Obtain sentiment analysis, topic prediction, and other in-depth analyses.
- Directly call data in AI tools like Claude, Cursor, etc.
👉 **Learn More**: [AI Intelligent Analysis](#-ai-智能分析) — Unlock the hidden capabilities of the project and make hot tracking more efficient!
<br>
<a name="配置详解"></a>
## ⚙️ Configuration Details
> **📖 Reminder**: This section provides detailed configuration instructions. It is recommended to complete the basic configuration in [Quick Start](#-快速开始) first, and then return to check detailed options as needed.
### 1. Platform Configuration
<details id="Custom Monitoring Platform">
<summary>👉 Click to expand: <strong>Custom Monitoring Platform</strong></summary>
<br>
**Configuration Location:** The `platforms` section of `config/config.yaml`
The information data for this project comes from [newsnow](https://github.com/ourongxing/newsnow). You can click on the [website](https://newsnow.busiyi.world/) and click on [More] to see if there are any platforms you want.
You can access the specific additions at [project source code](https://github.com/ourongxing/newsnow/tree/main/server/sources). Modify the `platforms` configuration in the `config/config.yaml` file according to the file names inside:
```yaml
platforms:
- id: "toutiao"
name: "今日头条"
- id: "baidu"
name: "百度热搜"
- id: "wallstreetcn-hot"
name: "华尔街见闻"
# Add more platforms...
```
> 💡 **Shortcut**: If you are not familiar with reading source code, you can copy the organized [platform configuration summary](https://github.com/sansan0/TrendRadar/issues/95) from others.
> ⚠️ **Note**: More platforms are not necessarily better. It is recommended to choose 10-15 core platforms. Too many platforms can lead to information overload, which may reduce the user experience.
</details>
### 2. Keyword Configuration
Configure the monitored keywords in the `frequency_words.txt` file, supporting seven types of syntax, regional tags, and phrase functions.
| Syntax Type | Symbol | Function | Example | Matching Logic |
|-------------|--------|----------|---------|----------------|
| **Normal Word** | None | Basic matching | `华为` | Any one must be included |
| **Must Word** | `+` | Restrict range | `+手机` | Must include all |
| **Filter Word** | `!` | Exclude interference | `!广告` | Excluded if included |
| **Quantity Limit** | `@` | Control display quantity | `@10` | Display up to 10 news articles (added in v3.2.0) |
| **Global Filter** | `[GLOBAL_FILTER]` | Globally exclude specified content | See example below | Filtered under any circumstances (added in v3.5.0) |
| **Regular Expression** | `/pattern/` | Exact matching pattern | `/\bai\b/` | Matches using regular expressions (added in v4.7.0) |
| **Display Name** | `=> Note` | Custom display text | `/\bai\b/ => AI相关` | Push and HTML display note name (added in v4.7.0) |
#### 2.1 Basic Syntax
<a name="关键词基础语法"></a>
<details>
<summary>👉 Click to expand: <strong>Basic Syntax Tutorial</strong></summary>
<br>
**Configuration Location:** `config/frequency_words.txt`
##### 1. **Common Keywords** - Basic Matching
```txt
Huawei
OPPO
Apple
```
**Function:** News titles containing **any one of these words** will be captured.
##### 2. **Must Words** `+Vocabulary` - Scope Limitation
```txt
Huawei
OPPO
+Mobile
```
**Function:** Must contain both common words **and** must words to be captured.
##### 3. **Filter Words** `!Vocabulary` - Exclude Interference
```txt
Apple
Huawei
!Fruit
!Price
```
**Function:** News containing filter words will be **directly excluded**, even if they contain keywords.
##### 4. **Quantity Limit** `@number` - Control the display quantity (added in v3.2.0)
```txt
Tesla
Musk
@5
```
**Function:** Limits the maximum number of news items displayed for this keyword group.
**Configuration Priority:** `@number` > Global Configuration > No Limit
##### 5. **Global Filter** `[GLOBAL_FILTER]` - Globally exclude specified content (added in v3.5.0)
```txt
[GLOBAL_FILTER]
ads
promotion
marketing
shocking
clickbait
[WORD_GROUPS]
technology
AI
Huawei
HarmonyOS
!car
```
**Function:** Filters news containing specified words under any circumstances, **highest priority**
**Use Cases:**
- Filter low-quality content: shocking, clickbait, leaks, etc.
- Filter marketing content: ads, promotions, sponsorships, etc.
- Filter specific topics: entertainment, gossip (as needed)
**Filtering Priority:** Global filter > Group filter (`!`) > Group match
**Area Description:**
- `[GLOBAL_FILTER]`: Global filtering area, words included will be filtered under any circumstances
- `[WORD_GROUPS]`: Group area, maintain existing syntax (`!`, `+`, `@`)
- If no area markers are used, all will be treated as groups by default (backward compatible)
**Matching Examples:**
```txt
[GLOBAL_FILTER]
ads
[WORD_GROUPS]
technology
AI
```
- ❌ "Ads: Latest technology product launch" ← Contains global filter word "ads", directly rejected
- ✅ "Technology company launches new AI product" ← Does not contain global filter word, matches "technology" group
- ✅ "AI technology breakthrough attracts attention" ← Does not contain global filter word, matches "AI" in the "technology" group
**Notes:**
- Global filter words should be used with caution to avoid excessive filtering that leads to missing valuable content
- It is recommended to keep global filter words within 5-15
- For filtering specific groups, prioritize using group filter words (with `!` prefix)
##### 6. **Regular Expression** `/pattern/` - Exact Match Pattern (added in v4.7.0)
Common keywords use substring matching, which is convenient in Chinese environments but may lead to false matches in English environments. For example, `ai` will match the `ai` in `training`.
Using the regular expression syntax `/pattern/` allows for exact matching:
```txt
/(?<![a-z])ai(?![a-z])/
Artificial Intelligence
```
**Function:** Match using regular expressions, supporting all Python regular syntax.
**Common Regular Patterns:**
| Requirement | Regular Expression | Description |
|-------------|--------------------|-------------|
| English Word Boundary | `/\bword\b/` | Matches standalone words, e.g., `/\bai\b/` matches "AI" but not "training" |
| Non-letter Before and After | `/(?<![a-z])ai(?![a-z])/` | Looser boundaries, suitable for mixed Chinese and English scenarios |
| Start Match | `/^breaking/` | Matches titles that start with "breaking" only |
| End Match | `/发布$/` | Matches titles that end with "发布" only |
| One of Many | `/苹果\|华为\|小米/` | Matches any one of them (note to escape `\|`) |
**Matching Example:**
```txt
# Configuration
/(?<![a-z])ai(?![a-z])/
Artificial Intelligence
```
- ✅ "AI is the future" ← Matches the standalone "AI"
- ✅ "你好ai这里" ← Surrounded by Chinese, matches "ai"
- ✅ "人工智能发展迅速" ← Matches "人工智能"
- ❌ "Resistance training is important" ← "ai" in "training" does not match
- ❌ "The maid cleaned the room" ← "ai" in "maid" does not match
**Combined Usage:**
```txt
# Regex + Normal Words + Filter Words
/\bai\b/
Artificial Intelligence
Machine Learning
!Advertisement
```
**Notes:**
- The regular expression automatically enables case-insensitive matching (`re.IGNORECASE`)
- Supports JavaScript-style syntax like `/pattern/i` (flags will be ignored as case-insensitivity is enabled by default)
- Invalid regex syntax will be treated as normal words
- Regex can be used for normal words, must-have words (`+`), and filter words (`!`)
**💡 Not good at writing regex? Let AI help you generate it!**
If you're not familiar with regular expressions, you can directly ask ChatGPT / Claude / DeepSeek to help you generate one. Just tell the AI:
> I need a Python regular expression to match the English word "ai," but not match "ai" in "training."
> Please provide the regex directly in the format `/pattern/`, without any additional explanation.
The AI will give you a result like this: `/(?<![a-zA-Z])ai(?![a-zA-Z])/`
##### 7. **Display Name** `=> Note` - Custom display text (added in v4.7.0)
Regular expressions may not be very user-friendly when displaying push messages and HTML pages. The `=> Note` syntax can be used to set a display name:
```txt
/(?<![a-zA-Z])ai(?![a-zA-Z])/ => AI related
Artificial Intelligence
```
**Effect:** Displays "AI related" in push messages and HTML pages instead of the complex regular expression.
**Syntax format:**
```txt
# Regex + Display Name
/pattern/ => Display Name
/pattern/i => Display Name # Supports flags syntax (flags are ignored)
/pattern/ => Display Name # Spaces around => are optional
# Common Words + Display Name
deepseek => DeepSeek Dynamic
```
**Matching Example:**
```txt
# Configuration
/(?<![a-zA-Z])ai(?![a-zA-Z])/ => AI Related
Artificial Intelligence
```
| Original Configuration | Push/HTML Display |
|-----------------------|-------------------|
| `/(?<![a-z])ai(?![a-z])/` + `人工智能` | `(?<![a-z])ai(?![a-z]) 人工智能` |
| `/(?<![a-z])ai(?![a-z])/ => AI 相关` + `人工智能` | **`AI 相关`** |
**Notes:**
- The display name should only be written on the first word of the phrase.
- If multiple words in the phrase have display names, use the first one.
- If no display name is set, all words in the phrase will be concatenated automatically.
---
#### 🔗 Phrase Function - The Important Role of Empty Lines
**Core Rule:** Use **empty lines** to separate different phrases, with each phrase being counted independently.
##### Example Configuration:
```txt
iPhone
Huawei
OPPO
+Release
A-shares
Shanghai Stock Exchange
Shenzhen Stock Exchange
+Price Change
!Prediction
World Cup
European Championship
Asian Cup
+Match
```
##### Phrase Explanation and Matching Effect:
**Group 1 - Mobile New Products:**
- Keywords: iPhone, Huawei, OPPO
- Must-have word: release
- Effect: Must include the mobile brand name and also include "release"
**Matching Examples:**
- ✅ "iPhone 15正式发布售价公布" ← Contains "iPhone" + "release"
- ✅ "华为Mate60系列发布会直播" ← Contains "Huawei" + "release"
- ✅ "OPPO Find X7发布时间确定" ← Contains "OPPO" + "release"
- ❌ "iPhone销量创新高" ← Contains "iPhone" but lacks "release"
**Group 2 - Stock Market Trends:**
- Keywords: A-shares, Shanghai Composite, Shenzhen Composite
- Must-have word: rise and fall
- Filter word: forecast
- Effect: Focus on the actual rise and fall of the stock market, excluding forecast content
**Matching Examples:**
- ✅ "A股今日大幅涨跌分析" ← Contains "A-shares" + "rise and fall"
- ✅ "上证指数涨跌幅创新高" ← Contains "Shanghai Composite" + "rise and fall"
- ❌ "专家预测A股涨跌趋势" ← Contains "A-shares" + "rise and fall" but includes "forecast"
**Group 3 - Football Events:**
- Keywords: World Cup, European Championship, Asian Cup
- Must-have word: match
- Effect: Only focus on news related to matches
#### 📝 Configuration Tips
##### 1. **From Broad to Strict**
```txt
# Step 1: Test with Broad Keywords First
Artificial Intelligence
AI
ChatGPT
# Step 2: After discovering mismatches, add necessary word restrictions
Artificial Intelligence
AI
ChatGPT
+Technology
# Step 3: After discovering the interference content, add filtering words
Artificial Intelligence
AI
ChatGPT
+Technology
!Advertisement
!Training
```
##### 2. **Avoid Over-Complexity**
❌ **Not Recommended:** A phrase contains too many words
```txt
Huawei
OPPO
Apple
Samsung
vivo
OnePlus
Meizu
+mobile
+release
+sales
!counterfeit
!repair
!second-hand
```
✅ **Recommended:** Split into multiple precise phrases
```txt
Huawei
OPPO
+new products
Apple
Samsung
+release
mobile
sales
+market
```
#### 2.2 Advanced Configuration (New in v3.2.0)
<a name="keywords-advanced-configuration"></a>
<details>
<summary>👉 Click to expand: <strong>Advanced Configuration Tutorial</strong></summary>
<br>
##### Keyword Sorting Priority
**Configuration Location:** `config/config.yaml`
```yaml
report:
sort_by_position_first: false # Sorting priority configuration
```
| Configuration Value | Sorting Rule | Applicable Scenarios |
|---------------------|--------------|----------------------|
| `false` (default) | Hotspot Count ↓ → Configuration Position ↑ | Focus on popularity trends |
| `true` | Configuration Position ↑ → Hotspot Count ↓ | Focus on personal priorities |
**Example:** Configuration order A, B, C, Hotspot counts A(3), B(10), C(5)
- `false`: B(10) → C(5) → A(3)
- `true`: A(3) → B(10) → C(5)
##### Global Display Quantity Limit
```yaml
report:
max_news_per_keyword: 10 # Maximum 10 entries displayed per keyword (0=no limit)
```
**Docker Environment Variables:**
```bash
SORT_BY_POSITION_FIRST=true
MAX_NEWS_PER_KEYWORD=10
```
**Comprehensive Example:**
```yaml
# config.yaml
report:
sort_by_position_first: true # Sort by configuration order first
max_news_per_keyword: 10 # Global default: up to 10 news items per keyword
```
# frequency_words.txt
Tesla
Musk
@20 # Focus on, display 20 entries (covers global configuration)
Huawei # Use global configuration, display 10 entries
BYD
@5 # Limit to 5 entries
```
**Final effect:** Display in configuration order Tesla (20 entries) → Huawei (10 entries) → BYD (5 entries)
</details>
### 3. Detailed Explanation of Push Modes
<details>
<summary>👉 Click to expand: <strong>Detailed Comparison of Three Push Modes</strong></summary>
<br>
**Configuration Location:** `report.mode` in `config/config.yaml`
```yaml
report:
mode: "daily" # Options: "daily" | "incremental" | "current"
```
**Docker Environment Variable:** `REPORT_MODE=incremental`
#### Detailed Comparison Table
| Mode | Target Audience | Push Timing | Display Content | Typical Use Cases |
|------|----------------|-------------|------------------|-------------------|
| **Daily Summary**<br/>`daily` | 📋 Business Managers/General Users | Scheduled push (default once per hour) | All matching news of the day<br/>+ New news section | **Example**: Check all important news of the day at 6 PM every day<br/>**Feature**: View the complete trend of the day without missing any hotspots<br/>**Note**: Will include news that has been pushed previously |
| **Current Rankings**<br/>`current` | 📰 Self-Media People/Content Creators | Scheduled push (default once per hour) | Current ranking matching news<br/>+ New news section | **Example**: Track "which topics are trending now" every hour<br/>**Feature**: Real-time understanding of current ranking changes<br/>**Note**: News that remains on the list will appear each time |
| **Incremental Monitoring**<br/>`incremental` | 📈 Investors/Traders | Push only when there is new content | Newly appeared matching frequency word news | **Example**: Monitor "Tesla", notify only when there is new information<br/>**Feature**: No duplicates, only view news that appears for the first time<br/>**Suitable for**: High-frequency monitoring, avoiding information disturbance |
#### Example of Actual Push Effects
Assuming you are monitoring the keyword "Apple" and executing once every hour:
| Time | daily Mode Push | current Mode Push | incremental Mode Push |
|-------|-----------------------|------------------------|-------------------------|
| 10:00 | News A, News B | News A, News B | News A, News B |
| 11:00 | News A, News B, News C | News B, News C, News D | **Only** News C |
| 12:00 | News A, News B, News C | News C, News D, News E | **Only** News D, News E |
**Note**:
- `daily`: Accumulates and displays all news of the day (A, B, C are all retained)
- `current`: Displays the current ranking news (ranking changes, News D enters the list, News A drops out)
- `incremental`: **Only pushes newly appeared news** (avoids duplicate interference)
#### Frequently Asked Questions
> **💡 Encountering this issue?** 👉 "Executed once every hour, the news output from the first execution still appears in the next hour's execution"
> - **Reason**: You may have selected the `daily` (daily summary) or `current` (current ranking) mode
> - **Solution**: Switch to the `incremental` (incremental monitoring) mode, which only pushes new content
#### ⚠️ Important Notes on Incremental Mode
> **Users who have selected the `incremental` mode please note:**
>
> 📌 **Incremental mode will only push notifications when there are new matching news articles**
>
> **If you haven't received any pushes for a long time, it may be due to:**
> 1. No new trending topics matching your keywords in the current period
> 2. The keyword configuration is too strict or too broad
> 3. A limited number of monitoring platforms
>
> **Solutions:**
> - Solution 1: 👉 [Optimize Keyword Configuration](#2-关键词配置) - Adjust the precision of keywords, add or modify monitored terms
> - Solution 2: Switch Push Mode - Change to `current` or `daily` mode to receive notifications at scheduled times
> - Solution 3: 👉 [Add Monitoring Platforms](#1-平台配置) - Add more news platforms to expand information sources
</details>
### 4. Hotspot Weight Adjustment
<details>
<summary>👉 Click to expand: <strong>Hotspot Weight Adjustment</strong></summary>
<br>
**Configuration Location:** The `advanced.weight` section of `config/config.yaml`
```yaml
advanced:
weight:
rank: 0.6 # Ranking weight
frequency: 0.3 # Frequency weight
hotness: 0.1 # Hotness weight
```
The current default configuration is a balanced configuration.
#### Two Core Scenarios
**Real-time Hotspot Pursuit**:
```yaml
advanced:
weight:
rank: 0.8 # Mainly focused on ranking
frequency: 0.1 # Less concerned about sustainability
hotness: 0.1
```
**Target Audience**: Self-media bloggers, marketers, users who want to quickly understand the hottest topics at the moment
**In-depth Topic Pursuit**:
```yaml
advanced:
weight:
rank: 0.4 # Moderately focused on ranking
frequency: 0.5 # Values sustained popularity within the day
hotness: 0.1
```
**Target Audience**: Investors, researchers, journalists, users who need in-depth analysis of trends
#### Adjustment Methods
1. **The sum of the three numbers must equal 1.0**
2. **Increase the one that matters most**: If ranking is important, increase `rank`; if consistency is important, increase `frequency`
3. **It is recommended to adjust by only 0.1-0.2 each time**, and observe the effects
Core idea: Users who prioritize speed and timeliness should increase the weight of ranking, while users who prioritize depth and stability should increase the weight of frequency.
### 5. Push Format Reference
<details>
<summary>👉 Click to expand: <strong>Push Format Description</strong></summary>
<br>
#### Push Example
📊 Hot Keyword Statistics
🔥 [1/3] AI ChatGPT: 2 items
1. [Baidu Hot Search] 🆕 ChatGPT-5 officially released [**1**] - 09:15 (1 time)
2. [Today's Headlines] AI chip concept stocks surge [**3**] - [08:30 ~ 10:45] (3 times)
━━━━━━━━━━━━━━━━━━━
📈 [2/3] BYD Tesla: 2 items
1. [Weibo] 🆕 BYD monthly sales break record [**2**] - 10:20 (1 time)
2. [Douyin] Tesla price reduction promotion [**4**] - [07:45 ~ 09:15] (2 times)
━━━━━━━━━━━━━━━━━━━
📌 [3/3] A-shares Stock Market: 1 item
1. [Wall Street News] A-shares midday commentary analysis [**5**] - [11:30 ~ 12:00] (2 times)
🆕 Newly added hot news (total 2 items)
**Baidu Hot Search** (1 item):
1. ChatGPT-5 officially released [**1**]
**Weibo** (1 item):
1. BYD monthly sales break record [**2**]
Last updated: 2025-01-15 12:30:15
#### Message Format Description
| Format Element | Example | Meaning | Description |
| ---------------- | --------------------------- | ------------- | ----------------------------------------- |
| 🔥📈📌 | 🔥 [1/3] AI ChatGPT | Popularity Level | 🔥 High popularity (≥10 articles) 📈 Medium popularity (5-9 articles) 📌 Normal popularity (<5 articles) |
| [Index/Total] | [1/3] | Ranking Position | The current phrase's rank among all matching phrases |
| Frequency Phrase | AI ChatGPT | Keyword Group | The phrases in the configuration file, the title must contain these words |
| : N Articles | : 2 Articles | Match Count | The total number of news articles matched by this phrase |
| [Platform Name] | [Baidu Hot Search] | Source Platform | The name of the platform to which the news belongs |
| 🆕 | 🆕 ChatGPT-5 Official Release | New Tag | A hot topic that appears for the first time in this round of scraping |
| [**Number**] | [**1**] | High Ranking | Hot searches with a rank ≤ threshold, displayed in bold red |
| [Number] | [7] | Normal Ranking | Hot searches with a rank > threshold, displayed normally |
| - Time | - 09:15 | First Time | The time when this news was first discovered |
| [Time~Time] | [08:30 ~ 10:45] | Duration | The time range from the first appearance to the last appearance |
| (N times) | (3 times) | Occurrence Frequency | The total number of occurrences during the monitoring period |
| **New Area** | 🆕 **New Hot News This Time** | New Topic Summary | A separate display of the newly emerged hot topics in this round |
### 6. Docker Deployment
**Image Description:**
TrendRadar provides two separate Docker images that can be deployed based on your needs:
| Image Name | Purpose | Description |
|------------|---------|-------------|
| `wantcat/trendradar` | News Push Service | Regularly fetches news and sends notifications (required) |
| `wantcat/trendradar-mcp` | AI Analysis Service | MCP protocol support, AI dialogue analysis (optional) |
> 💡 **Recommendation**:
> - If you only need the push functionality: Deploy only the `wantcat/trendradar` image
> - If you need AI analysis functionality: Deploy both images
<details>
<summary>👉 Click to expand: <strong>Complete Guide to Docker Deployment</strong></summary>
<br>
#### Method 1: Using docker compose (Recommended)
1. **Create project directory and configuration**:
**Method 1-A: Using git clone (Recommended, easiest)**
```bash
# Clone the project to local
git clone https://github.com/sansan0/TrendRadar.git
cd TrendRadar
```
**Method 1-B: Using wget to download configuration files**
```bash
# Create directory structure
mkdir -p trendradar/{config,docker}
cd trendradar
# Download configuration file templates
wget https://raw.githubusercontent.com/sansan0/TrendRadar/master/config/config.yaml -P config/
wget https://raw.githubusercontent.com/sansan0/TrendRadar/master/config/frequency_words.txt -P config/
# Download docker compose configuration
wget https://raw.githubusercontent.com/sansan0/TrendRadar/master/docker/.env -P docker/
wget https://raw.githubusercontent.com/sansan0/TrendRadar/master/docker/docker-compose.yml -P docker/
```
> 💡 **Note**: The key directory structure required for Docker deployment is as follows:
```
current directory/
├── config/
│ ├── config.yaml
│ └── frequency_words.txt
└── docker/
├── .env
└── docker-compose.yml
```
2. **Configuration file description**:
**Configuration division principle (v4.6.0 optimization)**:
- `config/config.yaml` - **Function configuration** (report mode, push settings, storage format, push window, etc.)
- `config/frequency_words.txt` - **Keyword configuration** (set the hot words you care about)
- `docker/.env` - **Sensitive information + Docker specific configuration** (webhook URLs, S3 keys, scheduled tasks)
> 💡 **Configuration modification takes effect**: After modifying `config.yaml`, execute `docker compose up -d` to restart the container for the changes to take effect.
**⚙️ Environment variable overriding mechanism (v3.0.5+)**
Environment variables in the `.env` file will override the corresponding configurations in `config.yaml`:
| Environment Variable | Corresponding Configuration | Example Value | Description |
|----------------------|----------------------------|---------------|-------------|
| `ENABLE_CRAWLER` | `advanced.crawler.enabled` | `true` / `false` | Whether to enable the crawler |
| `ENABLE_NOTIFICATION` | `notification.enabled` | `true` / `false` | Whether to enable notifications |
| `REPORT_MODE` | `report.mode` | `daily` / `incremental` / `current`| Report mode |
| `DISPLAY_MODE` | `report.display_mode` | `keyword` / `platform` | Display mode |
| `ENABLE_WEBSERVER` | - | `true` / `false` | Whether to automatically start the web server |
| `WEBSERVER_PORT` | - | `8080` | Web server port |
| `FEISHU_WEBHOOK_URL` | `notification.channels.feishu.webhook_url` | `https://...` | Feishu Webhook (separate multiple accounts with `;`) |
| `S3_*` | `storage.remote.*` | - | Remote storage configuration (5 parameters) |
**Configuration priority**: Environment variables > config.yaml
**Usage**:
- Modify the `.env` file to fill in the required configurations
- Or directly add in the "Environment Variables" section of the NAS/Synology Docker management interface
- Take effect after restarting the container: `docker compose up -d`
3. **Start services**:
**Option A: Start all services (push + AI analysis)**
```bash
# Pull the latest images
docker compose pull
# Start all services (trendradar + trendradar-mcp)
docker compose up -d
```
**Option B: Start only the news push service**
```bash
# Start only trendradar (scheduled fetching and pushing)
docker compose pull trendradar
docker compose up -d trendradar
```
**Option C: Start only the MCP AI analysis service**
```bash
# Start only trendradar-mcp (provides AI analysis interface)
docker compose pull trendradar-mcp
docker compose up -d trendradar-mcp
```
> 💡 **Tip**:
> - Most users only need to start `trendradar` to achieve news push functionality
> - Only start `trendradar-mcp` when you need to use Claude/ChatGPT for AI dialogue analysis
> - The two services are independent and can be flexibly combined based on needs
4. **Check running status**:
```bash
# View logs for the news push service
docker logs -f trendradar
# View logs for the MCP AI analysis service
docker logs -f trendradar-mcp
# View status of all containers
docker ps | grep trendradar
# Stop specific services
docker compose stop trendradar # Stop push service
docker compose stop trendradar-mcp # Stop MCP service
```
#### Method 2: Local Build (Developer Option)
If you need to customize the code or build your own image:
```bash
# Clone the Project
git clone https://github.com/sansan0/TrendRadar.git
cd TrendRadar
# Modify Configuration Files
vim config/config.yaml
vim config/frequency_words.txt
# Using the Build Version of Docker Compose
cd docker
cp docker-compose-build.yml docker-compose.yml
```
**Build and Start the Services**:
```bash
# Option A: Build and Start All Services
docker compose build
docker compose up -d
# Option B: Build and Start the News Push Service Only
docker compose build trendradar
docker compose up -d trendradar
# Option C: Build and Start the MCP AI Analysis Service Only
```bash
docker compose build trendradar-mcp
docker compose up -d trendradar-mcp
```
> 💡 **Architecture Parameter Description**:
> - By default, builds the `amd64` architecture image (suitable for most x86_64 servers)
> - To build the `arm64` architecture (Apple Silicon, Raspberry Pi, etc.), set the environment variable:
> ```bash
> export DOCKER_ARCH=arm64
> docker compose build
> ```
#### Image Update
```bash
```
# Method 1: Manual Update (Crawler + MCP Image)
docker pull wantcat/trendradar:latest
docker pull wantcat/trendradar-mcp:latest
docker compose down
docker compose up -d
# Method 2: Update using docker compose
```bash
docker compose pull
docker compose up -d
```
**Available Images**:
| Image Name | Purpose | Description |
|------------|---------|-------------|
| `wantcat/trendradar` | News Push Service | Regularly fetch news and push notifications |
| `wantcat/trendradar-mcp` | MCP Service | AI analysis functionality (optional) |
#### Service Management Commands
```bash
# View Running Status
docker exec -it trendradar python manage.py status
# Manually Execute the Crawler
docker exec -it trendradar python manage.py run
# View Real-time Logs
docker exec -it trendradar python manage.py logs
# Display Current Configuration
docker exec -it trendradar python manage.py config
# Display Output Files
docker exec -it trendradar python manage.py files
# Web Server Management (for Browser Access to Generated Reports)
docker exec -it trendradar python manage.py start_webserver # Start Web Server
docker exec -it trendradar python manage.py stop_webserver # Stop Web Server
docker exec -it trendradar python manage.py webserver_status # Check Web Server Status
# View Help Information
docker exec -it trendradar python manage.py help
# Restart the Container
docker restart trendradar
# Stop Container
docker stop trendradar
# Remove Container (Keep Data)
docker rm trendradar
```
> 💡 **Web Server Notes**:
> - After starting, you can access the latest reports via the browser at `http://localhost:8080`
> - Access historical reports through directory navigation (e.g., `http://localhost:8080/2025-xx-xx/`)
> - The port can be configured in the `.env` file with the `WEBSERVER_PORT` parameter
> - Auto-start: Set `ENABLE_WEBSERVER=true` in the `.env`
> - Security Note: Only static file access is provided, restricted to the output directory, and bound to local access only
#### Data Persistence
The generated reports and data are saved by default in the `./output` directory, and the data will be retained even if the container is restarted or deleted.
**📊 Web Report Access Paths**:
The daily summary HTML report generated by TrendRadar will be saved in two locations simultaneously:
| File Location | Access Method | Applicable Scenarios |
|---------------|---------------|----------------------|
| `output/index.html` | Direct access from the host | **Docker Deployment** (visible to the host through Volume mount) |
| `index.html` | Access from the root directory | **GitHub Pages** (repository root, automatically recognized by Pages) |
| `output/html/YYYY-MM-DD/daily_summary.html` | Access to historical reports | All environments (archived by date) |
**Local Access Example**:
```bash
# Method 1: Access via Web Server (Recommended, Docker Environment)
# 1. Start the Web Server
docker exec -it trendradar python manage.py start_webserver
# 2. Accessing in the Browser
http://localhost:8080 # Access the latest report (default index.html)
http://localhost:8080/html/2025-xx-xx/ # Access the report for a specific date
# Method 2: Open the file directly (local environment)
open ./output/index.html # macOS
start ./output/index.html # Windows
xdg-open ./output/index.html # Linux
# Method 3: Access Historical Archives
open ./output/html/2025-xx-xx/daily_summary.html
```
**Why are there two index.html files?**
- `output/index.html`: Docker Volume mounted to the host machine, can be opened locally
- `index.html`: Pushed to the repository by GitHub Actions, automatically deployed by GitHub Pages
> 💡 **Tip**: The contents of the two files are exactly the same, you can access either one.
#### Troubleshooting
```bash
```
# Check Container Status
docker inspect trendradar
# View Container Logs
docker logs --tail 100 trendradar
# Entering Container for Debugging
docker exec -it trendradar /bin/bash
# Verify Configuration File
docker exec -it trendradar ls -la /app/config/
```
#### MCP Service Deployment (AI Analysis Function)
If you need to use the AI analysis function, you can deploy a standalone MCP service container.
**Architecture Description**:
```mermaid
flowchart TB
subgraph trendradar["trendradar"]
A1[Scheduled News Fetching]
A2[Push Notifications]
end
subgraph trendradar-mcp["trendradar-mcp"]
B1[127.0.0.1:3333]
B2[AI Analysis API]
end
subgraph shared["Shared Volume"]
C1["config/ (ro)"]
C2["output/ (ro)"]
end
trendradar --> shared
trendradar-mcp --> shared
```
**Quick Start**:
If you have completed the deployment using [Method 1: Using Docker Compose](#方式一使用-docker-compose推荐), simply start the MCP service:
```bash
cd TrendRadar/docker
docker compose up -d trendradar-mcp
```
# View Running Status
docker ps | grep trendradar-mcp
```
**Start MCP Service Independently** (without using docker compose):
```bash
# Linux/Mac
docker run -d --name trendradar-mcp \
-p 127.0.0.1:3333:3333 \
-v $(pwd)/config:/app/config:ro \
-v $(pwd)/output:/app/output:ro \
-e TZ=Asia/Shanghai \
wantcat/trendradar-mcp:latest
# Windows PowerShell
docker run -d --name trendradar-mcp `
-p 127.0.0.1:3333:3333 `
-v ${PWD}/config:/app/config:ro `
-v ${PWD}/output:/app/output:ro `
-e TZ=Asia/Shanghai `
wantcat/trendradar-mcp:latest
```
> ⚠️ **Note**: When running separately, ensure that the `config/` and `output/` folders exist in the current directory and contain the configuration files and news data.
**Verify the service**:
```bash
# Check MCP Service Health Status
curl http://127.0.0.1:3333/mcp
# View MCP Service Logs
docker logs -f trendradar-mcp
```
**Configure in AI Client**:
After the MCP service starts, configure according to different clients:
**Cherry Studio** (recommended, GUI configuration):
- Settings → MCP Server → Add
- Type: `streamableHttp`
- URL: `http://127.0.0.1:3333/mcp`
**Claude Desktop / Cline** (JSON configuration):
```json
{
"mcpServers": {
"trendradar": {
"url": "http://127.0.0.1:3333/mcp",
"type": "streamableHttp"
}
}
}
```
> 💡 **Tip**: The MCP service only listens on the local port (127.0.0.1) for security. If remote access is needed, please configure reverse proxy and authentication yourself.
</details>
### 7. Report Configuration
<details>
<summary>👉 Click to expand: <strong>Report Related Parameter Configuration</strong></summary>
<br>
**Configuration Location:** The `report` section of `config/config.yaml`
```yaml
report:
mode: "daily" # Push mode
display_mode: "keyword" # Display mode (added in v4.6.0)
rank_threshold: 5 # Ranking highlight threshold
sort_by_position_first: false # Sorting priority
max_news_per_keyword: 0 # Maximum display quantity per keyword
reverse_content_order: false # Content order configuration
```
#### Configuration Item Details
| Configuration Item | Type | Default Value | Description |
|--------------------|--------|---------------|-------------|
| `mode` | string | `daily` | Push mode, options are `daily`/`incremental`/`current`, see [Push Mode Details](#3-推送模式详解) for more information |
| `display_mode` | string | `keyword` | Display mode, options are `keyword`/`platform`, see the explanation below |
| `rank_threshold` | int | `5` | Ranking highlight threshold, news with a rank ≤ this value will be displayed in bold |
| `sort_by_position_first` | bool | `false` | Sorting priority: `false` = sort by the number of hot topics, `true` = sort by configured position |
| `max_news_per_keyword` | int | `0` | Maximum display quantity per keyword, `0` = no limit |
| `reverse_content_order` | bool | `false` | Content order: `false` = hot vocabulary statistics first, `true` = new hot news first |
#### Display Mode Configuration (New in v4.6.0)
Controls the grouping of news in push messages and HTML reports:
| Mode | Grouping Method | Title Prefix | Applicable Scenarios |
|------------|------------------|--------------|------------------------------------|
| `keyword` (default) | Grouped by keyword | `[Platform Name]` | Users interested in specific topics |
| `platform` | Grouped by platform | `[Keyword]` | Users interested in specific platforms |
**Example Comparison:**
```
# keyword mode (Grouped by Keywords)
📊 Hot Word Statistics
🔥 [1/3] AI: 12 entries
1. [Weibo] OpenAI releases GPT-5 #1-#3 - 08:30 (5 times)
2. [Zhihu] How to view AI replacing programmers #2 - 09:15 (3 times)
# platform Mode (Grouped by Platform)
📊 Hot News Statistics
🔥 [1/4] Weibo: 12 Posts
1. [AI] OpenAI Releases GPT-5 #1-#3 - 08:30 (5 times)
2. [Trump] Trump Announces Major Policy #2 - 09:15 (3 times)
```
**Docker Environment Variable:**
```bash
DISPLAY_MODE=platform
```
#### Content Order Configuration (Added in v3.5.0)
Controls the display order of two parts of the push message and HTML report:
| Configuration Value | Display Order |
|---------------------|---------------|
| `false` (default) | ① Hot Keyword Statistics → ② New Hot News |
| `true` | ① New Hot News → ② Hot Keyword Statistics |
**Applicable Scenarios:**
- `false` (default): Suitable for users who focus on keyword matching results, viewing category statistics first.
- `true`: Suitable for users who focus on the latest updates, prioritizing new hot news.
**Docker Environment Variable:**
```bash
REVERSE_CONTENT_ORDER=true
```
#### Sorting Priority Configuration
**Example Scenario:** Configuration order A, B, C, Hotspot count A(3 items), B(10 items), C(5 items)
| Configuration Value | Display Order | Applicable Scenario |
|---------------------|---------------|---------------------|
| `false` (default) | B(10 items) → C(5 items) → A(3 items) | Focus on popularity trends |
| `true` | A(3 items) → B(10 items) → C(5 items) | Focus on personal priority |
**Docker Environment Variables:**
```bash
SORT_BY_POSITION_FIRST=true
MAX_NEWS_PER_KEYWORD=10
```
### 8. Push Time Window Configuration
<details>
<summary>👉 Click to expand: <strong>Detailed Explanation of Push Time Window Control</strong></summary>
<br>
**Configuration Location:** The `notification.push_window` section in `config/config.yaml`
```yaml
notification:
push_window:
enabled: false # Whether to enable
start: "20:00" # Start time (Beijing Time)
end: "22:00" # End time (Beijing Time)
once_per_day: true # Push only once per day
```
#### Configuration Item Details
| Configuration Item | Type | Default Value | Description |
|---------------------|------|---------------|-------------|
| `enabled` | bool | `false` | Whether to enable push time window control |
| `start` | string | `"20:00"` | Push time window start time (Beijing Time, HH:MM format) |
| `end` | string | `"22:00"` | Push time window end time (Beijing Time, HH:MM format) |
| `once_per_day` | bool | `true` | `true`=push only once within the window each day, `false`=push every time executed within the window |
#### Use Cases
| Scenario | Configuration Example |
|----------|-----------------------|
| **Work Hour Push** | `start: "09:00"`, `end: "18:00"`, `once_per_day: false` |
| **Evening Summary Push** | `start: "20:00"`, `end: "22:00"`, `once_per_day: true` |
| **Lunch Break Push** | `start: "12:00"`, `end: "13:00"`, `once_per_day: true` |
#### Important Notice
> ⚠️ **Attention GitHub Actions Users:**
> - The execution time of GitHub Actions is unstable and may vary by ±15 minutes
> - It is recommended to allow at least **2 hours** for the time range
> - If you want precise scheduled pushes, it is recommended to use **Docker deployment** on a personal server
#### Docker Environment Variables
```bash
PUSH_WINDOW_ENABLED=true
PUSH_WINDOW_START=09:00
PUSH_WINDOW_END=18:00
PUSH_WINDOW_ONCE_PER_DAY=false
```
#### Complete Configuration Example
**Scenario: Push summary once every day between 8 PM and 10 PM**
```yaml
notification:
push_window:
enabled: true
start: "20:00"
end: "22:00"
once_per_day: true
```
**Scenario: Push every hour during working hours**
```yaml
notification:
push_window:
enabled: true
start: "09:00"
end: "18:00"
once_per_day: false
```
### 9. Execution Frequency Configuration
<details>
<summary>👉 Click to expand: <strong>Automatic Run Frequency Settings</strong></summary>
<br>
**Configuration Location:** The `schedule` section of `.github/workflows/crawler.yml`
```yaml
on:
schedule:
- cron: "0 * * * *" # Runs once every hour
```
#### What is a Cron Expression?
Cron is a format for scheduled tasks, consisting of 5 parts: `Minute Hour Day Month Week`
```
┌───────────── Minute (0-59)
│ ┌───────────── Hour (0-23)
│ │ ┌───────────── Day of Month (1-31)
│ │ │ ┌───────────── Month (1-12)
│ │ │ │ ┌───────────── Day of Week (0-6, 0=Sunday)
│ │ │ │ │
* * * * *
```
#### Common Configuration Examples
| Desired Effect | Cron Expression | Description |
|----------------|-----------------|-------------|
| Run every hour | `0 * * * *` | Runs at the 0th minute of every hour (default) |
| Run every 30 minutes | `*/30 * * * *` | Runs once every 30 minutes |
| Run at 8 AM every day | `0 0 * * *` | UTC 0:00 = Beijing time 8:00 |
| Run during working hours | `*/30 0-14 * * *` | Beijing 8:00-22:00, every 30 minutes |
| Run 3 times a day | `0 0,6,12 * * *` | Beijing 8:00, 14:00, 20:00 |
#### Important Notes
> ⚠️ **Time Zone Notice**: GitHub Actions uses **UTC time**, Beijing time needs to be **minus 8 hours**
> - To run at 8:00 Beijing time → set to UTC 0:00
> - To run at 20:00 Beijing time → set to UTC 12:00
> ⚠️ **Rate Limiting**: GitHub imposes limits on the number of Actions runs per account
> - **Recommendation**: Do not set intervals shorter than 30 minutes
> - **Reason**: Running too frequently may be considered abuse, risking account suspension
> - **Actual Situation**: GitHub Actions execution times already have deviations, so setting too precisely is not very meaningful
#### Modification Method
1. Open your forked repository
2. Locate the `.github/workflows/crawler.yml` file
3. Click on edit (pencil icon)
4. Modify the expression in `cron: "0 * * * *"`
5. Click "Commit changes" to save
</details>
### 10. Multi-Account Push Configuration
<details>
<summary>👉 Click to expand: <strong>Detailed Explanation of Multi-Account Push Configuration</strong></summary>
> ### ⚠️ **Security Warning**
> **GitHub Fork users should not configure push information in `config.yaml`!**
>
> - **Risk Explanation**: `config.yaml` will be committed to a public Git repository, and configuring push information (Webhook URL, Token, etc.) will expose sensitive data.
> - **Recommended Methods**:
> - **GitHub Actions users** → Use GitHub Secrets environment variables.
> - **Docker users** → Use [`.env` file configuration](#6-docker-deployment) (the `.env` file is already in `.gitignore` and will not be committed).
> - **Local development users**: You can configure in `config.yaml` (ensure it will not be pushed to a public repository).
#### Multi-Account Push Configuration (New in v3.5.0)
- **Support for Multi-Account Configuration**: All push channels (Feishu, DingTalk, WeChat Work, Telegram, ntfy, Bark, Slack) support configuring multiple accounts.
- **Configuration Method**: Use English semicolon `;` to separate multiple account values.
- **Example**: For `FEISHU_WEBHOOK_URL`, the Secret value should be `https://webhook1;https://webhook2`.
- **Pairing Configuration**: Telegram and ntfy require that the number of paired parameters be consistent (e.g., both token and chat_id must be 2).
- **Quantity Limit**: By default, each channel supports a maximum of 3 accounts; any excess will be truncated.
**Multi-Account Configuration Examples**:
| Name | Secret Example |
|------|----------------|
| `FEISHU_WEBHOOK_URL` | `https://webhook1;https://webhook2;https://webhook3` |
| `TELEGRAM_BOT_TOKEN` | `token1;token2` |
| `TELEGRAM_CHAT_ID` | `chatid1;chatid2` |
| `NTFY_TOPIC` | `topic1;topic2` |
| `NTFY_TOKEN` | `;token2` (leave empty for the first token when there is none) |
#### Supported Channels
| Channel | Configuration Item | Pairing Required | Description |
|---------|--------------------|------------------|-------------|
| **Feishu** | `feishu_url` | No | Multiple webhook URLs |
| **DingTalk** | `dingtalk_url` | No | Multiple webhook URLs |
| **WeChat Work** | `wework_url` | No | Multiple webhook URLs |
| **Telegram** | `telegram_bot_token` + `telegram_chat_id` | ✅ Yes | The number of token and chat_id must be the same |
| **ntfy** | `ntfy_topic` + `ntfy_token` | ✅ Yes | The number of topic and token must be the same (token is optional) |
| **Bark** | `bark_url` | No | Multiple push URLs |
| **Slack** | `slack_webhook_url` | No | Multiple webhook URLs |
| **Email** | `email_to` | - | Supports multiple recipients (comma-separated), no modification needed |
#### Recommended Configuration Method 1: GitHub Actions Environment Variables
**Configuration Location**: GitHub Repo → Settings → Secrets and variables → Actions → Repository secrets
**Basic Configuration Example**:
```bash
# Multi-Account Limit
MAX_ACCOUNTS_PER_CHANNEL=3
# Feishu Multiple Accounts (3 Groups)
FEISHU_WEBHOOK_URL=https://hook1.feishu.cn/xxx;https://hook2.feishu.cn/yyy;https://hook3.feishu.cn/zzz
# Dingtalk Multiple Accounts (2 Groups)
DINGTALK_WEBHOOK_URL=https://oapi.dingtalk.com/xxx;https://oapi.dingtalk.com/yyy
# WeChat Work Multiple Accounts (2 Groups)
WEWORK_WEBHOOK_URL=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx;https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=yyy
# Bark Multiple Accounts (2 Devices)
BARK_URL=https://api.day.app/key1;https://api.day.app/key2
# Slack Multiple Accounts (2 Channels)
SLACK_WEBHOOK_URL=https://hooks.slack.com/xxx;https://hooks.slack.com/yyy
```
**Pairing Configuration Example (Telegram and ntfy)**:
<details>
<summary><strong>Telegram Pairing Configuration</strong></summary>
```bash
# ✅ Correct Configuration: 2 tokens corresponding to 2 chat_ids
TELEGRAM_BOT_TOKEN=123456:AAA-BBB;789012:CCC-DDD
TELEGRAM_CHAT_ID=-100111;-100222
# ❌ Incorrect Configuration: Inconsistent Quantity, Push Will Be Skipped
TELEGRAM_BOT_TOKEN=token1;token2;token3
TELEGRAM_CHAT_ID=id1;id2
```
**Note**: The number of `token` and `chat_id` must be exactly the same; otherwise, the push for this channel will be skipped.
</details>
<details>
<summary><strong>ntfy Pair Configuration</strong></summary>
```bash
# ✅ Correct Configuration: 3 topics, only the 2nd one requires a token
NTFY_TOPIC=topic1;topic2;topic3
NTFY_TOKEN=;token_for_topic2;
# ✅ Correct Configuration: Both topics require tokens
NTFY_TOPIC=topic1;topic2
NTFY_TOKEN=token1;token2
# ❌ Incorrect Configuration: Mismatch between topic and token counts
NTFY_TOPIC=topic1;topic2
NTFY_TOKEN=token1;token2;token3
```
**Note**:
- If a topic does not require a token, leave the corresponding position empty (between the two semicolons)
- The number of `topic` and `token` must be the same
</details>
---
#### Recommended Configuration Method 2: Docker Environment Variables (.env)
**Configuration Location**: Project root directory `docker/.env` file
**Basic Configuration Example**:
```bash
# Multi-Account Limit
MAX_ACCOUNTS_PER_CHANNEL=3
# Feishu Multiple Accounts (3 Groups)
FEISHU_WEBHOOK_URL=https://hook1.feishu.cn/xxx;https://hook2.feishu.cn/yyy;https://hook3.feishu.cn/zzz
# DingTalk Multiple Accounts (2 Groups)
DINGTALK_WEBHOOK_URL=https://oapi.dingtalk.com/xxx;https://oapi.dingtalk.com/yyy
# WeChat Work Multiple Accounts (2 Groups)
WEWORK_WEBHOOK_URL=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx;https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=yyy
# Bark Multiple Accounts (2 Devices)
BARK_URL=https://api.day.app/key1;https://api.day.app/key2
# Slack Multiple Accounts (2 Channels)
SLACK_WEBHOOK_URL=https://hooks.slack.com/xxx;https://hooks.slack.com/yyy
```
**Pairing Configuration Example (Telegram and ntfy)**:
<details>
<summary><strong>Telegram Pairing Configuration</strong></summary>
```bash
# ✅ Correct Configuration: 2 tokens corresponding to 2 chat_ids
TELEGRAM_BOT_TOKEN=123456:AAA-BBB;789012:CCC-DDD
TELEGRAM_CHAT_ID=-100111;-100222
# ❌ Incorrect Configuration: Inconsistent Quantity, Push Will Be Skipped
TELEGRAM_BOT_TOKEN=token1;token2;token3
TELEGRAM_CHAT_ID=id1;id2
```
**Note**: The number of `token` and `chat_id` must match exactly; otherwise, the push for this channel will be skipped.
</details>
<details>
<summary><strong>ntfy Pair Configuration</strong></summary>
```bash
# ✅ Correct Configuration: 3 topics, only the 2nd requires a token
NTFY_TOPIC=topic1;topic2;topic3
NTFY_TOKEN=;token_for_topic2;
# ✅ Correct Configuration: Both topics require tokens
NTFY_TOPIC=topic1;topic2
NTFY_TOKEN=token1;token2
# ❌ Incorrect Configuration: The Number of Topics and Tokens Do Not Match
NTFY_TOPIC=topic1;topic2
NTFY_TOKEN=token1;token2;token3
```
**Note**:
- If a certain topic does not require a token, leave the corresponding position empty (between the two semicolons).
- The number of `topics` and `tokens` must be the same.
</details>
---
#### Push Behavior Description
1. **Independent Push**: Each account sends independently; a failure does not affect other accounts.
2. **Partial Success Determination**: As long as one account sends successfully, the overall result is considered successful.
3. **Log Distinction**: When multiple accounts are used, the logs will display labels such as "Account 1", "Account 2", etc.
4. **Batch Interval**: Multiple accounts will increase the total sending time (the batch interval is calculated independently for each account).
#### Frequently Asked Questions
<details>
<summary><strong>Q1: What happens if there are more than 3 accounts?</strong></summary>
<br>
The system will automatically truncate to the configured maximum number and output a warning log. You can adjust the limit through `max_accounts_per_channel`.
**⚠️ Attention GitHub Actions users**:
- **It is not recommended to configure too many accounts** (suggested not to exceed 3), as it may lead to:
- **Triggering GitHub Actions rate limits**: Frequent network requests may be recognized as abnormal behavior
- **Potential account risks**: Excessive use of GitHub Actions resources may affect account status
</details>
<details>
<summary><strong>Q2: Will multiple accounts affect push speed?</strong></summary>
<br>
Yes. Each account sends independently, total time = number of accounts × time taken for a single account to send. It is recommended to control the number of accounts.
</details>
<details>
<summary><strong>Q3: How should local development users configure in config.yaml?</strong></summary>
<br>
If you are developing locally and **will not push the code to a public repository**, you can configure directly in `config/config.yaml`:
```yaml
notification:
enabled: true
channels:
feishu:
webhook_url: "https://hook1.feishu.cn/xxx;https://hook2.feishu.cn/yyy"
telegram:
bot_token: "token1;token2"
chat_id: "id1;id2"
advanced:
max_accounts_per_channel: 3
```
**⚠️ Important Reminder**:
- Ensure that `config/config.yaml` is in `.gitignore` (if you will commit code)
- Or only use it in the local development environment, **never commit to a public repository**
</details>
### 11. Storage Configuration
<details id="storage-config">
<summary>👉 Click to expand: <strong>Detailed Explanation of Storage Architecture Configuration</strong></summary>
<br>
#### Storage Backend Selection
**Configuration Location**: The `storage` section of `config/config.yaml`
Version 4.0.0 has restructured the storage architecture to support multiple storage backends:
```yaml
storage:
backend: auto # Storage backend: auto (automatic selection) / local (local SQLite) / remote (remote cloud storage)
formats:
sqlite: true # Whether to enable SQLite storage
txt: true # Whether to generate TXT snapshots
html: true # Whether to generate HTML reports
local:
data_dir: "output" # Local storage directory
retention_days: 0 # Local data retention days, 0 means permanent retention
remote:
endpoint_url: "" # S3 API endpoint
bucket_name: "" # Bucket name
access_key_id: "" # Access key ID
secret_access_key: "" # Access key
region: "" # Region (optional)
retention_days: 0 # Remote data retention days, 0 means permanent retention
pull:
enabled: false # Whether to enable pulling data from remote at startup
days: 7 # Pull data from the last N days
```
#### Backend Selection Strategy
| backend Value | Description | Applicable Scenarios |
|---------------|-------------|----------------------|
| `auto` | **Automatic Selection** (Recommended) | Smart selection based on the runtime environment:<br>• GitHub Actions → Remote<br>• Docker/Local → Local |
| `local` | Local SQLite Database | Docker deployment, local development |
| `remote` | Remote cloud storage (S3 compatible, such as Cloudflare R2) | GitHub Actions, multi-machine synchronization |
#### Remote Cloud Storage Configuration
**Environment Variables** (Recommended Method):
```bash
# GitHub Actions / Docker Environment Variables
STORAGE_BACKEND=remote # or auto
# Local/Remote Data Retention Days (0 means permanent retention)
LOCAL_RETENTION_DAYS=0
REMOTE_RETENTION_DAYS=0
# S3 Compatible Storage Configuration (Taking Cloudflare R2 as an Example)
S3_BUCKET_NAME=your-bucket-name
S3_ACCESS_KEY_ID=your-access-key-id
S3_SECRET_ACCESS_KEY=your-secret-access-key
S3_ENDPOINT_URL=https://<account-id>.r2.cloudflarestorage.com
S3_REGION=auto
# Data Pull Configuration (Optional, Sync from Remote to Local)
PULL_ENABLED=false
PULL_DAYS=7
```
**Get Credentials**: See [Quick Start - Remote Storage Configuration](#-quick-start)
#### Data Cleanup Strategy
**Automatic Cleanup**: Check and delete data that exceeds the retention days at the end of each run.
```yaml
storage:
local:
retention_days: 30 # Retain local data for the last 30 days
remote:
retention_days: 30 # Retain remote data for the last 30 days
```
**Cleanup Logic**:
- Local Storage: Delete database files with expired dates (e.g., `output/news/2025-11-10.db`, `output/rss/2025-11-10.db`)
- Remote Storage: Batch delete expired cloud objects (e.g., `news/2025-11-10.db`, `rss/2025-11-10.db`)
#### Time Zone Configuration (Added in v4.0.0)
**Global Time Zone Support**: Addresses the push time window issue for non-Chinese users.
```yaml
app:
timezone: "Asia/Shanghai" # Default China time zone
# Other examples:
# timezone: "America/Los_Angeles" # Pacific Time
# timezone: "Europe/London" # UK Time
```
**Supports all IANA Time Zone Names**: [Time Zone List](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
#### Incompatible Changes
⚠️ **v4.0.0 is incompatible with v3.x data**:
1. The database structure has been completely restructured, and old data cannot be read.
2. The file path format has changed (ISO format).
**Migration Recommendations**:
- Start collecting data anew from v4.0.0.
- If old data needs to be retained, please manually rename the directory format (not recommended).
## 🤖 AI Intelligent Analysis
TrendRadar v3.0.0 introduces AI analysis features based on **MCP (Model Context Protocol)**, allowing you to interact with news data through natural language for in-depth analysis.
### ⚠️ Read Before Use
**Important Note: AI features require local news data support**
The AI analysis feature does **not** directly query real-time data from the internet, but rather analyzes the **locally accumulated news data** (stored in the `output` folder).
#### Usage Instructions:
1. **Test Data Included**: The `output` directory by default contains hot news data for the week of **December 21, 2025 - December 27, 2025**, which can be used for a quick experience of AI features.
2. **Query Limitations**:
- ✅ You can only query data within the existing date range (December 21-27, a total of 7 days).
- ❌ Real-time news or future dates cannot be queried.
3. **Getting the Latest Data**:
- The test data is only for quick experience; **it is recommended to deploy the project yourself** to obtain real-time data.
- Follow the [Quick Start](#-快速开始) to deploy and run the project.
- After accumulating news data for at least 1 day, you can query the latest hot topics.
### 1. Quick Deployment
Cherry Studio provides a GUI configuration interface for quick deployment in 5 minutes, with the complex parts being one-click installations.
**Image and Text Deployment Tutorial**: Now updated on my [public account](#问题答疑与交流), reply with "mcp" to access.
**Detailed Deployment Tutorial**: [README-Cherry-Studio.md](README-Cherry-Studio.md)
**Deployment Mode Description**:
- **STDIO Mode (Recommended)**: After one-time configuration, no need for repeated configurations. The **Image and Text Deployment Tutorial** uses this mode as an example.
- **HTTP Mode (Alternative)**: If you encounter issues with the STDIO mode configuration, you can use the HTTP mode. The configuration method for this mode is basically the same as STDIO, but the content to copy and paste is just one line, reducing the chance of errors. The only thing to note is that you need to manually start the service each time before use. For details, please refer to the HTTP mode description at the bottom of [README-Cherry-Studio.md](README-Cherry-Studio.md).
### 2. Learning the Posture for Dialoguing with AI
**Detailed Dialog Tutorial**: [README-MCP-FAQ.md](README-MCP-FAQ.md)
> 💡 **Tip**: It is not recommended to ask multiple questions at once. If the AI model you selected cannot handle sequential calls as shown in the image below, it is advisable to switch to another one.
<img src="/_image/ai2.png" alt="mcp usage effect diagram" width="600">
<br>
## 🔌 MCP Client
TrendRadar MCP service supports the standard Model Context Protocol (MCP), allowing various AI clients that support MCP to connect for intelligent analysis.
### Supported Clients
**Notes**:
- Replace `/path/to/TrendRadar` with the actual path of your project
- Use double backslashes for Windows paths: `C:\\Users\\YourName\\TrendRadar`
- Remember to restart after saving
<details>
<summary>👉 Click to expand: <b>Claude Desktop</b></summary>
#### Configuration File Method
Edit the MCP configuration file for Claude Desktop:
**Windows**:
`%APPDATA%\Claude\claude_desktop_config.json`
**Mac**:
`~/Library/Application Support/Claude/claude_desktop_config.json`
**Configuration Content**:
```json
{
"mcpServers": {
"trendradar": {
"command": "uv",
"args": [
"--directory",
"/path/to/TrendRadar",
"run",
"python",
"-m",
"mcp_server.server"
],
"env": {},
"disabled": false,
"alwaysAllow": []
}
}
}
```
</details>
<details>
<summary>👉 Click to expand: <b>Cursor</b></summary>
#### Method 1: HTTP Mode
1. **Start HTTP Service**:
```bash
# Windows
start-http.bat
# Mac/Linux
./start-http.sh
```
2. **Configure Cursor**:
**Project-level Configuration** (Recommended):
Create a `.cursor/mcp.json` in the project root directory:
```json
{
"mcpServers": {
"trendradar": {
"url": "http://localhost:3333/mcp",
"description": "TrendRadar news hotspot aggregation analysis"
}
}
}
```
**Global Configuration**:
Create a `~/.cursor/mcp.json` in the user directory (same content)
3. **Usage Steps**:
- Restart Cursor after saving the configuration file
- Check the connected tools in the "Available Tools" section of the chat interface
- Start using: `Search for today's news related to "AI"`
#### Method 2: STDIO Mode (Recommended)
Create `.cursor/mcp.json`:
```json
{
"mcpServers": {
"trendradar": {
"command": "uv",
"args": [
"--directory",
"/path/to/TrendRadar",
"run",
"python",
"-m",
"mcp_server.server"
]
}
}
}
```
</details>
<details>
<summary>👉 Click to expand: <b>VSCode (Cline/Continue)</b></summary>
#### Cline Configuration
Add to the MCP settings of Cline:
**HTTP Mode**:
```json
{
"trendradar": {
"url": "http://localhost:3333/mcp",
"type": "streamableHttp",
"autoApprove": [],
"disabled": false
}
}
```
**STDIO Mode** (recommended):
```json
{
"trendradar": {
"command": "uv",
"args": [
"--directory",
"/path/to/TrendRadar",
"run",
"python",
"-m",
"mcp_server.server"
],
"type": "stdio",
"disabled": false
}
}
```
#### Continue Configuration
Edit `~/.continue/config.json`:
```json
{
"experimental": {
"modelContextProtocolServers": [
{
"transport": {
"type": "stdio",
"command": "uv",
"args": [
"--directory",
"/path/to/TrendRadar",
"run",
"python",
"-m",
"mcp_server.server"
]
}
}
]
}
}
```
**Usage Examples**:
```
Analyze the trend of "Tesla" popularity over the last 7 days
Generate today's hot topic summary report
Search for news related to "Bitcoin" and analyze sentiment tendency
```
</details>
<details>
<summary>👉 Click to expand: <b>Claude Code CLI</b></summary>
#### HTTP Mode Configuration
```bash
# 1. Start HTTP Service
# Windows: start-http.bat
# Mac/Linux: ./start-http.sh
# 2. Add MCP Server
claude mcp add --transport http trendradar http://localhost:3333/mcp
# 3. Verify Connection (Ensure the Service is Running)
claude mcp list
```
#### Usage Example
```bash
# Query News
claude "Search today's trending news on Zhihu, top 10"
# Trend Analysis
claude "Analyze the trend of the topic 'artificial intelligence' over the past week"
# Data Comparison
claude "Compare the attention on 'Bitcoin' between Zhihu and Weibo platforms"
```
</details>
<details>
<summary>👉 Click to expand: <b>MCP Inspector</b> (Debugging Tool)</summary>
<br>
MCP Inspector is the official debugging tool used for testing MCP connections:
#### Usage Steps
1. **Start the TrendRadar HTTP Service**:
```bash
# Windows
start-http.bat
# Mac/Linux
./start-http.sh
```
2. **Start the MCP Inspector**:
```bash
npx @modelcontextprotocol/inspector
```
3. **Connect in the Browser**:
- Visit: `http://localhost:3333/mcp`
- Test the "Ping Server" feature to verify the connection
- Check if "List Tools" returns 17 tools:
- Basic Queries: get_latest_news, get_news_by_date, get_trending_topics
- Intelligent Retrieval: search_news, find_related_news
- Advanced Analytics: analyze_topic_trend, analyze_data_insights, analyze_sentiment, aggregate_news, compare_periods, generate_summary_report
- RSS Queries: get_latest_rss, search_rss, get_rss_feeds_status
- System Management: get_current_config, get_system_status, resolve_date_range
</details>
<details>
<summary>👉 Click to expand: <b>Other Clients Supporting MCP</b></summary>
<br>
Any client that supports the Model Context Protocol can connect to TrendRadar:
#### HTTP Mode
**Service Address**: `http://localhost:3333/mcp`
**Basic Configuration Template**:
```json
{
"name": "trendradar",
"url": "http://localhost:3333/mcp",
"type": "http",
"description": "News Hotspot Aggregation Analysis"
}
```
#### STDIO Mode (Recommended)
**Basic Configuration Template**:
```json
{
"name": "trendradar",
"command": "uv",
"args": [
"--directory",
"/path/to/TrendRadar",
"run",
"python",
"-m",
"mcp_server.server"
],
"type": "stdio"
}
```
**Notes**:
- Replace `/path/to/TrendRadar` with the actual project path
- Use backslashes to escape Windows paths: `C:\\Users\\...`
- Ensure that project dependencies have been installed (the setup script has been run)
### Frequently Asked Questions
<details>
<summary>👉 Click to expand: <b>Q1: HTTP service cannot start?</b></summary>
<br>
**Check Steps**:
1. Confirm that port 3333 is not occupied:
```bash
# Windows
netstat -ano | findstr :3333
# Mac/Linux
lsof -i :3333
```
2. Check if project dependencies are installed:
```bash
# Re-run the installation script
# Windows: setup-windows.bat or setup-windows-en.bat
# Mac/Linux: ./setup-mac.sh
```
3. View detailed error logs:
```bash
uv run python -m mcp_server.server --transport http --port 3333
```
4. Try a custom port:
```bash
uv run python -m mcp_server.server --transport http --port 33333
```
</details>
<details>
<summary>👉 Click to expand: <b>Q2: Client cannot connect to MCP service?</b></summary>
<br>
**Solutions**:
1. **STDIO Mode**:
- Confirm the UV path is correct (run `which uv` or `where uv`)
- Ensure the project path is correct and does not contain Chinese characters
- Check the client error logs
2. **HTTP Mode**:
- Confirm the service is running (access `http://localhost:3333/mcp`)
- Check firewall settings
- Try using 127.0.0.1 instead of localhost
3. **General Checks**:
- Restart the client application
- Check the MCP service logs
- Use MCP Inspector to test the connection
</details>
<details>
<summary>👉 Click to expand: <b>Q3: Tool call fails or returns an error?</b></summary>
<br>
**Possible Reasons**:
1. **Data Does Not Exist**:
- Confirm that the crawler has been run (there is data in the output directory)
- Check if there is data in the queried date range
- View the available dates in the output directory
2. **Parameter Errors**:
- Check the date format: `YYYY-MM-DD`
- Confirm the platform ID is correct: `zhihu`, `weibo`, etc.
- Refer to the parameter descriptions in the tool documentation
3. **Configuration Issues**:
- Confirm that `config/config.yaml` exists
- Confirm that `config/frequency_words.txt` exists
- Check if the configuration file format is correct
</details>
<br>
## ☕ Q&A and Communication
> If you want to support this project, you can search for **Tencent Charity** on WeChat and donate to any of the **Educational Assistance** related projects as you wish.
>
> Thanks to friends who participated in **One Yuan Like**, you have been included in the top **Acknowledgment List**! Your support motivates open-source maintenance, and the personal donation code has now been removed.
>
> 🎯 If you are interested in sponsoring this project, your banner will be displayed at the top sponsor position.
- **GitHub Issues**: Suitable for targeted answers. Please provide complete information when asking questions (screenshots, error logs, system environment, etc.).
- **Public Account Communication**: Suitable for quick inquiries. It is recommended to communicate in the public comment section under related articles first; if messaging privately, please use polite language 😉
- **Contact Information**: path@linux.do
<div align="center">
| Follow Public Account |
|:---:|
| <img src="_image/weixin.png" width="400" title="Silicon-based Tea Room"/> |
</div>
<br>
## 📚 Project Related
> **4 Articles**:
- [You can leave comments below this article for the project author to answer questions via mobile](https://mp.weixin.qq.com/s/KYEPfTPVzZNWFclZh4am_g)
- [Breaking 1000 stars in 2 months: My practical experience in promoting GitHub projects](https://mp.weixin.qq.com/s/jzn0vLiQFX408opcfpPPxQ)
- [Notes on running this project after forking on GitHub](https://mp.weixin.qq.com/s/C8evK-U7onG1sTTdwdW2zg)
- [How to write articles for public accounts or news information based on this project](https://mp.weixin.qq.com/s/8ghyfDAtQZjLrnWTQabYOQ)
> **AI Development**:
- If you have niche requirements, you can definitely develop based on my project, even those with zero programming background can give it a try
- All my open-source projects use my own **AI辅助软件** (AI-assisted software) to enhance development efficiency, and this tool has been open-sourced
- **Core Functionality**: Quickly filter project code to feed to AI; you only need to supplement with your personal requirements
- **Project Address**: https://github.com/sansan0/ai-code-context-helper
### Other Projects
> 📍 Chairman Mao's Footprint Map - An interactive dynamic display of the complete trajectory from 1893 to 1976. Comrades are welcome to contribute data.
- https://github.com/sansan0/mao-map
> Bilibili (哔哩哔哩) Comment Area Data Visualization Analysis Software
- https://github.com/sansan0/bilibili-comment-analyzer
[](https://www.star-history.com/#sansan0/TrendRadar&Date)
<br>
## 📄 License
GPL-3.0 License
---
<div align="center">
[🔝 Back to Top](#trendradar)
</div>
Connection Info
You Might Also Like
awesome-mcp-servers
A collection of MCP servers.
git
A Model Context Protocol server for Git automation and interaction.
Appwrite
Build like a team of hundreds
chatbox
User-friendly Desktop Client App for AI Models/LLMs (GPT, Claude, Gemini, Ollama...)
continue
Continue is an open-source project for seamless server management.
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.