Content
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 hot spot assistant - Say goodbye to invalid brushing, only read the news information you really care about
<a href="https://trendshift.io/repositories/14726" target="_blank"><img src="https://trendshift.io/api/badge/repositories/14726" alt="sansan0%2FTrendRadar | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
[](https://github.com/sansan0/TrendRadar/stargazers)
[](https://github.com/sansan0/TrendRadar/network/members)
[](LICENSE)
[](https://github.com/sansan0/TrendRadar)
[](github.com/sansan0/TrendRadar)
[](https://github.com/sansan0/TrendRadar)
[](https:///sansan0/TrendRadar)
[](https://work.weixin.qq.com/)
[](https://weixin.qq[](https://telegram.org/)
ingTalk Notification](https://img.shields.io/badge/DingTalk-00D4AA?style=flat-square)](#)
[](www.feishu.cn/)
[fy Notification](https://img/badge/ntfy-Notification-00D4AA?style=flat-square)](https://github.com/binwiederhier/ntfy)
[](https://github.com/Finb/Bark)
[](https://slack.com/)
[](#)
[](https://github.com/sansan0/TrendRadar)
[](https://sansan0.github.io/TrendRadar)
[](https://hub.docker.com/r/wantcat/trendradar)
[](https://modelcontextprotocol.io/)
[](#)
[](#)
</div>
<div align="center">
**English** | **[English](README-EN.md)**
</div>
> This project aims to be lightweight and easy to deploy
<br 📑 Quick Navigation
> 💡 **Click the link to quickly jump to the corresponding section. It is recommended to "**Quick Start**" for deployment, and for detailed customization, to "**Configuration Details**".
<div align="center">
| | |
|:---:|:---:|:---:|
| [🚀 **Quick Start**quick-start) | [AI Intelligent Analysis](#-ai-intelligent | [⚙️ **Configuration Details**](#configuration-details) |
| [Docker Deployment](#6-docker-deployment) | [MCP Client](#-mcp-client) | [📝 **Update Log**](#-update-log) |
| [🎯 **Core Features**](#-core-features) | [☕ **Support Projects**](#-support-projects) | [📚 **Project Related**](#-project-related) |
</div>
<br>
- Thanks to the audience who **starred** the project, **forked** as you wish, and **starred** as I wish, both are the best support for the open-source spirit.
<details>
<summary>👉 Click to expand: <strong>Acknowledgments List</strong> (Honor List 🔥73+🔥 contributors)</summary>
### Early Supporters Acknowledgments
> 💡 **Special Note**:
>
> 1. **About the list**: The table below records the supporters during the early stages (angel round) of the project. Due to the tedious manual statistics, **there may be omissions or incomplete records, and any omissions are unintentional and appreciated for your understanding**.
> 2. **Future Plans**: In order to focus on code and feature iteration, **this list will no longer be manually maintained starting from now**.
> Regardless of whether your name is on the list, every support you provide is the cornerstone of TrendRadar's progress today. 🙏
### Infrastructure Support
Thanks to **GitHub** for providing free infrastructure, the biggest prerequisite for this **fork with one click** and run smoothly.
### Data Support
This project uses the API from [newsnow](https://github.com/ourongxing/newsnow) to obtain multi-platform data, and special thanks to the author for providing the service.
After contact, the author expressed no concerns about server pressure, but this is based on his 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 overexploitation.
### Promotion Assistance
> Thanks to the following platforms and individuals for their recommendations (in chronological order)
- [CoolShell](https://mp.weixin.qq.com/sutkJ_NPUelSW9OGK39aA) - Open-source software recommendation platform
- [LinuxDo Community](https://linux.do/) - A gathering place for tech enthusiasts
- [阮一峰周刊](https://github.com/ruanyf/weekly) - A popular newsletter
### Audience Support
> Thanks to **those who have financially supported** the project, your generosity has transformed into snacks and drinks beside the keyboard, accompanying every iteration of the project.
>
> **Regarding the return of "One Yuan Praise"**:
> With the release of version v5.0.0, the project has entered a new stage. To support the growing API costs and caffeine consumption, the "One Yuan Praise" channel has reopened. Every intention you have will be converted into tokens and motivation in the code world. 🚀 [Go to support](#-support-the-project)
| Supporters | 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 source, wish you success |
| *晨 | 8.88 | 2025.11.16 | The project is good, studying and learning |
| *海 | 1 | 2025.11.15 | |
| *德 | 1.99 | 2025.11.15 | |
| *疏 | 8.8 | 2025.11.14 | Thanks for open source, the project is great, support |
| M*e | 10 | 2025.11.14 | Open source is not easy, thanks for your hard work |
| **柯 | 1 | 2025.11.14 | |
| *云 | 88 | 2025.11.13 | Good project, thanks for open source |
| *W | 6 | 2025.11.13 | |
| *凯 | 1 | 2025.11.13 | |
| 对*. | 1 | 2025.11.13 | Thanks for your TrendRadar |
| s*y | 1 | 2025.11.13 | |
| **翔 | 10 | 2025.11.13 | Good project, great meeting, thanks for open source! |
| *韦 | 9.9 | 2025.11.13 | TrendRadar is great, please have a cup of coffee~ |
| h*p | 5 | 2025.11.12 | Support 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 open source sharing |
| *记 | 1 | 2025.11.11 | |
| *主 | 1 | 2025.11.10 | |
| *了 | 10 | 2025.11.09 | |
| *杰 | 5 | 2025.11.08 | |
| *点 | 8.80 | 2025.11.07 | Development is not easy, support |
| Q*Q | 6.66 | 2025.11.07 | Thanks for open source! |
| C*e | 1 | 2025.11.05 | |
| Peter Fan | 20 | 2025.10.29 | |
| M*n | 1 | 2025.10.27 | Thanks for open source |
| *许 | 8.88 | 2025.10.23 | Teacher, I'm a newbie, I've been trying for a few days but can't get it done, please teach me |
| Eason | 1 | 2025.10.22 | I haven't figured it out yet, but you're doing a great job |
| P*n | 1 | 2025.10.20 | |
| *杰 | 1 | 2025.10.19 | |
| *徐 | 1 | 2025.10.18 | |
| *志 | 1 | 2025.10.17 | |
| *😀 | 10 | 2025.10.16 | Like |
| **杰 | 10 | 2025.10.16 | |
| *啸 | 10 | 2025.10.16 | |
| *纪 | 5 | 2025.10.14 | TrendRadar |
| J*d | 1 | 2025.10.14 | Thanks for your tool, it's great... |
| *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!!! I'm a newbie and can use it directly... |
| **培 | 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 | Like |
| *家 | 10 | 2025.9.10 | |
| *X | 1.11 | 2025.9.3 | |
| *飙 | 20 | 2025.8.31 | Thanks from old Tong |
| *下 | 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 like |
| *远 | 1 | 2025.8.01 | |
| *邪 | 5 | 2025.8.01 | |
| *梦 | 0.1 | 2025.7.30 | |
| **龙 | 10 | 2025.7.29 | Support一下 |
</details>
<br>
## 🪄 Sponsors
<div align="center">
> **Awaiting sponsors**
>
> If you're interested in sponsoring, please trigger the auto-reply in the WeChat public account to get my contact information.
</div>
<br>
<a name="-support-the-project"></a>
### ❤️ Appreciate it?
> If TrendRadar has helped you capture value, consider giving it a boost to continue evolving
>
> Any amount is welcome, and 1 yuan is also an encouragement for open source. Feel free to leave a message when you donate (´▽`ʃ♡ƪ)
<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 draw inspiration from this project in your project, **it's highly welcome** to note the source and attach a link to this repository.
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. Please provide complete information (screenshots, error logs, etc.) to help with quick positioning.
- **Public Account Communication**: It's recommended to communicate in the comment section of relevant articles. If you need to ask questions in the background, **liking/recommending** the article is the best "knock on the door," and I can feel your intention.
- **QQ Group Communication**: Follow the public account and reply " **交流群** " to join. Whether you're an AI newbie or a hardcore developer, you can ask for help with technical issues or share your experiences. The group focuses on mutual assistance and inspiration, and please read the group announcement before joining; describe your questions clearly and attach screenshots, and group friends will help when they're available.
> **Friendly reminder**:
> This project is open-source sharing, not a commercial product. Treat the author as a friend rather than customer service, and communication will be more efficient!
<div align="center">
| Public Account |
|:---:|
| <img src="_image/weixin.png" width="500" title="硅基茶水间"/> |
</div>
<br>
## 📝 Update Log
> **📌 Check the latest updates**: **[Original repository update log](https://github.com/sansan0/TrendRadar?tab=readme-ov-file#-更新日志)** :
- **Tips**: It's recommended to view the [historical updates] and clarify the specific [functional content].
### 2026/06/02 - v6.9.0
- **Hot List Domain Security Verification**: Added `expected_domain` configuration item to verify the legitimacy of the returned data link domain. If it doesn't match, the data is automatically discarded and a warning is issued, effectively preventing link hijacking or data tampering.
- **Custom Hot List API Address**: Supports self-deployed newsnow and configuring `api_url` to use your own data source.
### 2026/02/09 - mcp-v4.0.0
- **🔥 AI Message Push to All Channels**: Let AI-written content be pushed to 9 channels including Feishu, DingTalk, Telegram, and email with one click, and Markdown automatically adapts to each platform's format.
- **Added Formatting Strategy Guide**: Added `get_channel_format_guide` tool to tell AI what format each channel supports and what limitations there are, making the generated content more presentable.
- **Intelligent Batch Sending**: Long messages are automatically split according to each channel's byte limit (Feishu 30KB, DingTalk 20KB, etc.), and the configuration is read from config.yaml.
- **Fix Channel Misdetection**: ntfy is no longer misreported as "configured" due to the default address.
- **Code Reuse Optimization**: Batch processing functions directly reuse trendradar core modules, eliminating duplicate wheel creation.
<details>
<summary>👉 Click to expand: <strong>Historical Updates</strong></summary>
### 2026/05/23 - v6.8.0
- **HTML Report Comprehensive Enhancement**: Added report metadata display (generation time, data source, version number), dark mode automatic adaptation, tab bar interaction optimization, trend arrow visualization, and significantly improved browser reading experience.
- **Version Check CDN Multi-Source Fallback**: The version check interface supports multiple CDN sources (GitHub → jsDelivr → Cloudflare, etc.) to automatically fallback, and domestic network environments can also stably obtain update prompts.
- **Display Area Switch Takes Effect**: HTML reports and emails now correctly respect `display.regions.ai_analysis` and `display.regions.standalone` switches, and closing them will not render.
- **Export Button Fix**: Fix the issue where the export button dropdown menu icon disappears after clicking.
- **Markdown Export Fix**: Fix the JS line break character escape error in HTML report Markdown export.
### 2026/05/15 - v6.7.0
- **Markdown Export**: The report export dropdown menu adds Markdown format, with one-click generation of structured text with links, making it easy for LLM secondary processing and cross-platform sharing ([#1121](https://github.com/sansan0/TrendRadar/issues/1121))
- **RSS guid Deduplication**: RSS storage adds guid field, deduplication priority becomes guid > url, solving the problem of duplicate entry caused by URL changes.
- **Empty Title Protection**: Parser, rendering layer, and translation backfill add empty title bottom-line logic to ensure that items without titles can still be displayed normally.
- **Translation Quality Enhancement**: Translation prompt words require retention of sequence numbers, and empty translation results no longer overwrite original titles.
### 2026/03/28 - v6.6.0
- **HTML Report Browser Enhancement**: Opening the report in a browser can automatically switch to a wide-screen layout, and keyword grouping and independent display areas support quick tab switching. The search box filters news titles in real-time, and the 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 hovering over the news serial number can copy the title and link, making it easy to share.
- **Export Optimization**: The whole page screenshot and segmented screenshot merge into a drop-down export button, and the screenshot automatically restores a clean layout.
- **Shortcut System**: Supports `W` wide-screen switching, `D` dark mode switching, `/` search, and `?` shortcut prompt.
- **Reading Progress Bar**: The page top displays the reading progress in real-time.
### 2026/03/12 - v6.5.0
- **AI Intelligent Screening System**: No need to manually set keywords! Write your concerns in `ai_interests.txt` in daily language (e.g., "I want to see AI and new energy-related news"), and AI will automatically extract tags and score each news item, pushing only relevant content. If AI screening encounters issues, it will automatically switch back to keyword matching and push uninterrupted.
- **Different Screening Methods and Focus Directions for Each Period**: Each period in Timeline can independently set what screening method to use and what type of news to look at. For example: use "technology keywords" to filter quickly in the morning, and switch to "financial AI interest description" for in-depth screening in the evening - the same system, different content at different times.
- **AI Analysis Range Independent of Push**: The data range of AI analysis can be different from the push content. For example, push only adds new messages (to avoid repeated disturbance), but AI analyzes all news of the day (to see the complete trend). Each period can also set the AI analysis mode independently.
- **AI Screening Smart Save Money**: Analyzed news will not consume tokens repeatedly; after changing interest descriptions, AI automatically judges the change amplitude - small changes only update affected tags, and large changes require a full reclassification.
- **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 tags without interfering with each other.
- **AI Translation Precise Control**: Can control whether hot list, RSS, and independent display areas translate or not, and areas that are not displayed will automatically skip, saving tokens.
- **Remote Storage Batch Upload**: Multiple write operations are accumulated and submitted to the cloud at once, reducing API call times.
- **Keyword/Tag Display Quantity Limit**: Through `max_news_per_keyword` control the maximum number of news items displayed in each group, avoiding a single hot topic occupying the entire push.
- 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 support adding your own templates under `presets:`, as long as the key is not repeated, and then fill in your template name in config.yaml.
- **Flexible Time Period Configuration**: Support workday/weekend differences, cross-midnight time periods, per-period once deduplication.
- **Visual Configuration Editor**:
- Added `timeline.yaml` editing tab, parallel with config.yaml / frequency_words.txt.
- Preset mode card selection: click to switch, automatically synchronize config.yaml's `schedule.preset`.
- Weekly timeline view: 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 drop to complete the scheduling configuration.
- **AI Prompt Stability Optimization** (ai_analysis_prompt.txt v2.0.0):
- Format specification independent description: extract line breaks/tags/serial numbers/prohibited items from JSON value, as an independent chapter.
- JSON template simplification: field description shortened to one sentence + word count limit, reduce AI output format confusion.
- Remove Markdown format in system prompt, consistent with "prohibit Markdown" instruction.
- All JSON fields declared as optional, missing any field will not error, enhance fault tolerance.
- **New Independent Display Area AI Summary** (`ai_analysis.include_standalone`):
- New independent switch, after opening, AI generates core summary for each standalone source.
- AI analysis and push display decoupling: no need to open independent display area push display, AI can also independently analyze complete hot list data.
- Support hot list platform and RSS source, including ranking/time/track data.
- Track analysis and `include_rank_timeline` linkage: when turned on, use track data for in-depth trend analysis, when turned off, based on ranking for simple judgment.
- New `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, just put it together.
- Add trendradar's visual configuration editor.
### 2026/02/02 - mcp-v3.2.0
- **New read_article tool**: read a single article body through Jina AI Reader (Markdown format).
- **New read_articles_batch tool**: batch read multiple articles (up to 5, 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 add 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**: add 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**: add `make_cache_key()` function, parameter sorting + MD5 hash to ensure consistency.
- **New check_version tool**: support checking TrendRadar and MCP Server version updates at the same time.
### 2026/01/23 - v5.4.0
- Add AI analysis mode independent control function, optional follow_report | daily | current | incremental.
- Add AI analysis time window control, support custom running segment and daily frequency limit.
- Add configuration file version management function.
- Fix several bugs.
### 2026/01/19 - v5.3.0
> **Major refactoring: AI module migration to LiteLLM**
- **Unified AI interface**: use LiteLLM instead of manual implementation, support 100+ AI providers.
- **Simplify configuration**: remove `provider` field, use `model: "provider/model_name"` format.
- **New features**: automatic retry (`num_retries`), backup model (`fallback_models`).
- **Configuration change**:
- `ai.provider` → remove (merged into model).
- `ai.base_url` → `ai.api_base`.
- `AI_PROVIDER` environment variable → remove.
- `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**: support translating push content into any language.
- **Batch translation**: intelligent batch processing, reduce API call times.
- **Custom prompt words**: support custom translation style.
**🔧 Configuration Architecture Optimization**
- **AI model configuration independent**: analysis and translation share model configuration.
- **Area switch unified**: unified management of push area display.
- **Area sorting custom**: support custom display order of each area.
**✨ AI Analysis Enhanced**
- **AI analysis embedded HTML**: analysis results directly embedded into HTML report, email notification directly use.
- **Rich style AI block**: gradient blue background card layout, clear separation of each analysis dimension.
- **Ranking timeline support**: AI can obtain precise ranking of each news at each grab time point.
- **Section reorganization (7→4)**: integrate into core hot spot situation, public opinion trend controversy, abnormal and weak signal, and strategy suggestions.
**🔧 Multi-model Adaptation**
- **General parameter pass-through**: support passing arbitrary advanced parameters to API.
- **Gemini adaptation**: native parameter support, built-in security strategy relaxation.
**🐛 Bug Fix**
- Fix several known issues, improve system stability.
### 2026/01/10 - v5.0.0
> **Development episode**:
> Salute 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 refactors the push message into five major sections:
1. **📊 Hot List News**: accurate screening of hot spots after your keyword.
2. **📰 RSS Subscription**: your personalized subscription source content, support grouping by keyword.
3. **🆕 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 **very important** sentiment analysis.
**✨ AI Intelligent Analysis Push Function**
- **AI analysis integration**: use large AI 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**: add in-depth sentiment recognition, accurately capture public opinion's positive, negative, controversy or worry emotion.
- **Multi-AI provider support**: support 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 the specified platform, not affected by keyword filtering.
- **RSS independent display**: RSS source content can be displayed completely, suitable for content less subscription source.
- **Flexible configuration**: support configuration display platform list, RSS source list, maximum display number.
**📊 Push Experience Refactor**
- **Typesetting upgrade**: redesign and unify statistical header of each channel, strengthen block organization, message level clear at a glance.
- **Configuration simplification**: optimize configuration logic of notification channels like Feishu, make it easier to get started.
- **Heat trend arrow**: add 🔺 (up), 🔻 (down), ➖ (flat) trend mark, intuitively display heat change.
- **General Webhook**: support custom Webhook URL and JSON template, easily adapt to Discord, Matrix, IFTTT and other platforms.
**🔧 Configuration Optimization**
- **Frequency word configuration enhancement**: add `[group name]` syntax, support `#` comment line, configuration clearer (thanks to [@songge8](https://github.com/sansan0/TrendRadar/issues/752) proposed suggestions).
- **Environment variable support**: AI analysis related configuration support environment variable coverage (`AI_API_KEY`, `AI_PROVIDER`, etc.).
> 💡 See detailed configuration tutorial in [让 AI 帮我分析热点](#12-让-ai-帮我分析热点)
### 2026/01/02 - v4.7.0
- **Fix RSS HTML display**: fix RSS data format mismatch causing rendering issue, now display correctly grouped by keyword.
- **Add regular expression syntax**: keyword configuration supports `/pattern/` regular expression syntax, solve English substring mis-matching problem (e.g., `ai` matches `training`).
- **Add display name syntax**: use `=> remark` to give complex regular expression a memorable name, push message display clearer (e.g., `/\bai\b/ => AI-related`).
- **No regular expression?** README adds 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 use SQLite database.
- **RSS query**: add `get_latest_rss`, `search_rss`, `get_rss_feeds_status`.
- **Unified search**: `search_news` support `include_rss` parameter to search hot list and RSS.
### 2026/01/01 - v4.6.0
- **Fix RSS HTML display**: merge RSS content into hot list HTML page, display grouped by source.
- **Add display_mode configuration**: support `keyword` (grouped by keyword) and `platform` (grouped by platform) two display modes.
### 2025/12/30 - v4.5.0
- **RSS subscription source support**: add RSS/Atom capture, grouped by keyword statistics (consistent with hot list format).
- **Storage structure refactoring**: flatten directory structure `output/{type}/{date}.db`.
- **Unified sorting configuration**: `sort_by_position_first` simultaneously affect hot list and RSS.
- **Configuration structure refactoring**: `config.yaml` reorganized into 7 logical groups (app, report, notification, storage, platforms, rss, advanced), configuration path clearer.
### 2025/12/26 - mcp-v1.2.0
**MCP module update - optimize toolset, add aggregation comparison function, merge redundant tools:**
- Add `aggregate_news` tool - cross-platform news deduplication aggregation.
- Add `compare_periods` tool - period comparison analysis (weekly/monthly comparison).
- Merge `find_similar_news` + `search_related_news_history` → `find_related_news`.
- Enhance `get_trending_topics` - add `auto_extract` mode automatically extract hot spots.
- Fix several bugs.
- Synchronously update README-MCP-FAQ.md document's Chinese and English version (Q1-Q18).
### 2025/12/20 - v4.0.3
- Add URL standardization function, solve duplicate push problem caused by dynamic parameters (e.g., `band_rank`) on some platforms.
- Fix incremental mode detection logic, correctly identify historical titles.
### 2025/12/17 - v4.0.1
- StorageManager add push record proxy method.
- S3 client switch to virtual-hosted style to improve compatibility (support 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.
- Add 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**: introduce new storage module, support 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 policy, time zone configuration support, time display optimization, and fix remote storage data persistence problem, ensure data merge accuracy.
- **Cleanup and compatibility**: remove most historical compatibility code, unify 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 keyword**
- Add `[GLOBAL_FILTER]` area mark, support global filter 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 in Docker environment.
- **Double-path generation**: generate today's summary HTML to 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 version report.
**🐳 Docker MCP image support**
- Add independent MCP service image `wantcat/trendradar-mcp`.
- Support Docker deployment AI analysis function through HTTP interface (port 3333) provide service.
- Double-container architecture: news push service and MCP service run independently, can expand and restart separately.
- See [Docker deployment - MCP service](#6-docker-部署).
**🌐 Web server support**
- Add built-in web server, support access 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: static file service, directory limit, local access.
- Support automatic start and manual control two modes.
**📖 Document optimization**
- Add [How to display push content?](#7-how-to-display-push-content) section: customize push style and content.
- Add [When will I get push?](#8-when-will-i-get-push-content) section: set push time period.
- Add [How often run?](#9-how-often-run) section: set automatic run frequency.
- Add [Push to multiple groups/devices](#10-push-to-multiple-groupsdevices) section: push to multiple receivers.
- Optimize each configuration section: add "configuration location" description.
- Simplify quick start configuration: three core files at a glance.
- Optimize [Docker deployment](#6-docker-部署) section: add image description, recommend git clone deployment, reorganize deployment method.
**🔧 Upgrade note**:
- **GitHub Fork user**: update `main.py`, `config.yaml` (add multi-account push support, no need to modify existing configuration).
- **Multi-account push**: new function, default not enabled, existing single account configuration not affected.
### 2025/11/25 - v3.4.0
**🎉 New Slack Push Support**
1. **Team Collaboration Push Channel**
- Support for Slack Incoming Webhooks (a popular team collaboration tool globally)
- Centralized message management, suitable for teams to share hot news
- Support for mrkdwn format (bold, links, etc.)
2. **Multiple Deployment Methods**
- GitHub Actions: Configure `SLACK_WEBHOOK_URL` Secret
- Docker: Environment variable `SLACK_WEBHOOK_URL`
- Local Run: `config/config.yaml` configuration file
> 📖 **Detailed Configuration Tutorial**: [Quick Start - Slack Push](#-quick-start)
- Optimized setup-windows.bat and setup-windows-en.bat for a better one-click installation experience for MCP
**🔧 Upgrade Instructions**:
- **GitHub Fork Users**: Update `main.py`, `config/config.yaml`, `.github/workflows/crawler.yml`
### 2025/11/24 - v3.3.0
**🎉 New Bark Push Support**
1. **iOS Exclusive Push Channel**
- Support for Bark push (based on APNs, iOS platform)
- Free, open-source, efficient, and ad-free
- Support for official servers and self-built servers
2. **Multiple Deployment Methods**
- GitHub Actions: Configure `BARK_URL` Secret
- Docker: Environment variable `BARK_URL`
- Local Run: `config/config.yaml` configuration file
> 📖 **Detailed Configuration Tutorial**: [Quick Start - Bark Push](#-quick-start)
**🐛 Bug Fixes**
- Fixed the issue where `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
**🎯 New Advanced Customization Features**
1. **Keyword Sorting Priority Configuration**
- Support for two sorting strategies: heat priority vs. configuration order priority
- Meet different usage scenarios: hot spot tracking or personalized focus
2. **Precise Control of Display Quantity**
- Global configuration: uniformly limit the display quantity of all keywords
- Individual configuration: use `@number` syntax to set limits for specific keywords
- Effectively control push length 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 query for today's news to avoid incorrect returns of past dates
### 2025/11/22 - v3.1.1
- **Fixed Data Exception Leading to Crash**: Solved the `'float' object has no attribute 'lower'` error encountered by some users in the GitHub Actions environment
- Added dual protection mechanism: filter invalid titles (None, float, empty string) during data acquisition, and add type checking at function calls
- Improved system stability to ensure normal operation even when data sources return abnormal formats
**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
- **New Personal WeChat Push Support**: Enterprise WeChat applications can push to personal WeChat without installing the Enterprise WeChat app
- Support for two message formats: `markdown` (Enterprise WeChat group robot) and `text` (personal WeChat application)
- Added `WEWORK_MSG_TYPE` environment variable configuration, supporting GitHub Actions, Docker, docker compose, and other deployment methods
- `text` mode automatically clears Markdown syntax to provide pure text push effect
- See the "Personal WeChat Push" configuration instructions in the Quick Start
**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 logic 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 overriding through environment variables, solving the issue of NAS users' configuration file modifications not taking effect (see [🐳 Docker Deployment](#-docker-deployment) chapter)
### 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 due to push content being too long, and implemented batch push
### 2025/10/23 - v3.0.3
- Expanded ntfy error message 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)
- Support for 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, hot spot detection, trend prediction)
- Data insights (platform comparison, activity statistics, keyword co-occurrence)
- Sentiment analysis, similar news search, intelligent summary generation
- Historical related news retrieval, multi-mode search
- **Update Tips**:
- This is an independent AI analysis function, not affecting existing push functions
- Optional use, no need to upgrade existing deployment
### 2025/10/15 - v2.4.4
- **Update Content**:
- Fixed ntfy push encoding issue + 1
- Fixed push time window judgment issue
- **Update Tips**:
- 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
- Clarified push time window as an optional additional function, can be used with three push modes
- Improved comments and document descriptions for clearer functional positioning
- **Update Tips**:
- 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 Tips**:
- Recommended to use 【major version update】
### 2025/10/2 - v2.4.0
**New ntfy Push Notification**
- **Core Features**:
- Support for ntfy.sh public service and self-hosted server
- **Usage Scenarios**:
- Suitable for users pursuing privacy (support self-hosting)
- Cross-platform push (iOS, Android, Desktop, Web)
- No need for account registration (public server)
- Open-source and free (MIT protocol)
- **Update Tips**:
- Recommended to use 【major version update】
### 2025/09/26 - v2.3.2
- Corrected the email notification configuration check being missed ([#88](https://github.com/sansan0/TrendRadar/issues/88))
**Fix Description**:
- Solved the issue where even with correct email notification configuration, the system still prompts "no webhook configured"
### 2025/09/22 - v2.3.1
- **New Email Push Function**: support sending hot news reports to email
- **Intelligent SMTP Identification**: automatically identify Gmail, QQ email, Outlook, NetEase email, and over 10 other email service providers' configurations
- **HTML Format**: email content uses the same HTML format as the web version, with beautiful layout and mobile-end adaptation
- **Batch Sending Support**: support multiple recipients, separated by commas
- **Custom SMTP**: allow custom SMTP server and port
- Fixed Docker build network connection issue
**Usage Instructions**:
- Applicable scenarios: suitable for users needing email archiving, team sharing, and timing reports
- Supported email: Gmail, QQ email, Outlook/Hotmail, 163/126 email, Sina email, Sohu email, etc.
**Update Tips**:
- This update has significant changes, recommended to use 【major version upgrade】
### 2025/09/17 - v2.2.0
- Added one-click save news image function, making it easy to share hot spots
**Usage Instructions**:
- Applicable scenarios: when you enable the web version function (GitHub Pages)
- Usage method: open the web link on your mobile or computer, click the "Save as Image" button at the top of the page
- Actual effect: the system will automatically create a beautiful image of the current news report and save it to your mobile album or computer desktop
- Sharing convenience: you can directly share the image with friends, post it on your friend circle, or share it to your work group
### 2025/09/13 - v2.1.2
- Solved the DingTalk push capacity limit issue leading to news push failure (using batch push)
### 2025/09/04 - v2.1.1
- Fixed the issue where Docker cannot run normally on certain architectures
- Officially released the official Docker image wantcat/trendradar, supporting multi-architecture
- 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 "each execution pushes" to "controllable push within a time window"
- **Time Window Control**: can set push time range to avoid disturbing during non-working hours
- **Push Frequency Optional**: support single push or multiple pushes within a time segment
**Update Tips**:
- This function is disabled by default, need to manually enable in config.yaml
- Upgrade requires updating main.py and config.yaml files
### 2025/08/27 - v2.0.4
- This version is not a functional fix but an important reminder
- Please properly keep webhooks secure, do not expose them publicly, and do not fill them in config.yaml
- If you have exposed webhooks or filled them in config.yaml, suggest deleting and regenerating
### 2025/08/06 - v2.0.3
- Optimized GitHub page web version effect for better mobile usage
### 2025/07/28 - v2.0.2
- Refactored code
- Solved the issue of version number being easily missed and modified
### 2025/07/27 - v2.0.1
**Fix Issues**:
1. Docker shell script execution exception due to CRLF line ending
2. frequency_words.txt being empty leads to news sending being empty logic issue
- Fixed, when frequency_words.txt is empty, will **push all news**, but limited by message push size restrictions, please make adjustments as follows
- Scheme 1: close mobile push, only choose GitHub Pages deployment (this is the best scheme to get complete information, will reorder hot spots according to your **custom hot search algorithm**)
- Scheme 2: reduce push platforms, prioritize **WeChat** or **Telegram**, these two push have batch push functions (because batch push affects push experience, and only these two platforms have limited push capacity, so had to do batch push function, but at least ensure complete information)
- 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 now managed through `config/config.yaml` file (main.py not split, for easy copying and upgrading)
- Operation mode upgrade: support three modes - `daily` (daily summary), `current` (current ranking), `incremental` (incremental monitoring)
- Docker support: complete Docker deployment solution, support containerized operation
**Configuration File Description**:
- `config/config.yaml` - main configuration file (application settings, crawler configuration, notification configuration, platform configuration, etc.)
- `config/frequency_words.txt` - keyword configuration (monitoring vocabulary settings)
### 2025/07/09 - v1.4.1
**New Feature**: added incremental push (configured FOCUS_NEW_ONLY at the beginning of main.py), this switch only cares about new topics rather than continuous heat, only sends notifications when new content is available.
**Fix Issues**: certain situations where news itself contains special symbols lead to occasional layout anomalies.
### 2025/06/23 - v1.3.0
WeChat and Telegram push message have length limits, so I use message splitting and push method. See documentation for [WeChat](https://developer.work.weixin.qq.com/document/path/91770) and [Telegram](https://core.telegram.org/bots/api)
### 2025/06/21 - v1.2.1
Before this version, old versions not only require main.py to be copied and replaced, but also crawler.yml 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 platform APIs, allowing me to quickly complete platform adaptations (although the code is redundant~
1. Support Telegram, WeChat, DingTalk push channels, support multi-channel configuration and simultaneous push
### 2025/06/18 - v1.1.0
> **200 star⭐**, continue to help~ Recent, under my "encouragement", many people star and share recommendations on my public account, I can see specific account encouragement data, many became angel wheel old powder (I play public account for over a year, although registered seven or eight years ago, belong to early car, late departure), but because you did not leave a message or private message me, so I also cannot respond and thank support, hereby thank you all!
1. Important update, added weight, you now see the news are the hottest and most concerned at the top
2. Update documentation usage, because recent updates many functions, and previous documentation I lazy wrote simple (see below ⚙️ frequency_words.txt configuration complete tutorial)
### 2025/06/16 - v1.0.0
1. Added a project new version update prompt, default open, if you want to turn it off, you can change True to False in main.py
### 2025/06/13+14
1. Removed compatible code, previous fork classmates, direct copy code will display abnormal on that day (the second day will return to normal)
2. feishu and html bottom add a new news display
### 2025/06/09
**100 star⭐**, write a small function for everyone to help~
frequency_words.txt file added a **must-have word** function, use + sign
1. Must-have word syntax:
Tang Seng or Zhu Bajie must appear in the title at the same time, will be included in push news
```
+ Tang Seng
+ Zhu Bajie```
2. Filter words have higher priority:
If the title filter words match Tang Seng chant, even if must-have words include Tang Seng, it will not display
```
+ Tang Seng
! Tang Seng chant```
### 2025/06/02
1. **Web** and **Feishu message** support mobile direct jump to news details
2. Optimize display effect + 1
### 2025/05/26
1. Feishu message display effect optimization
<table>
<tr>
<td align="center">
Before optimization<br>
<img src="_image/before.jpg" alt="Feishu message interface - before optimization" width="400"/>
</td>
<td align="center">
After optimization<br>
<img src="_image/after.jpg" alt="Feishu message interface - after optimization" width="400"/>
</td>
</tr>
</table>
</details>
<br>
## ✨ Core Function
### **Global Hot Spot Aggregation**
- Zhihu
- Douyin
- Bilibili hot search
- Wall Street Journal
- Tieba
- Baidu hot search
- Cai Lian She hot
- Pengpai News
- Phoenix.com
- Today`s Headlines
- Weibo
Default monitoring 11 mainstream platforms, can also add additional platforms
> 💡 See detailed configuration tutorial [Configuration Details - Platform Configuration](#1-platform-configuration)
### **RSS Feed Support** (v4.5.0 added)
Support RSS/Atom feed capture, grouped by keywords (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`
- **Merge push**: hot list and RSS merge into one message push
- **Freshness filter**: automatically filter old articles exceeding specified days, avoid duplicate push. Support global default days and single source independent settings
> 💡 RSS uses the same `frequency_words.txt` for keyword filtering
**Visual Configuration Editor**
Provide web-based graphical configuration interface, no need to manually edit YAML files, all configuration items can be modified and exported through 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** (daily) | Enterprise managers/ordinary users | Pushes all matching news for the day (including previously pushed) on schedule |
| **Current Hotlist** (current) | Self-media people/content creators | Pushes current hotlist matching news on schedule (continuously on the list appear every time) |
| **Incremental Monitoring** (incremental) | Investors/traders | Only pushes new content, zero repetition |
> 💡 **Quick Selection Guide:**
> - Don't want to see duplicate news → Use `incremental` (Incremental Monitoring)
> - Want to see the complete hotlist trend → Use `current` (Current Hotlist)
> - Need 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: allocate 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**, achieving 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 differentiation,跨午夜时段, per-period去重, time period conflict detection (v6.0.0 + v6.5.0) | morning_evening |
| **Content Order Configuration** | Adjust the display order of each area (hotlist, new hotspots, 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 keywords, `platform`=grouped by platform (added in v4.6.0) | keyword |
> 💡 For detailed configuration tutorials, see [How to Display Pushed Content](#7-how-to-display-pushed-content) and [When to Push](#8-when-to-push)
### **Accurate Content Filtering**
Set personal keywords (e.g., AI, BYD, education policy) to only push relevant hotspots and filter out unrelated information
> 💡 **Basic Configuration Tutorial**: [Keyword Configuration - Basic Syntax](#keyword-basic-syntax)
>
> 💡 **Advanced Configuration Tutorial**: [Keyword Configuration - Advanced Configuration](#keyword-advanced-configuration)
>
> 💡 You can also choose not to filter and push all hotspots (leave frequency_words.txt empty)
### **AI Smart News Filtering** (added in v6.5.0)
Use natural language to describe your interests, and AI automatically classifies news, replacing traditional keyword matching
- **Natural Language Interest Description**: Write your focus directions in `ai_interests.txt` in daily language, without needing to learn keyword syntax
- **Two-Stage Intelligent Processing**: AI extracts structured labels from interest descriptions and then batch classifies and scores news by labels
- **Score Threshold Control**: Precisely control push quality through `ai_filter.min_score`, only pushing high-correlation news
- **Automatic Fallback Guarantee**: Automatically fall back to keyword matching if AI filtering fails, ensuring uninterrupted pushes
- **Intelligent Label Update**: AI automatically evaluates the magnitude of changes when interests change and decides incremental or full reclassification
- **Flexible Switching**: `filter.method` supports `keyword` (default) and `ai` modes, and 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 "tech 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 filtering shares model configuration with AI analysis/translation, just configure `ai.api_key` once
### **Hotspot Trend Analysis**
Real-time tracking of news heat changes, letting you know not only "what's trending" but also "how trends evolve"
- **Time Axis Tracking**: Record the complete time span of each piece of news from its first appearance to its last appearance
- **Heat Change**: Statistics on news ranking changes and appearance frequency in different time periods
- **New Detection**: Real-time identification of new hotspots with 🆕 marking the first time to remind
- **Sustainability Analysis**: Distinguish between one-time hotspots and continuously fermenting in-depth news
- **Cross-Platform Comparison**: Compare the ranking performance of the same news on different platforms to see differences in media attention
> 💡 For push format descriptions, see [Message Style Description](#5-message-style-description)
### **Personalized Hotspot Algorithm**
No longer be led by algorithms from various platforms; TrendRadar will reorganize the entire network's hot searches
> 💡 Three ratios can be adjusted, see [Configuration Details - Hotspot Weight Adjustment](#4-hotspot-weight-adjustment)
### **Multi-Channel and Multi-Account Push**
Supports **WeChat** (+ WeChat push solution), **Feishu**, **DingTalk**, **Telegram**, **Email**, **ntfy**, **Bark**, **Slack**, **Universal Webhook** (can connect to Discord, IFTTT, etc.), messages directly to 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 pushed content into any language, breaking language barriers, whether reading domestic hotspots or subscribing to overseas information through RSS
- **One-Click Translation**: Set `ai_translation.enabled: true` and target language in `config.yaml`
- **Multi-Language Support**: Supports English, Korean, Japanese, French, and any other language
- **Intelligent Batch Processing**: Automatically batch translate to reduce API call times and save costs
- **Custom Style**: Customize translation style and terminology through `ai_translation_prompt.txt`
- **Shared Model Configuration**: Share model settings with AI analysis function using the `ai` configuration section
```yaml
# config.yaml quick enable example
ai_translation:
enabled: true
language: "English" # target language for translation
```
> 💡 Translation function shares model configuration with AI analysis function, just configure `ai.api_key` once to use both functions
**RSS Source Reference**: Here are some RSS subscription source collections that can be used 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 around the world
> ⚠️ Some overseas media content may involve sensitive topics; AI models may refuse to translate, and it is recommended to filter subscription sources according to actual needs
### **HTML Report Browser Enhancement** (added in v6.6.0)
Open the pushed HTML report in a browser to automatically unlock an enhanced experience (email clients are not affected):
- **Wide-Screen Mode**: Automatically switch to 1200px wide-screen layout on desktop to make full use of screen space
- **Tab Quick Switch**: Both keyword grouping and independent display areas support Tab navigation, eliminating the need to scroll through long pages
- **Dark Mode**: One-click switch to dark theme, automatically remembering preferences
- **Real-Time Search**: Press `/` to bring up the search box and instantly filter news titles
- **One-Click Copy**: Hover over news serial numbers to copy titles and links
- **Shortcuts**: `W` for wide-screen, `D` for dark mode, `/` for search, `?` for viewing all shortcuts
> 💡 All enhancements are based on progressive enhancement; 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**: Default for GitHub Actions environment, supports S3 compatible protocol (R2/OSS/COS, etc.), data stored in the cloud, not polluting the repository
- **Local SQLite Database**: Default for Docker/local environment, data completely controllable
- **Automatic Backend Selection**: Intelligent switching of storage methods based on the running environment
> 💡 For detailed descriptions, see [Where is data stored?](#11-where-is-data-stored)
### **Multi-Platform Deployment**
- **GitHub Actions**: Automatic crawling + remote cloud storage (requires sign-in renewal)
- **Docker Deployment**: Supports multi-architecture containerized operation, data stored locally
- **Local Operation**: Direct operation on Windows/Mac/Linux
### **AI Analysis and Push** (added in v5.0.0)
Use large AI models to conduct in-depth analysis of pushed content and automatically generate hotspot insight reports
- **Intelligent Analysis**: Automatically analyze hotspot trends, keyword heat, cross-platform associations, and potential impacts
- **Multi-Provider**: Based on the LiteLLM unified interface, supports 100+ AI providers (DeepSeek, OpenAI, Gemini, Anthropic, local Ollama, etc.), also supports automatic switching of backup models
- **Independent Analysis Mode**: AI's analysis scope can be different from pushes - pushes only send new messages (to avoid disturbance), but AI can analyze all news for the day (to see the complete trend)
- **Flexible Push**: Optional to push only raw 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)
Provides complete hotspot display for specified platforms, unaffected by keyword filtering
- **Complete Hotlist**: Complete display of the specified platform's hotlist, suitable for users who want to see the complete ranking
- **RSS Independent Display**: Complete display of RSS source content, unaffected by keywords
- **AI In-Depth Analysis**: Can independently enable AI to analyze the complete hotlist trend, without needing to display in pushes
- **Flexible Configuration**: Supports configuration of display platforms, RSS sources, and maximum number of entries
> 💡 For detailed configuration tutorials, see [How to Display Pushed Content - Independent Display Area](#7-how-to-display-pushed-content)
### **AI Intelligent Analysis** (added in v3.0.0)
AI dialogue analysis system based on the MCP (Model Context Protocol) protocol, allowing you to deeply mine news data using natural language
> **💡 Usage Tips**: AI functionality requires local news data support
> - The project comes with test data, allowing immediate experience of the functionality
> - 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
### **Web Deployment**
After running, the root directory generates `index.html`, 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.
>
> **💡 Tip**: Enabling GitHub Pages will obtain an online access address; go to 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 high server load on GitHub, affecting platform stability).
### **Reduce APP Dependence**
From being "controlled by algorithm recommendations" to "actively obtaining the information you want"
**Suitable人群**: Investors, self-media people, enterprise public relations, ordinary users concerned about current events
**Typical Scenarios**: Stock investment monitoring, brand public opinion tracking, industry dynamics attention, life information acquisition
| Web 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)** first to ensure configuration steps are up-to-date.
### Please Choose a Deployment Method That Suits You
#### 🅰️ Option 1: Docker Deployment (Recommended 🔥)
* **Characteristics**: More stable than GitHub Actions, data stored locally (no need to configure cloud storage)
* **Applicable**: For those with their own servers, NAS, or long-running computers
* **Note**: You need to read and understand the basic configuration process below, then jump to the Docker tutorial for deployment.
#### 🅱️ Option 2: GitHub Actions Deployment (content of this chapter ⬇️)
* **Characteristics**: Serverless, data stored in **remote cloud storage** (recommended configuration)
* **Applicable**: For users without servers, utilizing GitHub free resources
* **Note**: Cloud storage needs to be configured for a complete experience, and periodic sign-in renewal is required
### 1️⃣ Step 1: Obtain Project Code
Click the green **[Use this template]** button in the top right corner of this repository page → Select "Create a new repository".
> ⚠️ Reminder:
> - Subsequent documentation mentions "Fork" which can be understood as "Use this template"
> - Using Fork may lead to operational exceptions, see [Issue #606](https://github.com/sansan0/TrendRadar/issues/606) for details
<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, when you re-edit after saving, you can only see the Name (name) and not the content of the Secret (value).
- **Do not create names arbitrarily**: The Name (name) of the Secret must **strictly use** the names listed below (such as `WEWORK_WEBHOOK_URL`, `FEISHU_WEBHOOK_URL`, etc.), and cannot be modified or created randomly, otherwise the system cannot identify it.
- **Multiple platforms can be configured at the same time**: 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 (such as `WEWORK_WEBHOOK_URL`).
- **Secret**: Fill in the actual content you obtained from the corresponding platform (such as Webhook address, Token, etc.).
<br>
<details>
<summary>👉 Click to expand: <strong>WeWork Robot</strong> (easiest and quickest configuration)</summary>
<br>
**GitHub Secret Configuration (⚠️ Name must be consistent):**
- **Name**: `WEWORK_WEBHOOK_URL` (please copy and paste this name, don't type it manually)
- **Secret**: Your WeWork robot Webhook address
<br>
**Robot Setting Steps:**
#### Mobile Setting:
1. Open WeWork App → Enter the target internal group chat
2. Click the "…" button in the upper right corner → Select "Message Push"
3. Click "Add" → Enter "TrendRadar"
4. Copy the Webhook address, click Save, and copy the content to configure to the GitHub Secret above
#### PC Setting Process is Similar
</details>
<details>
<summary>👉 Click to expand: <strong>Personal WeChat Push</strong> (based on WeWork application, push to personal WeChat)</summary>
<br>
> Since this solution is based on the plugin mechanism of WeWork, the push style is plain text (without markdown format), but it can be pushed directly to personal WeChat without installing WeWork 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 WeWork application Webhook address
- **Name**: `WEWORK_MSG_TYPE` (please copy and paste this name, don't type it manually)
- **Secret**: `text`
<br>
**Setting Steps:**
1. Complete the WeWork robot Webhook setting above
2. Add `WEWORK_MSG_TYPE` Secret, set the value to `text`
3. Follow the picture below to operate and associate personal WeChat
4. After configuration, the WeWork App on the mobile phone can be deleted
<img src="_image/wework.png" title="Personal WeChat Push Configuration"/>
**Description**:
- Use the same Webhook address as WeWork robot
- The difference lies in the message format: `text` is plain text, `markdown` is rich text (default)
- Plain text format will automatically remove all markdown syntax (bold, link, etc.)
</details>
<details>
<summary>👉 Click to expand: <strong>Feishu Robot</strong> (message display is relatively friendly)</summary>
<br>
If **AI Analysis** is enabled, Feishu push may occasionally (about 5% probability) have a delay of several minutes (speculated to be the platform's compliance audit for 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 robot Webhook address (the link starts with https://www.feishu.cn/flow/api/trigger-webhook/********)
<br>
There are two schemes, **Scheme 1** is simple to configure, and **Scheme 2** is complex (but stable push).
Among them, Scheme 1 was discovered and suggested by **ziventian**, thanks to him, it is a personal push by default, and you can also configure group push operation [#97](https://github.com/sansan0/TrendRadar/issues/97),
**Scheme 1:**
> For some people, there are additional operations, otherwise it will report "system error". You need to search for the robot on your mobile phone and then enable the Feishu robot application (this suggestion comes from netizens, you can refer to it)
1. Open https://botbuilder.feishu.cn/home/my-command in your computer browser
2. Click "New Robot Command"
3. Click "Select Trigger", scroll down, and click "Webhook Trigger"
4. You will see the "Webhook Address", copy this link to a local notepad for temporary storage, and continue with the next operation
5. Put the following content in "Parameter" and click "Complete"
```json
{
"message_type": "text",
"content": {
"text": "{{content}}"
}
}
```
6. Click "Select Operation" > "Send Message through Official Robot"
7. Fill in the message title as "TrendRadar Hotspot Monitoring"
8. The key part is, click the + button, select "Webhook Trigger", and arrange according to the picture below

9. After configuration, copy the Webhook address in step 4 to the `FEISHU_WEBHOOK_URL` in GitHub Secrets
<br>
**Scheme 2:**
1. Open https://botbuilder.feishu.cn/home/my-app in your computer browser
2. Click "New Robot Application"
3. After entering the created application, click "Process Design" > "Create Process" > "Select Trigger"
4. Scroll down and click "Webhook Trigger"
5. You will see the "Webhook Address", copy this link to a local notepad for temporary storage, and continue with the next operation
6. Put the following content in "Parameter" and click "Complete"
```json
{
"message_type": "text",
"content": {
"text": "{{content}}"
}
}
```
7. Click "Select Operation" > "Send Feishu Message", select "Group Message", and click the input box below, click "My Managed Groups" (if you don't have a group, you can create a group on Feishu App)
8. Fill in the message title as "TrendRadar Hotspot Monitoring"
9. The key part is, click the + button, select "Webhook Trigger", and arrange according to the picture below

10. After configuration, copy the Webhook address in step 5 to the `FEISHU_WEBHOOK_URL` in GitHub Secrets
</details>
<details>
<summary>👉 Click to expand: <strong>DingTalk Robot</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 robot Webhook address
<br>
**Robot Setting Steps:**
1. **Create Robot (only PC supports)**:
- Open DingTalk PC client, enter the target group chat
- Click the group setting icon (⚙️) → find "Robot" and open it
- Select "Add Robot" → "Custom"
2. **Configure Robot**:
- Set robot name
- **Security Settings**:
- **Custom Keywords**: Set "hotspot"
3. **Complete Settings**:
- Check the service terms agreement → Click "Complete"
- Copy the obtained Webhook URL
- Configure the URL to `DINGTALK_WEBHOOK_URL` in GitHub Secrets
**Note**: Mobile can only receive messages, cannot create new robots.
</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
**Description**: Telegram needs to configure **two** Secrets, please click the "New repository secret" button twice to add
<br>
**Robot Setting Steps:**
1. **Create Robot**:
- Search for `@BotFather` in Telegram (pay attention to case, with blue badge, with about 37849827 monthly users, this is the official one, some fake official accounts please distinguish)
- Send `/newbot` command to create a new robot
- Set robot name (must end with "bot", it is easy to encounter duplicate names, so you have to think of different names)
- Get Bot Token (format like: `123456789:AAHfiqksKZ8WmR2zSjiQ7_v4TMAKdiHm9T0`)
2. **Get Chat ID**:
**Method 1: Get through official API**
- Send a message to your robot
- Visit: `https://api.telegram.org/bot<YourBotToken>/getUpdates`
- Find the number in `"chat":{"id":number}` in the returned JSON
**Method 2: Use third-party tools**
- 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> (support all mainstream email)</summary>
<br>
- Precautions: To prevent the email group sending function from being **abused**, the current group sending is that all recipients can see each other's email addresses.
- If you have not configured the email sending experience below, it is not recommended to try
> ⚠️ **Important Configuration Dependency**: Email push requires HTML report file. Please ensure that `storage.formats.html` in `config/config.yaml` is set to `true`:
> ```yaml
> storage:
> formats:
> sqlite: true
> txt: false
> html: true # Must be enabled, otherwise email push will fail
> ```
> If set to `false`, 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 are 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)
**Description**: 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, no need to manually configure `EMAIL_SMTP_SERVER` and `EMAIL_SMTP_PORT`, the system will automatically identify.
>
> **Feedback Description**:
> - If you test successfully with **other email**, welcome to open [Issues](https://github.com/sansan0/TrendRadar/issues) to inform, 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 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-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 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 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 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 letters)
4. Fill in authorization code in `EMAIL_PASSWORD`, not QQ password
#### Gmail:
1. Enable two-step verification
2. Generate app-specific password
3. Fill in app-specific password in `EMAIL_PASSWORD`
#### 163/126 Mail:
1. Log in to web version → Settings → POP3/SMTP/IMAP
2. Enable SMTP service
3. Set client authorization code
4. Fill in authorization code in `EMAIL_PASSWORD`
<br>
**Advanced Configuration**:
If automatic identification fails, you can manually configure SMTP:
- `EMAIL_SMTP_SERVER`: such as smtp.gmail.com
- `EMAIL_SMTP_PORT`: such as 587 (TLS) or 465 (SSL)
<br>
**If there are multiple recipients (note separated by English commas)**:
- EMAIL_TO="user1@example.com,user2@example.com,user3@example.com"
</details>
<details>
<summary>👉 Click to expand: <strong>ntfy Push</strong> (open source and free, support self-hosting)</summary>
<br>
**Two Usage Methods:**
### Method 1: Free Use (Recommended for Novices) 🆓
**Features**:
- ✅ No need to register an account, use immediately
- ✅ 250 messages per day (enough for 90% users)
- ✅ Topic name is "password" (need to choose a name that is not easy to guess)
- ⚠️ Messages are not encrypted, not suitable for sensitive information, but suitable for non-sensitive information in this project
## Tool List
**Quick Start:**
1. **Download ntfy app**:
- Android: [Google Play](https://play.google.com/store/apps/details?id=io.heckel.ntfy) / [F-Droid](https://f-droid.org/en/packages/io.heckel.ntfy/)
- iOS: [App Store](https://apps.apple.com/us/app/ntfy/id1625396347)
- Desktop: Visit [ntfy.sh](https://ntfy.sh)
2. **Subscribe to a topic** (choose a hard-to-guess name):
```
Suggested format: trendradar-{your initials}-{random number}
No Chinese characters allowed
✅ Good example: trendradar-zs-8492
❌ Bad example: news, alerts (too easy to guess)
```
3. **Configure GitHub Secret (⚠️ Name must match exactly)**:
- **Name**: `NTFY_TOPIC` (copy and paste this name)
- **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 skills
**Advantages**:
- ✅ Completely open-source (Apache 2.0 + GPLv2)
- ✅ Data completely under your control
- ✅ No restrictions
- ✅ Zero cost
**One-click Docker deployment**:
```bash
docker run -d \
--name ntfy \
-p 80:80 \
-v /var/cache/ntfy:/var/cache/ntfy \
binwiederhier/ntfy \
serve --cache-file /var/cache/ntfy/cache.db
```
**Configure TrendRadar**:
```yaml
NTFY_SERVER_URL: https://ntfy.yourdomain.com
NTFY_TOPIC: trendradar-alerts # Simple name available for self-hosting
NTFY_TOKEN: tk_your_token # Optional: enable access control
```
**Subscribe in the app**:
- Click "Use another server"
- Enter your server address
- Enter the topic name
- (Optional) Enter login credentials
---
**Frequently Asked Questions:**
<details>
<summary><strong>Q1: Is the free version enough?</strong></summary>
250 messages per day are sufficient for most users. Assuming 30 minutes per fetch, there are approximately 48 pushes per day, which is more than enough.
</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 attacks are almost impossible:
- ntfy has strict rate limiting (1 request per second)
- 64 character choices (A-Z, a-z, 0-9, _, -)
- 10 random 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 |
| Technical users | Method 2 (self-hosting) | Complete control, no restrictions |
| High-frequency users | Method 3 (paid) | Check the official website for this |
**Related links**:
- [ntfy official documentation](https://docs.ntfy.sh/)
- [Self-hosting tutorial](https://docs.ntfy.sh/install/)
- [GitHub repository](https://github.com/binwiederhier/ntfy)
</details>
<details>
<summary>👉 Click to expand: <strong>Bark push</strong> (iOS exclusive, simple and efficient)</summary>
<br>
**GitHub Secret configuration (⚠️ Name must match exactly)**:
- **Name**: `BARK_URL` (copy and paste this name)
- **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/cn/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-built server (complete privacy control) 🔒
**Suitable for**: Those with servers, pursuing complete privacy, and having strong technical skills
**One-click Docker deployment**:
```bash
docker run -d \
--name bark-server \
-p 8080:8080 \
finab/bark-server
```
**Configure TrendRadar**:
```yaml
BARK_URL: http://your-server-ip:8080/your_device_key
```
---
**Notes**:
- ✅ Bark uses APNs push, with a maximum message size of 4KB
- ✅ Supports automatic batching, 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 match exactly)**:
- **Name**: `SLACK_WEBHOOK_URL` (copy and paste this name)
- **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 creation method**:
- Click **"From scratch"**
3. **Fill in 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 to 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 authorization page will pop up
- Select the channel to receive messages from the dropdown list (e.g., `#hot-news`)
- ⚠️ If you want to select a private channel, you must first join 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 (4KB per batch)
- ✅ Suitable for team collaboration, centralized message management
- ⚠️ Webhook URL contains the key, do not expose
**Message format preview**:
```
*[1/2 batches]*
📊 *Hot word statistics*
🔥 *[1/3] AI ChatGPT* : 2
1. [Baidu Hot Search] 🆕 ChatGPT-5 officially released *[1]* - 09:15 (1 time)
2. [Today's Headline] 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 match exactly)**:
- **Name**: `GENERIC_WEBHOOK_URL` (copy and paste this name)
- **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 Webhook URL**:
- Go to Discord server settings → Integrations → Webhooks
- Create a new Webhook, copy the URL
2. **Configure template**:
```json
{"content": "{content}"}
```
3. **GitHub Secret configuration**:
- `GENERIC_WEBHOOK_URL`: Discord Webhook URL
- `GENERIC_WEBHOOK_TEMPLATE`: `{"content": "{content}"}`
### Custom template
The template supports two placeholders:
- `{title}` - Message title
- `{content}` - Message content
**Template example**:
```json
# Default format (leave blank when using)
{"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
- ✅ 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: Manually test news push
> ⚠️ Reminder:
> - After completing steps 1-2, please test immediately! Test successfully before adjusting configurations as needed (step 4)
> - Please enter your project, not this project!
**How to find your Actions page**:
- **Method 1**: Open your forked project homepage, 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 these exact words), click into it, and click the **"Run workflow"** button on the right
- If you can't see this, 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 limits
> - After clicking Run workflow, you need to refresh the browser page to see the new 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 your concerned words, 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)
<br>
### 5️⃣ Step 5: Remote Cloud Storage & Check-in Configuration
**v4.0.0 Important Change**: Introduced an "activity detection" mechanism, requiring GitHub Actions to check in periodically to maintain operation.
- **Operation Cycle**: Valid for **7 days**, with services automatically suspended after the countdown ends.
- **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 isn't urgently needed for you. Timely pauses help you step away from the information flow and give your mind some breathing space.
- GitHub Actions are valuable public computing resources. The check-in mechanism is introduced 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 (choose based on deployment method):**
- **GitHub Actions Users**:
- **Current Status**: Each Actions run is a new environment, with no file saving. If cloud storage isn't configured, the project will run in **lightweight mode** (no incremental push, no history 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, enabling R2 requires binding a payment method.
* **Purpose**: Only for identity verification (Verify Only), **no charges incurred**.
* **Payment**: Supports dual-currency credit cards or mainland China PayPal.
* **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 | Secret Description |
|-------------|-----------------|
| `S3_BUCKET_NAME` | Bucket name (e.g., `trendradar-data`) |
| `S3_ACCESS_KEY_ID` | Access Key ID |
| `S3_SECRET_ACCESS_KEY` | Secret Access Key |
| `S3_ENDPOINT_URL` | S3 API endpoint (e.g., R2: `https://<account-id>.r2.cloudflarestorage.com`) |
**Optional Configuration:**
| Name | Secret Description |
|-------------|-----------------|
| `S3_REGION` | Region (default `auto`, some providers may require specification) |
> 💡 **More storage configuration options**: See [Where is the data stored?](#11-where-is-the-data-stored)
<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**:
- Go back 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`.
- **⚠️ Critical settings**:
- **Token name**: Fill in arbitrarily (e.g., `github-action-write`).
- **Permissions**: Select `Admin Read & Write`.
- **Specify bucket**: For security, recommend selecting `For specified buckets only` and select your bucket (e.g., `trendradar-data`).
- Click `Create API token`, **immediately copy** 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 is needed, and you'll see intelligent analysis reports on the next push.
<br>
### 7️⃣ Step 7: 🎉 Deployment Successful!
Congratulations! Now you can start enjoying the efficient information flow brought by TrendRadar.
💬 **Join the community**: Welcome to follow the public account **"[Silicon-based Tea Room](#-support-the-project)"**, 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 big things happened today?" | "Analyze the changes in the AI industry 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-intelligent-analysis)**.
<br>
<a name="配置详解"></a>
## ⚙️ Configuration Details
> **📖 Reminder**: This section provides detailed configuration instructions, recommend completing the [Quick Start](#-quick-start) basic configuration first, then review detailed options as needed.
### 1. Which platforms do I want to watch?
<details id="自定义监控平台">
<summary>👉 Click to expand: <strong>Select information sources</strong></summary>
<br>
**Configuration location:** `config/config.yaml` `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 check if you want the platform.
Specific addition can be accessed [project source code](https://github.com/ourongxing/newsnow/tree/main/server/sources), according to the file name, modify the `platforms` configuration in `config/config.yaml`:
```yaml
platforms:
enabled: true # Whether to enable hot list platform capture
sources:
- id: "toutiao"
name: "Today's Headlines"
- id: "baidu"
name: "Baidu Hot Search"
- id: "wallstreetcn-hot"
name: "Wall Street Journal"
# 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 the experience.
</details>
### 2. What content am I concerned about?
In the `frequency_words.txt` file, tell the robot what you want to see, and it will help you monitor. Supports ordinary words, must words, filter words, and other gameplay.
| Syntax type | Symbol | Effect | Example | Matching logic |
|---------|------|------|------|---------|
| **Ordinary words** | None | Basic match | `Huawei` | Contains any one can |
| **Must words** | `+` | Limit scope | `+Mobile` | Must contain simultaneously |
| **Filter words** | `!` | Exclude interference | `!Advertisement` | Contains direct exclusion |
| **Quantity limit** | `@` | Control display quantity | `@10` | Display up to 10 news (v3.2.0 added) |
| **Global filter** | `[GLOBAL_FILTER]` | Global exclusion of specified content | See below | Filter in any case (v3.5.0 added) |
| **Regular expression** | `/pattern/` | Precise matching mode | `/\bai\b/` | Use regular expression matching (v4.7.0 added) |
| **Display name** | `=> Remark` | Custom display text | `/\bai\b/ => AI related` | Push and HTML display remark name (v4.7.0 added) |
#### 2.1 Basic syntax
<a name="关键词基础语法"></a>
<details>
<summary>👉 Click to expand: <strong>Basic syntax tutorial</strong></summary>
<br>
**Configuration location:** `config/frequency_words.txt`
##### 1. **Ordinary keywords** - Basic match
```txt
Huawei
OPPO
Apple
```
**Effect:** News titles contain **any one word** will be captured
##### 2. **Must words** `+Vocabulary` - Limit scope
```txt
Huawei
OPPO
+Mobile
```
**Effect:** Must contain ordinary words **and** must words to be captured
##### 3. **Filter words** `!Vocabulary` - Exclude interference
```txt
Apple
Huawei
!Fruit
!Price
```
**Effect:** Contains filter words will be **directly excluded**, even if it contains keywords
##### 4. **Quantity limit** `@Number` - Control display quantity (v3.2.0 added)
```txt
Tesla
Musk
@5
```
**Effect:** Limit the maximum display news quantity of the keyword group
**Configuration priority:** `@Number` > Global configuration > Not limited
##### 5. **Global filter** `[GLOBAL_FILTER]` - Global exclusion of specified content (v3.5.0 added)
```txt
[GLOBAL_FILTER]
Advertisement
Promotion
Marketing
Shock
Title party
[WORD_GROUPS]
Technology
AI
Huawei
Hongmeng
!Car
```
**Effect:** Filter specified words in any case, **highest priority**
**Usage scenario:**
- Filter low-quality content: Shock, title party, exposure, etc.
- Filter marketing content: Advertisement, promotion, sponsorship, etc.
- Filter specific topics: Entertainment, gossip (according to needs)
**Filter priority:** Global filter > Word group filter (`!`) > Word group match
**Area description:**
- `[GLOBAL_FILTER]`: Global filter area, containing words will be filtered in any case
- `[WORD_GROUPS]`: Word group area, keep existing syntax (`!`, `+`, `@`)
- If not using area markers, default all as word group processing (backward compatible)
**Matching example:**
```txt
[GLOBAL_FILTER]
Advertisement
[WORD_GROUPS]
Technology
AI
```
- ❌ "Advertisement: Latest technology product release" ← Contains global filter word "Advertisement", direct rejection
- ✅ "Technology company releases AI new product" ← Not containing global filter words, match "Technology" word group
- ✅ "AI technology breakthrough attracts attention" ← Not containing global filter words, match "Technology" word group
**Note:**
- Global filter words should be used cautiously to avoid excessive filtering and missing valuable content
- Recommend controlling global filter words within 5-15
- For specific word group filtering, prioritize using word group filter words (`!` prefix)
##### 6. **Regular expression** `/pattern/` - Precise matching mode (v4.7.0 added)
Ordinary keywords use substring matching, which is convenient in the Chinese environment but may cause mismatches in the English environment. For example, `ai` will match to `ai` in `training`.
Using regular expression syntax `/pattern/` can achieve precise matching:
```txt
/(?<![a-z])ai(?![a-z])/
Artificial intelligence
```
**Effect:** Use regular expressions for matching, support all Python regular syntax
**Common regular patterns:**
| Demand | Regular writing | Description |
|------|---------|------|
| English word boundary | `/\bword\b/` | Match independent words, such as `/\bai\b/` match "AI" but not "training" |
| Non-letter before and after | `/(?<![a-z])ai(?![a-z])/` | Loose boundary, suitable for Chinese-English mixed scene |
| Head matching | `/^breaking/` | Only match titles starting with "breaking" |
| Tail 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 development is rapid" ← Match "artificial intelligence"
- ❌ "Resistance training is important" ← "training" in "ai" does not match
- ❌ "The maid cleaned the room" ← "maid" in "ai" does not match
**Combination use:**
```txt
# Regular + ordinary words + filter words
/\bai\b/
Artificial intelligence
Machine learning
!Advertisement
```
**Note:**
- Regular expressions automatically enable case-insensitive matching (`re.IGNORECASE`)
- Support `/pattern/i` and other JavaScript style writing (flags will be ignored because default is enabled case-insensitive)
- Invalid regular syntax will be treated as ordinary words
- Regular can be used for ordinary words, must words (`+`), filter words (`!`)
**💡 Don't write regular expressions? Let AI help you generate!**
If you are not familiar with regular expressions, you can directly let ChatGPT / Gemini / DeepSeek help you generate. Just tell AI:
> I need a Python regular expression to match English words "ai", but not match "ai" in "training".
> Please directly give the regular expression in the format `/pattern/`, no need to explain.
AI will give you results like this: `/(?<![a-zA-Z])ai(?![a-zA-Z])/`
##### 7. **Display name** `=> Remark` - Custom display text (v4.7.0 added)
Regular expressions in push messages and HTML page display may not be friendly. Using `=> Remark` syntax can set display name:
```txt
/(?<![a-zA-Z])ai(?![a-zA-Z])/ => AI related
Artificial intelligence```
**Effect:** Push messages and HTML page display "AI related" instead of complex regular expressions
**Syntax format:**
```txt
# Regular + display name
/pattern/ => Display name
/pattern/i => Display name # Support flags writing (flags are ignored)
/pattern/=>display name # => Both spaces optional
# Ordinary words + 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`** |
**Note:**
- Display name only need to write on the first word
- If multiple words in a word group have display names, use the first one
- If no display name is set, automatically use all words in the group concatenation
---
#### 🔗 Word group function - The role of empty line separation
**Core rules:** Use **empty line** to separate different word groups, each group independent statistics
##### Example configuration:
```txt
iPhone
Huawei
OPPO
+Release```
##### Word group explanation and matching effect:
**Group 1 - Mobile new product category:**
- Keywords: iPhone, Huawei, OPPO
- Must words: Release
- Effect: Must contain mobile brand name and "release"
**Matching example:**
- ✅ "iPhone 15 formal release price announced" ← Have "iPhone" + "release"
- ✅ "Huawei Mate60 series release live" ← Have "Huawei" + "release"
- ✅ "OPPO Find X7 release time confirmed" ← Have "OPPO" + "release"
- ❌ "iPhone sales high" ← Have "iPhone" but lack "release"
**Matching example:**
- ✅ "A股 today big rise analysis" ← Have "A股" + "rise"
- ✅ "Shanghai index rise and fall innovation high" ← Have "Shanghai" + "rise and fall"
- ❌ "Expert prediction A股 rise and fall trend" ← Have "A股" + "rise and fall" but contain "prediction"
**Group 3 - Football event category:
- Keywords: World Cup, European Cup, but not match "release"
**Matching example:**
- ✅ "The World Cup final match begins" ← Have "The World Cup" + "match"
- ✅ "The European Cup semi-final match starts" ← Have "The European Cup" + "match"
- ❌ "The expert predicts the World Cup match results" ← Have "The World Cup" + "match" but contain "prediction"
**Note:**
- Regular expressions automatically enable case-insensitive matching (`re.IGNORECASE`)
- Support `/pattern/i` and other JavaScript style writing (flags will be ignored because default is enabled case-insensitive)
- Invalid regular syntax will be treated as ordinary words
- Regular can be used for ordinary words, must words (`+`), filter words (`!`)
**💡 Don't write regular expressions? Let AI help you generate!**
If you are not familiar with regular expressions, you can directly let ChatGPT / Gemini / DeepSeek help you generate. Just tell AI:
> I need a Python regular expression to match English words "ai", but not match "ai" in "training".
> Please directly give the regular expression in the format `/pattern/`, no need to explain.
AI will give you results like this: `/(?<![a-zA-Z])ai(?![a-zA-Z])/`
##### 7. **Display name** `=> Remark` - Custom display text (v4.7.0 added)
Regular expressions in push messages and HTML page display may not be friendly. Using `=> Remark` syntax can set display name:
```txt
/(?<![a-zA-Z])ai(?![a-zA-Z])/ => AI related
Artificial intelligence
```
**Effect:** Push messages and HTML page display "AI related" instead of complex regular expressions
**Syntax format:**
```txt
# Regular + display name
/pattern/ => Display name
/pattern/i => Display name # Support flags writing (flags are ignored)
/pattern/=>display name # => Both spaces optional
# Ordinary words + 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`** |
**Note:**
- Display name only need to write on the first word
- If multiple words in a word group have display names, use the first one
- If no display name is set, automatically use all words in the group concatenation
---
#### 2.2 Advanced configuration (v3.2.0 added)
<a name="关键词高级配置"></a>
<details>
<summary>👉 Click to expand: <strong>Advanced configuration tutorial</strong></summary>
<br>
##### Keyword Sorting Priority
**Configuration Location:** `config/config.yaml`
```yaml
report:
sort_by_position_first: false # Sorting priority configuration
```
| Configuration Value | Sorting Rule | Applicable 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 # High priority, 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 news) → Huawei (10 news) → BYD (5 news)
</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" # Options: "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) | 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 Rankings**<br/>`current` | 📰 Self-media creators/content creators | Timed push (default hourly) | Current rankings matching news<br/>+ New news area | **Example**: Track "what topics are trending now"<br/>**Characteristics**: Real-time understanding of current popularity rankings<br/>**Reminder**: News that continues to rank 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 for**: High-frequency monitoring, avoiding 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 |
**Explanation**:
- `daily`: Accumulate and display all news for the day (A, B, C are retained)
- `current`: Display current rankings news (rankings change, News D ranks up, News A ranks down)
- `incremental`: **Only push newly appeared news** (avoid repetitive disturbance)
#### Frequently Asked Questions
> **💡 Encountering this issue?** 👉 "Each hour, the first execution outputs news, which still appears in the next hour"
> - **Cause**: You might have chosen `daily` (daily summary) or `current` (current rankings) mode
> - **Solution**: Switch to `incremental` (incremental monitoring) mode, which only pushes new content
#### ⚠️ Important Note for Incremental Mode
> **Users who choose `incremental` (incremental monitoring) mode, please note:**
>
> 📌 **Incremental mode only pushes when new matching news appears**
>
> **If you haven't received a push for a long time, it might be because:**
> 1. There are no new hotspots matching your keywords during the current period
> 2. Keyword configuration is too strict or too broad
> 3. The number of monitored platforms is relatively small
>
> **Solutions:**
> - Solution 1: 👉 [Optimize keyword configuration](#2-keyword-configuration) - Adjust keyword precision, add or modify monitoring words
> - Solution 2: Switch push mode - Use `current` or `daily` mode, which can receive timed pushes
> - Solution 3: 👉 [Add monitoring platforms](#1-platform-configuration) - Add more news platforms to expand information sources
</details>
### 4. Adjusting Hotspot Algorithm
<details>
<summary>👉 Click to expand: <strong>Customizing hotspot weights</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
```
The current default configuration is a balanced configuration.
#### Two Core Scenarios
**Pursuing Real-time Hotspots**:
```yaml
advanced:
weight:
rank: 0.8 # Mainly consider 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
**Pursuing In-depth Topics**:
```yaml
advanced:
weight:
rank: 0.4 # Moderately consider ranking
frequency: 0.5 # Emphasize daily sustainability
hotness: 0.1
```
**Applicable Users**: Investors, researchers, news workers, users who need in-depth trend analysis
#### Adjustment Method
1. **The 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. **It is recommended to adjust by 0.1-0.2 each time**, observe the effect
Core idea: Users who pursue speed and timeliness increase ranking weight, while users who pursue depth and stability increase frequency weight.
</details>
### 5. What Does the Message I Receive Look Like?
<details>
<summary>👉 Click to expand: <strong>Message style preview</strong></summary>
<br>
#### Push Example
📊 Hotspot Vocabulary Statistics
🔥 [1/3] AI ChatGPT : 2 News
1. [Baidu Hot Search] 🆕 ChatGPT-5 Officially Released [**1**] - 09:15 (1 time)
2. [Toutiao] AI Chip Concept Stocks Soar [**3**] - [08:30 ~ 10:45] (3 times)
━━━━━━━━━━━━━━━━━━━
📈 [2/3] BYD Tesla : 2 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 News] A-share Mid-day Review Analysis [**5**] - [11:30 ~ 12:00] (2 times)
🆕 **Newly Added Hotspot News** (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 | Explanation |
| ------------- | --------------------------- | ------------ | --------------------------------------- |
| 🔥📈📌 | 🔥 [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 matched word groups |
| Frequency Word Group | AI ChatGPT | Keyword Group | Word group in the configuration file, title must contain the keyword |
| : N News | : 2 News | Matched Quantity | Total news matched for the word group |
| [Platform Name] | [Baidu Hot Search] | Source Platform | News platform name |
| 🆕 | 🆕 ChatGPT-5 Officially Released | New Marker | Newly appeared hotspot in this round |
| [**Number**] | [**1**] | High Ranking | Ranking ≤ threshold, displayed in red and bold |
| [Number] | [7] | Ordinary Ranking | Ranking > threshold, displayed normally |
| - Time | - 09:15 | First Time | Time when the 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** | 🆕 **Newly Added Hotspot News** | New Topic Summary | Separate display of newly appeared hotspots |
</details>
### 6. Docker Deployment
**Image Description:**
TrendRadar provides two independent Docker images, which can be deployed according to demand:
| Image Name | Purpose | Description |
|---------|------|------|
| `wantcat/trendradar` | News push service | Timely crawl news, push notifications (mandatory) |
| `wantcat/trendradar-mcp` | AI analysis service | MCP protocol support, AI dialogue analysis (optional) |
> 💡 **Recommendation**:
> - Only need push function: Deploy `wantcat/trendradar` image only
> - 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 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 functionality 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 functionality configuration** | Low | Report mode, push settings, storage format, push window, AI analysis switch, platform enablement, etc. |
| `config/frequency_words.txt` | **Keyword configuration** | High | Set up hot words you care about, support grouping, regular expressions, aliases, and other advanced syntax |
| `config/timeline.yaml` | **Timeline configuration** | Low | Control news timeline display and filtering rules |
| `config/ai_analysis_prompt.txt` | **AI analysis prompt words** | Medium | Customize AI analysis role definition and output format (v5.0.0+) |
| `config/ai_translation_prompt.txt` | **AI translation prompt words** | Low | Customize 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 Key, S3 credentials, scheduled tasks, etc., **will not be tracked by git** |
> 💡 **Division points**:
> - **Functional 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` (API Key, Webhook URL, and other sensitive information unified here)
> - **Personalized extension** → Use `config/custom/` directory, avoid directly modifying default configuration to prevent upgrade coverage
> 💡 **Configuration modification takes effect**: After modifying `config.yaml`, execute `docker compose up -d` to restart the container to take effect
**⚙️ Environment variable override mechanism (v3.0.5+)**:
Environment variables in `.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 required 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 (timely crawl and push)
docker compose pull trendradar
docker compose up -d trendradar
```
**Option C: Start MCP AI analysis service only**
```bash
# Start trendradar-mcp (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. **View Running Status**:
```bash
# View news push service logs
docker logs -f trendradar
# View MCP AI analysis service logs
docker logs -f trendradar-mcp
# View all container status
docker ps | grep trendradar
# Stop specific service
docker compose stop trendradar # Stop push service
docker compose stop trendradar-mcp # Stop MCP service
```
#### Method 2: Local Build (Developer Option)
If you need to customize and modify code or build your own image:
```bash
# Clone project
git clone https://github.com/sansan0/TrendRadar.git
cd TrendRadar
# Modify configuration file
vim config/config.yaml
vim config/frequency_words.txt
# 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 (suitable for 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 update
docker compose pull
docker compose up -d
```
**Available images**:
| Image name | Purpose | Description |
|---------|------|------|
| `wantcat/trendradar` | News push service | Timely 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 crawler
docker exec -it trendradar python manage.py run
# View real-time logs
docker exec -it trendradar python manage.py logs
# Display current configuration
docker exec -it trendradar python manage.py config
# Display output files
docker exec -it trendradar python manage.py files
# Web server management (for browser access generated report)
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
# Delete container (retain data)
docker rm trendradar
```
> 💡 **Web server description**:
> - Automatically started in cron mode, access `http://localhost:8080` through browser to view the latest report
> - 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 prompt: Only provide static file access, restrict in output directory, bind local access only
#### Data Persistence
Generated reports and data are saved in `./output` directory by default, and data will be retained even if the container is restarted or deleted.
**📊 Web version report access path**:
TrendRadar generated daily summary HTML report will be saved in two locations:
| File location | Access method | Applicable scenario |
|---------|---------|---------|
| `output/index.html` | Host direct access | **Docker deployment** (through Volume mount, host visible) |
| `index.html` | Root directory access | **GitHub Pages** (repository root directory, Pages automatically identified) |
| `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 specified date report
# 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, locally directly openable
- `index.html`: GitHub Actions pushed to repository, GitHub Pages automatically deployed
> 💡 **Hint**: Two files have the same content, choose either one to 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 file
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[Timely crawl news]
A2[Push notifications]
end
subgraph trendradar-mcp["trendradar-mcp"]
B1[127.0.0.1:3333]
B2[AI analysis interface]
end
subgraph shared["Shared volume"]
C1["config/ (ro)"]
C2["output/ (ro)"]
end
trendradar --> shared
trendradar-mcp --> shared
```
**Quick start**:
If you have already completed deployment using [Method 1: Using docker compose](#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/` directories 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
```
# View MCP Service Logs
docker logs -f trendradar-mcp
**Configure in AI Client**:
After MCP service starts, configure according to different clients:
**Cherry Studio** (Recommended, GUI configuration):
- Settings → MCP Server → Add
- Type: `streamableHttp`
- URL: `http://127.0.0.1:3333/mcp`
**Claude Desktop / Cline** (JSON configuration):
```json
{
"mcpServers": {
"trendradar": {
"url": "http://127.0.0.1:3333/mcp",
"type": "streamableHttp"
}
}
}
```
> 💡 **Tip**: MCP service only listens to the local port (127.0.0.1) for security. If you need remote access, configure a reverse proxy and authentication yourself.
</details>
### 7. How to Display Pushed Content?
<details>
<summary>👉 Click to expand: <strong>Custom Push Style 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
- hotlist # Hotlist
- rss # RSS subscription
- standalone # Independent display
- ai_analysis # AI analysis
```
#### 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 **bolded** for easy viewing |
| **Sorting rule** | `sort_by_position_first` | `false` | `false`=high heat ranks first, `true`=configured words rank first |
| **Quantity limit** | `max_news_per_keyword` | `0` | Maximum news per keyword? `0` means no limit |
| **Display order** | `display.region_order` | See above configuration | Adjust list order to control region display position |
#### Grouping Method Comparison (display_mode)
Do you want to see "which news are under this topic" or "which news are on this platform"?
| Mode | Grouping method | Title prefix | Applicable scenario |
|------|---------|---------|---------|
| `keyword` (default) | **Group by keyword** | `[Platform name]` | I follow "AI" and want to see news about AI from various platforms |
| `platform` | **Group by platform** | `[Keyword]` | I follow "Weibo" and want to see news about my followed words on Weibo |
#### Region Display Order (region_order)
By adjusting the `display.region_order` list order, you can control the display position of each region in the push message.
**Default order**: New hotspots → Hotlist → RSS → Independent display → AI analysis
**Custom example**: Want AI analysis to be at the 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. It is in the `region_order` list
2. The corresponding switch in `display.regions` is `true`
#### Region Switch (regions)
Control whether each region is displayed in the push:
```yaml
display:
regions:
hotlist: true # Hotlist region (keyword-matched hot news)
new_items: false # New hotspots region (including new hotlist + RSS)
rss: true # RSS subscription region (keyword-matched RSS content)
standalone: false # Independent display (complete hotlist/RSS, not filtered by keyword)
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 new hotlist + RSS). Note: The 🆕 mark in the hotlist region is not affected by this switch |
| **RSS** | `rss` | `true` | Keyword-matched RSS subscription content. Closing will skip RSS analysis, but RSS in the independent display will not be affected |
| **Independent display** | `standalone` | `false` | Complete content display for specified platforms/RSS, not filtered by keyword |
| **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 heat: BYD (10 articles), Tesla (3 articles).
| Configuration value | Sorting result | Your idea |
|-------|---------|---------|
| `false` (default) | BYD (10 articles) → Tesla (3 articles) | "Who is hot, who ranks first" |
| `true` | Tesla (3 articles) → BYD (10 articles) | "The order I configured is the priority, regardless of heat" |
#### Independent Display (standalone)
**Scenario**: Some platforms (e.g., Zhihu hotlist, HackerNews), I want to **browse completely**, regardless of whether it matches my keywords.
```yaml
display:
regions:
standalone: true # Display independent display in push (closing will 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
```
> 💡 **Push display and AI analysis are controlled independently**: `regions.standalone` only controls whether the independent display is shown in the push. Even if the push display is closed, as long as `include_standalone: true` is enabled in the AI configuration, AI will still analyze the complete data of these platforms. Suitable for users who want AI to perform in-depth analysis but do not want the push message to be too long.
</details>
### 8. When to Push?
<details>
<summary>👉 Click to expand: <strong>Set Push Time (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` | Daily incremental + evening summary (recommended) | Incremental throughout the day + evening summary from 19:00-21:00 |
| `always_on` | Always on | Push whenever there is an update, no time segment division |
| `office_hours` | Office hours | Three-stage push on weekdays (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跨 midnight) |
| `custom` | Completely custom | Edit the `custom` section at the bottom of `timeline.yaml` |
#### Completely Custom
If preset templates do not meet your needs, edit the `custom` section at the bottom of `timeline.yaml` to define time segments, daily plans, and weekly mappings. See comments in `timeline.yaml` for details.
#### Important Reminder
> ⚠️ **Note for users upgrading from old versions:**
> - v6.0.0 removed old `notification.push_window` and `ai_analysis.analysis_window` configurations
> - Use the new `schedule` + `timeline.yaml` scheduling system instead
> - 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 note:**
> - GitHub Actions execution time is unstable and may have ±15-minute deviation
> - Time segment range should be at least **2 hours**
> - For precise timing push, it is recommended to use **Docker deployment** on a personal server
</details>
### 9. How Often to Run?
<details>
<summary>👉 Click to expand: <strong>Set Automatic Running Frequency</strong></summary>
<br>
**Configuration Location:** `.github/workflows/crawler.yml` in `schedule` section
```yaml
on:
schedule:
- cron: "0 * * * *" # Run once an hour
```
#### How to Modify Running Frequency?
GitHub Actions uses a "Cron" time format. No need to understand deeply, 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** | `- cron: "0 0 * * *"` | ⚠️ Write `0` because UTC time (0:00) = Beijing time (8:00) |
| **Office hours every half hour** | `- cron: "*/30 0-14 * * *"` | Corresponds to Beijing time 8:00 - 22:00 |
| **Three meals a day** | `- cron: "0 0,6,12 * * *"` | Corresponds to Beijing time 8:00, 14:00, 20:00 |
#### ⚠️ Two Important Reminders
1. **Time difference issue**: GitHub servers are abroad, using UTC time.
- **Simple arithmetic**: Beijing time **minus 8 hours** = time to fill in.
- *Example: Want it to run at 20:00 Beijing time, set to 12:00 in settings*
2. **Do not be too frequent**: Interval should not be less than 30 minutes.
- GitHub free resources are limited, running too frequently may be restricted by official account.
- Actions startup itself has a few minutes delay, too precise control is meaningless.
#### Step-by-Step Modification
1. In your GitHub repository, find `.github/workflows/crawler.yml` file
2. Click the ✏️ (Edit) button in the upper right corner
3. Find the `cron: "..."` line, replace the content in quotes with the above "code"
4. Click the 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 a file containing passwords to GitHub, the whole world can see it.
>
> **Correct approach**:
> - **GitHub Actions users**: Go to Settings -> Secrets to add
> - **Docker users**: Write in `.env` file (this file will not be uploaded)
#### How to push to multiple places simultaneously?
Simply use semicolon `;` to separate multiple addresses.
**Example**:
Assume you have two Feishu groups, want to receive push simultaneously:
- 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 |
|------|---------|----------|
| **Feishu/Dingtalk/WeChat** | Use `;` to separate multiple Webhook URLs | Simplest, just string them up |
| **Bark (iOS)** | Use `;` to separate multiple Key URLs | Push to multiple iPhones |
| **Telegram** | Both Token and ChatID use `;` to separate | ⚠️ **Note correspondence**:<br>Token1 corresponds to ChatID1<br>Token2 corresponds to ChatID2 |
| **ntfy** | Both Topic and Token use `;` to separate | If a topic does not need a token, leave blank:<br>`token1;;token3` (the middle one is blank) |
#### Common Configuration Examples (GitHub Secrets / .env)
```bash
# Feishu 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, a limit of 3 accounts per platform is set by default. If you need more, modify the `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, usually no need to worry:
| Your running environment | Data stored in | Description |
|-------------|-----------|------|
| **Docker / Local run** | **Local hard drive** | Stored in `output/` folder in project directory, can be viewed anytime. |
| **GitHub Actions** | **Cloud storage** | Since GitHub Actions will delete environment after running, cloud storage (e.g., Cloudflare R2) must be configured. |
#### How to configure cloud storage? (GitHub Actions users must read)
If you run with 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 in GitHub Secrets:**
| Variable name | Fill in |
|-------|-------|
| `STORAGE_BACKEND` | `remote` |
| `S3_BUCKET_NAME` | Your bucket name |
| `S3_ACCESS_KEY_ID` | Your Access Key |
| `S3_SECRET_ACCESS_KEY` | Your Secret Key |
| `S3_ENDPOINT_URL` | Your R2 interface address |
> 💡 **Detailed tutorial**: How to apply for R2? See [Quick Start - Remote Storage Configuration](#-quick-start)
#### How long will data be saved?
By default, we will not automatically delete your data. But if you think data takes up too much space, you can set "automatic cleanup".
**Configuration location**: `config/config.yaml`
```yaml
storage:
local:
retention_days: 30 # Local data retained for 30 days (0 means permanent)
remote:
retention_days: 30 # Cloud data retained for 30 days
```
#### Push time is incorrect? (Timezone setting)
If you are abroad or find push time does not match local time, modify the timezone.
**Configuration location**: `config/config.yaml`
```yaml
app:
timezone: "Asia/Shanghai" # Default is China time
```
- For example, if you are in Los Angeles, change to: `America/Los_Angeles`
- For example, if you are in London, change to: `Europe/London`
</details>
### 12. Let AI Analyze Hotspots for You
<details id="ai-analysis-config">
<summary>👉 Click to expand: <strong>Enable AI Intelligent Analysis Function</strong></summary>
<br>
#### What can AI do for me?
Enabling this function, AI will act like a professional analyst, for each batch of news pushed:
1. **Automatic reading**: Read all matched hot news
2. **In-depth thinking**: Analyze the correlation between originally isolated news
3. **Write report**: Append a short and profound "insight report" at the end of the push message
**Includes**: Hotspot trend summary, public opinion trend judgment, cross-platform correlation analysis, potential impact assessment, etc.
</details>
#### How to Enable AI Analysis?
The simplest method 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), supporting 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 time (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 into 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 fit your preferred style (e.g., "sarcastic commentator", "experienced investment advisor").
- **Edit File**: `config/ai_analysis_prompt.txt`
- **Edit Method**: Open with a text editor and tell AI what analysis style you want.
</details>
<br>
## ✨ AI Intelligent Analysis
TrendRadar v3.0.0 introduces AI analysis 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 network data but analyzes your **locally accumulated news data** (stored in the `output` folder).
#### Instructions for Use:
1. **Project comes with test data**: The `output` directory contains default news data for **2025-12-21 ~ 2025-12-27** for quick AI feature experience.
2. **Query Limitations**:
- ✅ Only query data within the existing date range (December 21-27, 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 the [Quick Start](#-quick-start) deployment 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.
**Graphic Deployment Tutorial**: Updated to my [public account](#-support-the-project), reply "mcp" to get it.
**Detailed Deployment Tutorial**: [README-Cherry-Studio.md](README-Cherry-Studio.md)
**Deployment Mode Instructions**:
- **STDIO Mode (Recommended)**: Configure once and no need to repeat; **graphic deployment tutorial** 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 copy-paste content, 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 details.
### 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 example" 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
**Notes**:
- 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**:
- Restart Cursor after saving the configuration file.
- Check the connected tools in the "Available Tools" section of the chat interface.
- 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**:
- Visit: `http://localhost:3333/mcp`
- Test "Ping Server" to verify connection.
- Check "List Tools" to see if it returns 17 tools:
- Basic Query: get_latest_news, get_news_by_date, get_trending_topics
- Intelligent Retrieval: search_news, find_related_news
- Advanced Analysis: analyze_topic_trend, analyze_data_insights, analyze_sentiment, aggregate_news, compare_periods, generate_summary_report
- RSS Query: get_latest_rss, search_rss, get_rss_feeds_status
- System Management: get_current_config, get_system_status, resolve_date_range
</details>
<details>
<summary>👉 Click to expand: <b>Other MCP-supported Clients</b></summary>
<br>
Any client supporting the Model Context Protocol can connect to TrendRadar:
#### HTTP Mode
**Service Address**: `http://localhost:3333/mcp`
**Basic Configuration Template**:
```json
{
"name": "trendradar",
"url": "http://localhost:3333/mcp",
"type": "http",
"description": "News Hotspot Aggregation Analysis"
}
```
#### STDIO Mode (Recommended)
**Basic Configuration Template**:
```json
{
"name": "trendradar",
"command": "uv",
"args": [
"--directory",
"/path/to/TrendRadar",
"run",
"python",
"-m",
"mcp_server.server"
],
"type": "stdio"
}
```
**Notes**:
- Replace `/path/to/TrendRadar` with the actual project path.
- Use backslashes for Windows paths: `C:\\Users\\...`
- Ensure project dependencies are installed (run setup scripts).
</details>
### Frequently Asked Questions
<details>
<summary>👉 Click to expand: <b>Q1: HTTP Service Fails to Start?</b></summary>
<br>
**Checklist**:
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 (visit `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 Calls 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**:
- [Leave a message at the end of this article for easy project author response](https://mp.weixin.qq.com/s/KYEPfTPVzZNWFclZh4am_g)
- [2 months to break 1000 stars, my GitHub project promotion experience](https://mp.weixin.qq.com/s/jzn0vLiQFX408opcfpPPxQ)
- [GitHub fork operation notes for this project ](https://mp.weixin.qq.com/s/C8evK-U7onG1sTTdwdW2zg)
- [How to write public accounts or news articles based on this project](https://mp.weixin.qq.com/s/8ghyfDAtQZjLrnWTQabYOQ)
>**AI Development**:
- If you have niche needs, you can develop based on my project; even those with no programming background can try.
- All my open-source projects use **AI-assisted software** to improve development efficiency; this tool is open-sourced.
- **Core Function**: Quickly feed project code to AI; you only need to supplement personal needs.
- **Project Address**: https://github.com/sansan0/ai-code-context-helper
### Other Projects
> 📍 Chairman Mao Footprint Map - Interactive dynamic display of complete trajectory from 1893-1976. Welcome comrades to contribute data.
- https://github.com/sansan0/mao-map
> Bilibili comment area data visualization analysis software.
- https://github.com/sansan0/bilibili-comment-analyzer
[](https://www.star-history.com/#sansan0/TrendRadar&Date)
<br>
## 📄 License
GPL-3.0 License
---
<div align="center">
[🔝 Back to Top](#trendradar)
</div>
Connection Info
You Might Also Like
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,...