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> deployment of TrendRadar - Say goodbye to ineffective screen brushing and only read the news information you really care about
<a href="https://trendradar.sandev.cc/en/" title="TrendRadar Official Website"><strong>🌐 Official Website</strong></a> · <a href="https://trendradar.sandev.cc/en/docs/quick-start/" title="TrendRadar Official Documentation"><strong>📖 Official Documentation</strong></a>
<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://hub.docker.com/r/wantcat/trendradar)
[](https://hub.docker.com/r/wantcat/trendradar-mcp)
[](#rss-source-support-v450-new)
[](#ai-multi-language-translation-v520-new)
[](#-mcp-client)
[](#ai-analysis-push-v500-new)
[](#ai-intelligent-news-screening-v650-new)
[](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/)
[](#)
[](#-quick-start)
[](https://sansan0.github.io/TrendRadar)
[](#6-docker-deployment)
[](#local-deploy)
[](#cloudflare-deploy)
</div>
<div align="center">
**English** | **[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 section. It is recommended to start with "**Quick Start**" for deployment, and for detailed customization, please refer to "**Detailed Configuration**".
<div align="center">
| | | |
|:---:|:---:|:---:|
| [🚀 **Quick Start**](#-quick-start) | [AI Intelligent Analysis](#-ai-intelligent-analysis) | [⚙️ **Detailed Configuration**](#detailed-configuration) |
| [Docker Deployment](#6-docker-deployment) / [Local Deployment](#local-deploy) | [MCP Client](#-mcp-client) | [📝 **Update Log**](#-update-log) |
| [🎯 **Core Features**](#-core-features) | [☕ **Supported Projects**](#-supported-projects) | [📚 **Project Related**](#-project-related) |
</div>
<br>
- Thanks to the **star** contributors, **fork** as you wish, **star** as I wish, and having both is the best support for open-source spirit.
<details>
<summary>👉 Click to expand: <strong>Acknowledgment List</strong> (Angel Round Honor List 🔥73+🔥 people)</summary>
### Early Supporters Acknowledgment
> 💡 **Special Note**:
>
> 1. **About the List**: The list below records the supporters during the early stages (angel round) of the project. Due to manual statistics being cumbersome, **there may be omissions or incomplete records, and if there are any omissions, it is not intentional, and we appreciate your understanding**.
> 2. **Future Plans**: In order to focus limited energy on code and feature iteration, **this list will no longer be manually maintained from now on**.
Regardless of whether your name is on the list, every bit of support you provide is the foundation for TrendRadar to reach where it is today. 🙏
### Infrastructure Support
Thanks to **GitHub** for providing free infrastructure, which is the biggest prerequisite for this project to be able to **fork with one click** and run smoothly.
### Data Support
This project uses the API from the [newsnow](https://github.com/ourongxing/newsnow) project to obtain multi-platform data, and we specially thank the author for providing the service.
After contacting the author, they expressed no concerns about server pressure, but this is based on their goodwill and trust. Please:
- **Go to the [newsnow project](https://github.com/ourongxing/newsnow) and star it for support**
- When deploying with Docker, please reasonably control the push frequency and avoid overfishing.
### Promotion and Assistance
> Thanks to the following platforms and individuals for their recommendations (in chronological order)
- [Minor Software](https://mp.weixin.qq.com/s/fvutkJ_NPUelSW9OGK39aA) - Open-source software recommendation platform
- [LinuxDo Community](https://linux.do/) - A gathering place for technology enthusiasts
- [Ruanyf Weekly](https://github.com/ruanyf/weekly) - A weekly newsletter with influence in the tech circle
### Audience Support
> Thanks to **those who have financially supported** us, your generosity has transformed into snacks and drinks beside our keyboards, accompanying every iteration of the project.
>
> **Regarding the return of "One Yuan Appreciation"**:
> With the release of version 5.0.0, the project has entered a new phase. To support the growing API costs and caffeine consumption, the "One Yuan Appreciation" channel has been reopened. Every thought you share will be converted into tokens and motivation in the world of code. 🚀 [Support Us](#-support-the-project)
| Donor | 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, brother |
| J*o | 1 | 2025.11.17 | Thanks for open-sourcing, wishing you success |
| *晨 | 8.88 | 2025.11.16 | The project is great, I'm studying and learning |
| *海 | 1 | 2025.11.15 | |
| *德 | 1.99 | 2025.11.15 | |
| *疏 | 8.8 | 2025.11.14 | Thanks for open-sourcing, the project is great, supporting |
| M*e | 10 | 2025.11.14 | Open-sourcing is not easy, thanks for your hard work |
| **柯 | 1 | 2025.11.14 | |
| *云 | 88 | 2025.11.13 | Good project, thanks for open-sourcing |
| *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, it's a pity we met late, thanks for open-sourcing! |
| *韦 | 9.9 | 2025.11.13 | TrendRadar is awesome, please have a cup of coffee~ |
| h*p | 5 | 2025.11.12 | Supporting China's open-source power, come on! |
| c*r | 6 | 2025.11.12 | |
| a*n | 5 | 2025.11.12 | |
| 。*c | 1 | 2025.11.12 | Thanks for sharing |
| *记 | 1 | 2025.11.11 | |
| *主 | 1 | 2025.11.10 | |
| *了 | 10 | 2025.11.09 | |
| *杰 | 5 | 2025.11.08 | |
| *点 | 8.80 | 2025.11.07 | It's not easy to develop, supporting |
| Q*Q | 6.66 | 2025.11.07 | Thanks for open-sourcing! |
| C*e | 1 | 2025.11.05 | |
| Peter Fan | 20 | 2025.10.29 | |
| M*n | 1 | 2025.10.27 | Thanks for open-sourcing |
| *许 | 8.88 | 2025.10.23 | Teacher, I'm a newbie, I've been playing around for a few days and still can't get it, seeking guidance |
| Eason | 1 | 2025.10.22 | I 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 | Appreciate |
| **杰 | 10 | 2025.10.16 | |
| *啸 | 10 | 2025.10.16 | |
| *纪 | 5 | 2025.10.14 | TrendRadar |
| J*d | 1 | 2025.10.14 | Thanks 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 | ...it's really great!!!even for a newbie like me... |
| **培 | 5.2 | 2025.10.2 | github-yzyf1312:open-source forever |
| *椿 | 3 | 2025.9.23 | Keep going, it's great |
| *🍍 | 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 | Appreciate |
| *家 | 10 | 2025.9.10 | |
| *X | 1.11 | 2025.9.3 | |
| *飙 | 20 | 2025.8.31 | From old Tong, thanks |
| *下 | 1 | 2025.8.30 | |
| 2*D | 88 | 2025.8.13 Afternoon | |
| 2*D | 1 | 2025.8.13 Morning | |
| S*o | 1 | 2025.8.05 | Support |
| *侠 | 10 | 2025.8.04 | |
| x*x | 2 | 2025.8.03 | trendRadar great project appreciate |
| *远 | 1 | 2025.8.01 | |
| *邪 | 5 | 2025.8.01 | |
| *梦 | 0.1 | 2025.7.30 | |
| **龙 | 10 | 2025.7.29 | Support |
</details>
<br>
## 🪄 Sponsors
<div align="center">
> **Position available**
>
> Interested in sponsoring? Trigger the auto-reply in the WeChat public account to get my contact information
</div>
<br>
<a name="-support-the-project"></a>
### ❤️ If you find it useful? Support us
> If TrendRadar has helped you capture value, consider injecting energy into it to help it continue to evolve
>
> The amount is arbitrary, and 1 yuan is also an encouragement for open-source. Welcome to leave a message when appreciating (´▽`ʃ♡ƪ)
<div align="center">
| WeChat Appreciation | Alipay Appreciation |
|:---:|:---:|
| <img src="https://cdn-1258574687.cos.ap-shanghai.myqcloud.com/img/%2F2025%2F07%2F17%2F2ae0a88d98079f7e876c2b4dc85233c6-9e8025.JPG" width="240" alt="WeChat Appreciation"> | <img src="https://cdn-1258574687.cos.ap-shanghai.myqcloud.com/img/%2F2025%2F07%2F17%2F1ed4f20ab8e35be51f8e84c94e6e239b4-fe4947.JPG" width="240" alt="Alipay Appreciation"> |
</div>
### 🤝 Secondary development and citation
If you use or refer to the ideas or core code of this project in your project, **very welcome** to indicate the source and attach a link to this repository in the README or documentation.
This will help with the continued maintenance and community development of the project, thank you for your respect and support! ❤️
### 💬 Communication and feedback
- **GitHub Issues**: Suitable for specific technical issues. When asking questions, please provide complete information (screenshots, error logs, etc.) to help with quick positioning.
- **Public account communication**: It is recommended to communicate in the comment area under the relevant article first. If you need to ask questions in the background, **liking/recommending** the article is the best "knock on the door", I can feel this thought in the background (´▽`ʃ♡ƪ).
- **QQ group communication**: Follow the public account and reply " **communication group** " to join. Whether you are an AI novice or a hardcore developer, you are welcome to ask technical questions or share experiences. The group is mainly for mutual assistance and communication, and the entry group please see the group announcement; when asking questions, describe the problem clearly, attach a screenshot, and the group friends will help if they have time, and everyone's practical experience is often faster and more comprehensive than I alone 🤝
> **Friendly reminder**:
> This project is for open-source sharing, non-commercial products. Treating the author as a friend rather than a customer service, the communication efficiency will be higher!
<div align="center">
|Public account follow |
|:---:|
| <img src="_image/weixin.png" width="500" title="硅基茶水间"/> |
</div>
<br>
## 📝 Update Log
> **📌 View the latest updates**: **[Original repository update log](https://github.com/sansan0/TrendRadar?tab=readme-ov-file#-更新日志)** :
- **Tips**: It is recommended to view the [historical updates] and clarify the specific [functional content]
### 2026/06/19 - v6.10.0
- **AI translation batch processing**: Automatically batch requests for large title translations to avoid translation failures due to exceeding limits
- **Module splitting and refactoring**: Split context.py and __main__.py, AI screening pipeline independently as filter_pipeline module, clearer responsibilities, easier maintenance
- **Fix Feishu source label display**: Fix the issue that Feishu card source labels and AI independent source point overview are swallowed by CommonMark and not displayed
### 2026/02/09 - mcp-v4.0.0
- **🔥 AI message direct push to all channels**: Let AI-written content push to 9 channels including Feishu, DingTalk, Telegram, and email with one click, Markdown automatically adapts to each platform's format, no need to worry about format differences
- **Add formatting strategy guide**: Add get_channel_format_guide tool to tell AI what format each channel supports, what limitations there are, and generate content with better layout
- **Intelligent batch sending**: Automatically split super long messages according to each channel's byte limit (Feishu 30KB, DingTalk 20KB, etc.), configuration reads from config.yaml
- **Fix channel misdetection**: ntfy no longer reports as "configured" because of the default address
- **Code reuse optimization**: Batch processing functions directly reuse trendradar core modules, no duplicate wheel making
<details>
<summary>👉 Click to expand: <strong>Historical updates</strong></summary>
### 2026/06/02 - v6.9.0
- **Hot list domain security verification**: Add expected_domain configuration item to verify the domain legitimacy of returned data links, automatically discard data and warn if it does not match, effectively preventing link hijacking or data tampering
- **Custom hot list API address**: Support self-deployed newsnow and configure api_url to use your own data source
### 2026/05/23 - v6.8.0
- **HTML report comprehensive enhancement**: Add report metadata display (generation time, data source, version number), dark mode automatic adaptation, tab bar interaction optimization, trend arrow visualization, greatly improving browser reading experience
- **Version check CDN multi-source fallback**: Version check interface supports GitHub → jsDelivr → Cloudflare and other multiple CDN source automatic fallback, domestic network environment can also stably obtain update prompts
- **Display area switch takes effect**: HTML report and email now correctly respect display.regions.ai_analysis and display.regions.standalone switches, closing does not render
- **Export button repair**: Fix the problem that the export button dropdown menu icon disappears after clicking
- **Markdown export repair**: Fix HTML report Markdown export JS line break character escape error
### 2026/05/15 - v6.7.0
- **Markdown export**: Report export dropdown menu adds Markdown format, one-click generation of structured text with links, convenient for LLM secondary processing and cross-platform sharing ([#1121](https://github.com/sansan0/TrendRadar/issues/1121))
- **RSS guid de-duplication**: RSS storage adds guid field, de-duplication priority becomes guid > url, solving the problem of duplicate entry into the warehouse due to URL changes
- **Empty title protection**: Parser, rendering layer, translation backfill full-chain increase empty title bottom line logic to ensure that title-less entries can also be displayed normally
- **Translation quality enhancement**: Translation prompt word requirements retain number order, empty translation results no longer overwrite original title
### 2026/03/28 - v6.6.0
- **HTML report browser enhancement**: Open the report in the browser to automatically switch to a wide-screen layout, keyword grouping and independent exhibition area support Tab quick switching, search box real-time filter news title, email client still displays the original narrow-screen layout
- **Dark mode**: One-click switch to dark theme, automatically remember preferences, suitable for night reading
- **One-click copy news**: Mouse hover news serial number can copy title and link, convenient for quick sharing
- **Export optimization**: Whole page screenshot and segmented screenshot merge into a drop-down export button, automatically restore clean layout when exporting
- **Shortcut key system**: Support `W` wide-screen switching, `D` dark mode, `/` search, `?` view shortcut key prompts
- **Reading progress bar**: Real-time display of reading progress at the top of the page
### 2026/03/12 - v6.5.0
- **AI intelligent screening system**: No need to manually set keywords! Write down the directions you are concerned about in ai_interests.txt (e.g., "I want to see AI and new energy-related news"), AI will automatically extract tags and score each piece of news, only push content that is really relevant to you. If AI screening has problems, it will automatically switch back to keyword matching, and the push will not be interrupted
- **Each time period supports different screening methods and focus directions**: Each time period in the Timeline can now independently set what method to use for screening and what type of news to look at. For example: morning use "technology keywords" quick filter, evening switch to "financial AI interest description" for in-depth screening - the same system, different time periods to see different content
- **AI analysis range independent of push**: The data range of AI analysis can be different from the push content. For example, push only sends new messages (to avoid repeated disturbance), but AI analysis all news of the day (to see the complete trend). Each time period can also set AI analysis mode independently
- **AI screening smart saving**: Already analyzed news will not consume duplicate tokens; after interest description changes, AI automatically judges the change range - small changes only update affected tags, large changes re-classify all
- **Multi-file configuration and tag isolation**: Custom keyword files are placed in config/custom/keyword/, AI interest files are placed in config/custom/ai/, and different files produce independent labels that do not interfere with each other
- **AI translation precise control**: Can control whether hot list, RSS, and independent display area are translated, and areas that are not displayed are skipped without consuming tokens
- **Remote storage batch upload**: Multiple write operations are accumulated and submitted to the cloud at one time to reduce API calls
- **Each group of keywords/tags display limit**: Control the maximum number of news displayed in each group through max_news_per_keyword to avoid a single hot topic occupying the entire push
- **Time period conflict intelligent detection**: If two time periods have time overlaps, the system will automatically report an error and modify it to avoid unexpected behavior
- Fix several bugs
### 2026/02/09 - v6.0.0
> **Breaking Change**: Config file upgrade (config.yaml 2.0.0), old `push_window` and `analysis_window` configurations are no longer compatible, please refer to the new config.yaml for migration.
- **Unified Scheduling System**: Added `timeline.yaml`, use one configuration to control "when to collect / push / AI analyze"
- **5 Preset Templates**: `always_on` (always on, default), `morning_evening` (morning and evening summary), `office_hours` (office hours), `night_owl` (night owl), `custom` (custom); also supports adding your own templates under `presets:`, as long as the key is not repeated, then fill in your template name in config.yaml
- **Flexible Time Period Configuration**: supports workday/weekend differences, cross-midnight time periods, per-period once deduplication
- **Visual Configuration Editor**:
- Added `timeline.yaml` editing tab, parallel to config.yaml / frequency_words.txt
- Preset mode card selection: click to switch, automatically synchronize config.yaml's `schedule.preset`
- Weekly view timeline: 7 days × 24 hours horizontal bar, use color to distinguish push/analysis/collect status
- Interactive controls: switches, drop-down boxes, time selectors, modify on the right and synchronize to the left YAML in real time
- Weekly mapping drop-down selection: dynamically fill in according to the daily plan, drag and click to complete scheduling configuration
- **AI Prompt Stability Optimization** (ai_analysis_prompt.txt v2.0.0):
- Format specification independent description: extract line breaks/tags/serial numbers/forbidden items from JSON value, as an independent chapter
- JSON template simplification: field description shortened to one sentence + word limit, reduce AI output format confusion
- Remove Markdown format in system prompt, consistent with "forbidden Markdown" instruction
- All JSON fields declared as optional, missing any field will not error, enhance fault tolerance
- **Added Independent Display Area AI Summary** (`ai_analysis.include_standalone`):
- Added independent switch, after enabling, AI generates core summary for each standalone source
- AI analysis and push display decoupling: no need to enable push display in independent display area, AI can also independently analyze complete hot list data
- Supports hot list platform and RSS source, including ranking/time/track data
- Track analysis linked with `include_rank_timeline`: when enabled, use track data for in-depth trend analysis, when disabled, based on ranking for brief judgment
- Added `standalone_summaries` JSON field (independent source quick view), all push channels have adapted rendering
### 2026/01/28 - v5.5.0
> Same as mcp functionality, this small tool doesn't need a separate repository for maintenance, it's pure frontend, so it's put together.
- Added trendradar's visual configuration editor
### 2026/02/02 - mcp-v3.2.0
- **Added read_article tool**: read a single article body through Jina AI Reader (Markdown format)
- **Added read_articles_batch tool**: batch read multiple articles (up to 5 articles, automatic speed limit)
- **Recommended workflow**: `search_news(query="keyword", include_url=True)` → `read_article(url=...)` read the body
- **Document update**: README-MCP-FAQ.md and README-MCP-FAQ-EN.md added Q19-Q20 article reading related instructions
### 2026/01/10 - mcp-v3.0.0~v3.1.5
- **Breaking Change**: all tool return values unified to `{success, summary, data, error}` structure
- **Asynchronous consistency**: all 21 tool functions use `asyncio.to_thread()` to package synchronous calls
- **MCP Resources**: added 4 resources (platforms, rss-feeds, available-dates, keywords)
- **RSS enhancement**: `get_latest_rss` supports multi-day query (days parameter), cross-date URL deduplication
- **Regular expression fix**: `get_trending_topics` supports `/pattern/` regular expression syntax and `display_name`
- **Cache optimization**: added `make_cache_key()` function, parameter sorting + MD5 hash ensures consistency
- **Added check_version tool**: supports checking TrendRadar and MCP Server version updates at the same time
### 2026/01/23 - v5.4.0
- Added AI analysis mode independent control function, optional follow_report | daily | current | incremental
- Added AI analysis time window control, supports custom running segment and daily frequency limit
- 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 instead of manual implementation, supports 100+ AI providers
- **Simplified configuration**: removed `provider` field, changed to `model: "provider/model_name"` format
- **Added features**: automatic retry (`num_retries`), backup 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 example**:
- 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
> Mainly see config.yaml description
**🌐 AI Translation Function**
- **Multi-language translation**: supports translating push content into any language
- **Batch translation**: intelligent batch processing, reduces API call times
- **Custom prompt words**: supports custom translation style
**🔧 Configuration Architecture Optimization**
- **AI model configuration independent**: analysis and translation share model configuration
- **Regional switch unified**: unified management of regional display
- **Regional sorting custom**: supports custom display order of each region
**✨ AI Analysis Enhancement**
- **AI analysis embedded HTML**: analysis results directly embedded into HTML report, email notification directly uses
- **Rich style AI block**: gradient blue background card layout, clearly separates each analysis dimension
- **Ranking timeline support**: AI can obtain precise ranking of each news at each crawl time point
- **Sector reorganization (7→4)**: integrated into core hot spot situation, public opinion trend controversy, abnormal and weak signal, research strategy suggestion
**🔧 Multi-model Adaptation**
- **General parameter pass-through**: supports passing arbitrary advanced parameters to API
- **Gemini adaptation**: native parameter support, built-in security strategy relaxation
**🐛 Bug Fix**
- Fixed several known issues, improved system stability
### 2026/01/10 - v5.0.0
> **Development episode**:
> Pay tribute to the one that accompanied me for more than two years, but after renewing, it popped up `"This organization has been disabled"`.
**✨ Push Content "Five Major Sections" Refactor**
This update refactored the push message into five major sections, now the push content is clearly divided into five core sections:
1. **📊 Hot List News**: full network hot spot aggregation after precise screening according to your keywords.
2. **📰 RSS Subscription**: your personalized subscription source content, supports grouping by keyword.
3. **🆕 This newly added**: real-time capture of new hot spots since the last run (with 🆕 mark).
4. **📋 Independent Display Area**: complete hot list or RSS source display of the specified platform, **completely不受关键词过滤限制**.
5. **✨ AI Analysis Section**: in-depth insight driven by AI, including trend overview, heat trend and **extremely important** sentiment analysis.
**✨ AI Intelligent Analysis Push Function**
- **AI analysis integration**: use AI large model to deeply analyze push content, automatically generate hot spot trend overview, keyword heat analysis, cross-platform association, potential impact assessment, etc.
- **Sentiment tendency analysis**: added deep sentiment recognition, accurately capture public opinion's positive/negative, controversy or worry emotion
- **Multi-AI provider support**: supports DeepSeek (default, high cost-performance), OpenAI, Google Gemini and any OpenAI compatible interface
- **Two push modes**: `only_analysis` (only AI analysis), `both` (both push)
- **Custom prompt words**: customize AI analysis role and output format through `config/ai_analysis_prompt.txt` file
- **Multi-dimensional data analysis**: AI can analyze ranking changes, heat duration, cross-platform performance, trend prediction, etc.
**📋 Independent Display Area Function**
- **Complete hot list display**: complete hot list of specified platform separately displayed,不受关键词过滤影响
- **RSS independent display**: RSS source content can be completely displayed, suitable for content-less subscription source
- **Flexible configuration**: supports configuring display platform list, RSS source list, maximum display number
**📊 Push Experience Refactor**
- **Typesetting upgrade**: redesigned and unified statistical header of each channel, strengthened block organization, message hierarchy is clear at a glance
- **Configuration simplification**: optimized configuration logic of notification channels like Feishu, easier to get started
- **Heat trend arrow**: added 🔺(rising), 🔻(falling), ➖(stable) trend identification, intuitively display heat change
- **General Webhook**: supports custom Webhook URL and JSON template, easily adapt to Discord, Matrix, IFTTT and other arbitrary platforms
**🔧 Configuration Optimization**
- **Frequency word configuration enhancement**: added `[group name]` syntax, supports `#` comment line, configuration is clearer (thanks to [@songge8](https://github.com/sansan0/TrendRadar/issues/752) proposed suggestions)
- **Environment variable support**: AI analysis related configuration supports environment variable coverage (`AI_API_KEY`, `AI_PROVIDER`, etc.)
> 💡 See detailed configuration tutorial at [让 AI 帮我分析热点](#12-让-ai-帮我分析热点)
### 2026/01/02 - v4.7.0
- **Fix RSS HTML display**: fix RSS data format mismatch caused rendering problem, now correctly display according to keyword grouping
- **Added regular expression syntax**: keyword configuration supports `/pattern/` regular expression syntax, solve English substring mis-matching problem (e.g., `ai` matches `training`) [📖 View syntax details](#关键词基础语法)
- **Added display name syntax**: use `=> remark` to give complex regular expression a good name, push message display is clearer (e.g., `/\bai\b/ => AI-related`)
- **Don't know how to write regular expressions?** README added AI-generated regular expression guide, tell ChatGPT/Gemini/DeepSeek what you want to match, let AI help you write
### 2025/12/30 - mcp-v2.0.0
- **Architecture adjustment**: remove TXT support, unify using SQLite database
- **RSS query**: added `get_latest_rss`, `search_rss`, `get_rss_feeds_status`
- **Unified search**: `search_news` supports `include_rss` parameter to search hot list and RSS at the same time
### 2026/01/01 - v4.6.0
- **Fix RSS HTML display**: merge RSS content into hot list HTML page, display according to source grouping
- **Added display_mode configuration**: supports `keyword` (group by keyword) and `platform` (group by platform) two display modes
### 2025/12/30 - v4.5.0
- **RSS subscription source support**: added RSS/Atom capture, group by keyword statistics (consistent with hot list format)
- **Storage structure refactoring**: flattened directory structure `output/{type}/{date}.db`
- **Unified sorting configuration**: `sort_by_position_first` affects both hot list and RSS
- **Configuration structure refactoring**: `config.yaml` reorganized into 7 logical groups (app, report, notification, storage, platforms, rss, advanced), configuration path is clearer
### 2025/12/26 - mcp-v1.2.0
**MCP module update - optimize toolset, add aggregation comparison function, merge redundant tools:**
- Added `aggregate_news` tool - cross-platform news deduplication aggregation
- Added `compare_periods` tool - period comparison analysis (week-on-week/month-on-month)
- Merge `find_similar_news` + `search_related_news_history` → `find_related_news`
- Enhanced `get_trending_topics` - added `auto_extract` mode automatically extracts hot spots
- Fixed several bugs
- Synchronously update README-MCP-FAQ.md documentation in Chinese and English versions (Q1-Q18)
### 2025/12/20 - v4.0.3
- Added URL standardization function, solve duplicate push problem caused by dynamic parameters on some platforms (e.g., `band_rank`)
- Fixed incremental mode detection logic, correctly identify historical titles
### 2025/12/17 - v4.0.1
- StorageManager adds push record proxy method
- S3 client switched to virtual-hosted style to improve compatibility (supports Tencent Cloud COS and more services)
### 2025/12/13 - mcp-v1.1.0
**MCP module update:**
- Adapt to v4.0.0, also compatible with v3.x data
- Added storage synchronization tool: `sync_from_remote`, `get_storage_status`, `list_available_dates`
### 2025/12/13 - v4.0.0
**🎉 Major update: comprehensive refactoring of storage and core architecture**
- **Multi-storage backend support**: introduced new storage module, supports local SQLite and remote cloud storage (S3 compatible protocol, e.g., Cloudflare R2), adapt to GitHub Actions, Docker and local environment.
- **Database structure optimization**: refactor SQLite database table structure, improve data efficiency and query ability.
- **Core code modularization**: split main program logic into multiple modules of trendradar package, significantly improve code maintainability.
- **Enhanced function**: implement date format standardization, data retention strategy, time zone configuration support, time display optimization, and fix remote storage data persistence problem, ensure data merging accuracy.
- **Cleanup and compatibility**: removed most historical compatibility code, unified data storage and reading method.
### 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 semicolon `;` to separate multiple accounts, e.g., `FEISHU_WEBHOOK_URL=url1;url2`
- Automatically verify matching configuration (e.g., Telegram's token and chat_id) quantity consistency
2. **Push area configuration**
- Customize display order of each area through `display.region_order` (v5.2.0 replaces original `reverse_content_order`)
- Control display of each area through `display.regions` (hot list, new hot spots, RSS, independent display area, AI analysis)
3. **Global filter keywords**
- Added `[GLOBAL_FILTER]` area mark, supports global filtering of unwanted content
- Applicable scenarios: filter ads, marketing, low-quality content, etc.
**🐳 Docker double-path HTML generation optimization**
- **Problem fix**: solve `index.html` unable to synchronize to host machine problem in Docker environment
- **Double-path generation**: when-day summary HTML is generated in two locations
- `index.html` (project root directory): for GitHub Pages access
- `output/index.html`: through Docker Volume mount, host machine can directly access
- **Compatibility**: ensure Docker, GitHub Actions, local running environment can access webpage report
**🐳 Docker MCP image support**
- Added independent MCP service image `wantcat/trendradar-mcp`
- Supports Docker deployment of AI analysis function, through HTTP interface (port 3333) provide service
- Double-container architecture: news push service and MCP service run independently, can be expanded and restarted separately
- See [Docker deployment - MCP service](#6-docker-部署)
**🌐 Web server support**
- Added built-in web server, supports access to generated report through browser
- Control start/stop through `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 limit, local access
- Supports automatic start and manual control two modes
**📖 Documentation optimization**
- Added [How to display push content?](#7-推送内容怎么显示) section: customize push style and content
- Added [When will I be pushed?](#8-什么时候给我推送) section: set push time period
- Added [How often run?](#9-多久运行一次) section: set automatic running frequency
- Added [Push to multiple groups/devices](#10-推送到多个群设备) section: push to multiple receivers
- Optimize each configuration section: unified add "configuration location" description
- Simplified quick start configuration description: three core files at a glance
- Optimized [Docker deployment](#6-docker-部署) section: added image description, recommended git clone deployment, reorganized deployment method
**🔧 Upgrade instructions**:
- **GitHub Fork user**: update `main.py`, `config.yaml` (add multi-account push support, no need to modify existing configuration)
- **Multi-account push support**: new feature, default not enabled, existing single-account configuration unaffected
### 2025/11/25 - v3.4.0
**🎉 Added Slack Push Support**
1. **Team Collaboration Push Channel**
- Supports Slack Incoming Webhooks (a popular team collaboration tool globally)
- Centralized message management, suitable for teams to share hot news
- Supports mrkdwn format (bold, links, etc.)
2. **Multiple Deployment Methods**
- GitHub Actions: Configure `SLACK_WEBHOOK_URL` Secret
- Docker: Environment variable `SLACK_WEBHOOK_URL`
- Local operation: `config/config.yaml` configuration file
> 📖 **Detailed Configuration Tutorial**: [Quick Start - Slack Push](#-quick-start)
- Optimized the one-click installation experience of setup-windows.bat and setup-windows-en.bat for MCP
**🔧 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, without ad 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 operation: `config/config.yaml` configuration file
> 📖 **Detailed Configuration Tutorial**: [Quick Start - Bark Push](#-quick-start)
**🐛 Bug Fixes**
- Fixed the issue that `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: heat priority vs. configuration order priority
- Meets different usage scenarios: hot spot tracking or personalized attention
2. **Precise Control of Display Quantity**
- Global configuration: uniformly limit the display quantity of all keywords
- Separate configuration: use `@number` syntax to set limits for specific keywords
- Effectively control push length and highlight key content
> 📖 **Detailed Configuration Tutorial**: [Keyword Configuration - Advanced Configuration](#keyword-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 might incorrectly return past dates
### 2025/11/22 - v3.1.1
- **Fixed Crash Issues Caused by Abnormal Data**: 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 string) at the data acquisition stage, and add type checks at function calls
- Improved system stability to ensure normal operation even when the data source returns an abnormal format
**Upgrade Instructions** (GitHub Fork Users):
- Must update: `main.py`
- Recommended to use 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 push 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, supporting multiple deployment methods such as GitHub Actions, Docker, and docker compose
- `text` mode automatically clears Markdown syntax to provide pure 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)
- Recommended to use minor version upgrade method: copy and replace the above files
### 2025/11/12 - v3.0.5
- Fixed the logical error in email sending SSL/TLS port configuration
- 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 coverage through environment variables, solving the issue that NAS users' modified configuration files do not take effect (see [🐳 Docker Deployment](#-docker-deployment) chapter for details)
### 2025/10/26 - mcp-v1.0.1
**MCP Module Update:**
- Fixed date query parameter passing error
- Unified time parameter format for all tools
### 2025/10/31 - v3.0.4
- Solved the error caused by Feishu's push content being too long and implemented batch push
### 2025/10/23 - v3.0.3
- Expanded ntfy error information display range
### 2025/10/21 - v3.0.2
- Fixed ntfy push encoding issue
### 2025/10/20 - v3.0.0
**Major Update - AI Analysis Function Launched** ✨
- **Core Features**:
- 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 (heat tracking, life cycle, explosion 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 Instructions**:
- This is an independent AI analysis function that does not affect existing push functions
- Can be used selectively without upgrading existing deployment
### 2025/10/15 - v2.4.4
- **Update Content**:
- Fixed ntfy push encoding issue + 1
- Fixed push time window judgment issue
- **Update Instructions**:
- Recommended to use [minor version upgrade]
### 2025/10/10 - v2.4.3
> Thanks to [nidaye996](https://github.com/sansan0/TrendRadar/issues/98) for discovering experience issues
- **Update Content**:
- Refactored "silent push mode" to "push time window control" to improve functional understanding
- Clearly defined push time window as an optional additional function that can be used with three push modes
- Improved comments and document descriptions to make functional positioning clearer
- **Update Instructions**:
- This is just a refactoring, no need to 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 segment export function
- **Update Instructions**:
- Recommended to use [major version update]
### 2025/10/2 - v2.4.0
**Added NTFY Push Notification**
- **Core Features**:
- Supports ntfy.sh public service and self-hosted server
- **Usage Scenarios**:
- Suitable for users pursuing privacy (supports self-hosting)
- Cross-platform push (iOS, Android, Desktop, Web)
- No need to register an account (public server)
- Open-source and free (MIT protocol)
- **Update Instructions**:
- Recommended to use [major version update]
### 2025/09/26 - v2.3.2
- Corrected the email notification configuration check omission issue ([#88](https://github.com/sansan0/TrendRadar/issues/88))
**Fix Instructions**:
- Solved the issue that even with correct email notification configuration, the system still prompts "no webhook configured"
### 2025/09/22 - v2.3.1
- **Added Email Push Function**, supports sending hot news reports to email
- **Intelligent SMTP Identification**: automatically identifies 10+ email service providers' configurations such as Gmail, QQ mailbox, Outlook, and NetEase mailbox
- **HTML Beautiful Format**: email content adopts the same HTML format as the web version, with beautiful layout and mobile adaptation
- **Batch Sending Support**: supports multiple recipients, separated by commas to send to multiple people at once
- **Custom SMTP**: customizable SMTP server and port
- Fixed Docker build network connection issue
**Instructions for Use**:
- Applicable scenarios: suitable for users who need email archiving, team sharing, and timing reports
- Supported email: Gmail, QQ mailbox, Outlook/Hotmail, 163/126 mailbox, Sina mailbox, Sohu mailbox, etc.
**Update Instructions**:
- This update has more content, if you want to upgrade, it is recommended to use [major version upgrade]
### 2025/09/17 - v2.2.0
- Added one-click save news image function, making it easy to share concerned hotspots
**Instructions for Use**:
- Applicable scenarios: when you enable the web version function (GitHub Pages) according to the tutorial
- Usage method: open the webpage link with a mobile phone or computer, click the "Save as Picture" button at the top of the page
- Actual effect: the system will automatically make the current news report into a beautiful image and save it to your mobile phone album or computer desktop
- Convenient sharing: you can directly send the image to friends, post it on Moments, or share it to the work group, letting others see the important information you discovered
### 2025/09/13 - v2.1.2
- Solved the DingTalk push capacity limit issue (adopted batch push)
### 2025/09/04 - v2.1.1
- Fixed the issue that Docker cannot run normally on certain architectures
- Officially released the official Docker image wantcat/trendradar, supporting multiple architectures
- Optimized Docker deployment process, no need for local build to quickly use
### 2025/08/30 - v2.1.0
**Core Improvements**:
- **Push Logic Optimization**: changed from "push every execution" to "controllable push within a time window"
- **Time Window Control**: can set push time range to avoid disturbing during non-working hours
- **Optional Push Frequency**: supports single push or multiple pushes within a time period
**Update Instructions**:
- This function is disabled by default, need to manually enable push time window control in config.yaml
- Upgrade requires updating main.py and config.yaml files simultaneously
### 2025/08/27 - v2.0.4
- This version is not a functional fix but an important reminder
- Please properly keep webhooks confidential, do not expose them publicly, and do not fill them into config.yaml
- If you have exposed webhooks or filled them into config.yaml, it is recommended to delete and regenerate them
### 2025/08/06 - v2.0.3
- Optimized GitHub page web version effect for mobile use
### 2025/07/28 - v2.0.2
- Refactored code
- Solved the issue of version number easily being omitted and modified
### 2025/07/27 - v2.0.1
**Fixed Issues**:
1. Docker shell script's line ending character CRLF caused execution exception
2. frequency_words.txt being empty caused news sending to be empty logic issue
- Fixed, when you choose frequency_words.txt to be empty, it will **push all news**, but limited by message push size, please make adjustments as follows
- Scheme 1: close mobile push, only choose GitHub Pages deployment (this is the best scheme to obtain complete information, will reorder all platform hotspots according to your **custom hotspot algorithm**)
- Scheme 2: reduce push platforms, prioritize **Enterprise WeChat** or **Telegram**, these two pushes have batch push function (because batch push affects push experience, and only these two platforms have a little push capacity, so had to do batch push function, but at least can ensure information integrity)
- Scheme 3: can combine with Scheme 2, mode selection current or incremental can effectively reduce one-time push content
### 2025/07/17 - v2.0.0
**Major Refactor**:
- Configuration management refactor: all configurations are now managed through `config/config.yaml` file (main.py still not split, for your convenience to copy and upgrade)
- Running mode upgrade: supports three modes - `daily` (daily summary), `current` (current ranking), `incremental` (incremental monitoring)
- Docker support: complete Docker deployment solution, supports containerized operation
**Configuration File Instructions**:
- `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 (configured FOCUS_NEW_ONLY at the head of main.py), this switch only cares about new topics rather than continuous heat, only sends notifications when there is new content.
**Fixed Issues**: occasional layout anomalies caused by certain news containing special symbols.
### 2025/06/23 - v1.3.0
Enterprise WeChat and Telegram push messages have length limits, so I adopted a method of splitting messages for push. Development documentation see [Enterprise WeChat](https://developer.work.weixin.qq.com/document/path/91770) and [Telegram](https://core.telegram.org/bots/api)
### 2025/06/21 - v1.2.1
In versions before this, 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 each platform's API, which allowed me to quickly complete platform adaptations (although the code is more redundant~
1. Supports Telegram, Enterprise WeChat, DingTalk push channels, supports multi-channel configuration and simultaneous push
### 2025/06/18 - v1.1.0
> **200 stars⭐**, continue to help everyone~ Recently, under my "instigation", many people liked, shared, and recommended on my public account, and I saw the specific account encouragement data in the background, many of which became angel round old powder (I started the public account more than a month ago, although it was registered seven or eight years ago, haha, belonging to early car, late departure), but because you did not leave a message or private message me, so I couldn't respond and thank you one by one, here thanks you together!
1. Important update, added weight, the news you see now are the hottest and most concerned at the top
2. Updated document usage, because recently updated many functions, and the previous usage document I wrote was simple (see the complete tutorial for ⚙️ frequency_words.txt configuration below)
### 2025/06/16 - v1.0.0
1. Added a project new version update prompt, default on, if you want to turn it off, you can change True to False in main.py "FEISHU_SHOW_VERSION_UPDATE"
### 2025/06/13+14
1. Removed compatible code, previous fork students, directly copying code will show abnormalities on that day (the next day will return to normal)
2. Added a new news display at the bottom of Feishu and HTML
### 2025/06/09
**100 stars⭐**, write a small function to help everyone~
Added a 'must-have word' function in frequency_words.txt using the + sign
1. Must-have word syntax:
Tang Sanzang or Zhu Bajie must appear in the title at the same time to be included in the pushed news
```
+Tang Sanzang
+Zhu Bajie
```
2. Filtering words have higher priority:
If the filtering words match Tang Sanzang chanting, even if the must-have words have Tang Sanzang, it will not be displayed
```
+Tang Sanzang
!Tang Sanzang chanting
```
### 2025/06/02
1. **Webpage** and **Feishu message** support direct jump to news details
2. Optimized display effect + 1
### 2025/05/26
1. Optimized Feishu message display effect
<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
### **All-Network Hotspot Aggregation**
- Zhihu
- Douyin
- Bilibili hot search
- Wall Street insights
- Tieba
- Baidu hot search
- Financial news
- Pengpai News
- Phoenix.com
- Toutiao
- Weibo
Default monitoring of 11 mainstream platforms, can also add extra platforms
> 💡 Detailed configuration tutorial see [Configuration Details - Platform Configuration](#1-platform-configuration)
### **RSS Subscription Source Support** (added in v4.5.0)
Supports RSS/Atom subscription source capture, grouped by keyword statistics (consistent with hot list format):
- **Unified format**: RSS and hot list use the same keyword matching and display format
- **Simple configuration**: directly add RSS source in `config.yaml`
- **Merged push**: hot list and RSS are merged into one message push
- **Freshness filtering**: automatically filter old articles exceeding the specified number of days to avoid repeated push. Supports global default days and single-source independent settings
> 💡 RSS uses the same `frequency_words.txt` for keyword filtering
### **Visual Configuration Editor**
Provides a web-based graphical configuration interface, no need to manually edit YAML files, all configuration items can be modified and exported through the form.
👉 **Online experience**: [https://sansan0.github.io/TrendRadar/](https://sansan0.github.io/TrendRadar/)
<img src="/_image/editor.png" alt="Visual configuration editor" width="80%">
### **Smart Push Strategy**
**Three Push Modes**:
| Mode | Applicable Scenario | Push Characteristics |
|------|---------|---------|
| **Daily Summary** | Enterprise Managers / Ordinary Users | Push all matching news of the day (including previously pushed) on time |
| **Current Hot List** | Self-Media People / Content Creators | Push current hot list matching news on time (continuously on the list appear every time) |
| **Incremental Monitoring** | 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 hot list trend → Use `current` (Current Hot List)
> - Need a daily summary report → Use `daily` (Daily Summary)
>
> For detailed comparison and configuration tutorials, see [Configuration Details - Push Mode Details](#3-push-mode-details)
**Additional Features** (Optional):
| Feature | Description | Default |
|------|------|------|
| **Scheduling System** | Arrange from Monday to Sunday: assign different time periods, push modes, and AI analysis strategies for each day. **Each time period can independently set filtering methods (keywords/AI) and focus directions**, to see different types of news at different times. Built-in 5 presets (always_on / morning_evening / office_hours / night_owl / custom), also customizable. Supports workday/weekend differences,跨午夜时段, per-period去重, time period conflict detection (v6.0.0 + v6.5.0) | morning_evening |
| **Content Order Configuration** | Adjust the display order of each area (hot list, new hot spots, RSS, independent display area, AI analysis) through `display.region_order`; control whether each area is displayed through `display.regions` (v5.2.0) | See configuration file |
| **Display Mode Switching** | `keyword`=grouped by keyword, `platform`=grouped by platform (added in v4.6.0) | keyword |
> 💡 For detailed configuration tutorials, see [How to display push content?](#7-how-to-display-push-content) and [When to push to me?](#8-when-to-push-to-me)
### **Accurate Content Filtering**
Set personal keywords (e.g., AI, BYD, education policy), only push relevant hotspots, and filter out irrelevant information
> 💡 **Basic Configuration Tutorial**: [Keyword Configuration - Basic Syntax](#keyword-basic-syntax)
>
> 💡 **Advanced Configuration Tutorial**: [Keyword Configuration - Advanced Configuration](#keyword-advanced-configuration)
>
> 💡 You can also not do filtering and push all hotspots completely (leave `frequency_words.txt` empty)
### **AI Intelligent News Screening** (added in v6.5.0)
Use natural language to describe your interests, and AI automatically classify news, replacing traditional keyword matching
- **Natural Language Interest Description**: Write down your focus directions in `ai_interests.txt` in daily language, no need to learn keyword syntax
- **Two-Stage Intelligent Processing**: AI extracts structured tags from interest descriptions and then classifies news into tags in batches and scores them
- **Score Threshold Control**: Precisely control the push quality through `ai_filter.min_score`, only push high-relevance news
- **Automatic Fallback Guarantee**: When AI screening fails, automatically fall back to keyword matching to ensure uninterrupted push
- **Intelligent Tag Update**: When interests change, AI automatically evaluates the change amplitude and decides incremental or full reclassification
- **Flexible Switching**: `filter.method` supports `keyword` (default) and `ai` modes, Timeline can cover by time period
- **Personalized by Time Period**: Different time periods can use different keyword files or AI interest descriptions. For example, use "technology thesaurus" for quick filtering in the morning and switch to "financial interest" for AI in-depth screening at night
```yaml
# config.yaml quick enable example
filter:
method: ai # keyword (default) | ai
ai_filter:
min_score: 6 # minimum score threshold for pushing (1-10)
```
> 💡 AI screening and AI analysis/translation share model configuration, just configure once `ai.api_key`
### **Hotspot Trend Analysis**
Real-time tracking of news heat changes, let you not only know "what's on the hot search" but also understand "how the hotspot evolves"
- **Time Axis Tracking**: Record the complete time span of each news from first appearance to last appearance
- **Heat Change**: Statistics of news ranking changes and appearance frequency in different time periods
- **New Detection**: Real-time identify new hotspot topics and mark them with 🆕 for first-time reminders
- **Sustainability Analysis**: Distinguish one-time hotspot topics and deep news that continue to ferment
- **Cross-Platform Comparison**: Compare the ranking performance of the same news on different platforms and see the difference in media attention
> 💡 For push format description, see [Message Style Description](#5-what-does-my-message-look-like)
### **Personalized Hotspot Algorithm**
No longer be driven by the algorithms of each platform, TrendRadar will reorganize the entire network's hot search
> 💡 Three ratios can be adjusted, see [Configuration Details - Hotspot Weight Adjustment](#4-hotspot-weight-adjustment)
### **Multi-Channel and Multi-Account Push**
Supports **Enterprise WeChat** (+ WeChat push solution), **Feishu**, **DingTalk**, **Telegram**, **Email**, **ntfy**, **Bark**, **Slack**, **Universal Webhook** (can be connected to Discord, IFTTT, etc.), messages directly reach mobile phones and email
> 💡 For detailed configuration tutorials, see [Push to multiple groups/devices](#10-push-to-multiple-groups-devices)
### **AI Multi-Language Translation** (added in v5.2.0)
Translate push content into any language, breaking language barriers, whether reading domestic hotspots or subscribing to overseas information through RSS, can be easily accessed in your native language
- **One-Click Translation**: Set `ai_translation.enabled: true` and target language in `config.yaml`
- **Multi-Language Support**: Supports English, Korean, Japanese, French, and other languages
- **Intelligent Batch Processing**: Automatically batch translate to reduce API call times and save costs
- **Customizable Style**: Customize translation style and terminology through `ai_translation_prompt.txt`
- **Shared Model Configuration**: Share `ai` configuration section model settings with AI analysis function
```yaml
# config.yaml quick enable example
ai_translation:
enabled: true
language: "English" # target language for translation
```
> 💡 Translation function and AI analysis function share model configuration, just configure once `ai.api_key` to use both functions
**RSS Source Reference**: The following are some RSS subscription source collections, which can be selected as needed
- [awesome-tech-rss](https://github.com/tuan3w/awesome-tech-rss) - Technology, entrepreneurship, programming blogs, and media
- [awesome-rss-feeds](https://github.com/plenaryapp/awesome-rss-feeds) - Mainstream news media RSS collections from various countries
> ⚠️ Some overseas media content may involve sensitive topics, and AI models may refuse to translate. It is recommended to select subscription sources according to actual needs.
### **HTML Report Browser Enhancement** (added in v6.6.0)
Open the pushed HTML report in a browser and automatically unlock enhanced experience (email clients are not affected):
- **Wide-Screen Mode**: Desktop automatically switch to 1200px wide-screen layout, fully utilizing screen space
- **Tab Quick Switching**: Keyword grouping and independent display areas both support Tab navigation, goodbye to long page scrolling
- **Dark Mode**: One-click switch to dark theme, automatically remember preferences
- **Real-Time Search**: Press `/` to activate the search box and filter news titles in real-time
- **One-Click Copy**: Hover over the news serial number to copy the title and link
- **Shortcut Keys**: `W` wide-screen, `D` dark mode, `/` search, `?` view all shortcut keys
> 💡 All enhanced functions are based on progressive enhancement, and email clients still display the original 600px layout, with zero regression.
### **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 stored in the cloud, no repository pollution
- **Local SQLite Database**: Docker/local environment default, data completely controllable
- **Automatic Backend Selection**: Intelligent switching of storage methods based on the running environment
> 💡 For detailed description, see [Where is the data stored?](#11-where-is-the-data-stored)
### **Multi-Endpoint Deployment**
- **GitHub Actions**: Timed automatic crawling + remote cloud storage (need to sign in for renewal)
- **Docker Deployment**: Supports multi-architecture containerized operation, data locally stored
- **Local Operation**: Windows/Mac/Linux direct operation
### **AI Analysis Push** (added in v5.0.0)
Use AI large models to conduct in-depth analysis of push content and automatically generate hotspot insight reports
- **Intelligent Analysis**: Automatically analyze hotspot trends, keyword heat, cross-platform association, and potential impact
- **Multi-Provider**: Based on LiteLLM unified interface, supports 100+ AI providers (DeepSeek, OpenAI, Gemini, Anthropic, local Ollama, etc.), also supports backup model automatic switching
- **Independent Analysis Mode**: AI's analysis scope can be different from push - push only sends new messages (to avoid disturbance), but AI can analyze all news of the day (to see the complete trend)
- **Flexible Push**: Optional only original content, only AI analysis, or both
- **Customizable Prompt Words**: Customize analysis angles through `config/ai_analysis_prompt.txt`
> 💡 For detailed configuration tutorials, see [Let AI help me analyze hotspots](#12-let-ai-help-me-analyze-hotspots)
### **Independent Display Area** (added in v5.0.0)
Provide complete hot list display for specified platforms, not affected by keyword filtering
- **Complete Hot List**: Specify the platform's hot list complete display, suitable for users who want to see the complete ranking
- **RSS Independent Display**: RSS source content can be completely displayed, not limited by keywords
- **AI In-Depth Analysis**: Can independently enable AI to analyze the complete hot list trend, no need to display in push
- **Flexible Configuration**: Supports configuration display platform, RSS source, maximum number of articles
> 💡 For detailed configuration tutorials, see [How to display push content? - Independent Display Area](#7-how-to-display-push-content)
### **AI Intelligent Analysis** (added in v3.0.0)
AI dialogue analysis system based on MCP (Model Context Protocol) protocol, let you use natural language to deeply mine news data
> **💡 Usage Tips**: AI function needs local news data support
> - The project comes with test data, which can be experienced immediately
> - It is recommended to deploy and run the project yourself to obtain more real-time data
>
> See [AI Intelligent Analysis](#-ai-intelligent-analysis) for details.
### **Webpage Deployment**
Run and generate `index.html` in the root directory, which is a complete news report page.
> **Deployment Method**: Click **Use this template** to create a repository, which can be deployed to Cloudflare Pages or GitHub Pages and other static hosting platforms.
>
> **💡 Tips**: Enable GitHub Pages to obtain an online access address, enter the repository Settings → Pages to enable. [Effect Preview](https://sansan0.github.io/TrendRadar/)
>
> ⚠️ The original GitHub Actions automatic storage function has been discontinued (this solution once caused GitHub server load to be high, affecting platform stability).
<a id="cloudflare-deploy"></a>
### ☁️ Automatically Deploy to Cloudflare Pages (optional, faster domestic access)
GitHub Pages has slower access in China, and [Cloudflare Pages](https://pages.cloudflare.com/) has a friendlier access speed. After configuration is complete, GitHub Actions will automatically push the latest `index.html` to Cloudflare Pages, without any manual operation.
> **Prerequisites**: Already completed [GitHub Actions deployment](#-quick-start) and can normally generate webpage reports.
**① Create Cloudflare Pages Project**
Log in to [Cloudflare Dashboard](https://dash.cloudflare.com/) → **Workers & Pages** → **Create** → **Pages** → Select **Upload assets (direct upload)**, fill in a project name (e.g., `trendradar`, please remember it), and upload a file to complete the first creation (subsequent actions will automatically cover).
**② Obtain API Token and Account ID**
- **API Token**: Top right corner avatar → **My Profile** → **API Tokens** → **Create Token** → **Create Custom Token**, select `Account` → `Cloudflare Pages` → `Edit`, copy the token after creation (only displayed once).
- **Account ID**: On the **Workers & Pages** page, find it in the right sidebar (or any domain **Overview** page bottom right corner).
**③ Add 3 Secrets to GitHub Repository**
Enter repository `Settings` → `Secrets and variables` → `Actions` → `New repository secret`, add:
| Name | Secret |
|:---|:---|
| `CLOUDFLARE_API_TOKEN` | API Token created in the previous step |
| `CLOUDFLARE_ACCOUNT_ID` | Your Cloudflare Account ID |
| `CLOUDFLARE_PROJECT_NAME` | Cloudflare Pages project name (e.g., `trendradar`) |
After configuration is complete, the next GitHub Actions run will automatically deploy. The access address is `https://<project name>.pages.dev`.
> 💡 **Description**: If any of the three Secrets are missing, Cloudflare deployment will be skipped, which will not affect news push and other functions. If you want to bind a custom domain, you can set it in the Pages project's **Custom domains**.
### **Reduce APP Dependency**
From being "bound by algorithm recommendation" to "actively obtaining the information you want"
**Suitable for**: Investors, self-media people, enterprise public relations, and ordinary users concerned about current events.
**Typical Scenarios**: Stock investment monitoring, brand public opinion tracking, industry dynamic attention, and life information acquisition.
| Webpage Effect (Email Push Effect) | Feishu Push Effect | AI Analysis Push Effect |
|:---:|:---:|:---:|
|  |  |  |
<br>
## 🚀 Quick Start
> **Reminder**: It is recommended to **[view the latest official documentation](https://github.com/sansan0/TrendRadar?tab=readme-ov-file)** to ensure the configuration steps are the latest.
### Please Choose Your Deployment Method
#### Ⓐ Solution 1: Docker Deployment (Recommended 🔥)
* **Features**: More stable than GitHub Actions, local data storage (no need to configure cloud storage)
* **Applicable**: Those with their own servers, NAS, or long-running computers
* **Note**: You need to understand the basic configuration process below, then jump to the Docker tutorial for deployment.
#### Ⓑ Solution 2: GitHub Actions Deployment (this section ⬇️)
* **Features**: Serverless, data stored in **remote cloud storage** (recommended configuration)
* **Applicable**: Users without servers, utilizing GitHub free resources
* **Note**: Need to configure cloud storage for a complete experience and regular sign-in renewal.
<a id="local-deploy"></a>
#### Ⓒ Solution 3: Local Deployment (uv)
* **Features**: Directly run on your local machine, no Docker required, suitable for development debugging or no Docker environment users
* **Applicable**: Windows / Mac / Linux users (no need to pre-install Python, uv will automatically manage)
* **Steps**:
**1. Install uv** (if already installed, skip, no need to pre-install Python)
```bash
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```
**2. Clone and Run**
```bash
git clone https://github.com/sansan0/TrendRadar.git
cd TrendRadar
uv sync # Automatically install Python and project dependencies
uv run python -m trendradar
```
> 💡 **Tips**:
> - uv will automatically manage Python version, no need to manually install Python
> - Windows users can also double-click `setup-windows.bat` to install dependencies
> - Mac users can use `bash setup-mac.sh`
> - Before running, please edit `config/config.yaml` to fill in push channels and other configurations, refer to the basic configuration process below
### 1️⃣ Step 1: Get Project Code
Click the green **[Use this template]** button on the top right corner of this repository → select "Create a new repository".
> ⚠️ Reminder:
> - Subsequent documents mention "Fork" can be understood as "Use this template"
> - Using Fork may lead to 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 corresponds to one Secret**: For each configuration item, click the "New repository secret" button once and fill in a pair of "Name" and "Secret".
* **You won't see the value after saving**: For security reasons, after saving, you won't be able to see the Secret value when re-editing; only the Name will be visible.
* **Do not create names arbitrarily**: The Name of the Secret must **strictly use** the names listed below (e.g., `WEWORK_WEBHOOK_URL`, `FEISHU_WEBHOOK_URL`, etc.); do not modify or create new names randomly, or the system won't be able to identify 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 Configuration Example"/>
As shown in the figure, each line is a configuration item:
* **Name**: Must use the fixed name listed in the expanded content below (e.g., `WEWORK_WEBHOOK_URL`).
* **Secret**: Fill in the actual content you obtained from the corresponding platform (e.g., Webhook address, Token, etc.).
<br>
<details>
<summary>👉 Click to expand: <strong>WeChat Work Bot</strong> (easiest and quickest to configure)</summary>
<br>
**GitHub Secret Configuration (⚠️ Name must be consistent):**
* **Name**: `WEWORK_WEBHOOK_URL` (please copy and paste this name; don't type it manually to avoid typos)
* **Secret**: Your WeChat Work bot Webhook address
<br>
**Bot Setup Steps:**
#### Mobile Setup:
1. Open the WeChat Work app → enter the target internal group chat.
2. Click the "..." button in the top right corner → select "Message Push".
3. Click "Add" → enter "TrendRadar" as the name.
4. Copy the Webhook address, click Save, and copy the content to configure in the GitHub Secret above.
#### PC Setup is similar
</details>
<details>
<summary>👉 Click to expand: <strong>Personal WeChat Push</strong> (based on WeChat Work app, push to personal WeChat)</summary>
<br>
> Since this solution is based on the plugin mechanism of WeChat Work, the push style is plain text (no markdown format), but it can directly push to personal WeChat without installing the WeChat Work app.
**GitHub Secret Configuration (⚠️ Name must be consistent):**
* **Name**: `WEWORK_WEBHOOK_URL` (please copy and paste this name; don't type it manually)
* **Secret**: Your WeChat Work app Webhook address
* **Name**: `WEWORK_MSG_TYPE` (please copy and paste this name; don't type it manually)
* **Secret**: `text`
<br>
**Setup Steps:**
1. Complete the WeChat Work bot Webhook setup above.
2. Add the `WEWORK_MSG_TYPE` Secret, set the value to `text`.
3. Follow the image below to associate your personal WeChat.
4. After configuration, you can delete the WeChat Work app on your phone.
<img src="_image/wework.png" title="Personal WeChat Push Configuration"/>
**Note**:
* Use the same Webhook address as the WeChat Work bot.
* The difference lies in the message format: `text` is plain text, and `markdown` is rich text (default).
* The plain text format will automatically remove all markdown syntax (bold, links, etc.).
</details>
<details>
<summary>👉 Click to expand: <strong>Feishu Bot</strong> (message display is relatively friendly)</summary>
<br>
> **Note**: The original "Feishu Bot Assistant (BotBuilder)" will be discontinued on June 30, 2026; please use the **custom group bot** method below. Existing BotBuilder webhook addresses will become invalid and need to be reconfigured.
If **AI analysis** is enabled, Feishu push may occasionally (about 5% probability) experience a few minutes of delay (presumably due to the platform's compliance audit of AI-generated content).
**GitHub Secret Configuration (⚠️ Name must be consistent):**
* **Name**: `FEISHU_WEBHOOK_URL` (please copy and paste this name; don't type it manually)
* **Secret**: Your Feishu custom bot Webhook address (format: `https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxx`)
**Setup Steps:**
1. Enter the target group, click the **More** button in the top right corner of the group, and click **Settings**.

2. On the right **Settings** interface, click **Group Bot**.

3. On the **Group Bot** interface, click **Add Bot**.
4. In the **Add Bot** dialog box, find and click **Custom Bot**.

5. Set the custom bot's avatar, name (e.g., "TrendRadar Hotspot Monitoring"), and description, and click **Add**.

6. Obtain the custom bot's **webhook address** and click **Complete**.
> ⚠️ Please keep this webhook address secure and do not publish it on publicly accessible websites like GitHub or blogs to avoid address leakage and malicious calls to send spam messages.

7. Configure the copied Webhook address to `FEISHU_WEBHOOK_URL` in GitHub Secrets.
> 💡 After configuration, you can click the bot image on the right side of the group name to enter the custom bot details page and manage configuration information.
>
> 📖 Official documentation: [Custom Bot Usage Guide](https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot)
</details>
<details>
<summary>👉 Click to expand: <strong>DingTalk Bot</strong></summary>
<br>
**GitHub Secret Configuration (⚠️ Name must be consistent):**
* **Name**: `DINGTALK_WEBHOOK_URL` (please copy and paste this name; don't type it manually)
* **Secret**: Your DingTalk bot Webhook address
<br>
**Bot Setup Steps:**
1. **Create a bot (only PC supports)**:
- Open the DingTalk PC client and enter the target group chat.
- Click the group settings icon (⚙️) → scroll down to find "Bot" and open it.
- Select "Add Bot" → "Custom".
2. **Configure the bot**:
- Set the bot name.
- **Security settings**:
- **Custom keywords**: Set "hotspot".
3. **Complete setup**:
- Check the service terms agreement → click "Complete".
- Copy the obtained Webhook URL.
- Configure the URL to `DINGTALK_WEBHOOK_URL` in GitHub Secrets.
**Note**: The mobile end can only receive messages and cannot create a new bot.
</details>
<details>
<summary>👉 Click to expand: <strong>Telegram Bot</strong></summary>
<br>
**GitHub Secret Configuration (⚠️ Name must be consistent):**
* **Name**: `TELEGRAM_BOT_TOKEN` (please copy and paste this name; don't type it manually)
* **Secret**: Your Telegram Bot Token
* **Name**: `TELEGRAM_CHAT_ID` (please copy and paste this name; don't type it manually)
* **Secret**: Your Telegram Chat ID
**Note**: Telegram requires **two** Secrets to be configured; please click the "New repository secret" button twice to add them separately.
<br>
**Bot Setup Steps:**
1. **Create a bot**:
- Search for `@BotFather` on Telegram (pay attention to case sensitivity; it has a blue badge and similar 37849827 monthly users; this is the official one; be cautious of unofficial accounts).
- Send the `/newbot` command to create a new bot.
- Set the bot name (must end with "bot"; it's easy to encounter duplicate names, so think of different names).
- Obtain the Bot Token (format: `123456789:AAHfiqksKZ8WmR2zSjiQ7_v4TMAKdiHm9T0`)
2. **Get Chat ID**:
**Method 1: Get through official API**:
- Send a message to your bot.
- Visit: `https://api.telegram.org/bot<YourBotToken>/getUpdates`.
- Find the number in `"chat":{"id":number}` in the returned JSON.
**Method 2: Use a third-party tool**:
- Search for `@userinfobot` and send `/start`.
- Get your user ID as 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)</summary>
<br>
- Precautions: To prevent email bulk sending from being **abused**, the current bulk sending allows all recipients to see each other's email addresses.
- If you have not configured email sending like this before, it's not recommended to try.
> ⚠️ **Important configuration dependency**: Email push requires an HTML report file. Please ensure that `storage.formats.html` is set to `true` in `config/config.yaml`:
> ```yaml
> storage:
> formats:
> sqlite: true
> txt: false
> html: true # Must be enabled; otherwise, email push will fail
> ```
> If set to `false`, email push will report an error: `Error: HTML file does not exist or is not provided: None`
<br>
**GitHub Secret Configuration (⚠️ Name must be consistent):**
* **Name**: `EMAIL_FROM` (please copy and paste this name; don't type it manually)
* **Secret**: Sender's email address
* **Name**: `EMAIL_PASSWORD` (please copy and paste this name; don't type it manually)
* **Secret**: Email password or authorization code
* **Name**: `EMAIL_TO` (please copy and paste this name; don't type it manually)
* **Secret**: Recipient's email address (multiple recipients separated by English commas; can also be the same as EMAIL_FROM; send to yourself)
* **Name**: `EMAIL_SMTP_SERVER` (optional configuration; please copy and paste this name)
* **Secret**: SMTP server address (can be left blank; the system will automatically 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 at least **3 required** Secrets (EMAIL_FROM, EMAIL_PASSWORD, EMAIL_TO); the last two are optional configurations.
<br>
**Supported email service providers** (automatically identify SMTP configuration):
| Email Service Provider | Domain | SMTP Server | Port | Encryption |
|-----------|------|------------|------|---------|
| **Gmail** | gmail.com | smtp.gmail.com | 587 | TLS |
| **QQ Mail** | qq.com | smtp.qq.com | 465 | SSL |
| **Outlook** | outlook.com | smtp-mail.outlook.com | 587 | TLS |
| **Hotmail** | hotmail.com | smtp-mail.outlook.com | 587 | TLS |
| **Live** | live.com | smtp-mail.outlook.com | 587 | TLS |
| **163 Mail** | 163.com | smtp.163.com | 465 | SSL |
| **126 Mail** | 126.com | smtp.126.com | 465 | SSL |
| **Sina Mail** | sina.com | smtp.sina.com | 465 | SSL |
| **Sohu Mail** | sohu.com | smtp.sohu.com | 465 | SSL |
| **Tianyi Mail** | 189.cn | smtp.189.cn | 465 | SSL |
| **Alibaba Mail** | aliyun.com | smtp.aliyun.com | 465 | TLS |
| **Yandex Mail** | yandex.com | smtp.yandex.com | 465 | TLS |
| **iCloud Mail** | icloud.com | smtp.mail.me.com | 587 | SSL |
> **Automatic identification**: When using the above email, there is no need to manually configure `EMAIL_SMTP_SERVER` and `EMAIL_SMTP_PORT`; the system will automatically identify.
>
> **Feedback**:
> - If you test other email successfully, welcome to open [Issues](https://github.com/sansan0/TrendRadar/issues) to inform me; I will add it to the support list.
> - If the above email configuration is incorrect or cannot be used, please open [Issues](https://github.com/sansan0/TrendRadar/issues) to provide feedback and help improve the project.
>
> **Special thanks**:
> - Thanks to [@DYZYD](https://github.com/DYZYD) for contributing Tianyi Mail (189.cn) configuration and completing self-sending and self-receiving test ([#291](https://github.com/sansan0/TrendRadar/issues/291))
> - Thanks to [@longzhenren](https://github.com/longzhenren) for contributing Alibaba Mail (aliyun.com) configuration and completing the test ([#344](https://github.com/sansan0/TrendRadar/issues/344))
> - Thanks to [@ACANX](https://github.com/ACANX) for contributing Yandex Mail (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 iCloud Mail (icloud.com) configuration and completing the test ([#728](https://github.com/sansan0/TrendRadar/issues/728))
**Common email settings:**
#### QQ Mail:
1. Log in to QQ Mail web version → Settings → Account.
2. Enable POP3/SMTP service.
3. Generate authorization code (16-letter).
4. Fill in the authorization code in `EMAIL_PASSWORD`, not the QQ password.
#### Gmail:
1. Enable two-step verification.
2. Generate app-specific password.
3. Fill in the app-specific password in `EMAIL_PASSWORD`.
#### 163/126 Mail:
1. Log in to the web version → Settings → POP3/SMTP/IMAP.
2. Enable SMTP service.
3. Set client authorization code.
4. Fill in the authorization code in `EMAIL_PASSWORD`.
<br>
**Advanced configuration**:
If automatic identification fails, you can manually configure SMTP:
* `EMAIL_SMTP_SERVER`: e.g., smtp.gmail.com
* `EMAIL_SMTP_PORT`: e.g., 587 (TLS) or 465 (SSL)
<br>
**If there are multiple recipients (note English commas)**:
- EMAIL_TO="user1@example.com,user2@example.com,user3@example.com"
</details>
<details>
<summary>👉 Click to expand: <strong>ntfy Push</strong> (open-source and free, supports self-hosting)</summary>
<br>
**Two usage methods:**
### Method 1: Free use (recommended for beginners) 🆓
**Features**:
- ✅ No need to register an account; use immediately.
- ✅ 250 messages per day (enough for 90% of users).
- ✅ Topic name is "password" (need to choose a name that is not easily guessed).
- ⚠️ Messages are not encrypted; not suitable for sensitive information, but suitable for non-sensitive information in this project.
**Quick start**:
1. **Download the ntfy app**:
- Android: [Google Play](https://play.google.com/store/apps/details?id=io.heckel.ntfy) / [F-Droid](https://f-droid.org/en/packages/io.heckel.ntfy/)
- iOS: [App Store](https://apps.apple.com/us/app/ntfy/id1625396347)
- Desktop: Visit [ntfy.sh](https://ntfy.sh)
2. **Subscribe Topic** (choose a hard-to-guess name):
```
Suggested format: trendradar-{your initials}-{random number}
No Chinese characters allowed
✅ Good example: trendradar-zs-8492
❌ Bad example: news, alerts (too easy to guess)
```
3. **Configure GitHub Secret (⚠️ Name must be exactly the same)**:
- **Name**: `NTFY_TOPIC` (copy and paste this name, don't type it manually)
- **Secret**: fill in the topic name you just subscribed to
- **Name**: `NTFY_SERVER_URL` (optional configuration, copy and paste this name)
- **Secret**: leave blank (default uses ntfy.sh)
- **Name**: `NTFY_TOKEN` (optional configuration, copy and paste this name)
- **Secret**: leave blank
**Note**: ntfy requires at least 1 required Secret (NTFY_TOPIC), the other two are optional configurations
4. **Test**:
```bash
curl -d "Test message" ntfy.sh/your topic name
```
### Method 2: Self-hosting (complete privacy control) 🔒
**Suitable for**: Those with servers, pursuing complete privacy, and having strong technical capabilities
**Advantages**:
- ✅ Completely open-source (Apache 2.0 + GPLv2)
- ✅ Data completely under your control
- ✅ No limitations
- ✅ Zero cost
**One-click Docker deployment**:
```bash
docker run -d \
--name ntfy \
-p 80:80 \
-v /var/cache/ntfy:/var/cache/ntfy \
binwiederhier/ntfy \
serve --cache-file /var/cache/ntfy/cache.db
```
**Configure TrendRadar**:
```yaml
NTFY_SERVER_URL: https://ntfy.yourdomain.com
NTFY_TOPIC: trendradar-alerts # Simple name available for self-hosting
NTFY_TOKEN: tk_your_token # Optional: enable access control
```
**Subscribe in the application**:
- Click "Use another server"
- Enter your server address
- Enter the topic name
- (Optional) enter login credentials
---
**Frequently Asked Questions:**
<details>
<summary><strong>Q1: Is the free version sufficient?</strong></summary>
250 messages per day are enough for most users. Assuming a 30-minute crawl interval, there are approximately 48 pushes per day, which is sufficient.
</details>
<details>
<summary><strong>Q2: Is the topic name really secure?</strong></summary>
If you choose a random, sufficiently long name (e.g., `trendradar-zs-8492-news`), brute-force cracking is almost impossible:
- ntfy has strict rate limiting (1 request per second)
- 64 character choices (A-Z, a-z, 0-9, _, -)
- 10 random string characters have 64^10 possibilities (takes years to crack)
</details>
---
**Recommendations:**
| User type | Recommended solution | Reason |
|---------|---------|------|
| Ordinary users | Method 1 (free) | Simple and quick, sufficient |
| Tech-savvy users | Method 2 (self-hosting) | Complete control, no limitations |
| High-frequency users | Method 3 (paid) | Check the official website for details |
**Related links:**
- [ntfy official documentation](https://docs.ntfy.sh/)
- [Self-hosting tutorial](https://docs.ntfy.sh/install/)
- [GitHub repository](https://github.com/binwiederhier/ntfy)
</details>
<details>
<summary>👉 Click to expand: <strong>Bark push</strong> (iOS exclusive, simple and efficient)</summary>
<br>
**GitHub Secret configuration (⚠️ Name must be exactly the same)**:
- **Name**: `BARK_URL` (copy and paste this name, don't type it manually)
- **Secret**: your Bark push URL
<br>
**Bark introduction:**
Bark is a free and open-source push tool for iOS, characterized by simplicity, speed, and no ads.
**Usage:**
### Method 1: Use the official server (recommended for beginners) 🆓
1. **Download Bark App**:
- iOS: [App Store](https://apps.apple.com/app/bark-给你的手机发推送/id1403753865)
2. **Get the push URL**:
- Open the Bark App
- Copy the push URL displayed on the homepage (format: `https://api.day.app/your_device_key`)
- Configure the URL to `BARK_URL` in GitHub Secrets
### Method 2: Self-hosting (complete privacy control) 🔒
**Suitable for**: Those with servers, pursuing complete privacy, and having strong technical capabilities
**One-click Docker deployment**:
```bash
docker run -d \
--name bark-server \
-p 8080:8080 \
finab/bark-server
```
**Configure TrendRadar**:
```yaml
BARK_URL: http://your-server-ip:8080/your_device_key
```
---
**Notes:**
- ✅ Bark uses APNs push, with a maximum message size of 4KB
- ✅ Supports automatic batching and pushing, no need to worry about long messages
- ✅ Push format is plain text (automatically removes Markdown syntax)
- ⚠️ Only supports iOS platform
**Related links:**
- [Bark official website](https://bark.day.app/)
- [Bark GitHub repository](https://github.com/Finb/Bark)
- [Bark Server self-hosting tutorial](https://github.com/Finb/bark-server)
</details>
<details>
<summary>👉 Click to expand: <strong>Slack push</strong></summary>
<br>
**GitHub Secret configuration (⚠️ Name must be exactly the same)**:
- **Name**: `SLACK_WEBHOOK_URL` (copy and paste this name, don't type it manually)
- **Secret**: your Slack Incoming Webhook URL
<br>
**Slack introduction:**
Slack is a team collaboration tool, and Incoming Webhooks can push messages to Slack channels.
**Setup steps:**
### Step 1: Create a Slack App
1. **Access the Slack API page**:
- Open https://api.slack.com/apps?new_app=1
- If not logged in, log in to your Slack workspace
2. **Choose the creation method**:
- Click **"From scratch"**
3. **Fill in the App information**:
- **App Name**: fill in the app name (e.g., `TrendRadar` or `Hot News Monitor`)
- **Workspace**: select your workspace from the dropdown list
- Click **"Create App"**
### Step 2: Enable Incoming Webhooks
1. **Navigate to Incoming Webhooks**:
- Find and click **"Incoming Webhooks"** in the left menu
2. **Enable the feature**:
- Find **"Activate Incoming Webhooks"**
- Switch from `OFF` to `ON`
- The page will automatically refresh and display new configuration options
### Step 3: Generate Webhook URL
1. **Add a new Webhook**:
- Scroll to the bottom of the page
- Click **"Add New Webhook to Workspace"**
2. **Select the target channel**:
- The system will pop up an authorization page
- Select the channel to receive messages from the dropdown list (e.g., `#hot-news`)
- ⚠️ If you want to select a private channel, you must first join the channel
3. **Authorize the app**:
- Click **"Allow"** to complete 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 just-generated Webhook URL
- Format: `https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX`
2. **Copy the URL**:
- Click the **"Copy"** button next to the URL
- Or manually select and copy the URL
3. **Configure to TrendRadar**:
- **GitHub Actions**: add the URL to `SLACK_WEBHOOK_URL` in GitHub Secrets
- **Local testing**: fill the URL in `config/config.yaml`'s `slack_webhook_url` field
- **Docker deployment**: add the URL to `docker/.env` file's `SLACK_WEBHOOK_URL` variable
---
**Notes:**
- ✅ Supports Markdown format (automatically converted to Slack mrkdwn)
- ✅ Supports automatic batching and pushing (4KB per batch)
- ✅ Suitable for team collaboration, centralized message management
- ⚠️ Webhook URL contains a secret key, do not expose it
**Message format preview:**
```
*[1/2 batches]*
📊 *Hot word 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 surge *[3]* - [08:30 ~ 10:45] (3 times)
```
**Related links:**
- [Slack Incoming Webhooks official documentation](https://api.slack.com/messaging/webhooks)
- [Slack API app management](https://api.slack.com/apps)
</details>
<details>
<summary>👉 Click to expand: <strong>Generic Webhook push</strong> (supports Discord, Matrix, IFTTT, etc.)</summary>
<br>
**GitHub Secret configuration (⚠️ Name must be exactly the same)**:
- **Name**: `GENERIC_WEBHOOK_URL` (copy and paste this name, don't type it manually)
- **Secret**: your Webhook URL
- **Name**: `GENERIC_WEBHOOK_TEMPLATE` (optional configuration, 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 channels via Webhook
- **Matrix**: push via Webhook bridge
- **IFTTT**: trigger automation processes
- **Self-built services**: any custom services that support Webhooks
**Configuration example:**
### Discord configuration
1. **Get the Webhook URL**:
- Go to Discord server settings → Integrations → Webhooks
- Create a new Webhook and copy the URL
2. **Configure the 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 (use if left blank)
{"title": "{title}", "content": "{content}"}
# Discord format
{"content": "{content}"}
# Custom format
{"text": "{content}", "username": "TrendRadar"}
```
---
**Notes:**
- ✅ Supports Markdown format (consistent with WeChat format)
- ✅ Supports automatic batching and pushing
- ✅ Supports multi-account configuration (use `;` to separate)
- ⚠️ 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>
### Step 3: Manual testing of news pushes
> ⚠️ Reminder:
> - After completing steps 1-2, please test immediately! Test successfully before adjusting configurations (step 4)
> - Please enter your own project, not this project!
**How to find your Actions page**:
- **Method 1**: Open your forked project homepage and click the **Actions** tab at the top
- **Method 2**: Directly access `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`
**Testing steps**:
1. Enter your project's Actions page
2. Find **"Get Hot News"** (must be this exact text) and click into it, then click the **"Run workflow"** button on the right
- If you can't see the text, refer to [#109](https://github.com/sansan0/TrendRadar/issues/109) for a solution
3. After about 3 minutes, the message will be pushed to your configured platform
<br>
> ⚠️ Reminder:
> - Manual testing should not be too frequent to avoid triggering GitHub Actions limitations
> - After clicking Run workflow, you need to refresh the browser page to see the new run records
<br>
### Step 4: Configuration instructions (optional)
The default configuration is already usable. If you need personalized adjustments, understand the following files:
| File | Function |
|------|------|
| `config/config.yaml` | Main configuration file: push mode, time window, platform list, hot word weight, etc. |
| `config/frequency_words.txt` | Keyword file: set words you care about, filter push content |
| `config/ai_analysis_prompt.txt` | AI prompt template: customize AI analyst role and analysis dimensions |
| `.github/workflows/crawler.yml` | Execution frequency: control how often to run (⚠️ be cautious when modifying) |
👉 **Detailed configuration tutorial**: [Configuration details](#configuration-details)
### 5️⃣ Step 5: Remote Cloud Storage & Check-in Configuration
**v4.0.0 Important Change**: Introduced an 'activity detection' mechanism, GitHub Actions require periodic check-ins to maintain operation.
- **Operation Cycle**: Valid for **7 days**, services will automatically suspend after countdown.
- **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. Timely suspension can help you detach from the information flow and give your brain a breather.
- GitHub Actions are valuable public computing resources. Introducing a check-in mechanism aims to avoid idle computing power and ensure resources are allocated to truly active and needed users. Thank you for your understanding and support.
---
**About Remote Cloud Storage Configuration (select according to deployment method):**
- **GitHub Actions Users**:
- **Current Status**: Actions run in a fresh environment each time, without saving files. If cloud storage is not configured, the project will run in **lightweight mode** (no incremental push, no historical tracking).
- **Recommendation**: Configure remote cloud storage for a complete experience.
- **Docker / Local Users**:
- **Current Status**: Data is saved locally by default.
- **Recommendation**: Cloud storage is optional and can be used for off-site backup.
<details>
<summary>👉 Click to expand: <strong>Remote Cloud Storage Configuration Tutorial (using Cloudflare R2 as an example)</strong></summary>
<br>
**⚠️ Preconditions (important):**
According to Cloudflare platform rules, opening R2 requires binding a payment method.
* **Purpose**: Only for identity verification (Verify Only), **no charges incurred**.
* **Payment**: Supports dual-currency credit cards or PayPal in China.
* **Usage**: R2's free quota (10GB storage/month) is sufficient to cover daily operation, no need to worry about payment.
---
**GitHub Secret Configuration (need to add 4 items):**
| Name(Name) | Secret(value)description |
|-------------|-----------------|
| `S3_BUCKET_NAME` | Bucket name (e.g., `trendradar-data`) |
| `S3_ACCESS_KEY_ID` | Access key ID (Access Key ID) |
| `S3_SECRET_ACCESS_KEY` | Access key (Secret Access Key) |
| `S3_ENDPOINT_URL` | S3 API endpoint (e.g., R2: `https://<account-id>.r2.cloudflarestorage.com`) |
**Optional Configuration:**
| Name(Name) | Secret(value)description |
|-------------|-----------------|
| `S3_REGION` | Region (default `auto`, some service providers may require specification) |
> 💡 **More storage configuration options**: See [Where is the data saved?](#11-数据保存在哪里)
<br>
**Detailed operation steps (obtaining credentials):**
1. **Enter R2 Overview**:
- Log in to [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 top 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` in the bottom right corner to find and click `Manage R2 API Tokens`.
- You will see `S3 API`: `https://<account-id>.r2.cloudflarestorage.com` (this is S3_ENDPOINT_URL).
- Click `Create Account API token`.
- **⚠️ Key settings**:
- **Token name**: Fill in freely (e.g., `github-action-write`).
- **Permissions**: Select `Admin Read & Write`.
- **Specify bucket**: For security, recommend selecting `For specified bucket only` and selecting your bucket (e.g., `trendradar-data`).
- Click `Create API token`, **copy immediately** the displayed `Access Key ID` and `Secret Access Key` (only shown once!).
</details>
<br>
### 6️⃣ Step 6: Enable AI Analysis Push
This is a core feature of v5.0.0, allowing AI to summarize and analyze news for you, recommended for trying.
**Configuration method:**
Add to 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 needed, and you'll see intelligent analysis reports on the next push.
<br>
### 7️⃣ Step 7: 🎉 Deployment Successful!
Congratulations! You can now start enjoying the efficient information flow brought by TrendRadar.
💬 **Join the community**: Welcome to follow the official account **[硅基茶水间](#-支持项目)**, 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's happening today?" | "Analyze AI industry changes over the past week" |
| **Deployment** | Simple (fill in Key) | Advanced (need local operation/Docker) |
| **Client** | Mobile | Computer |
👉 **Conclusion**: Start with **AI Analysis Push** to meet daily needs; if you're a data analyst or need in-depth mining, try **[AI Intelligent Analysis](#-ai-智能分析)**.
<br>
<a name="配置详解"></a>
## ⚙️ Configuration Details
> **📖 Reminder**: This section provides detailed configuration instructions, recommend completing the [Quick Start](#-快速开始) basic configuration before referring back to detailed options.
### 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` `platforms` section
This project's information data comes from [newsnow](https://github.com/ourongxing/newsnow). You can click [website](https://newsnow.busiyi.world/), click [more], and see if there is a platform you want.
Specific additions can be accessed [project source code](https://github.com/ourongxing/newsnow/tree/main/server/sources), according to the file name inside, modify the `platforms` configuration in `config/config.yaml`:
```yaml
platforms:
enabled: true # Whether to enable hot list platform crawling
sources:
- id: "toutiao"
name: "Today's Headlines"
- id: "baidu"
name: "Baidu Hot Search"
- id: "wallstreetcn-hot"
name: "Wall Street Insights"
# Add more platforms...
```
> 💡 **Shortcut**: If you can't read the source code, you can copy others' sorted [platform configuration summary](https://github.com/sansan0/TrendRadar/issues/95)
> ⚠️ **Note**: The platform is not the more the better, recommend choosing 10-15 core platforms. Too many platforms will lead to information overload and reduce user experience.
</details>
### 2. What content do I care about?
Tell the robot what you want to see in the `frequency_words.txt` file, and it will help you monitor it. Supports ordinary words, must words, filter words, and other gameplay.
| Syntax type | Symbol | Effect | Example | Matching logic |
|---------|------|------|------|---------|
| **Ordinary word** | None | Basic matching | `Huawei` | Contains any one |
| **Must word** | `+` | Limit scope | `+mobile` | Must contain simultaneously |
| **Filter word** | `!` | Exclude interference | `!advertising` | Contains then directly exclude |
| **Quantity limit** | `@` | Control display quantity | `@10` | Display at most 10 news (added in v3.2.0) |
| **Global filter** | `[GLOBAL_FILTER]` | Global exclusion of specified content | See below | Filter in any case (added in v3.5.0) |
| **Regular expression** | `/pattern/` | Precise matching mode | `/\bai\b/` | Use regular expression matching (added in v4.7.0) |
| **Display name** | `=> remark` | Custom display text | `/\bai\b/ => AI related` | Push and HTML display remark name (added in v4.7.0) |
#### 2.1 Basic syntax
<a name="关键词基础语法"></a>
<details>
<summary>👉 Click to expand: <strong>Basic syntax tutorial</strong></summary>
<br>
**Configuration location:** `config/frequency_words.txt`
##### 1. **Ordinary keyword** - Basic matching
```txt
Huawei
OPPO
Apple
```
**Effect:** News titles containing **any one** will be captured
##### 2. **Must word** `+vocabulary` - Limit scope
```txt
Huawei
OPPO
+mobile
```
**Effect:** Must contain ordinary words **and** must words to be captured
##### 3. **Filter word** `!vocabulary` - Exclude interference
```txt
Apple
Huawei
!fruit
!price
```
**Effect:** News containing filter words will be **directly excluded**, even if containing keywords
##### 4. **Quantity limit** `@number` - Control display quantity (v3.2.0 added)
```txt
Tesla
Musk
@5
```
**Effect:** Limit the maximum number of news displayed by the keyword group
**Configuration priority:** `@number` > global configuration > no limit
##### 5. **Global filter** `[GLOBAL_FILTER]` - Global exclusion of specified content (v3.5.0 added)
```txt
[GLOBAL_FILTER]
advertising
promotion
marketing
shocking
headline party
[WORD_GROUPS]
technology
AI
Huawei
HarmonyOS
!car
```
**Effect:** Filter news containing specified words in any case, **highest priority**
**Usage scenarios:**
- Filter low-quality content: shocking, headline party, exposure, etc.
- Filter marketing content: advertising, promotion, sponsorship, etc.
- Filter specific topics: entertainment, gossip (according to needs)
**Filter priority:** Global filter > word group filter (`!`) > word group matching
**Area description:**
- `[GLOBAL_FILTER]`: Global filter area, containing words will be filtered in any case
- `[WORD_GROUPS]`: Word group area, keeping existing syntax (`!`, `+`, `@`)
- If no area mark is used, default all as word group processing (backward compatible)
**Matching example:**
```txt
[GLOBAL_FILTER]
advertising
[WORD_GROUPS]
technology
AI
```
- ❌ "Advertising: latest technology product launch" ← Contains global filter word "advertising", directly reject
- ✅ "Technology company releases AI new product" ← Does not contain global filter word, match "technology" word group
- ✅ "AI technology breakthrough attracts attention" ← Does not contain global filter word, match "technology" word group
**Notes:**
- Global filter words should be used cautiously to avoid excessive filtering leading to omission of valuable content
- Recommend controlling global filter words within 5-15
- For filtering specific word groups, prioritize using word group internal filter words (`!` prefix)
##### 6. **Regular expression** `/pattern/` - Precise matching mode (v4.7.0 added)
Ordinary keywords use substring matching, which is convenient in Chinese environments but may cause mis-matching in English environments. For example, `ai` will match to `training` in `ai`.
Using regular expression syntax `/pattern/` can achieve precise matching:
```txt
/(?<![a-z])ai(?![a-z])/
artificial intelligence
machine learning
```
**Effect:** Use regular expressions for matching, supporting all Python regular syntax
**Common regular patterns:**
| Demand | Regular writing | Description |
|------|---------|------|
| English word boundary | `/\bword\b/` | Match independent words, e.g., `/\bai\b/` matches "AI" but not "training" |
| Non-letter before and after | `/(?<![a-z])ai(?![a-z])/` | Looser boundary, suitable for Chinese-English mixed scenarios |
| Start matching | `/^breaking/` | Only match titles starting with "breaking" |
| End matching | `/release$/` | Only match titles ending with "release" |
| Multi-select | `/apple\|huawei\|xiaomi/` | Match any one (note escape `\|`) |
**Matching example:**
```txt
# Configuration
/(?<![a-z])ai(?![a-z])/
artificial intelligence
```
- ✅ "AI is the future" ← Match independent "AI"
- ✅ "Hello ai here" ← Before and after are Chinese, match "ai"
- ✅ "Artificial intelligence develops rapidly" ← Match "artificial intelligence"
- ❌ "Resistance training is important" ← "ai" in "training" does not match
- ❌ "The maid cleaned the room" ← "ai" in "maid" does not match
**Combination use:**
```txt
# Regular + ordinary word + filter word
/\bai\b/
artificial intelligence
machine learning
!advertising
```
**Notes:**
- Regular expressions automatically enable case-insensitive matching (`re.IGNORECASE`)
- Supports `/pattern/i` and other JavaScript style writing (flags will be ignored because default is case-insensitive)
- Invalid regular syntax will be treated as ordinary words
- Regular can be used for ordinary words, must words (`+`), filter words (`!`)
**💡 Can't write regular? Let AI help you generate!**
If you're not familiar with regular expressions, you can directly let ChatGPT / Gemini / DeepSeek help you generate. Just tell AI:
> I need a Python regular expression to match the English word "ai" but not "ai" in "training".
> Please directly provide the regular expression in the format of `/pattern/`, no need for additional explanation.
AI will give you a result like: `/(?<![a-zA-Z])ai(?![a-zA-Z])/`
##### 7. **Display name** `=> remark` - Custom display text (v4.7.0 added)
Regular expressions may not be friendly when pushing messages and displaying HTML pages. Use the `=> remark` syntax to set the display name:
```txt
/(?<![a-zA-Z])ai(?![a-zA-Z])/ => AI related
artificial intelligence
```
**Effect:** Push messages and HTML pages display "AI related" 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 dynamics
```
**Matching example:**
```txt
# Configuration
/(?<![a-zA-Z])ai(?![a-zA-Z])/ => AI related
artificial intelligence
```
| Original configuration | Push/HTML display |
|---------|---------------|
| `/(?<![a-z])ai(?![a-z])/` + `artificial intelligence` | `(?<![a-z])ai(?![a-z]) artificial intelligence` |
| `/(?<![a-z])ai(?![a-z])/ => AI related` + `artificial intelligence` | **`AI related`** |
**Notes:**
- Display name only needs to be written on the first word of the group
- If multiple words in a group have display names, use the first one
- If no display name is set, automatically use all words in the group to concatenate
---
#### 🔗 Word group function - Important role of empty lines
**Core rules:** Use **empty lines** to separate different word groups, each group independently counts
##### Example configuration:
```txt
iPhone
Huawei
OPPO
+release
A-share
Shanghai stock exchange
Shenzhen stock exchange
+rise and fall
!prediction
World Cup
European Cup
Asian Cup
+match
```
##### Word group explanation and matching effect:
**Group 1 - Mobile new product class:**
- Keywords: iPhone, Huawei, OPPO
- Must word: release
- Effect: Must contain mobile brand name and "release"
**Matching example:**
- ✅ "iPhone 15 officially released price announced" ← Has "iPhone" + "release"
- ✅ "Huawei Mate60 series release live" ← Has "Huawei" + "release"
- ✅ "OPPO Find X7 release time confirmed" ← Has "OPPO" + "release"
- ❌ "iPhone sales hit a new high" ← Has "iPhone" but lacks "release"
**Group 2 - Stock market class:**
- Keywords: A-share, Shanghai stock exchange, Shenzhen stock exchange
- Must word: rise and fall
- Filter word: prediction
- Effect: Focus on stock market ups and downs, exclude predictions
**Matching example:**
- ✅ "A-share rose sharply today" ← Has "A-share" + "rise and fall"
- ✅ "Shanghai stock exchange hit a new high" ← Has "Shanghai stock exchange" + "rise and fall"
- ❌ "Expert predicts A-share trend" ← Has "A-share" + "rise and fall" but contains "prediction"
**Group 3 - Football match class:**
- Keywords: World Cup, European Cup, Asian Cup
- Must word: match
- Effect: Only focus on match-related news
---
#### 📝 Configuration tips
##### 1. **From loose to strict**
```txt
# Step 1: Use loose keywords to test
artificial intelligence
AI
ChatGPT
# Step 2: Add must words to limit after finding mis-matching
artificial intelligence
AI
ChatGPT
+technology
# Step 3: Add filter words after finding interference
artificial intelligence
AI
ChatGPT
+technology
!advertising
!training
```
##### 2. **Avoid excessive complexity**
❌ **Not recommended:** A word group contains too many words
```txt
Huawei
OPPO
Apple
Samsung
vivo
OnePlus
Meizu
+mobile
+release
+sales
!fake
!maintenance
!second-hand
```
✅ **Recommended:** Split into multiple precise word groups
```txt
Huawei
OPPO
+new product
Apple
Samsung
+release
mobile
sales
+market
```
##### Keyword Sorting Priority
**Configuration Location:** `config/config.yaml`
```yaml
report:
sort_by_position_first: false # Sorting priority configuration
```
| Configuration Value | Sorting Rule | Applicable Scenario |
|--------|---------|---------|
| `false` (Default) | Hotspot count ↓ → Configuration position ↑ | Focus on heat trend |
| `true` | Configuration position ↑ → Hotspot count ↓ | Focus on personal priority |
**Example:** Configuration order A, B, C, hotspot 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 10 news per keyword (0 = no limit)
```
**Docker Environment Variables:**
```bash
SORT_BY_POSITION_FIRST=true
MAX_NEWS_PER_KEYWORD=10
```
**Comprehensive Example:**
```yaml
# config.yaml
report:
sort_by_position_first: true # Prioritize by configuration order
max_news_per_keyword: 10 # Global default 10 news per keyword
```
```txt
# frequency_words.txt
Tesla
Musk
@20 # Focus on, display 20 news (override global config)
Huawei # Use global config, display 10 news
BYD
@5 # Limit to 5 news
```
**Final Effect:** Display by configuration order: Tesla(20) → Huawei(10) → BYD(5)
</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` under `report.mode`
```yaml
report:
mode: "daily" # Optional: "daily" | "incremental" | "current"
```
#### Detailed Comparison Table
| Mode | Applicable Users | Push Timing | Display Content | Typical Use Case |
|------|----------|----------|----------|------------|
| **Daily Summary**<br/>`daily` | 📋 Enterprise managers/ordinary users | Timed push (default hourly push) | All matching news for the day<br/>+ New news area | **Example**: Check all important news for the day at 6 pm<br/>**Characteristics**: See the complete trend for the day, without missing any hotspots<br/>**Reminder**: Includes previously pushed news |
| **Current Hot List**<br/>`current` | 📰 Self-media people/content creators | Timed push (default hourly push) | Current hot list matching news<br/>+ New news area | **Example**: Track "which topics are currently trending"<br/>**Characteristics**: Understand current hot ranking changes in real-time<br/>**Reminder**: News that continues to be on the list will appear every time |
| **Incremental Monitoring**<br/>`incremental` | 📈 Investors/traders | Push only when new | New matching frequency word news | **Example**: Monitor "Tesla", notify only when new news appears<br/>**Characteristics**: Zero repetition, only see first-appearing news<br/>**Suitable**: High-frequency monitoring, avoid information disturbance |
#### Actual Push Effect Example
Assuming you monitor the keyword "Apple" and execute it every hour:
| Time | daily Mode Push | current Mode Push | incremental Mode Push |
|-----|--------------|----------------|-------------------|
| 10:00 | News A, News B | News A, News B | News A, News B |
| 11:00 | News A, News B, News C | News B, News C, News D | **Only** News C |
| 12:00 | News A, News B, News C | News C, News D, News E | **Only** News D, News E |
**Description**:
- `daily`: Accumulate and display all news for the day (A, B, C are retained)
- `current`: Display current hot list news (ranking changes, News D ranks up, News A ranks down)
- `incremental`: **Push only new news** (avoid repetition)
#### Frequently Asked Questions
> **💡 Encountered this problem?** 👉 "Executed once every hour, the news output at the first execution appears again at the next hour"
> - **Cause**: You may have chosen `daily` (daily summary) or `current` (current hot list) mode
> - **Solution**: Switch to `incremental` (incremental monitoring) mode, push only new content
#### ⚠️ Important Note for Incremental Mode
> **Users who choose `incremental` (incremental monitoring) mode, please note:**
>
> 📌 **Incremental mode pushes only when new matching news appears**
>
> **If no push is received for a long time, it may be because:**
> 1. No new hotspots appear for the current time period that match your keywords
> 2. Keyword configuration is too strict or too broad
> 3. Few monitoring platforms
>
> **Solution:**
> - Solution 1: 👉 [Optimize keyword configuration](#2-keyword-configuration) - Adjust keyword accuracy, add or modify monitoring words
> - Solution 2: Switch push mode - Use `current` or `daily` mode, can receive push regularly
> - Solution 3: 👉 [Add monitoring platforms](#1-platform-configuration) - Add more news platforms, expand information sources
</details>
### 4. Adjust Hotspot Algorithm
<details>
<summary>👉 Click to expand: <strong>Custom hotspot weight</strong></summary>
<br>
**Configuration Location:** `config/config.yaml` under `advanced.weight`
```yaml
advanced:
weight:
rank: 0.6 # Ranking weight
frequency: 0.3 # Frequency weight
hotness: 0.1 # Hotness weight
```
Current default configuration is balanced
#### Two Core Scenarios
**Pursue Real-time Hotspots**:
```yaml
advanced:
weight:
rank: 0.8 # Mainly look at ranking
frequency: 0.1 # Less concerned about sustainability
hotness: 0.1
```
**Applicable Users**: Self-media bloggers, marketing personnel, users who want to quickly understand current trending topics
**Pursue In-depth Topics**:
```yaml
advanced:
weight:
rank: 0.4 # Moderately look at ranking
frequency: 0.5 # Emphasize daily sustained hotness
hotness: 0.1
```
**Applicable Users**: Investors, researchers, news workers, users who need in-depth trend analysis
#### Adjustment Method
1. **Three numbers must add up to 1.0**
2. **Increase the important one**: If you care about ranking, increase `rank`; if you care about sustainability, increase `frequency`
3. **Suggest adjusting by 0.1-0.2** each time, observe the effect
Core idea: Users pursuing speed and timeliness increase ranking weight, users pursuing depth and stability increase frequency weight.
</details>
### 5. What Does the Message Look Like?
<details>
<summary>👉 Click to expand: <strong>Message style preview</strong></summary>
<br>
#### Push Example
📊 Hotspot Vocabulary Statistics
🔥 [1/3] AI ChatGPT : 2 News
1. [Baidu Hot Search] 🆕 ChatGPT-5 Officially Released [**1**] - 09:15 (1 time)
2. [Today's Headlines] AI Chip Concept Stocks Soar [**3**] - [08:30 ~ 10:45] (3 times)
━━━━━━━━━━━━━━━━━━━
📈 [2/3] BYD Tesla : 2 News
1. [Weibo] 🆕 BYD Monthly Sales Record Broken [**2**] - 10:20 (1 time)
2. [Douyin] Tesla Price Reduction Promotion [**4**] - [07:45 ~ 09:15] (2 times)
━━━━━━━━━━━━━━━━━━━
📌 [3/3] A-share Stock Market : 1 News
1. [Wall Street Insights] A-share Mid-day Review Analysis [**5**] - [11:30 ~ 12:00] (2 times)
🆕 **New Hotspot News Added** (Total 2 News)
**Baidu Hot Search** (1 News):
1. ChatGPT-5 Officially Released [**1**]
**Weibo** (1 News):
1. BYD Monthly Sales Record Broken [**2**]
Update Time: 2025-01-15 12:30:15
#### Message Format Description
| Format Element | Example | Meaning | Description |
| ------------- | --------------------------- | ------------ | --------------------------------------- |
| 🔥📈📌 | 🔥 [1/3] AI ChatGPT | Heat Level | 🔥High heat (≥10 news) 📈Medium heat (5-9 news) 📌Ordinary heat (<5 news) |
| [Serial Number/Total] | [1/3] | Sorting Position | Current word group ranking among all matching word groups |
| Frequency Word Group | AI ChatGPT | Keyword Group | Word group in configuration file, title must contain the word |
| : N News | : 2 News | Matching Quantity | Total news matched for the word group |
| [Platform Name] | [Baidu Hot Search] | Source Platform | News platform name |
| 🆕 | 🆕 ChatGPT-5 Officially Released | New Addition Mark | First appearance in this round of hotspots |
| [**Number**] | [**1**] | High Ranking | Ranking ≤ threshold, red and bold display |
| [Number] | [7] | Ordinary Ranking | Ranking > threshold, ordinary display |
| - Time | - 09:15 | First Time | Time when news was first discovered |
| [Time~Time] | [08:30 ~ 10:45] | Duration | Time range from first appearance to last appearance |
| (N times) | (3 times) | Appearance Frequency | Total appearances during monitoring |
| **New Area** | 🆕 **New Hotspot News Added** | New Topic Summary | Separate display of newly appeared hot topics |
</details>
### 6. Docker Deployment
**Image Description:**
TrendRadar provides two independent Docker images, choose one according to needs:
| Image Name | Purpose | Description |
|---------|------|------|
| `wantcat/trendradar` | News push service | Timely crawl news, push notifications (required) |
| `wantcat/trendradar-mcp` | AI analysis service | MCP protocol support, AI dialogue analysis (optional) |
> 💡 **Suggestion**:
> - Only need push function: Deploy only `wantcat/trendradar` image
> - Need AI analysis function: Deploy both images
<details>
<summary>👉 Click to expand: <strong>Complete Docker deployment guide</strong></summary>
<br>
#### Method 1: Using Docker Compose (Recommended)
1. **Create Project Directory and Configuration**:
```bash
# Clone the project to local
git clone https://github.com/sansan0/TrendRadar.git
cd TrendRadar
```
> 💡 **Description**: The key directory structure required for Docker deployment is as follows:
```
Current Directory/
├── config/
│ ├── config.yaml # Core function configuration (required)
│ ├── frequency_words.txt # Keyword configuration (required)
│ ├── timeline.yaml # Timeline configuration
│ ├── ai_analysis_prompt.txt # AI analysis prompt words (optional)
│ ├── ai_translation_prompt.txt # AI translation prompt words (optional)
│ ├── ai_interests.txt # AI interest filtering configuration (optional)
│ ├── ai_filter/ # AI filtering related prompt words
│ │ ├── prompt.txt
│ │ ├── extract_prompt.txt
│ │ └── update_tags_prompt.txt
│ └── custom/ # User-defined configuration (optional)
│ ├── ai/ # Custom AI prompt words
│ └── keyword/ # Custom keyword files
└── docker/
├── .env # Sensitive information + Docker-specific configuration
└── docker-compose.yml # Docker Compose orchestration file
```
2. **Configuration File Description**:
**Configuration Division Principle (v4.6.0 optimized)**:
| File | Purpose | Modification Frequency | Description |
|------|------|---------------------|------|
| `config/config.yaml` | **Core Function Configuration** | Low | Report mode, push settings, storage format, push window, AI analysis switch, platform enablement, etc. |
| `config/frequency_words.txt` | **Keyword Configuration** | High | Set hot words you care about, support grouping, regular expressions, aliases, etc. |
| `config/timeline.yaml` | **Timeline Configuration** | Low | Control news timeline display and filtering rules |
| `config/ai_analysis_prompt.txt` | **AI Analysis Prompt Words** | Medium | Custom AI analysis role definition and output format (v5.0.0+) |
| `config/ai_translation_prompt.txt` | **AI Translation Prompt Words** | Low | Custom AI translation prompt word templates |
| `config/ai_interests.txt` | **AI Interest Filtering** | Medium | Define AI-based interest automatic filtering news rules |
| `config/ai_filter/` | **AI Filtering Prompt Words** | Low | AI filtering module's internal prompt words (generally no need to modify) |
| `config/custom/` | **User-defined Extension** | As needed | `custom/ai/` for custom AI prompt words, `custom/keyword/` for custom keyword files |
| `docker/.env` | **Sensitive Information + Docker-specific Configuration** | Low | Webhook URLs, API Keys, S3 credentials, scheduled tasks, etc., **not tracked by git** |
> 💡 **Division Points**:
> - **Function Behavior** → Modify `config.yaml` (e.g., enable/disable a platform, adjust push mode)
> - **Concerned Content** → Modify `frequency_words.txt` (e.g., add new concerned keywords)
> - **AI Output Style** → Modify `ai_analysis_prompt.txt` or `ai_translation_prompt.txt`
> - **Credentials and Certificates** → Modify `docker/.env` (sensitive information like API Keys, Webhook URLs)
> - **Personalized Extension** → Use `config/custom/` directory, avoid direct modification of default configuration being upgraded and overwritten
> 💡 **Configuration Modification Takes Effect**: After modifying `config.yaml`, execute `docker compose up -d` to restart the container for it to take effect
**⚙️ Environment Variable Override Mechanism (v3.0.5+)**:
Environment variables in `.env` file will override corresponding configurations in `config.yaml`:
| Environment Variable | Corresponding Configuration | Example Value | Description |
|---------|---------|-------|------|
| `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 (added 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
**Usage**:
- Modify `.env` file and fill in needed configurations
- Or add directly in NAS/Synology Docker management interface's "environment variables"
- 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: Start News Push Service Only**
```bash
# Start trendradar only (periodic crawling and pushing)
docker compose pull trendradar
docker compose up -d trendradar
```
**Option C: Start MCP AI Analysis Service Only**
```bash
# Start trendradar-mcp only (provide AI analysis interface)
docker compose pull trendradar-mcp
docker compose up -d trendradar-mcp
```
> 💡 **Hint**:
> - Most users only need to start `trendradar` to achieve news push functionality
> - Only when using ChatGPT/Gemini for AI dialogue analysis, `trendradar-mcp` needs to be started
> - Two services are independent and can be flexibly combined according to needs
4. **Check 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 and modify code or build your own image:
```bash
# Clone the project
git clone https://github.com/sansan0/TrendRadar.git
cd TrendRadar
# Modify configuration files
vim config/config.yaml
vim config/frequency_words.txt
# Use build version of docker compose
cd docker
cp docker-compose-build.yml docker-compose.yml
```
**Build and Start Service**:
```bash
# Option A: Build and start all services
docker compose build
docker compose up -d
# Option B: Build and start news push service only
docker compose build trendradar
docker compose up -d trendradar
# Option C: Build and start MCP AI analysis service only
docker compose build trendradar-mcp
docker compose up -d trendradar-mcp
```
> 💡 **Architecture Parameter Description**:
> - Default build `amd64` architecture image (applicable to most x86_64 servers)
> - If you need to build `arm64` architecture (Apple Silicon, Raspberry Pi, etc.), set 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: Use docker compose to update
docker compose pull
docker compose up -d
```
**Available Images**:
| Image Name | Purpose | Description |
|---------|------|------|
| `wantcat/trendradar` | News Push Service | Periodically crawl news, push notifications |
| `wantcat/trendradar-mcp` | MCP Service | AI analysis function (optional) |
#### Service Management Commands
```bash
# View running status
docker exec -it trendradar python manage.py status
# Manually execute a crawl
docker exec -it trendradar python manage.py run
# View real-time logs
docker exec -it trendradar python manage.py logs
# Display current configuration
docker exec -it trendradar python manage.py config
# Display output files
docker exec -it trendradar python manage.py files
# Web server management (for browser access to generated reports)
docker exec -it trendradar python manage.py start_webserver # Start web server
docker exec -it trendradar python manage.py stop_webserver # Stop web server
docker exec -it trendradar python manage.py webserver_status # View web server status
# View help information
docker exec -it trendradar python manage.py help
# Restart container
docker restart trendradar
# Stop container
docker stop trendradar
# Remove container (retain data)
docker rm trendradar
```
> 💡 **Web Server Description**:
> - Automatically started in cron mode, access generated reports via browser at `http://localhost:8080`
> - Access historical reports through directory navigation (e.g., `http://localhost:8080/2025-xx-xx/`)
> - Port can be configured in `.env` file with `WEBSERVER_PORT` parameter
> - Manual stop: `docker exec -it trendradar python manage.py stop_webserver`
> - Manual start: `docker exec -it trendradar python manage.py start_webserver`
> - Security tip: Only provides static file access, restricted to output directory, bound only to local access
#### Data Persistence
Generated reports and data are saved in `./output` directory by default, and data is retained even if the container is restarted or deleted.
**📊 Web Version Report Access Path**:
TrendRadar generated daily summary HTML reports are saved in two locations:
| File Location | Access Method | Applicable Scenario |
|---------|---------|---------|
| `output/index.html` | Direct access on host machine | **Docker Deployment** (accessible through Volume mount, visible on host machine) |
| `index.html` | Access from root directory | **GitHub Pages** (repository root directory, automatically identified by Pages) |
| `output/html/YYYY-MM-DD/daily_summary.html` | Historical report access | All environments (archived by date) |
**Local Access Example**:
```bash
# Method 1: Access through web server (recommended, Docker environment)
# 1. Start web server
docker exec -it trendradar python manage.py start_webserver
# 2. Access in browser
http://localhost:8080 # Access latest report (default index.html)
http://localhost:8080/html/2025-xx-xx/ # Access report for specific date
# Method 2: Directly open file (local environment)
open ./output/index.html # macOS
start ./output/index.html # Windows
xdg-open ./output/index.html # Linux
# Method 3: Access historical archive
open ./output/html/2025-xx-xx/daily_summary.html
```
**Why are there two index.html files?**
- `output/index.html`: Docker Volume mounted to host machine, can be directly opened locally
- `index.html`: GitHub Actions pushed to repository, GitHub Pages automatically deployed
> 💡 **Hint**: Two files have identical content, choose either one for access.
#### Troubleshooting
```bash
# Check container status
docker inspect trendradar
# View container logs
docker logs --tail 100 trendradar
# Enter container for debugging
docker exec -it trendradar /bin/bash
# Verify configuration files
docker exec -it trendradar ls -la /app/config/
```
#### MCP Service Deployment (AI Analysis Function)
If you need to use AI analysis function, you can deploy an independent MCP service container.
**Architecture Description**:
```mermaid
flowchart TB
subgraph trendradar["trendradar"]
A1[Periodic News Crawling]
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 deployment using [Method 1: Using Docker Compose (Recommended)], just start MCP service:
```bash
cd TrendRadar/docker
docker compose up -d trendradar-mcp
# View running status
docker ps | grep trendradar-mcp
```
**Start MCP Service Alone** (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 alone, ensure that `config/` and `output/` folders exist in the current directory and contain configuration files and news data.
**Verify Service**:
```bash
# Check MCP service health status
curl http://127.0.0.1:3333/mcp
```
# Tool List
## Check MCP Service Logs
docker logs -f trendradar-mcp
## Configure in AI Client:
MCP service starts, then configure according to different clients:
### Cherry Studio (Recommended, GUI Configuration):
- Settings → MCP Server → Add
- Type: `streamableHttp`
- URL: `http://127.0.0.1:3333/mcp`
### Claude Desktop / Cline (JSON Configuration):
```json
{
"mcpServers": {
"trendradar": {
"url": "http://127.0.0.1:3333/mcp",
"type": "streamableHttp"
}
}
}
```
> 💡 **Tip**: MCP service only listens to local port (127.0.0.1), ensuring security. If you need remote access, configure a reverse proxy and authentication yourself.
</details>
### 7. How is Content Displayed?
<details>
<summary>👉 Click to expand: <strong>Custom Push Styles and Content</strong></summary>
<br>
**Configuration Location:** `config/config.yaml` in `report` and `display` sections
```yaml
report:
mode: "daily" # Push mode
display_mode: "keyword" # Display mode (added in v4.6.0)
rank_threshold: 5 # Ranking highlight threshold
sort_by_position_first: false # Sorting priority
max_news_per_keyword: 0 # Maximum news per keyword
display:
region_order: # Region display order (added in v5.2.0)
- new_items # New hotspots region
- hotlist # Hotlist region
- rss # RSS subscription region
- standalone # Independent display area
- ai_analysis # AI analysis region
```
#### Common Configuration Item Description
| What do I want to adjust? | Which parameter to modify? | Default value | Description |
|-------------|-------------|-------|------|
| **Push Mode** | `mode` | `daily` | Determines push timing and content, see [Push Mode Details](#3-push-mode-details) |
| **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 ranking top 5 will be **bold**, easy to see the hottest ones |
| **Sorting Rule** | `sort_by_position_first` | `false` | `false`=hottest ones on top, `true`=your configured words on top |
| **Quantity Limit** | `max_news_per_keyword` | `0` | How many news per keyword? `0` means no limit |
| **Display Order** | `display.region_order` | See above configuration | Adjust list order to control each region's display position |
#### Grouping Method Comparison (display_mode)
Do you want to see "what news are under this topic" or "what news are on this platform"?
| Mode | Grouping Method | Title Prefix | Applicable Scenario |
|------|---------|---------|---------|
| `keyword` (Default) | **Grouped by keyword** | `[Platform Name]` | I follow "AI" and want to see news about AI from various platforms |
| `platform` | **Grouped by platform** | `[Keyword]` | I follow "Weibo" and want to see news about my concerned words on Weibo |
#### Region Display Order (region_order)
By adjusting the order of `display.region_order` list, you can control the display position of each region in push messages.
**Default Order**: New hotspots → Hotlist → RSS → Independent display area → AI analysis
**Custom Example**: Want AI analysis on top?
```yaml
display:
region_order:
- ai_analysis # Move to the first line
- new_items
- hotlist
- rss
- standalone
```
**Note**: A region will only be displayed if it meets two conditions:
1. In `region_order` list
2. Corresponding switch in `display.regions` is `true`
#### Region Switches (regions)
Control whether each region is displayed in push messages:
```yaml
display:
regions:
hotlist: true # Hotlist region (keyword-matched hot news)
new_items: false # New hotspots region (including hotlist new + RSS new)
rss: true # RSS subscription region (keyword-matched RSS content)
standalone: false # Independent display area (complete hotlist/RSS, not filtered by keywords)
ai_analysis: true # AI analysis region
```
| Region | Configuration Key | Default Value | Description |
|------|--------|-------|------|
| **Hotlist** | `hotlist` | `true` | Keyword-matched hot news aggregation |
| **New Hotspots** | `new_items` | `false` | Newly appeared hot topics (including hotlist new + RSS new). Note: Hotlist region's 🆕 mark is not affected by this switch |
| **RSS** | `rss` | `true` | Keyword-matched RSS subscription content. If turned off, skip RSS analysis, but independent display area's RSS is not affected |
| **Independent Display Area** | `standalone` | `false` | Specified platform/RSS complete content display, not filtered by keywords |
| **AI Analysis** | `ai_analysis` | `true` | AI-generated hotspot analysis summary |
#### Sorting Priority (sort_by_position_first)
Assume you configured keywords: 1. Tesla, 2. BYD.
Actual popularity: BYD (10 news), Tesla (3 news).
| Configuration Value | Sorting Result | Your Idea |
|-------|---------|---------|
| `false` (Default) | BYD (10 news) → Tesla (3 news) | "Who's hotter comes first" |
| `true` | Tesla (3 news) → BYD (10 news) | "My configured order is priority, no matter how hot" |
#### Independent Display Area (standalone)
**Scenario**: Some platforms (e.g., Zhihu Hotlist, HackerNews), you want to **see the complete list**, regardless of matching your keywords.
```yaml
display:
regions:
standalone: true # Display independent display area in push (turning off does not affect AI analysis)
standalone:
platforms: ["zhihu", "weibo"] # These platforms' hotlists are displayed completely
rss_feeds: ["hacker-news"] # These RSS sources' content is displayed completely
max_items: 20 # Maximum display items
```
> 💡 **Push Display and AI Analysis are Independent**: `regions.standalone` only controls whether independent display area is shown in push. Even if turned off, AI will still analyze these platforms' complete data if `include_standalone: true` is configured in AI settings.
</details>
### 8. When to Push?
<details>
<summary>👉 Click to expand: <strong>Set Push Timing (Scheduling System)</strong></summary>
<br>
**Configuration Location:** `config/config.yaml` in `schedule` section + `config/timeline.yaml`
#### Quick Start
Just select a preset template in `config.yaml`, no need to edit `timeline.yaml`:
```yaml
schedule:
enabled: true
preset: "morning_evening" # Change here
```
#### Optional Preset Templates
| Template Name | Description | Push Behavior |
|-------|------|---------|
| `morning_evening` | All-day incremental + evening summary (recommended) | Push when new throughout the day + 19:00-21:00 evening summary |
| `always_on` | Always-on monitoring | Push whenever new, no time segment division |
| `office_hours` | Office hours | Three-segmented push during workdays (morning review → midday hotspots → end-of-work summary), weekend incremental free push |
| `night_owl` | Night owl | Afternoon review + late-night full-day summary (22:00-01:00跨午夜) |
| `custom` | Completely custom | Edit `timeline.yaml` bottom `custom` section |
#### Completely Custom
If preset templates do not meet requirements, edit `config/timeline.yaml` bottom `custom` section to define time segments, daily plans, and weekly mappings. See `timeline.yaml` file comments for details.
#### Important Notes
> ⚠️ **Users upgrading from old versions**:
> - v6.0.0 removed old `notification.push_window` and `ai_analysis.analysis_window` configurations
> - Use new `schedule` + `timeline.yaml` scheduling system
> - Old "push once a day" can be replaced with `morning_evening` preset
> - Old "office hours push" can be replaced with `office_hours` preset
> ⚠️ **GitHub Actions Users**:
> - GitHub Actions execution time is unstable, may have ±15 minutes deviation
> - Time segment range is recommended to leave at least **2 hours**
> - For precise timing push, recommend using **Docker deployment** on personal servers
</details>
### 9. How Often to Run?
<details>
<summary>👉 Click to expand: <strong>Set Auto-Run Frequency</strong></summary>
<br>
**Configuration Location:** `.github/workflows/crawler.yml` in `schedule` section
```yaml
on:
schedule:
- cron: "0 * * * *" # Run once an hour
```
#### How to Modify Run Frequency?
GitHub Actions uses a "Cron" time format, no need to deeply understand, just copy and replace.
**Configuration Location:** `.github/workflows/crawler.yml` file in `schedule` section
| What I want... | Copy this line | Description |
|-----------|------------|------|
| **Once an hour** | `- cron: "0 * * * *"` | **Default configuration**, runs at minute 0 |
| **Every 30 minutes** | `- cron: "*/30 * * * *"` | Run every 30 minutes |
| **Daily at 8:00 AM** | `- cron: "0 0 * * *"` | ⚠️ Write `0` because UTC time (0:00) = Beijing time (8:00 AM) |
| **Work hours every half hour** | `- cron: "*/30 0-14 * * *"` | Corresponds to Beijing time 8:00 AM - 10:00 PM |
| **Three meals a day** | `- cron: "0 0,6,12 * * *"` | Corresponds to Beijing time 8:00 AM, 2:00 PM, 8:00 PM |
#### ⚠️ Two Important Reminders
1. **Time difference issue**: GitHub servers are abroad, using UTC time.
- **Simple arithmetic**: Your desired Beijing time **minus 8 hours** = time to fill.
- *Example: Want it to run at 20:00 Beijing time, fill 12:00*
2. **Don't be too frequent**: Recommend interval not less than 30 minutes.
- GitHub free resources are limited, running too often may be restricted by official account.
- Actions start-up itself has minutes of delay, precise control is not meaningful.
#### Step-by-Step Modification
1. In your GitHub repository, find `.github/workflows/crawler.yml` file
2. Click the top-right corner ✏️ (Edit) button
3. Find `cron: "..."` line, replace content with above "code"
4. Click top-right green **Commit changes** button to save
</details>
### 10. Push to Multiple Groups/Devices
<details>
<summary>👉 Click to expand: <strong>Push to Multiple Receivers Simultaneously</strong></summary>
> ### ⚠️ **Security First**
> **Do not write passwords/ Tokens directly in `config.yaml`!**
> If you upload files containing passwords to GitHub, the whole world can see.
>
> **Correct approach**:
> - **GitHub Actions users**: Add to Settings -> Secrets
> - **Docker users**: Write in `.env` file (this file will not be uploaded)
#### How to push to multiple places?
Simple, use semicolon `;` to separate multiple addresses.
**Example**:
Assume you have two Lark groups, want to receive push:
- Group 1 address: `https://.../webhook/aaa`
- Group 2 address: `https://.../webhook/bbb`
Fill in configuration:
`https://.../webhook/aaa;https://.../webhook/bbb`
#### Platforms Supporting Multiple Accounts
| Platform | Configuration Method | Notes |
|------|---------|----------|
| **Lark/DingTalk/WeChat** | Use `;` to separate multiple Webhook URLs | Easiest, just string them up |
| **Bark (iOS)** | Use `;` to separate multiple Key URLs | Push to multiple iPhones |
| **Telegram** | Token and ChatID both use `;` to separate | ⚠️ **Note order correspondence**:<br>Token1 corresponds to ChatID1<br>Token2 corresponds to ChatID2 |
| **ntfy** | Topic and Token both use `;` to separate | If a topic does not require a token, leave blank:<br>`token1;;token3` (middle one is blank) |
#### Common Configuration Examples (GitHub Secrets / .env)
```bash
# Lark send to 3 groups
FEISHU_WEBHOOK_URL=https://hook1...;https://hook2...;https://hook3...
# DingTalk send to 2 groups
DINGTALK_WEBHOOK_URL=https://oapi...;https://oapi...
# Telegram send to 2 people (note correspondence)
TELEGRAM_BOT_TOKEN=tokenA;tokenB
TELEGRAM_CHAT_ID=userA;userB
```
> **Tip**: To prevent abuse, default limit is 3 accounts per platform. If you need more, modify `MAX_ACCOUNTS_PER_CHANNEL` configuration.
</details>
### 11. Where is Data Stored?
<details id="storage-config">
<summary>👉 Click to expand: <strong>Choose Data Storage Location</strong></summary>
<br>
#### Where will data be stored?
The system will automatically choose the most suitable location for you, you usually don't need to worry:
| Your running environment | Data storage location | Description |
|-------------|-----------|------|
| **Docker / Local Run** | **Local hard drive** | Stored in project directory's `output/` folder, can be viewed anytime. |
| **GitHub Actions** | **Cloud storage** | Since GitHub Actions environment is destroyed after running, a cloud storage (e.g., Cloudflare R2) must be configured. |
#### How to configure cloud storage? (GitHub Actions users must read)
If you use GitHub Actions, you need a "cloud hard drive" to store data. For example, use Cloudflare R2 (because it has free quota).
**Add these 5 variables to GitHub Secrets:**
| Variable name | What to fill |
|-------|-------|
| `STORAGE_BACKEND` | `remote` |
| `S3_BUCKET_NAME` | Your storage 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? See [Quick Start - Remote Storage Configuration](#-quick-start)
#### How long will data be saved?
By default, we won't automatically delete your data. But if you think data takes up too much space, set "auto-cleanup".
**Configuration location**: `config/config.yaml`
```yaml
storage:
local:
retention_days: 30 # Local data retained for 30 days (0 means forever)
remote:
retention_days: 30 # Cloud data retained for 30 days
```
#### Push time is incorrect? (Timezone setting)
If you're overseas or find push time not matching your local time, modify timezone.
**Configuration location**: `config/config.yaml`
```yaml
app:
timezone: "Asia/Shanghai" # Default is China time
```
- For example, if you're in Los Angeles, change to: `America/Los_Angeles`
- For example, if you're in London, change to: `Europe/London`
</details>
### 12. Let AI Analyze Hotspots
<details id="ai-analysis-config">
<summary>👉 Click to expand: <strong>Enable AI Intelligent Analysis</strong></summary>
<br>
#### What can AI do for me?
Enabling this feature, AI will act like a professional analyst, for each batch of news push:
1. **Auto-read**: Read all matched hot news
2. **Deep thinking**: Analyze isolated news' associations
3. **Write report**: Append a short, profound "insight report" at the end of push messages
**Includes**: Hot trend summary, opinion trend judgment, cross-platform association analysis, potential impact assessment, etc.
</details>
#### How to Enable AI Analysis?
The simplest way is through environment variable configuration (recommended GitHub Secrets or .env).
**Required Configurations**:
| Variable Name | What to Fill | Description |
|---------------|--------------|-------------|
| `AI_ANALYSIS_ENABLED` | `true` | Enable 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 for AI_MODEL | Description |
|-----------|--------------------------|-------------|
| **DeepSeek** (Recommended) | `deepseek/deepseek-chat` | High cost-effectiveness, 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 unified interface based on [LiteLLM](https://github.com/BerriAI/litellm), supports 100+ AI providers, simpler configuration, and better error handling.
**Optional Configurations**:
| Variable Name | Default Value | Description |
|---------------|--------------|-------------|
| `AI_API_BASE` | (Automatic) | Custom API Address (e.g., OneAPI, local model) |
| `AI_TEMPERATURE` | `1.0` | Sampling Temperature (0-2, higher is more random) |
| `AI_MAX_TOKENS` | `5000` | Maximum generated tokens |
| `AI_TIMEOUT` | `120` | Request timeout in seconds |
| `AI_NUM_RETRIES` | `2` | Number of retries on failure |
#### Advanced Play: AI Translation
If you follow foreign RSS sources (like Hacker News), AI can help translate content into Chinese for you.
**Configuration Location**: `config/config.yaml`
```yaml
ai_translation:
enabled: true # Enable translation
language: "Chinese" # Translate to what language (Chinese, English, Japanese...)
```
#### Advanced Play: Custom AI Persona
Do you find AI speaking too formally? You can modify its prompt to make it sound like your favorite style (e.g., "toxic commentator", "experienced investment advisor").
- **Edit File**: `config/ai_analysis_prompt.txt`
- **Edit Method**: Open and edit directly, tell AI what analysis style you want.
<br>
## ✨ AI Intelligent Analysis
TrendRadar v3.0.0 adds AI analysis capabilities based on **MCP (Model Context Protocol)**, allowing you to converse with news data in natural language for in-depth analysis.
### ⚠️ Read Before Use
**Important Note**: AI functionality requires local news data support.
AI analysis is **not** a direct query of real-time internet data but analyzes your **locally accumulated news data** (stored in the `output` folder).
#### Instructions:
1. **Project-Included Test Data**: The `output` directory contains default test data for **2025-12-21~2025-12-27** one week's hot list news data for quick AI feature experience.
2. **Query Limitations**:
- ✅ 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 Latest Data**:
- Test data is for quick experience; **recommended to deploy the project yourself** to get real-time data.
- Follow [Quick Start](#-quick-start) to deploy and run the project.
- Wait at least 1 day to accumulate news data before querying the latest hotspots.
### 1. Quick Deployment
Cherry Studio provides a GUI configuration interface for quick deployment in 5 minutes, handling complex parts with a one-click installation.
**Graphic Deployment Tutorial**: Updated in my [public account](#-support-project), reply "mcp" for access.
**Detailed Deployment Tutorial**: [README-Cherry-Studio.md](README-Cherry-Studio.md)
**Deployment Mode Description**:
- **STDIO Mode (Recommended)**: Configure once and no need to repeat; **graphic deployment tutorial** only uses this mode as an example.
- **HTTP Mode (Alternative)**: If STDIO mode configuration encounters issues, use HTTP mode. The configuration is similar to STDIO but with a one-line configuration, less prone to errors. The only difference is that the service needs to be manually started each time. Refer to [README-Cherry-Studio.md](README-Cherry-Studio.md) for HTTP mode instructions.
### 2. Learning How to Dialogue with AI
**Detailed Dialogue Tutorial**: [README-MCP-FAQ.md](README-MCP-FAQ.md)
> 💡 **Tip**: It's not recommended to ask multiple questions at once. If your chosen AI model can't handle sequential calls like the example below, consider switching to another model.
<img src="/_image/ai4.png" alt="mcp usage diagram" width="600">
<br>
## 🔌 MCP Client
TrendRadar MCP service supports the standard Model Context Protocol (MCP) and can connect to various MCP-supported AI clients for intelligent analysis.
### Supported Clients
**Note**:
- Replace `/path/to/TrendRadar` with your actual project path.
- Use double backslashes for Windows paths: `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` (with the same content).
3. **Usage Steps**:
- Save the configuration file and restart Cursor.
- Check the "Available Tools" in the chat interface for the connected tool.
- Start using: `Search 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 to 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"
]
}
}
]
}
}
```
**Usage Example**:
```
Analyze the trend of "Tesla" in the last 7 days
Generate today's hotspot summary report
Search for news related to "Bitcoin" and analyze sentiment
```
</details>
<details>
<summary>👉 Click to expand: <b>MCP Inspector</b> (Debugging Tool)</summary>
<br>
MCP Inspector is an 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" functionality to verify connection
- Check "List Tools" for 17 tools:
- Basic Query: get_latest_news, get_news_by_date, get_trending_topics
- Intelligent Search: 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 supporting Model Context Protocol can connect to TrendRadar:
#### HTTP Mode
**Service Address**: `http://localhost:3333/mcp`
**Basic Configuration Template**:
```json
{
"name": "trendradar",
"url": "http://localhost:3333/mcp",
"type": "http",
"description": "News Hotspot Aggregation Analysis"
}
```
#### STDIO Mode (Recommended)
**Basic Configuration Template**:
```json
{
"name": "trendradar",
"command": "uv",
"args": [
"--directory",
"/path/to/TrendRadar",
"run",
"python",
"-m",
"mcp_server.server"
],
"type": "stdio"
}
```
**Notes**:
- Replace `/path/to/TrendRadar` with the actual project path.
- Use backslashes for Windows paths: `C:\\Users\\...`
- Ensure project dependencies are installed (setup script has been run).
</details>
### Frequently Asked Questions
<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
# Re-run 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 custom port:
```bash
uv run python -m mcp_server.server --transport http --port 33333
```
</details>
<details>
<summary>👉 Click to expand: <b>Q2: Client Cannot Connect to MCP Service?</b></summary>
<br>
**Solutions**:
1. **STDIO Mode**:
- Confirm UV path is correct (run `which uv` or `where uv`).
- Confirm project path is correct and has no Chinese characters.
- Check client error logs.
2. **HTTP Mode**:
- Confirm service is started (access `http://localhost:3333/mcp`).
- Check firewall settings.
- Try using 127.0.0.1 instead of localhost.
3. **General Check**:
- Restart client application.
- Check MCP service logs.
- Use MCP Inspector to test connection.
</details>
<details>
<summary>👉 Click to expand: <b>Q3: Tool Call Fail or Return Errors?</b></summary>
<br>
**Possible Causes**:
1. **Data Does Not Exist**:
- Confirm spider has been run (output directory data exists).
- Check query date range for available 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 tool documentation for parameter instructions.
3. **Configuration Issue**:
- Confirm `config/config.yaml` exists.
- Confirm `config/frequency_words.txt` exists.
- Check configuration file format.
</details>
<br>
## 📚 Project Related
> **4 Articles**:
- [You can leave a message at the bottom of this article for the project author to answer questions on your mobile phone.](https://mp.weixin.qq.com/s/KYEPfTPVzZNWFclZh4am_g)
- [2 months to break 1000 stars, my GitHub project promotion practical experience](https://mp.weixin.qq.com/s/jzn0vLiQFX408opcfpPPxQ)
- [GitHub fork running this project precautions ](https://mp.weixin.qq.com/s/C8evK-U7onG1sTTdwdW2zg)
- [How to develop public accounts or news articles based on this project](https://mp.weixin.qq.com/s/8ghyfDAtQZjLrnWTQabYOQ)
>**AI Development**:
- If you have niche demands, you can develop based on my project, even with zero programming experience.
- All my open-source projects use **AI-assisted software** to improve development efficiency, and this tool is open-sourced.
- **Core Function**: Quickly filter project code and feed it to AI; you only need to supplement personal demands.
- **Project Address**: https://github.com/sansan0/ai-code-context-helper
### Other Projects
> 📍 Mao Zedong Footprint Map - Interactive dynamic display of complete trajectory from 1893-1976. Welcome comrades to contribute data.
- https://github.com/sansan0/mao-map
> Bilibili (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
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
awesome-mcp-servers
A collection of MCP servers.
git
A Model Context Protocol server for Git automation and interaction.
oh-my-opencode
Background agents · Curated agents like oracle, librarians, frontend...
Appwrite
Build like a team of hundreds
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...