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>
Fastest <strong>30 seconds</strong> to deploy hotspot assistant - Say goodbye to invalid screen swiping, only look at the news and information you really care about
<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>
[](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://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 to be lightweight and easy to deploy
<br>
## 📑 Quick Navigation
> 💡 **Click the link below** to quickly jump to the corresponding chapter. Deployment is recommended to start with "**Quick Start**", and for detailed customization, please see "**Configuration Details**"
<div align="center">
| | | |
|:---:|:---:|:---:|
| [🚀 **Quick Start**](#-快速开始) | [AI Intelligent Analysis](#-ai-智能分析) | [⚙️ **Configuration Details**](#配置详解) |
| [Docker Deployment](#6-docker-部署) | [MCP Client](#-mcp-客户端) | [📝 **Update Log**](#-更新日志) |
| [🎯 **Core Functions**](#-核心功能) | [☕ **Supported Projects**](#-支持项目) | [📚 **Project Related**](#-项目相关) |
</div>
<br>
- Thank you to the audience who **starred the project**, **forking** is what you want, and **starring** is what I want. Having both😍 is the best support for the spirit of open source
<details>
<summary>👉 Click to expand: <strong>Acknowledgement List</strong> (Angel Round Honor Roll 🔥73+🔥)</summary>
### Early Supporter Acknowledgements
> 💡 **Special Instructions**:
>
> 1. **About the list**: The table below records the supporters in the early stage (angel round) of the project. Due to the cumbersome manual statistics in the early stage, **there are inevitably omissions or incomplete records. If there are any omissions, it is not intentional, please forgive me**.
> 2. **Future plans**: In order to return limited energy to code and function iteration, **this list will no longer be manually maintained from now on**.
>
> Regardless of whether your name is on the list, every support you give is the cornerstone of TrendRadar's ability to get to where it is today. 🙏
### Infrastructure Support
Thank you to **GitHub** for providing free infrastructure, which is the biggest prerequisite for this project to be **forked with one click** and run conveniently.
### Data Support
This project uses the API of the [newsnow](https://github.com/ourongxing/newsnow) project to obtain data from multiple platforms. Special thanks to the author for providing the service.
After contacting the author, he said that there is no need to worry about server pressure, but this is based on his kindness and trust. Please everyone:
- **Go to [newsnow project](https://github.com/ourongxing/newsnow) and star to support**
- When deploying Docker, please reasonably control the push frequency and do not exhaust the fish
### Promotion Assistance
> Thank you to the following platforms and individuals for their recommendations (arranged by time)
- [小众软件](https://mp.weixin.qq.com/s/fvutkJ_NPUelSW9OGK39aA) - Open source software recommendation platform
- [LinuxDo 社区](https://linux.do/) - A gathering place for technology enthusiasts
- [阮一峰周刊](https://github.com/ruanyf/weekly) - Influential weekly in the technology circle
### Audience Support
> Thank you to the friends who **provided financial support**. Your generosity has transformed into snacks and drinks by the keyboard, accompanying every iteration of the project.
>
> **Regarding the return of "One Yuan Appreciation"**:
> With the release of v5.0.0, the project has entered a new stage. To support the increasing API costs and caffeine consumption, the "One Yuan Appreciation" channel has now been reopened. Every bit of your support will be transformed into Tokens and motivation in the code world. 🚀 [Go to Support](#-support-project)
| Supporter | Amount | Date | Remarks |
| :-------------------------: | :----: | :----: | :-----------------------: |
| D*5 | 1.8 * 3 | 2025.11.24 | |
| *鬼 | 1 | 2025.11.17 | |
| *超 | 10 | 2025.11.17 | |
| R*w | 10 | 2025.11.17 | This agent is awesome, bro |
| J*o | 1 | 2025.11.17 | Thanks for open source, wish you success |
| *晨 | 8.88 | 2025.11.16 | Good project, studying |
| *海 | 1 | 2025.11.15 | |
| *德 | 1.99 | 2025.11.15 | |
| *疏 | 8.8 | 2025.11.14 | Thanks for open source, great project, support |
| M*e | 10 | 2025.11.14 | Open source is not easy, thank you |
| **柯 | 1 | 2025.11.14 | |
| *云 | 88 | 2025.11.13 | Good project, thanks for open source |
| *W | 6 | 2025.11.13 | |
| *凯 | 1 | 2025.11.13 | |
| 对*. | 1 | 2025.11.13 | Thanks for your TrendRadar |
| s*y | 1 | 2025.11.13 | |
| **翔 | 10 | 2025.11.13 | Good project, wish I had found it sooner, thanks for open source! |
| *韦 | 9.9 | 2025.11.13 | TrendRadar is awesome, coffee for the teacher~ |
| h*p | 5 | 2025.11.12 | Support Chinese open source power, keep it up! |
| c*r | 6 | 2025.11.12 | |
| a*n | 5 | 2025.11.12 | |
| 。*c | 1 | 2025.11.12 | Thanks for sharing open source |
| *记 | 1 | 2025.11.11 | |
| *主 | 1 | 2025.11.10 | |
| *了 | 10 | 2025.11.09 | |
| *杰 | 5 | 2025.11.08 | |
| *点 | 8.80 | 2025.11.07 | Development is not easy, support. |
| Q*Q | 6.66 | 2025.11.07 | Thanks for open source! |
| C*e | 1 | 2025.11.05 | |
| Peter Fan | 20 | 2025.10.29 | |
| M*n | 1 | 2025.10.27 | Thanks for open source |
| *许 | 8.88 | 2025.10.23 | Teacher, I'm a newbie, I've been trying for a few days and haven't got it working, please teach me |
| Eason | 1 | 2025.10.22 | Haven't figured it out yet, but you're doing a good thing |
| P*n | 1 | 2025.10.20 | |
| *杰 | 1 | 2025.10.19 | |
| *徐 | 1 | 2025.10.18 | |
| *志 | 1 | 2025.10.17 | |
| *😀 | 10 | 2025.10.16 | Like |
| **杰 | 10 | 2025.10.16 | |
| *啸 | 10 | 2025.10.16 | |
| *纪 | 5 | 2025.10.14 | TrendRadar |
| J*d | 1 | 2025.10.14 | Thank you for your tool, it's fun... |
| *H | 1 | 2025.10.14 | |
| 那*O | 10 | 2025.10.13 | |
| *圆 | 1 | 2025.10.13 | |
| P*g | 6 | 2025.10.13 | |
| Ocean | 20 | 2025.10.12 | ...really great!!! Even newbies can use it directly... |
| **培 | 5.2 | 2025.10.2 | github-yzyf1312: Long live open source |
| *椿 | 3 | 2025.9.23 | Keep it up, very good |
| *🍍 | 10 | 2025.9.21 | |
| E*f | 1 | 2025.9.20 | |
| *记 | 1 | 2025.9.20 | |
| z*u | 2 | 2025.9.19 | |
| **昊 | 5 | 2025.9.17 | |
| *号 | 1 | 2025.9.15 | |
| T*T | 2 | 2025.9.15 | Like |
| *家 | 10 | 2025.9.10 | |
| *X | 1.11 | 2025.9.3 | |
| *飙 | 20 | 2025.8.31 | From Lao Tong, thank you |
| *下 | 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
<div align="center">
> **Awaiting your presence**
>
> Looking for reliable product sponsorships.
> More than features, I value **your attitude towards users**.
> Please include your user base or feedback channels so I can see how you help users solve problems.
> [📩 Click to contact](mailto:path@linux.do)
</div>
<br>
<a name="-support-project"></a>
## ✨ Find it useful? Support it
TrendRadar is a completely open-source and free project, and continuous updates require your support.
### ❤️ Voluntary Donation
A bottle of water or a bag of spicy strips is love.
The amount is arbitrary, and 1 yuan is also a token of appreciation.
> Your donation will be used to replenish the caffeine ☕️ for carbon-based creatures and the API Token consumption 🤖 for silicon-based creatures.
<div align="center">
| WeChat Donation | Alipay Donation |
|:---:|:---:|
| <img src="https://cdn-1258574687.cos.ap-shanghai.myqcloud.com/img/%2F2025%2F07%2F17%2F2ae0a88d98079f7e876c2b4dc85233c6-9e8025.JPG" width="240" alt="微信赞赏"> | <img src="https://cdn-1258574687.cos.ap-shanghai.myqcloud.com/img/%2F2025%2F07%2F17%2F1ed4f20ab8e35be51f8e84c94e6e239b4-fe4947.JPG" width="240" alt="支付宝赞赏"> |
</div>
### 🌟 Other Ways to Support
1. **Star the project** ⭐️: Just **1 second** to move your finger and let more people see this project, which is my greatest recognition.
2. **Public welfare education assistance** 🌻: Search for **Tencent Public Welfare** on WeChat and support **education assistance** projects. Pass this kindness on to those in need.
### 🤝 Secondary Development and Citation
If you use or draw on the ideas or core code of this project in your project, you are **very welcome** to indicate the source in the README or documentation and attach the link to this repository.
> [https://github.com/sansan0/TrendRadar](https://github.com/sansan0/TrendRadar)
This will help the project's continued maintenance and community development. Thank you for your respect and support! ❤️
---
### 💬 Communication and Feedback
- **GitHub Issues**: Suitable for specific technical issues. Please provide complete information (screenshots, error logs, etc.) when asking questions, which will help to quickly locate the problem.
- **Public Account Communication**: It is recommended to communicate in the comment area under the relevant articles first. If you need to ask questions in the background, **liking/recommending** the article first is the best "door knocker". I can feel this kindness in the background (´▽`ʃ♡ƪ).
> **Friendly reminder**:
> This project is open source and shared, not a commercial product. The documentation has been put a lot of effort into, and most deployment issues can be found in [**🚀 Quick Start**](#-quick-start).
> *Please be patient and polite when asking questions, and treat the author as a friend rather than customer service, and the communication efficiency will be higher!*
<div align="center">
|Public Account Follow |
|:---:|
| <img src="_image/weixin.png" width="500" title="硅基茶水间"/> |
</div>
<br>
## 📝 Changelog
> **📌 View the latest updates**: **[Original Repository Changelog](https://github.com/sansan0/TrendRadar?tab=readme-ov-file#-更新日志)**:
- **Tip**: It is recommended to view the [Historical Updates] to clarify the specific [Function Content].
### 2026/01/28 - v5.5.0
> Like the mcp function, I won't create a new repository to maintain this small tool either. Anyway, it's purely front-end, so let's put it all together.
- Added a visual configuration editor for trendradar
### 2026/02/02 - mcp-v3.2.0
- **New read_article tool**: Read the full text of a single article (Markdown format) through Jina AI Reader
- **New read_articles_batch tool**: Batch read multiple articles (up to 5, automatically rate-limited)
- **Recommended workflow**: `search_news(query="keyword", include_url=True)` → `read_article(url=...)` to read the full text
- **Documentation update**: README-MCP-FAQ.md and README-MCP-FAQ-EN.md added Q19-Q20 article reading related instructions
<details>
<summary>👉 Click to expand: <strong>Historical Updates</strong></summary>
### 2026/01/10 - mcp-v3.0.0~v3.1.5
- **Breaking Change**: All tool return values are unified to `{success, summary, data, error}` structure
- **Asynchronous Consistency**: All 21 tool functions use `asyncio.to_thread()` to wrap synchronous calls
- **MCP Resources**: Added 4 resources (platforms, rss-feeds, available-dates, keywords)
- **RSS Enhancement**: `get_latest_rss` supports multi-day queries (days parameter), cross-date URL deduplication
- **Regular Expression Fix**: `get_trending_topics` supports `/pattern/` regular syntax and `display_name`
- **Cache Optimization**: Added `make_cache_key()` function, parameter sorting + MD5 hash ensures consistency
- **New check_version tool**: Supports checking TrendRadar and MCP Server version updates simultaneously
### 2026/01/23 - v5.4.0
- Added independent control function for AI analysis mode, optional follow_report | daily | current | incremental
- Added AI analysis time window control, supports custom running segments and daily frequency limits
- Added configuration file version management function
- Fixed several bugs
### 2026/01/19 - v5.3.0
> **Major Refactoring: AI Module Migrated to LiteLLM**
- **Unified AI Interface**: Use LiteLLM to replace manual implementation, supports 100+ AI providers
- **Simplified Configuration**: Removed `provider` field, replaced with `model: "provider/model_name"` format
- **New Features**: Automatic retry (`num_retries`), fallback models (`fallback_models`)
- **Configuration Changes**:
- `ai.provider` → Removed (merged into model)
- `ai.base_url` → `ai.api_base`
- `AI_PROVIDER` environment variable → Removed
- `AI_BASE_URL` environment variable → `AI_API_BASE`
- **Model Format Examples**:
- DeepSeek: `deepseek/deepseek-chat`
- OpenAI: `openai/gpt-4o`
- Gemini: `gemini/gemini-2.5-flash`
- Anthropic: `anthropic/claude-3-5-sonnet`
### 2026/01/17 - v5.2.0
> See config.yaml description for details
**🌐 AI Translation Function**
- **Multi-language Translation**: Supports translating push content into any language
- **Batch Translation**: Intelligent batch processing, reduces API call times
- **Custom Prompts**: Supports customizing translation style
**🔧 Configuration Architecture Optimization**
- **Independent AI Model Configuration**: Analysis and translation share model configuration
- **Unified Region Switch**: Unified management of push region display
- **Custom Region Sorting**: Supports customizing the display order of each region
**✨ AI Analysis Enhancement**
- **AI Analysis Embedded in HTML**: Analysis results are directly embedded in the HTML report, and email notifications can be used directly
- **Rich Style AI Blocks**: Gradient blue background card layout, clearly separates each analysis dimension
- **Ranking Timeline Support**: AI can obtain the precise ranking of each news at each crawling time point
- **Section Reorganization (7→4)**: Integrated into core hotspot situation, public opinion trend controversy, anomalies and weak signals, research and judgment strategy recommendations
**🔧 Multi-Model Adaptation**
- **General Parameter Passthrough**: Supports passing arbitrary advanced parameters to the API
- **Gemini Adaptation**: Native parameter support, built-in security policy relaxation
**🐛 Bug Fixes**
- Fixed several known issues, improved system stability
### 2026/01/10 - v5.0.0
> **Developer's Note**:
> A tribute to a certain C factory model that accompanied me for more than two years, but popped up `"This organization has been disabled"` right after I renewed it.
**✨ "Five Major Sections" Restructuring of Push Content**
This update restructures the push messages into regionalized sections, now clearly divided into five core sections:
1. **📊 Trending News**: Aggregation of trending topics across the entire network, precisely filtered based on your keywords.
2. **📰 RSS Subscription**: Your personalized subscription source content, supporting keyword-based grouping.
3. **🆕 Newly Added**: Real-time capture of new trending topics since the last run (marked with 🆕).
4. **📋 Independent Display Area**: Displays complete trending lists or RSS feeds from specified platforms, **completely unaffected by keyword filtering**.
5. **✨ AI Analysis Section**: Deep insights driven by AI, including trend overviews, popularity trends, and **extremely important** sentiment analysis.
**✨ AI Intelligent Analysis Push Function**
- **AI Analysis Integration**: Uses AI large models to perform in-depth analysis of push content, automatically generating trending topic overviews, keyword popularity analysis, cross-platform associations, potential impact assessments, etc.
- **Sentiment Analysis**: Adds deep sentiment recognition, accurately capturing positive, negative, controversial, or worried sentiments in public opinion.
- **Multi-AI Provider Support**: Supports DeepSeek (default, cost-effective), OpenAI, Google Gemini, and any OpenAI-compatible interface.
- **Two Push Modes**: `only_analysis` (AI analysis only), `both` (both are pushed).
- **Custom Prompts**: Customize the AI analysis role and output format through the `config/ai_analysis_prompt.txt` file.
- **Multi-Dimensional Data Analysis**: AI can analyze ranking changes, duration of popularity, cross-platform performance, trend predictions, etc.
**📋 Independent Display Area Function**
- **Complete Trending List Display**: Displays complete trending lists from specified platforms separately, unaffected by keyword filtering.
- **Independent RSS Display**: RSS feed content can be displayed completely, suitable for subscription sources with less content.
- **Flexible Configuration**: Supports configuring the list of display platforms, list of RSS feeds, and maximum number of displayed items.
**📊 Push Experience Restructuring**
- **Layout Upgrade**: Redesigned and unified statistical headers for each channel, strengthened block organization, making message hierarchy clear at a glance.
- **Configuration Simplification**: Optimized the configuration logic for notification channels such as Feishu, making it easier to get started.
- **Popularity Trend Arrows**: Added 🔺 (rising), 🔻 (falling), ➖ (stable) trend indicators to visually display changes in popularity.
- **Universal Webhook**: Supports custom Webhook URLs and JSON templates, easily adapting to any platform such as Discord, Matrix, IFTTT, etc.
**🔧 Configuration Optimization**
- **Enhanced Frequency Word Configuration**: Added `[Group Name]` syntax, supports `#` comment lines, making configuration clearer (thanks to [@songge8](https://github.com/sansan0/TrendRadar/issues/752) for the suggestion).
- **Environment Variable Support**: AI analysis-related configurations support environment variable overrides (`AI_API_KEY`, `AI_PROVIDER`, etc.).
> 💡 See [Let AI Help Me Analyze Trending Topics](#12-让-ai-帮我分析热点) for a detailed configuration tutorial.
### 2026/01/02 - v4.7.0
- **Fixed RSS HTML Display**: Fixed rendering issues caused by RSS data format mismatches, now correctly displayed by keyword grouping.
- **Added Regular Expression Syntax**: Keyword configuration supports `/pattern/` regular expression syntax, solving the problem of mis-matching English substrings (such as `ai` matching `training`) [📖 View Syntax Details](#关键词基础语法).
- **Added Display Name Syntax**: Use `=> Remarks` to give complex regular expressions an easy-to-remember name, making push messages clearer (such as `/\bai\b/ => AI相关`).
- **Can't Write Regular Expressions?** The README adds guidance on AI-generated regular expressions, telling ChatGPT/Gemini/DeepSeek what you want to match, and letting AI write it for you.
### 2025/12/30 - mcp-v2.0.0
- **Architecture Adjustment**: Removed TXT support, unified use of SQLite database.
- **RSS Query**: Added `get_latest_rss`, `search_rss`, `get_rss_feeds_status`.
- **Unified Search**: `search_news` supports the `include_rss` parameter to search both trending lists and RSS simultaneously.
### 2026/01/01 - v4.6.0
- **Fixed RSS HTML Display**: Merged RSS content into the trending list HTML page, displayed by source grouping.
- **Added 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 crawling, grouped by keyword statistics (consistent with the trending list format).
- **Storage Structure Restructuring**: Flattened directory structure `output/{type}/{date}.db`.
- **Unified Sorting Configuration**: `sort_by_position_first` affects both trending lists and RSS.
- **Configuration Structure Restructuring**: `config.yaml` is 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 Toolset, Added Aggregation Comparison Function, 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 to automatically extract trending topics
- Fixed several bugs
- Synchronously updated the Chinese and English versions of the README-MCP-FAQ.md document (Q1-Q18)
### 2025/12/20 - v4.0.3
- Added URL standardization function to solve the problem of duplicate pushes caused by dynamic parameters (such as `band_rank`) on platforms such as Weibo.
- Fixed incremental mode detection logic to correctly identify historical titles.
### 2025/12/17 - v4.0.1
- Added push record proxy method to StorageManager.
- Switched S3 client to virtual-hosted style to improve compatibility (supports more services such as Tencent Cloud COS).
### 2025/12/13 - mcp-v1.1.0
**MCP Module Update:**
- 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 Restructuring 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, such as Cloudflare R2), adapting to GitHub Actions, Docker, and local environments.
- **Database Structure Optimization**: Restructured the SQLite database table structure to improve data efficiency and query capabilities.
- **Core Code Modularization**: Split the main program logic into multiple modules of the trendradar package, significantly improving code maintainability.
- **Enhanced Features**: Implemented date format standardization, data retention policies, time zone 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 reading methods.
### 2025/12/03 - v3.5.0
**🎉 Core Function Enhancement**
1. **Multi-Account Push Support**
- All push channels (Feishu, DingTalk, Enterprise WeChat, Telegram, ntfy, Bark, Slack) support multi-account configuration
- Use semicolons `;` 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)
2. **Configurable Push Content Order**
- Added `reverse_content_order` configuration item
- Supports customizing the display order of trending vocabulary statistics and new trending news
3. **Global Filter Keywords**
- Added `[GLOBAL_FILTER]` area marker to support globally filtering content you don't want to see
- Applicable scenarios: filtering advertisements, marketing, low-quality content, etc.
**🐳 Docker Dual-Path HTML Generation Optimization**
- **Problem Fixed**: Solved the problem that `index.html` cannot be synchronized to the host machine in the Docker environment
- **Dual-Path Generation**: The daily summary HTML is generated to two locations simultaneously
- `index.html` (project root directory): for GitHub Pages access
- `output/index.html`: mounted through Docker Volume, the host machine can directly access
- **Compatibility**: Ensure that Docker, GitHub Actions, and local running environments can access the web version of the report normally
**🐳 Docker MCP Image Support**
- Added an independent MCP service image `wantcat/trendradar-mcp`
- Supports Docker deployment of AI analysis functions, providing services through the HTTP interface (port 3333)
- Dual-container architecture: The news push service and the MCP service run independently and can be scaled and restarted separately
- See [Docker Deployment - MCP Service](#6-docker-部署) for details
**🌐 Web Server Support**
- Added a built-in Web server to support accessing generated reports through a browser
- Controlled 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 automatic startup and manual control modes
**📖 Documentation Optimization**
- Added [How is the Push Content Displayed?](#7-推送内容怎么显示) section: customize push styles and content
- Added [When Will You Push to Me?](#8-什么时候给我推送) section: set push time periods
- Added [How Often to Run?](#9-多久运行一次) section: set automatic running frequency
- Added [Push to Multiple Groups/Devices](#10-推送到多个群设备) section: push to multiple recipients simultaneously
- Optimized each configuration section: uniformly added "Configuration Location" instructions
- Simplified quick start configuration instructions: three core files are clear at a glance
- Optimized [Docker Deployment](#6-docker-部署) section: added image instructions, 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, not enabled by default, existing single-account configurations are not affected
### 2025/11/26 - mcp-v1.0.3
**MCP Module Update:**
- Added date parsing tool resolve_date_range to solve the problem of inconsistent date calculations by AI models
- Supports natural language date expression parsing (this week, last 7 days, last month, etc.)
- The 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
- Enable native Markdown format: bold, links, lists, code blocks, etc.
- Remove plain text conversion, fully utilize Bark's native rendering capabilities
2. **Slack Format Precision**
- Use dedicated mrkdwn format to handle batched content
- Improve the accuracy of byte size estimation (avoid message overruns)
- Optimize link format: `<url|text>` and bold syntax: `*text*`
3. **Performance Improvement**
- Format conversion is completed during batching, avoiding secondary processing
- Accurately estimate message size, reducing the failure rate
**🔧 Upgrade Instructions**:
- **GitHub Fork Users**: Update `main.py`, `config.yaml`
### 2025/11/25 - v3.4.0
**🎉 Added Slack Push Support**
1. **Team Collaboration Push Channel**
- Supports Slack Incoming Webhooks (a globally popular team collaboration tool)
- Centralized message management, suitable for teams to share trending information
- 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](#-快速开始)
- Optimized the experience of one-click installation of MCP with setup-windows.bat and setup-windows-en.bat
**🔧 Upgrade Instructions**:
- **GitHub Fork Users**: Update `main.py`, `config/config.yaml`, `.github/workflows/crawler.yml`
### 2025/11/24 - v3.3.0
**🎉 Added Bark Push Support**
1. **iOS Exclusive Push Channel**
- Supports Bark push (based on APNs, iOS platform)
- Free and open source, simple and efficient, no advertising interference
- Supports both official servers and self-built servers
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](#-快速开始)
**🐛 Bug Fixes**
- Fixed the issue that the `ntfy_server_url` configuration in `config.yaml` does not take effect ([#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
**🎯 Added Advanced Customization Features**
1. **Keyword Sorting Priority Configuration**
- Supports two sorting strategies: popularity first vs configuration order first
- Meet different usage scenarios: trending topic tracking or personalized attention
2. **Precise Control of Display Quantity**
- Global configuration: uniformly limit the display quantity of all keywords
- Separate configuration: use the `@number` syntax to set limits for specific keywords
- Effectively control the push length and highlight key content
> 📖 **Detailed Configuration Tutorial**: [Keyword Configuration - Advanced Configuration](#关键词高级配置)
**🔧 Upgrade Instructions**:
- **GitHub Fork Users**: Update `main.py`, `config/config.yaml`
### 2025/11/18 - mcp-v1.0.2
**MCP Module Update:**
- Optimized the situation where querying today's news may incorrectly return past dates
### 2025/11/22 - v3.1.1
- **Fixed Crash Caused by Data Exceptions**: Solved the `'float' object has no attribute 'lower'` error encountered by some users in the GitHub Actions environment
- Added a dual protection mechanism: filter invalid titles (None, float, empty strings) during the data acquisition phase, and add type checking at the function call site
- Improved system stability to ensure normal operation even when the data source returns abnormal formats
**Upgrade Instructions** (GitHub Fork Users):
- Must update: `main.py`
- It is recommended to use the minor version upgrade method: copy and replace the above files
### 2025/11/20 - v3.1.0
- **Added Personal WeChat Push Support**: Enterprise WeChat applications can be pushed to personal WeChat without installing the Enterprise WeChat APP
- Supports two message formats: `markdown` (Enterprise WeChat group robot) and `text` (personal WeChat application)
- Added `WEWORK_MSG_TYPE` environment variable configuration to support multiple deployment methods such as GitHub Actions, Docker, docker compose, etc.
- The `text` mode automatically clears Markdown syntax, providing a plain text push effect
- See the "Personal WeChat Push" configuration instructions in the quick start for details
**Upgrade Instructions** (GitHub Fork Users):
- Must update: `main.py`, `config/config.yaml`
- Optional update: `.github/workflows/crawler.yml` (if using GitHub Actions deployment)
- It is recommended to use the minor version upgrade method: copy and replace the above files
### 2025/11/12 - v3.0.5
- Fixed the SSL/TLS port configuration logic error for email sending
- Optimized email service providers (QQ/163/126) to use port 465 (SSL) by default
- **Added Docker Environment Variable Support**: Core configuration items (`enable_crawler`, `report_mode`, `push_window`, etc.) support overriding through environment variables, solving the problem that 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 Update:**
- Fixed date query parameter passing error
- Unified the time parameter format for all tools
### 2025/10/31 - v3.0.4
- Solved the error caused by Feishu due to excessively long push content, and implemented batched push
### 2025/10/23 - v3.0.3
- Expanded the display range of ntfy error messages
### 2025/10/21 - v3.0.2
- Fixed ntfy push encoding issue
### 2025/10/20 - v3.0.0
**Major Update - AI Analysis Function Launched** ✨
- **Core Functions**:
- Added AI analysis server based on MCP (Model Context Protocol)
- Supports 17 intelligent analysis tools: basic query, intelligent retrieval, advanced analysis, RSS query, system management
- Natural language interaction: query and analyze news data through dialogue
- Multi-client support: Claude Desktop, Cherry Studio, Cursor, Cline, etc.
- **Analysis Capabilities**:
- Topic trend analysis (popularity tracking, life cycle, burst detection, trend prediction)
- Data insights (platform comparison, activity statistics, keyword co-occurrence)
- Sentiment analysis, similar news search, intelligent summary generation
- Historical related news retrieval, multi-mode search
- **Update Tips**:
- This is an independent AI analysis function and does not affect the existing push function
- Can be used selectively, no need to upgrade existing deployments
### 2025/10/15 - v2.4.4
- **Update Content**:
- Fixed ntfy push encoding issue + 1
- Fixed push time window judgment issue
- **Update Tips**:
- It is recommended to use [Minor Version Upgrade]
### 2025/10/10 - v2.4.3
> Thanks to [nidaye996](https://github.com/sansan0/TrendRadar/issues/98) for discovering the experience issue
- **Update Content**:
- Refactored "Silent Push Mode" to "Push Time Window Control" to improve functional understanding
- Clarified the push time window as an optional additional function that can be used with three push modes
- Improved comments and documentation descriptions to make the function positioning clearer
- **Update Tips**:
- This is just a refactoring and does not require an upgrade
### 2025/10/8 - v2.4.2
- **Update Content**:
- Fixed ntfy push encoding issue
- Fixed configuration file missing issue
- Optimized ntfy push effect
- Added github page image segmented export function
- **Update Tips**:
- It is recommended to use [Major Version Upgrade]
### 2025/10/2 - v2.4.0
**Added ntfy push notifications**
- **Core features**:
- Supports ntfy.sh public service and self-hosted servers
- **Use cases**:
- Suitable for users seeking privacy (supports self-hosting)
- Cross-platform push (iOS, Android, Desktop, Web)
- No account registration required (public server)
- Open source and free (MIT license)
- **Update Tips**:
- It is recommended to use [Major Version Update]
### 2025/09/26 - v2.3.2
- Fixed the issue of missing email notification configuration check ([#88](https://github.com/sansan0/TrendRadar/issues/88))
**Fix Description**:
- Solved the problem that the system still prompts "No webhook configured" even if the email notification is configured correctly
### 2025/09/22 - v2.3.1
- **Added email push function** to send hot news reports to email
- **Smart SMTP Recognition**: Automatically recognizes configurations for 10+ email service providers such as Gmail, QQ Mail, Outlook, and NetEase Mail
- **Beautiful HTML Format**: Email content uses the same HTML format as the web version, with beautiful layout and mobile adaptation
- **Batch Sending Support**: Supports multiple recipients, separated by commas for simultaneous sending to multiple people
- **Custom SMTP**: Customizable SMTP server and port
- Fixed Docker build network connection issues
**Instructions for use**:
- Applicable scenarios: Suitable for users who need email archiving, team sharing, and scheduled reports
- Supported mailboxes: Gmail, QQ Mail, Outlook/Hotmail, 163/126 Mail, Sina Mail, Sohu Mail, etc.
**Update Tips**:
- This update contains a lot of content. If you want to upgrade, it is recommended to use [Major Version Upgrade]
### 2025/09/17 - v2.2.0
- Added one-click saving of news images, allowing you to easily share the hot topics you are following
**Instructions for use**:
- Applicable scenario: When you have enabled the web version function according to the tutorial (GitHub Pages)
- How to use: Open the web link with 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 picture of the current news report and save it to your mobile phone album or computer desktop
- Sharing convenience: You can directly send this picture to friends, post it to Moments, or share it to work groups, so that others can also see the important information you have discovered
### 2025/09/13 - v2.1.2
- Solved the problem of news push failure caused by DingTalk's push capacity limit (using batch push)
### 2025/09/04 - v2.1.1
- Fixed the issue that docker could not run normally in some architectures
- Officially released the official Docker image wantcat/trendradar, supporting multiple architectures
- Optimized Docker deployment process, allowing for quick use without local building
### 2025/08/30 - v2.1.0
**Core improvements**:
- **Push logic optimization**: Changed from "push every time" to "controllable push within a time window"
- **Time window control**: You can set the push time range to avoid disturbing non-working hours
- **Optional push frequency**: Supports single or multiple pushes within a time period
**Update Tips**:
- This function is disabled by default and needs to be manually enabled in config.yaml to control the push time window
- Upgrading requires updating both main.py and config.yaml files at the same time
### 2025/08/27 - v2.0.4
- This version is not a function fix, but an important reminder
- Please be sure to keep your webhooks safe, do not make them public, do not make them public, do not make them public
- If you deploy this project on GitHub in a forked manner, please fill in the webhooks in GitHub Secret instead of config.yaml
- If you have exposed the webhooks or filled them in config.yaml, it is recommended to delete them and regenerate them
### 2025/08/06 - v2.0.3
- Optimize the web version effect of github page to facilitate mobile use
### 2025/07/28 - v2.0.2
- Refactor code
- Solve the problem that the version number is easily missed and modified
### 2025/07/27 - v2.0.1
**Fixed issues**:
1. The line break of the docker's shell script is CRLF, which causes execution exceptions
2. When frequency_words.txt is empty, it causes the news to be empty
- After the fix, when you choose frequency_words.txt to be empty, all news will be pushed, but due to the message push size limit, please make the following adjustments
- Option 1: Turn off mobile phone push and only select Github Pages deployment (this is the solution that can obtain the most complete information, and will reorder the hot topics of all platforms according to your custom hot search algorithm)
- Option 2: Reduce the push platform and give priority to **WeChat Work** or **Telegram**. I have done batch push functions for these two pushes (because batch push affects the push experience, and only these two platforms give a little push capacity, so I had to do batch push functions, but at least it can ensure that the information obtained is complete)
- Option 3: It can be combined with Option 2, and the mode selection current or incremental can effectively reduce the content pushed at one time
### 2025/07/17 - v2.0.0
**Major Refactoring**:
- Configuration Management Refactoring: All configurations are now managed through the `config/config.yaml` file (I still haven’t split main.py to make it easier for you to copy and upgrade)
- Running Mode Upgrade: Supports three modes - `daily` (daily summary), `current` (current list), `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 feature**: Added incremental push (configure FOCUS_NEW_ONLY at the top of main.py). This switch only cares about new topics rather than continuous popularity, and only sends notifications when there is new content.
**Fixed issue**: In some cases, occasional typesetting exceptions are caused by special symbols in the news itself.
### 2025/06/23 - v1.3.0
WeChat Work and Telegram have length limits for push messages, so I use the method of splitting and pushing messages. See the development documentation for details [WeChat Work](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 old version before this version, not only main.py needs 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 claude research for sorting out the APIs of each platform, which allowed me to quickly complete the adaptation of each platform (although the code is more redundant~
1. Support telegram, WeChat Work, DingTalk push channels, support multi-channel configuration and simultaneous push
### 2025/06/18 - v1.1.0
> **200 star⭐**, continue to cheer everyone up~ Recently, under my "instigation", many people have liked, shared, and recommended me on my official account, and I have seen the specific account's encouragement data in the background. Many have become angel round old fans (I have only been playing the official account for more than a month, although the registration was seven or eight years ago, haha, it belongs to getting on the bus early and starting late), but because you did not leave a message or send me a private message, so I cannot respond and thank you for your support one by one. Thank you all here!
2. Important update, added weight, the news you see now is the hottest and most concerned news that appears at the top
3. Update the documentation to use, because many functions have been updated recently, and the previous usage documentation was written simply by me (see the ⚙️ frequency_words.txt configuration complete tutorial below)
### 2025/06/16 - v1.0.0
1. Added a new version update prompt for the project, which is turned on by default. If you want to turn it off, you can change True to False in "FEISHU_SHOW_VERSION_UPDATE": True in main.py
### 2025/06/13+14
1. Removed the compatible code. Students who forked before will display abnormally on the same day when they directly copy the code (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 star⭐**, write a small function to help everyone cheer
The frequency_words.txt file adds a [must word] function, using the + sign
1. The must word syntax is as follows:
Tang Seng or Zhu Bajie must appear in the title at the same time to be included in the push news
```
+唐僧
+猪八戒
```
2. The priority of filtering words is higher:
If the filtering word matches Tang Seng chanting sutras in the title, it will not be displayed even if there is Tang Seng in the must word
```
+唐僧
!唐僧念经
```
### 2025/06/02
1. **Web page** and **Feishu message** support mobile phones to directly jump to detailed news
2. Optimize 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
### **Full Network Hotspot Aggregation**
- Zhihu
- Douyin
- bilibili Hot Search
- Wall Street News
- Tieba
- Baidu Hot Search
- Cailian Press Hot
- The Paper
- Phoenix Net
- Today's Headlines
- Weibo
The default is to monitor 11 mainstream platforms, and you can also add additional platforms yourself
> 💡 See [Configuration Details - Platform Configuration](#1-平台配置) for detailed configuration tutorials
### **RSS Feed Support** (New in v4.5.0)
Supports RSS/Atom feed crawling, grouped by keywords for statistics (consistent with the hot list format):
- **Unified Format**: RSS uses the same keyword matching and display format as the hot list
- **Simple Configuration**: Add RSS sources directly in `config.yaml`
- **Combined Push**: Hot list and RSS are combined into one message push
> 💡 RSS uses the same `frequency_words.txt` as the hot list for keyword filtering
### **Intelligent Push Strategy**
**Three Push Modes**:
| Mode | Applicable Scenarios | Push Features |
|------|---------|---------|
| **Daily Summary** (daily) | Enterprise managers/ordinary users | Push all matching news of the day on time (will include previously pushed news) |
| **Current List** (current) | Self-media people/content creators | Push the matching news of the current list on time (those that continue to be on the list will appear every time) |
| **Incremental Monitoring** (incremental) | Investors/traders | Only push new content, zero repetition |
> 💡 **Quick Selection Guide:**
> - Don't want to see repeated news → Use `incremental` (incremental monitoring)
> - Want to see the complete list trend → Use `current` (current list)
> - Need a daily summary report → Use `daily` (daily summary)
>
> See [Configuration Details - Detailed Explanation of Push Mode](#3-推送模式详解) for detailed comparison and configuration tutorials
**Additional Features** (Optional):
| Feature | Description | Default |
|------|------|------|
| **Push Time Window Control** | Set the push time range (such as 09:00-18:00) to avoid disturbing non-working hours | Off |
| **Content Order Configuration** | Adjust the display order of "Hot Word Statistics" and "New Hot News" (new in v3.5.0) | Statistics first |
| **Display Mode Switching** | `keyword`=grouped by keywords, `platform`=grouped by platform (new in v4.6.0) | keyword |
> 💡 See [How to display push content?](#7-推送内容怎么显示) and [When to push to me?](#8-什么时候给我推送) for detailed configuration tutorials
### **Precise Content Filtering**
Set personal keywords (such as: AI, BYD, education policy), only push relevant hot topics, and filter out irrelevant information
> 💡 **Basic Configuration Tutorial**: [Keyword Configuration - Basic Syntax](#关键词基础语法)
>
> 💡 **Advanced Configuration Tutorial**: [Keyword Configuration - Advanced Configuration](#关键词高级配置)
>
> 💡 You can also not do any filtering and completely push all hot topics (leave frequency_words.txt blank)
### **Hot Trend Analysis**
Track the change of news popularity in real time, so that you not only know "what is trending", but also understand "how the hot topic evolves"
- **Timeline Tracking**: Record the complete time span from the first appearance to the last appearance of each news
- **Popularity Change**: Statistics on the ranking changes and frequency of news in different time periods
- **New Detection**: Identify newly emerging hot topics in real time and remind you with 🆕 at the first time
- **Sustainability Analysis**: Distinguish between one-time hot topics and in-depth news that continues to ferment
- **Cross-Platform Comparison**: The ranking performance of the same news on different platforms, see the difference in media attention
> 💡 See [Message Style Description](#5-我收到的消息长什么样) for push format instructions
### **Personalized Hot Algorithm**
No longer be led by the algorithms of various platforms, TrendRadar will reorganize the hot searches of the entire network
> 💡 Three ratios can be adjusted, see [Configuration Details - Hot Weight Adjustment](#4-热点权重调整) for details
### **Multi-Channel Multi-Account Push**
Supports **WeChat Work** (+ WeChat push solution), **Feishu**, **DingTalk**, **Telegram**, **Email**, **ntfy**, **Bark**, **Slack**, messages directly reach mobile phones and mailboxes
> 💡 See [Push to multiple groups/devices](#10-推送到多个群设备) for detailed configuration tutorials
### **AI Multi-Language Translation** (New in v5.2.0)
Translate push content into any language, breaking language barriers, whether reading domestic hot topics or subscribing to overseas information through RSS, you can easily obtain it in your native language
- **One-click Translation**: Set `ai_translation.enabled: true` and the target language in `config.yaml`
- **Multi-Language Support**: Supports any language such as English, Korean, Japanese, French, etc.
- **Intelligent Batch Processing**: Automatically batch translate, reduce API call times, and save costs
- **Custom Style**: Customize translation style and terminology through `ai_translation_prompt.txt`
- **Shared Model Configuration**: Share model settings in the `ai` configuration section with the AI analysis function
```yaml
# config.yaml Quick Enable Example
ai_translation:
enabled: true
language: "English" # Target language for translation
```
> 💡 The translation function shares model configuration with the AI analysis function, you only need to configure `ai.api_key` once to use both functions at the same time
**RSS Source Reference**: The following are some RSS feed collections, which can be selected as needed
- [awesome-tech-rss](https://github.com/tuan3w/awesome-tech-rss) - Blogs and media in the fields of technology, entrepreneurship, and programming
- [awesome-rss-feeds](https://github.com/plenaryapp/awesome-rss-feeds) - RSS collection of mainstream news media in various countries around the world
> ⚠️ Some overseas media content may involve sensitive topics, and the AI model may refuse to translate. It is recommended to filter subscription sources according to actual needs
### **Flexible Storage Architecture** (Major Update in v4.0.0)
**Multi-Storage Backend Support**:
- **Remote Cloud Storage**: GitHub Actions environment default, supports S3 compatible protocol (R2/OSS/COS, etc.), data is stored in the cloud without polluting the warehouse
- **Local SQLite Database**: Docker/local environment default, data is completely controllable
- **Automatic Backend Selection**: Intelligently switch storage methods according to the running environment
> 💡 See [Where is the data stored?](#11-数据保存在哪里) for detailed instructions
### **Multi-Terminal Deployment**
- **GitHub Actions**: Scheduled automatic crawling + remote cloud storage (need to check in for renewal)
- **Docker Deployment**: Supports multi-architecture containerized operation, data is stored locally
- **Local Run**: Windows/Mac/Linux run directly
### **AI Analysis Push (New in v5.0.0)**
Use AI large models to deeply analyze push content and automatically generate hot insight reports
- **Intelligent Analysis**: Automatically analyze hot trends, keyword popularity, cross-platform associations, and potential impacts
- **Multi-Provider**: Supports DeepSeek, OpenAI, Gemini, and OpenAI compatible interfaces
- **Flexible Push**: Optional original content only, AI analysis only, or both
- **Custom Prompts**: Customize analysis angles through `config/ai_analysis_prompt.txt`
> 💡 See [Let AI help me analyze hot topics](#12-让-ai-帮我分析热点) for detailed configuration tutorials
### **Independent Display Area (New in v5.0.0)**
Provide complete hot list display for designated platforms, unaffected by keyword filtering
- **Complete Hot List**: Complete display of the hot list of the designated platform, suitable for users who want to see the complete ranking
- **RSS Independent Display**: RSS source content can be completely displayed, without keyword restrictions
- **Flexible Configuration**: Supports configuring display platforms, RSS sources, and maximum number of entries
> 💡 See [How to display push content? - Independent Display Area](#7-推送内容怎么显示) for detailed configuration tutorials
### **AI Intelligent Analysis (New in v3.0.0)**
AI dialogue analysis system based on MCP (Model Context Protocol) protocol, allowing you to deeply mine news data in natural language
> **💡 Usage Tips**: AI function requires local news data support
> - The project comes with test data, you can immediately experience the function
> - It is recommended to deploy and run the project yourself to obtain more real-time data
>
> See [AI Intelligent Analysis](#-ai-智能分析) for details
### **Web Page Deployment**
After running, `index.html` is generated in the root directory, which is the complete news report page.
> **Deployment Method**: Click **Use this template** to create a repository, which can be deployed to static hosting platforms such as Cloudflare Pages or GitHub Pages.
>
> **💡 Tips**: Enable GitHub Pages to get an online access address, enter the repository Settings → Pages to enable it. [Effect Preview](https://sansan0.github.io/TrendRadar/)
>
> ⚠️ The original GitHub Actions automatic storage function has been offline (this solution once caused excessive load on the GitHub server, affecting platform stability).
### **Reduce APP Dependence**
From "being kidnapped by algorithm recommendations" to "actively obtaining the information you want"
**Suitable for:** Investors, self-media people, corporate public relations, ordinary users who care about current affairs
**Typical Scenarios:** Stock market investment monitoring, brand public opinion tracking, industry dynamic attention, life information acquisition
| Web Page Effect (Email Push Effect) | Feishu Push Effect | AI Analysis Push Effect |
|:---:|:---:|:---:|
|  |  |  |
<br>
## 🚀 Quick Start
> **Reminder**: It is recommended to first **[View the latest official documentation](https://github.com/sansan0/TrendRadar?tab=readme-ov-file)** to ensure that the configuration steps are the latest.
### Please choose the deployment method that suits you
#### 🅰️ Option 1: Docker Deployment (Recommended 🔥)
* **Features**: More stable than GitHub Actions, data is stored locally (no need to configure cloud storage)
* **Applicable**: Have your own server, NAS or long-running computer
* **Note**: You need to read and understand the basic configuration process below, and then jump to the Docker tutorial for deployment.
#### 🅱️ Option 2: GitHub Actions Deployment (Content of this chapter ⬇️)
* **Features**: Serverless, data is stored in **remote cloud storage** (recommended configuration)
* **Applicable**: Users who do not have a server, use GitHub free resources
* **Note**: You need to configure cloud storage to get the complete experience, and you need to check in regularly for renewal
### 1️⃣ Step 1: Get the Project Code
Click the green **[Use this template]** button in the upper right corner of this repository page → select "Create a new repository".
> ⚠️ Reminder:
> - "Fork" mentioned in subsequent documents can be understood as "Use this template"
> - Using Fork may cause abnormal operation, see [Issue #606](https://github.com/sansan0/TrendRadar/issues/606)
<br>
### 2️⃣ Step 2: Set Up GitHub Secrets
In your forked repository, go to `Settings` > `Secrets and variables` > `Actions` > `New repository secret`
**📌 Important Notes (Please Read Carefully):**
- **One Name for One Secret**: For each configuration item you add, click the "New repository secret" button once and fill in a pair of "Name" and "Secret".
- **It's Normal Not to See the Value After Saving**: For security reasons, you can only see the Name when you re-edit after saving, not the content of the Secret (value).
- **Do Not Create Names Yourself**: The Name of the Secret must **strictly use** the names listed below (such as `WEWORK_WEBHOOK_URL`, `FEISHU_WEBHOOK_URL`, etc.). You cannot modify or create new names at will, otherwise the system will not be able to recognize them.
- **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 配置示例"/>
As shown in the figure above, each line is a configuration item:
- **Name**: You must use the fixed names listed in the expanded content below (such as `WEWORK_WEBHOOK_URL`).
- **Secret**: Fill in the actual content you obtained from the corresponding platform (such as Webhook address, Token, etc.).
<br>
<details>
<summary>👉 Click to Expand: <strong>WeCom Robot</strong> (Easiest and Fastest to Configure)</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 WeCom robot Webhook address
<br>
**Robot Setup Steps:**
#### Mobile Setup:
1. Open the WeCom App → Enter the target internal group chat
2. Click the "…" button in the upper right corner → Select "Message Push"
3. Click "Add" → Enter "TrendRadar" for the name
4. Copy the Webhook address, click save, and configure the copied content into the GitHub Secret above
#### PC Setup Process is Similar
</details>
<details>
<summary>👉 Click to Expand: <strong>Personal WeChat Push</strong> (Based on WeCom Application, Push to Personal WeChat)</summary>
<br>
> Since this solution is based on the WeCom plugin mechanism, the push style is plain text (no markdown format), but it can be directly pushed to personal WeChat without installing the WeCom 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 WeCom 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 WeCom robot Webhook setup above
2. Add the `WEWORK_MSG_TYPE` Secret and set the value to `text`
3. Follow the image below to associate with personal WeChat
4. After configuration, the WeCom App on your phone can be deleted
<img src="_image/wework.png" title="个人微信推送配置"/>
**Note**:
- Uses the same Webhook address as the WeCom robot
- The difference lies in the message format: `text` is plain text, `markdown` is rich text (default)
- Plain text format will automatically remove all markdown syntax (bold, links, etc.)
</details>
<details>
<summary>👉 Click to Expand: <strong>Lark Robot</strong> (Relatively Friendly Message Display)</summary>
<br>
If **AI Analysis** is enabled, Lark push may have a delay of several minutes occasionally (approximately 5% probability) (speculated to be the platform's compliance review of AI-generated content).
**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 Lark robot Webhook address (the link starts like https://www.feishu.cn/flow/api/trigger-webhook/********)
<br>
There are two solutions, **Solution 1** is simple to configure, and **Solution 2** is complex to configure (but stable push)
Among them, Solution 1 was discovered and suggested by **ziventian**, thank him here, the default is personal push, and you can also configure group push operations [#97](https://github.com/sansan0/TrendRadar/issues/97) ,
**Solution 1:**
> There are extra operations for some people, otherwise it will report "System Error". You need to search for the robot on the mobile phone and then turn on the Lark robot application (this suggestion comes from netizens, for reference)
1. Open https://botbuilder.feishu.cn/home/my-command in your computer browser
2. Click "New Robot Command"
3. Click "Select Trigger", scroll down, and click "Webhook Trigger"
4. At this time, you will see the "Webhook Address". Copy this link to a local notepad for temporary storage and continue with the following operations
5. Put the following content in "Parameters" and click "Complete"
```json
{
"message_type": "text",
"content": {
"text": "{{内容}}"
}
}
```
6. Click "Select Action" > "Send Message via Official Robot"
7. Fill in "TrendRadar Hotspot Monitoring" for the message title
8. The most critical part is here, click the + button, select "Webhook Trigger", and then place it according to the picture below

9. After the configuration is complete, configure the Webhook address copied in step 4 into `FEISHU_WEBHOOK_URL` in GitHub Secrets
<br>
**Solution 2:**
1. Open https://botbuilder.feishu.cn/home/my-app in your computer browser
2. Click "New Robot Application"
3. After entering the created application, click "Process Design" > "Create Process" > "Select Trigger"
4. Scroll down and click "Webhook Trigger"
5. At this time, you will see the "Webhook Address". Copy this link to a local notepad for temporary storage and continue with the following operations
6. Put the following content in "Parameters" and click "Complete"
```json
{
"message_type": "text",
"content": {
"text": "{{内容}}"
}
}
```
7. Click "Select Action" > "Send Lark Message", check "Group Message", then click the input box below, and click "Groups I Manage" (if there are no groups, you can create a group on the Lark app)
8. Fill in "TrendRadar Hotspot Monitoring" for the message title
9. The most critical part is here, click the + button, select "Webhook Trigger", and then place it according to the picture below

10. After the configuration is complete, configure the Webhook address copied in step 5 into `FEISHU_WEBHOOK_URL` in GitHub Secrets
</details>
<details>
<summary>👉 Click to Expand: <strong>DingTalk Robot</strong></summary>
<br>
**GitHub Secret Configuration (⚠️ Name Must Be Strictly Consistent):**
- **Name**: `DINGTALK_WEBHOOK_URL` (Please copy and paste this name, do not type it manually)
- **Secret**: Your DingTalk robot Webhook address
<br>
**Robot Setup Steps:**
1. **Create Robot (PC Only)**:
- Open the DingTalk PC client and enter the target group chat
- Click the group settings icon (⚙️) → Scroll down to find "Robot" and click it
- Select "Add Robot" → "Custom"
2. **Configure Robot**:
- Set the robot name
- **Security Settings**:
- **Custom Keywords**: Set "Hotspot"
3. **Complete Setup**:
- Check the terms of service agreement → Click "Complete"
- Copy the obtained Webhook URL
- Configure the URL into `DINGTALK_WEBHOOK_URL` in GitHub Secrets
**Note**: The mobile client can only receive messages and cannot create new robots.
</details>
<details>
<summary>👉 Click to Expand: <strong>Telegram Bot</strong></summary>
<br>
**GitHub Secret Configuration (⚠️ Name Must Be Strictly Consistent):**
- **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 needs to configure **two** Secrets, please click the "New repository secret" button twice to add them separately
<br>
**Robot Setup Steps:**
1. **Create Robot**:
- Search for `@BotFather` in Telegram (pay attention to capitalization, there is a blue badge checkmark, and there are similar 37849827 monthly users, this is the official one, pay attention to identifying some imitation official accounts)
- Send the `/newbot` command to create a new robot
- Set the robot name (must end with "bot", it is easy to encounter duplicate names, so you have to rack your brains to think of different names)
- Get the Bot Token (format such as: `123456789:AAHfiqksKZ8WmR2zSjiQ7_v4TMAKdiHm9T0`)
2. **Get Chat ID**:
**Method 1: Get via Official API**
- First send a message to your robot
- Visit: `https://api.telegram.org/bot<YourBotToken>/getUpdates`
- Find the number in `"chat":{"id":数字}` in the returned JSON
**Method 2: Use Third-Party Tool**
- Search for `@userinfobot` and send `/start`
- Get your user ID as the Chat ID
3. **Configure to 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 Push</strong> (Supports All Mainstream Email Services)</summary>
<br>
- Note: To prevent the email mass sending function from being **abused**, the current mass sending allows all recipients to see each other's email addresses.
- If you have not had the experience of configuring the following email sending, it is not recommended to try
> ⚠️ **Important Configuration Dependency**: Email push requires an HTML report file. Please ensure that `storage.formats.html` in `config/config.yaml` is set to `true`:
> ```yaml
> storage:
> formats:
> sqlite: true
> txt: false
> html: true # Must be enabled, otherwise email push will fail
> ```
> If set to `false`, an error will be reported during email push: `Error: HTML file does not exist or is not provided: None`
<br>
**GitHub Secret Configuration (⚠️ Name Must Be Strictly Consistent):**
- **Name**: `EMAIL_FROM` (Please copy and paste this name, do not type it manually)
- **Secret**: Sender 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 email address (multiple recipients are separated by commas, or it can be the same as EMAIL_FROM, sending 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 identify)
- **Name**: `EMAIL_SMTP_PORT` (Optional configuration, please copy and paste this name)
- **Secret**: SMTP port (can be left blank, the system will automatically identify)
**Note**: Email push requires configuring at least **3 required** Secrets (EMAIL_FROM, EMAIL_PASSWORD, EMAIL_TO), the last two are optional configurations
<br>
**Supported Email Service Providers** (Automatic Identification of SMTP Configuration):
| Email Service Provider | Domain | SMTP Server | Port | Encryption Method |
|-----------|------|------------|------|---------|
| **Gmail** | gmail.com | smtp.gmail.com | 587 | TLS |
| **QQ Email** | 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 Email** | 163.com | smtp.163.com | 465 | SSL |
| **126 Email** | 126.com | smtp.126.com | 465 | SSL |
| **Sina Email** | sina.com | smtp.sina.com | 465 | SSL |
| **Sohu Email** | sohu.com | smtp.sohu.com | 465 | SSL |
| **Tianyi Email** | 189.cn | smtp.189.cn | 465 | SSL |
| **Alibaba Cloud Email** | aliyun.com | smtp.aliyun.com | 465 | TLS |
| **Yandex Email** | yandex.com | smtp.yandex.com | 465 | TLS |
| **iCloud Email** | icloud.com | smtp.mail.me.com | 587 | SSL |
> **Automatic Identification**: When using the above email services, there is no need to manually configure `EMAIL_SMTP_SERVER` and `EMAIL_SMTP_PORT`, the system will automatically identify them.
>
> **Feedback Instructions**:
> - If you successfully tested with **other email services**, you are welcome to open [Issues](https://github.com/sansan0/TrendRadar/issues) to inform us, and I will add them to the support list
> - If the above email configuration is incorrect or cannot be used, please also open [Issues](https://github.com/sansan0/TrendRadar/issues) to provide feedback to help improve the project
>
> **Special Thanks**:
> - Thanks to [@DYZYD](https://github.com/DYZYD) for contributing the Tianyi Email (189.cn) configuration and completing the self-sending and receiving test ([#291](https://github.com/sansan0/TrendRadar/issues/291))
> - Thanks to [@longzhenren](https://github.com/longzhenren) for contributing the Alibaba Cloud Email (aliyun.com) configuration and completing the test ([#344](https://github.com/sansan0/TrendRadar/issues/344))
> - Thanks to [@ACANX](https://github.com/ACANX) for contributing the Yandex Email (yandex.com) configuration and completing the test ([#663](https://github.com/sansan0/TrendRadar/issues/663))
> - Thanks to [@Sleepy-Tianhao](https://github.com/Sleepy-Tianhao) for contributing the iCloud Email (icloud.com) configuration and completing the test ([#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 letters)
4. Fill in the authorization code for `EMAIL_PASSWORD`, not the QQ password
#### Gmail:
1. Enable two-step verification
2. Generate an app-specific password
3. Fill in the app-specific password for `EMAIL_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 the authorization code for `EMAIL_PASSWORD`
<br>
**Advanced Configuration**:
If automatic identification fails, you can manually configure SMTP:
- `EMAIL_SMTP_SERVER`: such as smtp.gmail.com
- `EMAIL_SMTP_PORT`: such as 587 (TLS) or 465 (SSL)
<br>
**If there are multiple recipients (note that they are separated by 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 Ways to Use:**
### Method 1: Free to Use (Recommended for Beginners) 🆓
**Features**:
- ✅ No need to register an account, use immediately
- ✅ 250 messages per day (enough for 90% of users)
- ✅ Topic name is the "password" (need to choose a name that is not easy to guess)
- ⚠️ Messages are not encrypted, not suitable for sensitive information, but suitable for the non-sensitive information of our project
**Quick Start:**
1. **Download 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 numbers}
Cannot use Chinese
✅ Good example: trendradar-zs-8492
❌ Bad examples: news, alerts (too easy to guess)
```
3. **Configure GitHub Secret (⚠️ Name must be strictly consistent):**
- **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 required 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 (Full Privacy Control) 🔒
**Suitable for:** Those with servers, pursuing complete privacy, and strong technical skills
**Advantages:**
- ✅ Fully open source (Apache 2.0 + GPLv2)
- ✅ Data is completely self-controlled
- ✅ No restrictions
- ✅ Zero cost
**Docker One-Click 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 available 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
---
**Common questions:**
<details>
<summary><strong>Q1: Is the free version sufficient?</strong></summary>
250 messages per day is sufficient for most users. Calculated at a crawl every 30 minutes, 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, long enough name (such as `trendradar-zs-8492-news`), brute-force cracking is almost impossible:
- ntfy has strict rate limits (1 request per second)
- 64 character choices (A-Z, a-z, 0-9, _, -)
- A 10-digit random string has 64^10 possibilities (takes years to crack)
</details>
---
**Recommended options:**
| User Type | Recommended Solution | Reason |
|---------|---------|------|
| General User | Method 1 (Free) | Simple and fast, sufficient |
| Technical User | Method 2 (Self-Hosted) | Full control, no restrictions |
| High-Frequency User | Method 3 (Paid) | Check the official website yourself |
**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 be strictly consistent):**
- **Name:** `BARK_URL` (Please copy and paste this name, do not type it manually)
- **Secret:** Your Bark Push URL
<br>
**Bark Introduction:**
Bark is a free and open-source push tool for the iOS platform, characterized by simplicity, speed, and no ads.
**How to use:**
### Method 1: Use the official server (recommended for beginners) 🆓
1. **Download Bark App:**
- iOS: [App Store](https://apps.apple.com/cn/app/bark-给你的手机发推送/id1403753865)
2. **Get Push URL:**
- Open Bark App
- Copy the push URL displayed on the homepage (format such as: `https://api.day.app/your_device_key`)
- Configure the URL to `BARK_URL` in GitHub Secrets
### Method 2: Self-built server (full privacy control) 🔒
**Suitable for:** Those with servers, pursuing complete privacy, and strong technical skills
**Docker One-Click 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
```
---
**Precautions:**
- ✅ Bark uses APNs push, the maximum message size is 4KB
- ✅ Supports automatic batch push, no need to worry about messages being too long
- ✅ 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-Building Tutorial](https://github.com/Finb/bark-server)
</details>
<details>
<summary>👉 Click to expand: <strong>Slack Push</strong></summary>
<br>
**GitHub Secret Configuration (⚠️ Name must be strictly consistent):**
- **Name:** `SLACK_WEBHOOK_URL` (Please copy and paste this name, do not type it manually)
- **Secret:** Your Slack Incoming Webhook URL
<br>
**Slack Introduction:**
Slack is a team collaboration tool, 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 you are not logged in, log in to your Slack workspace first
2. **Choose a creation method:**
- Click **"From scratch"**
3. **Fill in App information:**
- **App Name:** Fill in the application name (such as `TrendRadar`)
- **Workspace:** Select your workspace from the drop-down 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 function:**
- Find the **"Activate Incoming Webhooks"** switch
- Switch the switch from `OFF` to `ON`
- The page will automatically refresh to display 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 the target channel:**
- The system will pop up an authorization page
- Select the channel to receive messages from the drop-down list (such as `#hot-news`)
- ⚠️ If you want to select a private channel, you must join the channel first
3. **Authorize the application:**
- Click the **"Allow"** button to complete the authorization
- The system will automatically jump back to the configuration page
### Step 4: Copy and save the Webhook URL
1. **View the generated URL:**
- In the "Webhook URLs for Your Workspace" area
- You will see the Webhook URL just generated
- Format such as: `https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX`
2. **Copy URL:**
- Click the **"Copy"** button on the right side of the URL
- Or manually select the URL and copy it
3. **Configure to TrendRadar:**
- **GitHub Actions:** Add the URL to `SLACK_WEBHOOK_URL` in GitHub Secrets
- **Local Test:** Fill in the URL in the `slack_webhook_url` field of `config/config.yaml`
- **Docker Deployment:** Add the URL to the `SLACK_WEBHOOK_URL` variable in the `docker/.env` file
---
**Precautions:**
- ✅ Supports Markdown format (automatically converted to Slack mrkdwn)
- ✅ Supports automatic batch push (4KB per batch)
- ✅ Suitable for team collaboration and centralized message management
- ⚠️ The Webhook URL contains a key, do not make it public
**Message format preview:**
```
*[Batch 1/2]*
📊 *Hot Word 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 soared *[3]* - [08:30 ~ 10:45] (3 times)
```
**Related Links:**
- [Slack Incoming Webhooks Official Documentation](https://api.slack.com/messaging/webhooks)
- [Slack API Application Management](https://api.slack.com/apps)
</details>
<details>
<summary>👉 Click to expand: <strong>Generic Webhook Push</strong> (Supports Discord, Matrix, IFTTT, etc.)</summary>
<br>
**GitHub Secret Configuration (⚠️ Name must be strictly consistent):**
- **Name:** `GENERIC_WEBHOOK_URL` (Please copy and paste this name, do not type it manually)
- **Secret:** Your Webhook URL
- **Name:** `GENERIC_WEBHOOK_TEMPLATE` (Optional configuration, please copy and paste this name)
- **Secret:** JSON template string, supports `{title}` and `{content}` placeholders
<br>
**Generic Webhook Introduction:**
Generic Webhook supports any platform that accepts HTTP POST requests, including but not limited to:
- **Discord:** Push to channel via Webhook
- **Matrix:** Push via Webhook bridging
- **IFTTT:** Trigger automated processes
- **Self-built service:** Any custom service that supports Webhooks
**Configuration example:**
### Discord Configuration
1. **Get Webhook URL:**
- Enter Discord server settings → Integrations → Webhooks
- Create a new Webhook and copy the URL
2. **Configure template:**
```json
{"content": "{content}"}
```
3. **GitHub Secret Configuration:**
- `GENERIC_WEBHOOK_URL`: Discord Webhook URL
- `GENERIC_WEBHOOK_TEMPLATE`: `{"content": "{content}"}`
### Custom Template
The template supports two placeholders:
- `{title}` - Message title
- `{content}` - Message content
**Template Example:**
```json
# Default format (used when left blank)
{"title": "{title}", "content": "{content}"}
# Discord format
{"content": "{content}"}
# Custom format
{"text": "{content}", "username": "TrendRadar"}
```
---
**Precautions:**
- ✅ Supports Markdown format (consistent with WeChat Work format)
- ✅ Supports automatic batch push
- ✅ Supports multi-account configuration (separated by `;`)
- ⚠️ The template must be a valid JSON format
- ⚠️ Different platforms have different requirements for message formats, please refer to the target platform documentation
</details>
<br>
### 3️⃣ Step 3: Manually Test News Push
> ⚠️ Reminder:
> - After completing steps 1-2, please test immediately! After the test is successful, adjust the configuration as needed (step 4)
> - Please enter your own project, not this project!
**How to find your Actions page:**
- **Method 1:** Open the homepage of the project you forked 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. Enter the Actions page of your project
2. Find **"Get Hot News"** (must be this word), click it, and click the **"Run workflow"** button on the right to run it
- If you can't see the word, refer to [#109](https://github.com/sansan0/TrendRadar/issues/109) to solve it
3. In about 3 minutes, the message will be pushed to the platform you configured
<br>
> ⚠️ Reminder:
> - Do not test manually too frequently to avoid triggering GitHub Actions restrictions
> - You need to refresh the browser page after clicking Run workflow to see the new running record
<br>
### 4️⃣ Step 4: Configuration Instructions (Optional)
The default configuration can be used normally. If you need to make personalized adjustments, understand the following files:
| File | Function |
|------|------|
| `config/config.yaml` | Main configuration file: push mode, time window, platform list, hotspot weight, etc. |
| `config/frequency_words.txt` | Keyword file: Set the words you care about to filter push content |
| `config/ai_analysis_prompt.txt` | AI prompt word template: Customize the role and analysis dimensions of the AI analyst |
| `.github/workflows/crawler.yml` | Execution frequency: Control how often to run (⚠️ modify with caution) |
👉 **Detailed configuration tutorial**: [Detailed Configuration](#配置详解)
<br>
### 5️⃣ Step 5: Remote Cloud Storage & Check-In Configuration
**v4.0.0 Important Change**: Introduced an "Activity Detection" mechanism. GitHub Actions need to check in regularly to maintain operation.
- **Operating Cycle**: The validity period is **7 days**. After the countdown ends, the service will be automatically suspended.
- **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 disengage from the information flow and give your brain some breathing space.
- GitHub Actions are valuable public computing resources. The introduction of the check-in mechanism aims to avoid the ineffective idling of computing power and ensure that resources are allocated to users who are truly active and in need. Thank you for your understanding and support.
---
**About Remote Cloud Storage Configuration (Please choose according to your deployment method):**
- **GitHub Actions Users**:
- **Current Situation**: Each run of Actions is a brand new environment that does not save files. If you do not configure cloud storage, the project will run in **lightweight mode** (no incremental push, no historical tracking).
- **Recommendation**: Configure remote cloud storage for the full experience.
- **Docker / Local Users**:
- **Current Situation**: Data is saved on the local hard drive by default.
- **Recommendation**: Cloud storage is optional and can be used as an offsite backup.
<details>
<summary>👉 Click to expand: <strong>Remote Cloud Storage Configuration Tutorial (using Cloudflare R2 as an example)</strong></summary>
<br>
**⚠️ Prerequisites (Important):**
According to Cloudflare platform rules, opening R2 requires binding a payment method.
* **Purpose**: Only for identity verification (Verify Only), **no charges will be incurred**.
* **Payment**: Supports dual-currency credit cards or PayPal in the China region.
* **Usage**: R2's free quota (10GB storage/month) is sufficient to cover the daily operation of this project, so there is no need to worry about payment.
---
**GitHub Secret Configuration (4 items need to be added):**
| Name | Secret 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 Description |
|-------------|-----------------|
| `S3_REGION` | Region (default `auto`, some service providers may need to specify) |
> 💡 **More storage configuration options**: See [Where is the data stored?](#11-数据保存在哪里)
<br>
**Detailed Operation Steps (Obtaining Credentials):**
1. **Enter R2 Overview**:
- Log in to the [Cloudflare Dashboard](https://dash.cloudflare.com/).
- Find and click `R2 Object Storage` in the left sidebar.
2. **Create a Bucket**:
- Click `Overview`
- Click `Create bucket` 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 `Manage` (Manage R2 API Tokens) in the **lower right corner** of `Account Details`.
- At the same time, you will see `S3 API`: `https://<account-id>.r2.cloudflarestorage.com` (this is S3_ENDPOINT_URL)
- Click `Create Account APl token`.
- **⚠️ Key Settings**:
- **Token Name**: Fill in arbitrarily (e.g., `github-action-write`).
- **Permissions**: Select `Administrator Read and Write`.
- **Specify Bucket**: For security, it is recommended to select `Only apply to specified buckets` and select 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️⃣ Step 6: Enable AI Analysis Push
This is the core function of v5.0.0, allowing AI to help you summarize and analyze news. It is recommended to try it.
**Configuration Method:**
Add the following in GitHub Secrets (or `.env` / `config.yaml`):
- `AI_API_KEY`: Your API Key (supports DeepSeek, OpenAI, etc.)
- `AI_PROVIDER`: Service provider name (e.g., `deepseek`, `openai`)
That's it. No complex deployment is required. You will see the intelligent analysis report next time you push.
<br>
### 7️⃣ Step 7: 🎉 Deployment Successful!
Congratulations! Now you can start enjoying the efficient information flow brought by TrendRadar.
💬 **Join the Community**: Welcome to follow the official account "[硅基茶水间](#-支持项目)" and share your usage experience and advanced gameplay.
<br>
### 8️⃣ Step 8: Advanced: Choose Your AI Assistant
TrendRadar provides two AI usage methods to meet different needs:
| Feature | ✨ AI Analysis Push | 🧠 AI Intelligent Analysis |
| :--- | :--- | :--- |
| **Mode** | **Passive Reception** (Daily Report) | **Active Dialogue** (In-depth Research) |
| **Scenario** | "What are the major events today?" | "Analyze the changes in the AI industry in the past week" |
| **Deployment** | Minimal (just fill in the Key) | Advanced (requires local running/Docker) |
| **Client** | Mobile Phone | Computer |
👉 **Conclusion**: First use **AI Analysis Push** to meet daily needs; if you are a data analyst or need in-depth mining, try **[AI Intelligent Analysis](#-ai-智能分析)**.
<br>
<a name="配置详解"></a>
## ⚙️ Configuration Details
> **📖 Reminder**: This chapter provides detailed configuration instructions. It is recommended to complete the basic configuration of [Quick Start](#-快速开始) first, and then come back to view the detailed options as needed.
### 1. Which platforms do I want to watch?
<details id="自定义监控平台">
<summary>👉 Click to expand: <strong>Select Information Sources</strong></summary>
<br>
**Configuration Location:** `config/config.yaml` in the `platforms` section
The information data of this project comes from [newsnow](https://github.com/ourongxing/newsnow). You can click [website](https://newsnow.busiyi.world/), click [More] to see if there is a platform you want.
To add specific platforms, you can visit [project source code](https://github.com/ourongxing/newsnow/tree/main/server/sources), according to the file name inside, modify the `platforms` configuration in the `config/config.yaml` file:
```yaml
platforms:
enabled: true # Whether to enable hot list platform crawling
sources:
- id: "toutiao"
name: "今日头条"
- id: "baidu"
name: "百度热搜"
- id: "wallstreetcn-hot"
name: "华尔街见闻"
# Add more platforms...
```
> 💡 **Shortcut**: If you don't know how to read the source code, you can copy the [platform configuration summary](https://github.com/sansan0/TrendRadar/issues/95) organized by others.
> ⚠️ **Note**: The more platforms, the better. It is recommended to choose 10-15 core platforms. Too many platforms will lead to information overload and reduce the user experience.
</details>
### 2. What content am I concerned about?
Tell the robot what you want to see in the `frequency_words.txt` file, and it will keep an eye on it for you. Supports ordinary words, required words, filter words and other gameplay.
| Syntax Type | Symbol | Function | Example | Matching Logic |
|---------|------|------|------|---------|
| **Ordinary Word** | None | Basic matching | `华为` | Contains any one |
| **Required Word** | `+` | Limited range | `+手机` | Must contain at the same time |
| **Filter Word** | `!` | Exclude interference | `!广告` | Exclude directly if included |
| **Quantity Limit** | `@` | Control the number of displays | `@10` | Display up to 10 news items (new in v3.2.0) |
| **Global Filter** | `[GLOBAL_FILTER]` | Globally exclude specified content | See example below | Filter in any case (new in v3.5.0) |
| **Regular Expression** | `/pattern/` | Exact matching mode | `/\bai\b/` | Use regular expression matching (new in v4.7.0) |
| **Display Name** | `=> Remark` | Customize display text | `/\bai\b/ => AI相关` | Push and HTML display remarks name (new 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. **Ordinary Keywords** - Basic Matching
```txt
华为
OPPO
苹果
```
**Function:** News titles containing **any one of the words** will be captured
##### 2. **Required Word** `+Vocabulary` - Limited Range
```txt
华为
OPPO
+手机
```
**Function:** Must contain both ordinary words **and** required words to be captured
##### 3. **Filter Word** `!Vocabulary` - Exclude Interference
```txt
苹果
华为
!水果
!价格
```
**Function:** News containing filter words will be **directly excluded**, even if it contains keywords
##### 4. **Quantity Limit** `@Number` - Control the Number of Displays (New in v3.2.0)
```txt
特斯拉
马斯克
@5
```
**Function:** Limit 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 (New in v3.5.0)
```txt
[GLOBAL_FILTER]
广告
推广
营销
震惊
标题党
[WORD_GROUPS]
科技
AI
华为
鸿蒙
!车
```
**Function:** Filter news containing specified words in any case, **highest priority**
**Usage Scenarios:**
- Filter low-quality content: Shocking, clickbait, breaking news, etc.
- Filter marketing content: Advertising, promotion, sponsorship, etc.
- Filter specific topics: Entertainment, gossip (depending on needs)
**Filtering Priority:** Global Filtering > In-group Filtering (`!`) > Group Matching
**Area Description:**
- `[GLOBAL_FILTER]`: Global filtering area, words contained will be filtered in any case
- `[WORD_GROUPS]`: Word group area, keep the existing syntax (`!`, `+`, `@`)
- If area tags are not used, all are treated as word groups by default (backward compatible)
**Matching Example:**
```txt
[GLOBAL_FILTER]
广告
[WORD_GROUPS]
科技
AI
```
- ❌ "广告:最新科技产品发布" ← Contains the global filter word "广告", rejected directly
- ✅ "科技公司发布AI新产品" ← Does not contain global filter words, matches the "科技" word group
- ✅ "AI技术突破引发关注" ← Does not contain global filter words, matches "AI" in the "科技" word group
**Precautions:**
- Global filter words should be used with caution to avoid over-filtering and missing valuable content
- It is recommended to keep global filter words within 5-15
- For filtering of specific word groups, prioritize using in-group filter words (`!` prefix)
##### 6. **Regular Expression** `/pattern/` - Exact Matching Mode (New in v4.7.0)
Ordinary keywords use substring matching, which is convenient in the Chinese environment, but may produce false matches in the English environment. For example, `ai` will match `ai` in `training`.
Using the regular expression syntax `/pattern/` can achieve exact matching:
```txt
/(?<![a-z])ai(?![a-z])/
人工智能
```
**Function:** Use regular expressions for matching, supports all Python regular syntax
**Common Regular Modes:**
| Requirement | Regular Expression | Description |
|------|---------|------|
| English Word Boundary | `/\bword\b/` | Matches independent words, such as `/\bai\b/` matches "AI" but not "training" |
| Non-Letter Before and After | `/(?<![a-z])ai(?![a-z])/` | More relaxed boundary, suitable for mixed Chinese and English scenarios |
| Start Matching | `/^breaking/` | Only matches titles starting with "breaking" |
| End Matching | `/发布$/` | Only matches titles ending with "发布" |
| Multiple Choice | `/苹果\|华为\|小米/` | Matches any one of them (note the escape `\|`) |
**Matching Example:**
```txt
# Configuration
/(?<![a-z])ai(?![a-z])/
人工智能
```
- ✅ "AI is the future" ← Matches the independent "AI"
- ✅ "你好ai这里" ← The front and back are 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 Use:**
```txt
# Regular + Ordinary Word + Filter Word
/\bai\b/
人工智能
机器学习
!广告
```
**Precautions:**
- Regular expressions automatically enable case-insensitive matching (`re.IGNORECASE`)
- Supports JavaScript-style writing such as `/pattern/i` (flags will be ignored because case-insensitive is enabled by default)
- Invalid regular syntax will be treated as ordinary words
- Regular expressions can be used for ordinary words, required words (`+`), and filter words (`!`)
**💡 Don't know how to write regular expressions? Let AI help you generate!**
If you are not familiar with regular expressions, you can directly let ChatGPT / Gemini / DeepSeek help you generate them. Just tell AI:
> I need a Python regular expression to match the English word "ai", but not "ai" in "training".
> Please give the regular expression directly in the format `/pattern/`, no additional explanation is needed.
AI will give you a result like this: `/(?<![a-zA-Z])ai(?![a-zA-Z])/`
##### 7. **Display Name** `=> Remark` - Customize Display Text (New in v4.7.0)
Regular expressions may not be friendly when displayed in push messages and HTML pages. Use the `=> Remark` syntax to set the display name:
```txt
/(?<![a-zA-Z])ai(?![a-zA-Z])/ => AI 相关
人工智能
```
**Function:** Push messages and HTML pages display "AI 相关" instead of complex regular expressions
**Syntax Format:**
```txt
# Regular + Display Name
/pattern/ => Display Name
/pattern/i => Display Name # Supports flags writing (flags are ignored)
/pattern/=>Display Name # => Spaces on both sides are optional
# Ordinary Word + Display Name
deepseek => DeepSeek 动态
```
**Matching Example:**
```txt
# Configuration
/(?<![a-zA-Z])ai(?![a-zA-Z])/ => AI 相关
人工智能
```
| Original Configuration | Push/HTML Display |
|---------|---------------|
| `/(?<![a-z])ai(?![a-z])/` + `人工智能` | `(?<![a-z])ai(?![a-z]) 人工智能` |
| `/(?<![a-z])ai(?![a-z])/ => AI 相关` + `人工智能` | **`AI 相关`** |
**Precautions:**
- The display name only needs to be written on the first word of the word group
- If multiple words in the word group have display names, use the first one
- When the display name is not set, all words in the word group are automatically spliced
---
#### 🔗 Word Group Function - The Important Role of Blank Lines
**Core Rule:** Use **blank lines** to separate different word groups, each word group is counted independently
##### Example Configuration:
```txt
iPhone
华为
OPPO
+发布
A股
上证
深证
+涨跌
!预测
世界杯
欧洲杯
亚洲杯
+比赛
```
##### Word Group Explanation and Matching Effect:
**Group 1 - Mobile Phone New Category:**
- Keywords: iPhone, 华为, OPPO
- Required Word: 发布
- Effect: Must contain the mobile phone brand name and also contain "发布"
**Matching Example:**
- ✅ "iPhone 15 officially released price announced" ← Has "iPhone" + "发布"
- ✅ "Huawei Mate60 series launch live broadcast" ← Has "华为" + "发布"
- ✅ "OPPO Find X7 release time confirmed" ← Has "OPPO" + "发布"
- ❌ "iPhone sales hit a new high" ← Has "iPhone" but lacks "发布"
**Group 2 - Stock Market Conditions:**
- Keywords: A股, 上证, 深证
- Required Word: 涨跌
- Filter Word: 预测
- Effect: Focus on the actual situation of stock market ups and downs, exclude prediction content
**Matching Example:**
- ✅ "A股 today's sharp ups and downs analysis" ← Has "A股" + "涨跌"
- ✅ "Shanghai Composite Index ups and downs hit a new high" ← Has "上证" + "涨跌"
- ❌ "Experts predict A股 ups and downs trend" ← Has "A股" + "涨跌" but contains "预测"
**Group 3 - Football Events:**
- Keywords: 世界杯, 欧洲杯, 亚洲杯
- Required Word: 比赛
- Effect: Only focus on news related to the game
---
#### 📝 Configuration Tips
##### 1. **From Broad to Strict**
```txt
# Step 1: First use broad keywords to test
人工智能
AI
ChatGPT
# Step 2: After finding false matches, add required words to limit
人工智能
AI
ChatGPT
+技术
# Step 3: After finding interference content, add filter words
人工智能
AI
ChatGPT
+技术
!广告
!培训
```
##### 2. **Avoid Overly Complex**
❌ **Not Recommended:** One word group contains too many words
```txt
华为
OPPO
苹果
三星
vivo
一加
魅族
+手机
+发布
+销量
!假货
!维修
!二手
```
✅ **Recommended:** Split into multiple precise word groups
```txt
华为
OPPO
+新品
苹果
三星
+发布
手机
销量
+市场
```
</details>
#### 2.2 Advanced Configuration (New in v3.2.0)
<a name="关键词高级配置"></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) | Hot Article Count ↓ → Configuration Position ↑ | Focus on Hot Trend |
| `true` | Configuration Position ↑ → Hot Article Count ↓ | Focus on Personal Priority |
**Example:** Configuration order A, B, C, hot article count 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 of 10 articles per keyword (0 = unlimited)
```
**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 # Priority by configuration order
max_news_per_keyword: 10 # Global default maximum of 10 articles per keyword
```
```txt
# frequency_words.txt
特斯拉
马斯克
@20 # Focus, display 20 articles (overrides global configuration)
华为 # Use global configuration, display 10 articles
比亚迪
@5 # Limit to 5 articles
```
**Final Result:** Display Tesla (20 articles) → Huawei (10 articles) → BYD (5 articles) in configuration order
</details>
### 3. Which Push Mode to Choose?
<details>
<summary>👉 Click to expand: <strong>Detailed Comparison of Three Push Modes</strong></summary>
<br>
**Configuration Location:** `config/config.yaml`'s `report.mode`
```yaml
report:
mode: "daily" # Optional: "daily" | "incremental" | "current"
```
#### Detailed Comparison Table
| Mode | Target Audience | Push Timing | Display Content | Typical Use Case |
|---|---|---|---|---|
| **Daily Summary**<br/>`daily` | 📋 Enterprise Managers/General Users | Scheduled Push (default: once per hour) | All matching news for the day<br/>+ New News Area | **Example**: Check all important news for today at 6 PM every day<br/>**Features**: See the complete trend for the whole day, without missing any hot topics<br/>**Reminder**: Will include previously pushed news |
| **Current Ranking**<br/>`current` | 📰 Self-Media/Content Creators | Scheduled Push (default: once per hour) | Current ranking matching news<br/>+ New News Area | **Example**: Track "which topics are hottest now" every hour<br/>**Features**: Real-time understanding of current hot ranking changes<br/>**Reminder**: News that continues to be on the list will appear every time |
| **Incremental Monitoring**<br/>`incremental` | 📈 Investors/Traders | Push only when there are new additions | Newly appeared news matching frequency words | **Example**: Monitor "Tesla" and only notify when there is new news<br/>**Features**: Zero duplication, only see the first appearance of news<br/>**Suitable for**: High-frequency monitoring, avoiding information disturbance |
#### Example of Actual Push Effect
Assume you are monitoring the "Apple" keyword, executed once per 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 |
**Explanation**:
- `daily`: Accumulatively display all news for the day (A, B, C are all retained)
- `current`: Display the news on the current ranking (ranking changes, News D is on the list, News A is off the list)
- `incremental`: **Only push newly appeared news** (avoiding repeated interference)
#### Common Issues
> **💡 Encountered this problem?** 👉 "The news output after the first execution every hour will still appear when executed in the next hour"
> - **Reason**: You may have selected `daily` (Daily Summary) or `current` (Current Ranking) mode
> - **Solution**: Use `incremental` (Incremental Monitoring) mode to only push new content
#### ⚠️ Important Reminder for Incremental Mode
> **Users who have selected `incremental` (Incremental Monitoring) mode, please note:**
>
> 📌 **Incremental mode will only push when there is new matching news**
>
> **If you haven't received a push for a long time, it may be because:**
> 1. There are no new hot topics that match your keywords in the current time period
> 2. The keyword configuration is too strict or too broad
> 3. The number of monitoring platforms is small
>
> **Solutions:**
> - Solution 1: 👉 [Optimize Keyword Configuration](#2-keyword-configuration) - Adjust the accuracy of keywords, add or modify monitoring vocabulary
> - Solution 2: Switch Push Mode - Use `current` or `daily` mode to receive pushes regularly
> - Solution 3: 👉 [Increase Monitoring Platforms](#1-platform-configuration) - Add more news platforms to expand information sources
</details>
### 4. Adjust Hot Algorithm
<details>
<summary>👉 Click to expand: <strong>Customize Hot Weight</strong></summary>
<br>
**Configuration Location:** `config/config.yaml`'s `advanced.weight` section
```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 Hot Topic Tracking Type**:
```yaml
advanced:
weight:
rank: 0.8 # Mainly look at ranking
frequency: 0.1 # Don't care much about persistence
hotness: 0.1
```
**Target Audience**: Self-media bloggers, marketers, users who want to quickly understand the hottest topics
**In-Depth Topic Tracking Type**:
```yaml
advanced:
weight:
rank: 0.4 # Moderately look at ranking
frequency: 0.5 # Focus on the continuous hotness within the day
hotness: 0.1
```
**Target Audience**: Investors, researchers, journalists, users who need in-depth trend analysis
#### How to Adjust
1. **The three numbers must add up to 1.0**
2. **Increase the weight of what is important**: If you care about ranking, increase `rank`; if you care about persistence, increase `frequency`
3. **It is recommended to adjust only 0.1-0.2 each time** and observe the effect
Core idea: Users who pursue speed and timeliness increase the ranking weight, and users who pursue depth and stability increase the frequency weight.
</details>
### 5. What Does the Message I Receive Look Like?
<details>
<summary>👉 Click to expand: <strong>Message Style Preview</strong></summary>
<br>
#### Push Example
📊 Hot Vocabulary Statistics
🔥 [1/3] AI ChatGPT : 2 Articles
1. [Baidu Hot Search] 🆕 ChatGPT-5 Officially Released [**1**] - 09:15 (1 time)
2. [Toutiao] AI Chip Concept Stocks Soar [**3**] - [08:30 ~ 10:45] (3 times)
━━━━━━━━━━━━━━━━━━━
📈 [2/3] BYD Tesla : 2 Articles
1. [Weibo] 🆕 BYD Monthly Sales Break Record [**2**] - 10:20 (1 time)
2. [Douyin] Tesla Price Cut Promotion [**4**] - [07:45 ~ 09:15] (2 times)
━━━━━━━━━━━━━━━━━━━
📌 [3/3] A-Shares Stock Market : 1 Article
1. [Wall Street News] A-Shares Midday Review Analysis [**5**] - [11:30 ~ 12:00] (2 times)
🆕 Newly Added Hot News (Total 2 Articles)
**Baidu Hot Search** (1 Article):
1. ChatGPT-5 Officially Released [**1**]
**Weibo** (1 Article):
1. BYD Monthly Sales Break Record [**2**]
Update Time: 2025-01-15 12:30:15
#### Message Format Description
| Format Element | Example | Meaning | Description |
|---|---|---|---|
| 🔥📈📌 | 🔥 [1/3] AI ChatGPT | Hot Level | 🔥 High Hotness (≥10 articles) 📈 Medium Hotness (5-9 articles) 📌 Normal Hotness (<5 articles) |
| [Serial Number/Total Number] | [1/3] | Sorting Position | Current phrase's ranking in all matching phrases |
| Frequency Phrase | AI ChatGPT | Keyword Phrase | Phrase in the configuration file, the title must contain the vocabulary |
| : N Articles | : 2 Articles | Matching Quantity | Total number of news matched by the phrase |
| [Platform Name] | [Baidu Hot Search] | Source Platform | Name of the platform to which the news belongs |
| 🆕 | 🆕 ChatGPT-5 Officially Released | New Mark | Hot topic that first appeared in this round of crawling |
| [**Number**] | [**1**] | High Ranking | Hot search with ranking ≤ threshold, displayed in red and bold |
| [Number] | [7] | Normal Ranking | Hot search with ranking > threshold, displayed normally |
| - Time | - 09:15 | First Time | The time when the 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** | 🆕 **Newly Added Hot News** | New Topic Summary | Separately display the hot topics that newly appeared in this round |
</details>
### 6. Docker Deployment
**Image Description:**
TrendRadar provides two independent Docker images, which can be selected for deployment according to requirements:
| Image Name | Purpose | Description |
|---|---|---|
| `wantcat/trendradar` | News Push Service | Regularly crawl news and push notifications (required) |
| `wantcat/trendradar-mcp` | AI Analysis Service | MCP protocol support, AI dialogue analysis (optional) |
> 💡 **Suggestion**:
> - Only need push function: Only deploy the `wantcat/trendradar` image
> - Need AI analysis function: Deploy both images at the same time
<details>
<summary>👉 Click to expand: <strong>Complete Docker Deployment Guide</strong></summary>
<br>
#### Method 1: Use docker compose (Recommended)
1. **Create Project Directory and Configuration**:
**Method 1-A: Use git clone (Recommended, Simplest)**
```bash
# Clone the project to local
git clone https://github.com/sansan0/TrendRadar.git
cd TrendRadar
```
**Method 1-B: Use wget to Download Configuration Files**
```bash
# Create directory structure
mkdir -p trendradar/{config,docker}
cd trendradar
# Download configuration file template
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/
wget https://raw.githubusercontent.com/sansan0/TrendRadar/master/config/ai_analysis_prompt.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/
```
> 💡 **Explanation**: The key directory structure required for Docker deployment is as follows:
```
Current Directory/
├── config/
│ ├── config.yaml
│ ├── frequency_words.txt
│ └── ai_analysis_prompt.txt # AI analysis prompt (new in v5.0.0, optional)
└── 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, AI analysis, etc.)
- `config/frequency_words.txt` - **Keyword Configuration** (set the hot words you care about)
- `config/ai_analysis_prompt.txt` - **AI Prompt Configuration** (customize AI analysis roles and output formats, new in v5.0.0)
- `docker/.env` - **Sensitive Information + Docker Specific Configuration** (webhook URLs, API Key, S3 secrets, scheduled tasks)
> 💡 **Configuration Modification Takes Effect**: After modifying `config.yaml`, execute `docker compose up -d` to restart the container to take effect
**⚙️ Environment Variable Override Mechanism (v3.0.5+)**
Environment variables in the `.env` file will override the corresponding configuration in `config.yaml`:
| Environment Variable | Corresponding Configuration | Example Value | Description |
|---|---|---|---|
| `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 (multiple accounts separated by `;`) |
| `AI_ANALYSIS_ENABLED` | `ai_analysis.enabled` | `true` / `false` | Whether to enable AI analysis (new in v5.0.0) |
| `AI_API_KEY` | `ai.api_key` | `sk-xxx...` | AI API Key (shared by ai_analysis and ai_translation) |
| `AI_PROVIDER` | `ai.provider` | `deepseek` / `openai` / `gemini` | AI Provider |
| `S3_*` | `storage.remote.*` | - | Remote storage configuration (5 parameters) |
**Configuration Priority**: Environment Variables > config.yaml
**How to Use**:
- Modify the `.env` file and fill in the required configuration
- Or directly add in the "Environment Variables" of the NAS/Synology Docker management interface
- Take effect after restarting the container: `docker compose up -d`
3. **Start Service**:
**Option A: Start All Services (Push + AI Analysis)**
```bash
# Pull the latest image
docker compose pull
# Start all services (trendradar + trendradar-mcp)
docker compose up -d
```
**Option B: Only Start News Push Service**
```bash
# Only start trendradar (regular crawling and pushing)
docker compose pull trendradar
docker compose up -d trendradar
```
**Option C: Only Start MCP AI Analysis Service**
```bash
# Only start trendradar-mcp (provide AI analysis interface)
docker compose pull trendradar-mcp
docker compose up -d trendradar-mcp
```
> 💡 **Tip**:
> - Most users only need to start `trendradar` to achieve the news push function
> - Only need to start `trendradar-mcp` when you need to use ChatGPT/Gemini for AI dialogue analysis
> - The two services are independent of each other and can be flexibly combined according to needs
4. **View Running Status**:
```bash
# View news push service logs
docker logs -f trendradar
# View MCP AI analysis service logs
docker logs -f trendradar-mcp
# View all container status
docker ps | grep trendradar
# Stop specific service
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 project
git clone https://github.com/sansan0/TrendRadar.git
cd TrendRadar
# Modify configuration file
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 Services**:
```bash
# Option A: Build and start all services
docker compose build
docker compose up -d
# Option B: Build and start only the news feed service
docker compose build trendradar
docker compose up -d trendradar
# Option C: Build and start only the MCP AI analysis service
docker compose build trendradar-mcp
docker compose up -d trendradar-mcp
```
> 💡 **Architecture Parameter Description**:
> - The default builds `amd64` architecture images (suitable for most x86_64 servers)
> - To build `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
docker compose pull
docker compose up -d
```
**Available Images**:
| Image Name | Purpose | Description |
|---------|------|------|
| `wantcat/trendradar` | News Feed Service | Periodically crawls news and pushes notifications |
| `wantcat/trendradar-mcp` | MCP Server | AI analysis function (optional) |
#### Service Management Commands
```bash
# View running status
docker exec -it trendradar python manage.py status
# Manually execute the crawler once
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 the web server
docker exec -it trendradar python manage.py stop_webserver # Stop the web server
docker exec -it trendradar python manage.py webserver_status # View web server status
# View help information
docker exec -it trendradar python manage.py help
# Restart the container
docker restart trendradar
# Stop the container
docker stop trendradar
# Delete the container (keep the data)
docker rm trendradar
```
> 💡 **Web Server Description**:
> - After starting, you can access `http://localhost:8080` in your browser to view the latest report
> - Access historical reports through directory navigation (e.g., `http://localhost:8080/2025-xx-xx/`)
> - The port can be configured in the `.env` file using the `WEBSERVER_PORT` parameter
> - Automatic startup: Set `ENABLE_WEBSERVER=true` in `.env`
> - Security Tip: Only provides static file access, limited to the output directory, and only binds to local access
#### Data Persistence
The generated reports and data are saved in the `./output` directory by default, and the data will be retained even if the container is restarted or deleted.
**📊 Web Version Report Access Path**:
The daily summary HTML report generated by TrendRadar is saved in two locations simultaneously:
| File Location | Access Method | Applicable Scenario |
|---------|---------|---------|
| `output/index.html` | Direct access from the host | **Docker Deployment** (visible to the host through Volume mounting) |
| `index.html` | Root directory access | **GitHub Pages** (repository root directory, Pages automatically recognizes) |
| `output/html/YYYY-MM-DD/当日汇总.html` | Historical report access | 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. Access in the browser
http://localhost:8080 # Access the latest report (default index.html)
http://localhost:8080/html/2025-xx-xx/ # Access the report for the specified 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/当日汇总.html
```
**Why are there two index.html files?**
- `output/index.html`: Docker Volume is mounted to the host, and can be opened directly locally
- `index.html`: GitHub Actions pushes to the repository, and GitHub Pages automatically deploys
> 💡 **Tip**: The content of the two files is exactly the same, choose any one to access.
#### Troubleshooting
```bash
# Check container status
docker inspect trendradar
# View container logs
docker logs --tail 100 trendradar
# Enter the container for debugging
docker exec -it trendradar /bin/bash
# Verify the 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 an independent MCP service container.
**Architecture Description**:
```mermaid
flowchart TB
subgraph trendradar["trendradar"]
A1[Periodically crawls news]
A2[Push notifications]
end
subgraph trendradar-mcp["trendradar-mcp"]
B1[127.0.0.1:3333]
B2[AI analysis interface]
end
subgraph shared["Shared Volume"]
C1["config/ (ro)"]
C2["output/ (ro)"]
end
trendradar --> shared
trendradar-mcp --> shared
```
**Quick Start**:
If you have already completed the deployment according to [Method 1: Using docker compose](#method-1-using-docker-compose-recommended), you only need to start the MCP service:
```bash
cd TrendRadar/docker
docker compose up -d trendradar-mcp
# View running status
docker ps | grep trendradar-mcp
```
**Start the MCP service separately** (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, make sure there are `config/` and `output/` folders in the current directory, and they contain configuration files and news data.
**Verify Service**:
```bash
# Check the health status of the MCP service
curl http://127.0.0.1:3333/mcp
# View MCP service logs
docker logs -f trendradar-mcp
```
**Configure in the AI Client**:
After the MCP service is started, configure it 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 to the local port (127.0.0.1) to ensure security. If you need remote access, please configure reverse proxy and authentication yourself.
</details>
### 7. How is the pushed content displayed?
<details>
<summary>👉 Click to expand: <strong>Customize push style and content</strong></summary>
<br>
**Configuration location:** `config/config.yaml` in the `report` and `display` sections
```yaml
report:
mode: "daily" # Push mode
display_mode: "keyword" # Display mode (new in v4.6.0)
rank_threshold: 5 # Ranking highlight threshold
sort_by_position_first: false # Sorting priority
max_news_per_keyword: 0 # Maximum number of news items to display per keyword
display:
region_order: # Region display order (new in v5.2.0)
- new_items # New hot spot area
- hotlist # Hot list area
- rss # RSS subscription area
- standalone # Standalone display area
- ai_analysis # AI analysis area
```
#### Common Configuration Item Description
| What do I want to adjust | Which parameter to modify | Default value | Description |
|-------------|-------------|-------|------|
| **Push mode** | `mode` | `daily` | Determines the timing and content of the push, see [Push Mode Explained](#3-push-mode-explained) |
| **Grouping method** | `display_mode` | `keyword` | `keyword`=group by keyword (e.g. "AI"), `platform`=group by platform (e.g. "Weibo") |
| **Highlight key points** | `rank_threshold` | `5` | News ranked in the top 5 will be displayed in **bold**, so you can see the hottest news at a glance |
| **Sorting rules** | `sort_by_position_first` | `false` | `false`=high popularity is ranked first, `true`=the words you configured are ranked first |
| **Quantity limit** | `max_news_per_keyword` | `0` | How many news items do you want to see for each keyword? `0` means no limit |
| **Display order** | `display.region_order` | See the configuration above | Adjust the order of the list to control the display position of each area |
#### Grouping Method Comparison (display_mode)
Do you want to see "what news is there under this topic" or "what news is there on this platform"?
| Mode | Grouping method | Title prefix | Applicable scene |
|------|---------|---------|---------|
| `keyword` (default) | **Aggregate by keyword** | `[Platform name]` | I am interested in "AI" and want to see news about AI on various platforms |
| `platform` | **Aggregate by platform** | `[Keyword]` | I am interested in "Weibo" and want to see news about the words I am interested in on Weibo |
#### Region Display Order (region_order)
By adjusting the order of the `display.region_order` list, you can control the display position of each area in the push message.
**Default order**: New hot spots → Hot list → RSS → Standalone display area → AI analysis
**Custom example**: Want to put AI analysis at the top?
```yaml
display:
region_order:
- ai_analysis # Move to the first line
- new_items
- hotlist
- rss
- standalone
```
**Note**: An area will only be displayed if it meets two conditions at the same time:
1. In the `region_order` list
2. The corresponding switch in `display.regions` is `true`
#### Sorting Priority (sort_by_position_first)
Suppose you have configured the keywords: 1. Tesla, 2. BYD.
Actual popularity: BYD (10 items), Tesla (3 items).
| Configuration value | Sorting result | Your idea |
|-------|---------|---------|
| `false` (default) | BYD (10 items) → Tesla (3 items) | "Whoever is popular is ranked first" |
| `true` | Tesla (3 items) → BYD (10 items) | "The order I configured is the priority, regardless of whether it is popular or not" |
#### Standalone Display Area (standalone)
**Scenario**: For some platforms (such as Zhihu Hot List, HackerNews), I want to **see the whole thing**, regardless of whether it matches my keywords.
```yaml
display:
regions:
standalone: true # Turn on this "privileged area"
standalone:
platforms: ["zhihu", "weibo"] # Show me the complete hot list of these platforms
rss_feeds: ["hacker-news"] # Show me the complete content of these RSS feeds
max_items: 20 # Show at most how many items
```
</details>
### 8. When will you push to me?
<details>
<summary>👉 Click to expand: <strong>Set push time period</strong></summary>
<br>
**Configuration location:** `config/config.yaml` in the `notification.push_window` section
```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 # Only push 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`=only push once in the window per day, `false`=push every time it is executed in the window |
#### Usage Scenarios
| Scenario | Configuration example |
|------|---------|
| **Push during working hours** | `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 Tips
> ⚠️ **GitHub Actions users note:**
> - GitHub Actions execution time is unstable, there may be a deviation of ±15 minutes
> - It is recommended to leave at least **2 hours** for the time range
> - If you want accurate scheduled push, 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: Only push a summary once every night from 8-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
```
</details>
### 9. How often to run?
<details>
<summary>👉 Click to expand: <strong>Set automatic running frequency</strong></summary>
<br>
**Configuration location:** ` .github/workflows/crawler.yml`'s `schedule` section
```yaml
on:
schedule:
- cron: "0 * * * *" # Run once per hour
```
#### How to change the running frequency?
GitHub Actions uses a time format called "Cron". You don't need to understand it deeply, just copy the code below to replace it.
**Configuration location:** ` .github/workflows/crawler.yml` file's `schedule` section
| I want... | Copy this line of code | Description |
|-----------|------------|------|
| **Once per hour** | `- cron: "0 * * * *"` | **Default configuration**, run at minute 0 |
| **Every 30 minutes** | `- cron: "*/30 * * * *"` | Run every 30 minutes |
| **8 AM every day** | `- cron: "0 0 * * *"` | ⚠️ Write `0` because UTC time (0:00) = Beijing time (8:00) |
| **Every half hour during work hours** | `- cron: "*/30 0-14 * * *"` | Corresponds to Beijing time 8:00 - 22:00 |
| **Three meals a day** | `- cron: "0 0,6,12 * * *"` | Corresponds to Beijing time 8:00, 14:00, 20:00 |
#### ⚠️ Two important reminders
1. **Time difference**: GitHub's servers are located abroad and use UTC time.
- **Simple arithmetic**: The Beijing time you want to set **minus 8 hours** = the time you need to fill in.
- *Example: If you want it to run at 20:00 Beijing time, you need to fill in 12:00 in the settings*
2. **Don't be too frequent**: It is recommended that the interval should not be less than 30 minutes.
- GitHub's free resources are limited, and running too frequently may result in the official limiting your account.
- Moreover, Actions startup itself has a few minutes of delay, so precise control is meaningless.
#### Step-by-step modification steps
1. In your GitHub repository, find the ` .github/workflows/crawler.yml` file
2. Click the ✏️ (Edit) button in the upper right corner
3. Find the line `cron: "..."` and replace the content in the quotes with the "code" above
4. Click the green **Commit changes** button in the upper right corner to save
</details>
### 10. Push to multiple groups/devices
<details>
<summary>👉 Click to expand: <strong>Push to multiple recipients at the same time</strong></summary>
> ### ⚠️ **Safety first**
> **Do not write passwords/Tokens directly in `config.yaml`!**
> If you upload a file containing passwords to GitHub, the whole world can see it.
>
> **Correct way**:
> - **GitHub Actions users**: Add it in Settings -> Secrets
> - **Docker users**: Write it in the ` .env` file (this file will not be uploaded)
#### How to push to multiple places at the same time?
It's very simple, just separate multiple addresses with a semicolon `;` when configuring.
**For example**:
Suppose you have two Feishu groups and want to receive pushes at the same time:
- Group 1 address: `https://.../webhook/aaa`
- Group 2 address: `https://.../webhook/bbb`
Fill in when configuring:
`https://.../webhook/aaa;https://.../webhook/bbb`
#### Platforms that support multiple accounts
| Platform | Configuration method | Notes |
|------|---------|----------|
| **Feishu/DingTalk/QWechat** | Separate multiple Webhook URLs with `;` | The simplest, just string them together |
| **Bark (iOS)** | Separate multiple Key URLs with `;` | Push to multiple iPhones |
| **Telegram** | Token and ChatID must be separated by `;` | ⚠️ **Note that the order must correspond**: <br>Token1 corresponds to ChatID1<br>Token2 corresponds to ChatID2 |
| **ntfy** | Topic and Token must be separated by `;` | If a Topic does not need a Token, leave it blank: <br>`token1;;token3` (the middle one is empty) |
#### Common configuration examples (GitHub Secrets / .env)
```bash
# Feishu sends to 3 groups
FEISHU_WEBHOOK_URL=https://hook1...;https://hook2...;https://hook3...
# DingTalk sends to 2 groups
DINGTALK_WEBHOOK_URL=https://oapi...;https://oapi...
# Telegram sends to 2 people (note the one-to-one correspondence)
TELEGRAM_BOT_TOKEN=tokenA;tokenB
TELEGRAM_CHAT_ID=userA;userB
```
> **Hint**: To prevent abuse, the default limit is to push to a maximum of 3 accounts per platform. If you need more, you can modify the `MAX_ACCOUNTS_PER_CHANNEL` configuration.
</details>
### 11. Where is the data stored?
<details id="storage-config">
<summary>👉 Click to expand: <strong>Select data storage location</strong></summary>
<br>
#### Where will the data be stored?
The system will automatically help you choose the most suitable place, you usually don't need to worry about it:
| Your running environment | Where the data is stored | Description |
|-------------|-----------|------|
| **Docker / Local run** | **Local hard drive** | Stored in the `output/` folder under the project directory, you can view it at any time. |
| **GitHub Actions** | **Cloud storage** | Because GitHub Actions destroys the environment after running, you must configure cloud storage (such as Cloudflare R2). |
#### How to configure cloud storage? (GitHub Actions users must read)
If you are running with GitHub Actions, you need a "cloud drive" to store data. For example, use Cloudflare R2 (because there is a free quota).
**Add these 5 variables in GitHub Secrets:**
| Variable name | What to fill in |
|-------|-------|
| `STORAGE_BACKEND` | `remote` |
| `S3_BUCKET_NAME` | Your bucket name |
| `S3_ACCESS_KEY_ID` | Your Access Key |
| `S3_SECRET_ACCESS_KEY` | Your Secret Key |
| `S3_ENDPOINT_URL` | Your R2 interface address |
> 💡 **Detailed tutorial**: How to apply for R2? Please see [Quick Start - Remote Storage Configuration](#-Quick Start)
#### How long will the data be saved?
By default, we will not automatically delete your data. But if you think there is too much data taking up space, you can set "automatic cleanup".
**Configuration location**: `config/config.yaml`
```yaml
storage:
local:
retention_days: 30 # Local data is only kept for 30 days (0 means forever)
remote:
retention_days: 30 # Cloud data is only kept for 30 days
```
#### Incorrect push time? (Time zone setting)
If you are located overseas, or find that the push time does not match your local time, you can modify the time zone.
**Configuration location**: `config/config.yaml`
```yaml
app:
timezone: "Asia/Shanghai" # The default is China time
```
- For example, if you are in Los Angeles, USA, change it to: `America/Los_Angeles`
- For example, if you are in London, UK, change it to: `Europe/London`
</details>
### 12. Let AI help me analyze hot spots
<details id="ai-analysis-config">
<summary>👉 Click to expand: <strong>Enable AI intelligent analysis function</strong></summary>
<br>
#### What can AI do for me?
After enabling this function, AI will be like a professional analyst, when pushing each batch of news:
1. **Automatic reading**: Read all matched hot news
2. **Deep thinking**: Analyze the relationship between originally isolated news
3. **Write a report**: Attach a short and profound "insight report" at the end of the push message
**Includes**: Hot trend summary, public opinion trend judgment, cross-platform correlation analysis, potential impact assessment, etc.
#### How to enable AI analysis?
The easiest way is to configure it through environment variables (recommended GitHub Secrets or .env).
**Required configuration items**:
| Variable name | What to fill in | Description |
|-------|-------|------|
| `AI_ANALYSIS_ENABLED` | `true` | Turn on the switch |
| `AI_API_KEY` | `sk-xxxxxx` | Your API Key |
| `AI_MODEL` | `deepseek/deepseek-chat` | Model identifier (format: `provider/model`) |
**Supported AI providers** (based on LiteLLM, supports 100+ providers):
| Provider | What to fill in for AI_MODEL | Description |
|-------|----------------|------|
| **DeepSeek** (recommended) | `deepseek/deepseek-chat` | Extremely cost-effective, suitable for high-frequency analysis |
| **OpenAI** | `openai/gpt-4o`<br>`openai/gpt-4o-mini` | GPT-4o series |
| **Google Gemini** | `gemini/gemini-1.5-flash`<br>`gemini/gemini-1.5-pro` | Gemini series |
| **Custom API** | Any format | Use with `AI_API_BASE` |
> 💡 **New feature**: Now based on [LiteLLM](https://github.com/BerriAI/litellm) unified interface, supports 100+ AI providers, configuration is simpler and error handling is more complete.
**Optional configuration items**:
| Variable name | Default value | Description |
|-------|-------|------|
| `AI_API_BASE` | (Automatic) | Custom API address (such as OneAPI, local model) |
| `AI_TEMPERATURE` | `1.0` | Sampling temperature (0-2, the higher the more random) |
| `AI_MAX_TOKENS` | `5000` | Maximum number of tokens generated |
| `AI_TIMEOUT` | `120` | Request timeout time (seconds) |
| `AI_NUM_RETRIES` | `2` | Number of retries on failure |
#### Advanced gameplay: AI translation
If you follow foreign RSS sources (such as Hacker News), AI can help you translate the content into Chinese for pushing.
**Configuration location**: `config/config.yaml`
```yaml
ai_translation:
enabled: true # Enable translation
language: "Chinese" # What language to translate to (Chinese, English, Japanese...)
```
#### Advanced gameplay: Customize AI "persona"
Think AI speaks too officially? You can modify its prompt words to make it your favorite style (such as "poisonous tongue commentator", "senior investment consultant").
- **Modify file**: `config/ai_analysis_prompt.txt`
- **Modification method**: Open and edit directly with Notepad, and tell AI what kind of analysis style you want.
</details>
<br>
## ✨ AI Intelligent Analysis
TrendRadar v3.0.0 adds AI analysis function based on **MCP (Model Context Protocol)**, allowing you to conduct in-depth analysis by interacting with news data in natural language.
### ⚠️ Must read before use
**Important reminder: AI function requires local news data support**
The AI analysis function **is not** directly querying real-time network data, but analyzing your **locally accumulated news data** (stored in the `output` folder)
#### Instructions for use:
1. **Project comes with test data**: The `output` directory by default contains one week of hot news data from **2025-12-21 to 2025-12-27**, which can be used for quick experience of AI functions
2. **Query restrictions**:
- ✅ Can only query data within the existing date range (December 21-27, a total of 7 days)
- ❌ Cannot query real-time news or future dates
3. **Get the latest data**:
- Test data is only for quick experience, **it is recommended to deploy the project yourself** to get real-time data
- Deploy and run the project according to [Quick Start](#-Quick Start)
- Wait at least 1 day to accumulate news data before you can query the latest hot spots
### 1. Quick Deployment
Cherry Studio provides a GUI configuration interface, which can be deployed quickly in 5 minutes. The complex part is one-click installation.
**Graphic deployment tutorial**: Now updated to my [public account](#-Support Project), reply "mcp" to get it
**Detailed deployment tutorial**: [README-Cherry-Studio.md](README-Cherry-Studio.md)
**Deployment mode description**:
- **STDIO mode (recommended)**: One-time configuration, no need to repeat configuration in the future. The **graphic deployment tutorial** only takes the configuration of this mode as an example.
- **HTTP mode (alternative)**: If you encounter problems with STDIO mode configuration, you can use HTTP mode. The configuration method of this mode is basically the same as STDIO, but the content copied and pasted is only one line, which is not easy to make mistakes. The only thing to note is that you need to manually start the service before each use. For details, please refer to the HTTP mode description at the bottom of [README-Cherry-Studio.md](README-Cherry-Studio.md).
### 2. Learn the posture of talking to AI
**Detailed dialogue tutorial**: [README-MCP-FAQ.md](README-MCP-FAQ.md)
> 💡 **Hint**: It is not actually recommended to ask multiple questions at once. If the AI model you choose cannot even achieve the sequential calling shown in the figure below, it is recommended to change one.
<img src="/_image/ai4.png" alt="mcp 使用效果图" width="600">
<br>
## 🔌 MCP Client
TrendRadar MCP service supports the standard Model Context Protocol (MCP) protocol, and can be connected to various AI clients that support MCP for intelligent analysis.
### Supported clients
**Precautions**:
- Replace `/path/to/TrendRadar` with the actual path of your project
- Windows paths use double backslashes: `C:\\Users\\YourName\\TrendRadar`
- Remember to restart after saving
<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 ` .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 ` ~/.cursor/mcp.json` in the user directory (same content)
3. **Steps to use**:
- Restart Cursor after saving the configuration file
- View the connected tools in the "Available Tools" in the chat interface
- Start using: `Search for today's "AI" related news`
#### 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 in Cline's MCP settings:
**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"
]
}
}
]
}
}
```
**Example usage**:
```
Analyze the trend of "Tesla" popularity in the last 7 days
Generate a summary report of today's hot spots
Search for "Bitcoin" related news and analyze sentiment
```
</details>
<details>
<summary>👉 Click to expand: <b>MCP Inspector</b> (debugging tool)</summary>
<br>
MCP Inspector is the official debugging tool for testing MCP connections:
#### Usage Steps
1. **Start TrendRadar HTTP Service**:
```bash
# Windows
start-http.bat
# Mac/Linux
./start-http.sh
```
2. **Start MCP Inspector**:
```bash
npx @modelcontextprotocol/inspector
```
3. **Connect in Browser**:
- Access: `http://localhost:3333/mcp`
- Test "Ping Server" function to verify the connection
- Check if "List Tools" returns 17 tools:
- Basic Query: get_latest_news, get_news_by_date, get_trending_topics
- Intelligent Retrieval: search_news, find_related_news
- Advanced Analysis: analyze_topic_trend, analyze_data_insights, analyze_sentiment, aggregate_news, compare_periods, generate_summary_report
- RSS Query: 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 MCP-Supported Clients</b></summary>
<br>
Any client that supports 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 backslash escaping for Windows paths: `C:\\Users\\...`
- Ensure project dependencies are installed (setup script has been run)
</details>
### FAQ
<details>
<summary>👉 Click to expand: <b>Q1: HTTP service fails to start?</b></summary>
<br>
**Check Steps**:
1. Confirm port 3333 is not occupied:
```bash
# Windows
netstat -ano | findstr :3333
# Mac/Linux
lsof -i :3333
```
2. Check if project dependencies are installed:
```bash
# Rerun 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 fails to connect to MCP service?</b></summary>
<br>
**Solution**:
1. **STDIO Mode**:
- Confirm UV path is correct (run `which uv` or `where uv`)
- Confirm project path is correct and contains no Chinese characters
- View client error logs
2. **HTTP Mode**:
- Confirm service is running (access `http://localhost:3333/mcp`)
- Check firewall settings
- Try using 127.0.0.1 instead of localhost
3. **General Checks**:
- Restart client application
- View MCP service logs
- Use MCP Inspector to test the connection
</details>
<details>
<summary>👉 Click to expand: <b>Q3: Tool invocation 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 the query date range has data
- View available dates in the output directory
2. **Parameter Error**:
- Check date format: `YYYY-MM-DD`
- Confirm platform ID is correct: `zhihu`, `weibo`, etc.
- View parameter descriptions in the tool documentation
3. **Configuration Issue**:
- Confirm `config/config.yaml` exists
- Confirm `config/frequency_words.txt` exists
- Check if the configuration file format is correct
</details>
<br>
## 📚 Project Related
> **4 Articles**:
- [You can leave a message under this article to facilitate the project author to answer questions on the phone](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 on github fork](https://mp.weixin.qq.com/s/C8evK-U7onG1sTTdwdW2zg)
- [Based on this project, how to carry out public account or news information article writing](https://mp.weixin.qq.com/s/8ghyfDAtQZjLrnWTQabYOQ)
>**AI Development**:
- If you have niche needs, you can develop it yourself based on my project, and those with zero programming experience can also try it.
- All my open source projects more or less use my own **AI-assisted software** to improve development efficiency. This tool is open source.
- **Core Function**: Quickly filter project code and feed it to AI, you only need to supplement personal needs
- **Project Address**: https://github.com/sansan0/ai-code-context-helper
### Other Projects
> 📍 Mao Zedong's Footprint Map - Interactive dynamic display of the complete trajectory from 1893-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...)
oh-my-opencode
Background agents · Curated agents like oracle, librarians, frontend...
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.