Skip to content

ymx10086/EventRadar

Repository files navigation

EventRadar

Multi-source event radar that discovers events from WeChat posts, links, text, and images, enriches them with vision understanding, deduplicates them, and turns them into a subscribable calendar.

Python 3.9+ FastAPI SQLite MiniMax Vision ICS Calendar License AGPL-3.0

WeChat Fetching · Daily Archives · Vision Understanding · Event Extraction · Dedupe · ICS Calendar · Automation

中文 · Why · Quick Start · Features · Architecture · API · Configuration

Why EventRadar

EventRadar is a local-first event intelligence tool. It currently focuses on WeChat article fetching, RSS subscriptions, and image archiving, while leaving room for future sources such as Xiaohongshu, web links, group-chat text, and event posters. It adds MiniMax-powered vision understanding, structured event extraction, deduplication, review workflows, automation, and ICS calendar subscriptions for lectures, competitions, registrations, roadshows, open days, summits, hackathons, and more.

This project is built on top of the open-source WeChat Download API project. The original project provides the WeChat login, article fetching, RSS, anti-risk controls, and image proxy foundation; EventRadar extends it into a calendar-centered event intelligence system.

Pain Point How EventRadar Helps
Event information is scattered across posts, posters, links, and text. Archive multi-source content and extract structured event records.
Image-only posters are hard to search, copy, and organize. Use MiniMax vision understanding to read event names, times, locations, signup methods, and organizers.
Repeated imports can quickly clutter a calendar. Dedupe at storage, listing, and ICS layers while preserving favorite and confirmed states.
Event start, signup open, and deadline times are often mixed together. Place events by the earliest actionable time whenever possible.
Manual calendar maintenance is expensive. Support scheduled polling, archiving, extraction, cleanup, and ICS subscriptions.

Under the hood, EventRadar combines:

  • FastAPI runtime: static pages, API routes, startup tasks, and health checks.
  • WeChat and RSS foundation: login, account search, subscription, polling, article parsing, and image proxying.
  • Daily archive pipeline: persist articles and images by date.
  • Event extraction pipeline: MiniMax plus fallback rules turn article text and image understanding results into events.
  • SQLite event store: dedupe, status, priority, favorite, cleanup, CSV, and ICS.
  • Browser calendar UI: review, filtering, editing, manual entry, settings, and automation progress.

What You Get Today

Area What it does
🔐 WeChat & RSS QR login, account search, subscriptions, polling, article lists, and full-content fetching.
🗂️ Daily archive Writes data/daily_archives/YYYY-MM-DD/articles.json and downloads cover/body images.
👁️ Vision understanding Uses MiniMax Token Plan vision to recover details from image-only WeChat posts.
🧠 Event extraction Combines article text and vision output, then extracts structured events with LLM and fallback rules.
⏱️ Calendar-first timing Prioritizes signup open/deadline when they come before the event start.
🧹 Re-import dedupe Keeps one event record for repeated imports while preserving review state.
⭐ Event store Manages pending / confirmed / ignored, S/A/B/C priority, favorites, and cleanup rules.
🗓️ Calendar UI Provides filters, month/week/list views, day modals, editing, favorites, and manual entry.
📤 ICS & CSV export Serves /api/events/calendar.ics and CSV exports for downstream tools.
⚙️ Automation Runs scheduled polling, archiving, extraction, dedupe, saving, and progress tracking.
🌐 Public access Works with cloudflared for a temporary trycloudflare.com URL when needed.

Product Screenshots

Main Calendar Workspace

EventRadar main calendar workspace

Calendar views and event review Event detail and editing
EventRadar calendar view EventRadar event detail view
More calendar interactions Admin console
EventRadar calendar interactions EventRadar admin console
Source management Personal profile Automation settings
Source management Personal profile Automation settings

Architecture

EventRadar architecture

The diagram above shows the main runtime layers and data flow. The detailed module responsibilities live in app.py, routes/, utils/, static/, and data/.

Quick Start

The recommended flow is to initialize the local environment, log in to WeChat, set up RSS subscriptions, archive articles, and then run event extraction.

Create env -> Start backend -> WeChat QR login -> Subscribe accounts -> Poll RSS -> Archive articles/images -> Extract events -> Review calendar -> Subscribe ICS

1. Create Environment

cd /path/to/eventradar
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp env.example .env

Edit .env and verify at least these settings:

PORT=5001
HOST=0.0.0.0
DAILY_ARCHIVE_TIMEZONE=Asia/Shanghai
DAILY_ARCHIVE_DOWNLOAD_IMAGES=true

MINIMAX_API_KEY=your MiniMax Token Plan key
MINIMAX_API_STYLE=anthropic
MINIMAX_BASE_URL=https://api.minimax.io/anthropic
MINIMAX_API_HOST=https://api.minimaxi.com
MINIMAX_MODEL=MiniMax-M2.7
MINIMAX_VISION_ENABLED=true

EVENT_AUTOMATION_ENABLED=false
EVENT_AUTOMATION_LOOKBACK_DAYS=0
EVENT_AUTOMATION_USE_LLM=true
EVENT_AUTOMATION_USE_VISION=true
EVENT_RETENTION_DAYS=15

Notes:

  • MINIMAX_MODEL is used for text-based structured extraction.
  • Vision understanding uses the Token Plan /v1/coding_plan/vlm endpoint and prefers MINIMAX_API_HOST, with automatic fallback between api.minimaxi.com and api.minimax.io.
  • Without a MiniMax key, fallback rules still work, but image-only event recognition will be much weaker.

2. Start Backend

source venv/bin/activate
python app.py

You should see output like:

EventRadar - FastAPI Service
Admin Page: http://localhost:5001/admin.html
Events Page: http://localhost:5001/events.html
API Docs:   http://localhost:5001/api/docs

Common pages:

Page Purpose
http://localhost:5001/admin.html Admin panel for login, RSS, and API checks
http://localhost:5001/login.html WeChat QR-code login
http://localhost:5001/rss.html WeChat RSS subscription management
http://localhost:5001/events.html Main EventRadar calendar UI
http://localhost:5001/api/docs Swagger API docs

3. Initialize the WeChat/RSS Foundation

Before using event extraction for the first time:

  1. Open login.html and scan the QR code with a WeChat official account administrator.
  2. Open admin.html or rss.html, search for accounts, and subscribe to the ones you want to monitor.
  3. Trigger RSS polling and confirm articles are written into data/rss.db.
  4. Generate a daily archive and confirm data/daily_archives/YYYY-MM-DD/articles.json plus the image directory exist.

Related API calls:

# Subscribe to an account. fakeid can be found through the search API or UI.
curl -X POST http://localhost:5001/api/rss/subscribe \
  -H "Content-Type: application/json" \
  -d '{"fakeid":"account fakeid","nickname":"account name"}'

# Poll subscribed accounts
curl -X POST http://localhost:5001/api/rss/poll

# Create today's article archive and download images
curl -X POST "http://localhost:5001/api/rss/archive/daily?poll=false&download_images=true"

4. Run Event Extraction

Open events.html, choose an account and date range, then run extraction. You can also call the API directly:

curl -X POST http://localhost:5001/api/events/extract \
  -H "Content-Type: application/json" \
  -d '{
    "date": "2026-05-21",
    "use_llm": true,
    "use_vision": true,
    "max_chars": 9000
  }'

You can also run the full pipeline by account and date range:

curl -X POST http://localhost:5001/api/events/run-account-range \
  -H "Content-Type: application/json" \
  -d '{
    "account": "account name",
    "start_date": "2026-05-15",
    "end_date": "2026-05-21",
    "use_llm": true,
    "use_vision": true,
    "download_images": true
  }'

Outputs:

  • Event store: data/events.db
  • Daily JSON: data/events/YYYY-MM-DD/events.json
  • CSV: data/events/YYYY-MM-DD/events.csv
  • ICS: data/events/YYYY-MM-DD/calendar.ics
  • Long-lived ICS: http://localhost:5001/api/events/calendar.ics

5. Enable Scheduled Automation

You can enable automation from the settings panel in events.html, or configure .env:

EVENT_AUTOMATION_ENABLED=true
EVENT_AUTOMATION_TIME=09:07
EVENT_AUTOMATION_LOOKBACK_DAYS=0
EVENT_AUTOMATION_USE_LLM=true
EVENT_AUTOMATION_USE_VISION=true
EVENT_RETENTION_DAYS=15

Meaning:

  • Poll automation-enabled accounts at the configured time every day.
  • EVENT_AUTOMATION_LOOKBACK_DAYS=0 means only today; a conservative free-mode setup should usually keep it at 0, with occasional manual backfill.
  • Each save triggers dedupe so repeated imports keep one record.
  • Unfavorited old events are cleaned after the retention window; favorited events are always preserved.

Check progress:

curl http://localhost:5001/api/events/settings

The response includes automation.progress, and the frontend settings panel also displays the current stage and progress.

Public Access

For local debugging, you can expose the service with Cloudflare Quick Tunnel:

cloudflared tunnel --url http://127.0.0.1:5001

It will return a URL like:

https://example-words.trycloudflare.com

Then visit:

  • https://example-words.trycloudflare.com/events.html
  • https://example-words.trycloudflare.com/admin.html

You can also let start.sh launch the tunnel automatically:

CLOUDFLARE_TUNNEL_ENABLED=true
PORT=5001

Then run:

bash start.sh

Cloudflare Quick Tunnel URLs are temporary and may change after restart. For production use, prefer a fixed domain and a formal tunnel.

Docker

Build and run locally:

cp env.example .env
docker-compose up -d --build
docker-compose logs -f

The default port is controlled by PORT in .env. After the first launch, visit login.html to complete WeChat QR login.

If you use the original upstream image, note that it may not include EventRadar's latest event extraction and calendar features. Building from this repository is recommended.

macOS Desktop Packaging

EventRadar can be packaged as a macOS desktop app with a Tauri shell and a PyInstaller-built FastAPI sidecar.

Install From GitHub Release

Download the latest EventRadar_*.dmg from the repository's GitHub Releases page, open it, and drag EventRadar.app into Applications.

On first launch, open the admin panel and configure MiniMax, Webhook, and proxy settings in Model & Runtime Config. The desktop app stores user data outside the project directory:

~/Library/Application Support/EventRadar/

This directory contains the desktop .env, SQLite databases, logs, QR codes, archives, and event exports.

If macOS warns that the app is from an unidentified developer, right-click EventRadar.app, choose Open, and confirm once. Code signing and notarization can be added later for a smoother public release.

Build Locally

Build the backend sidecar only:

bash packaging/desktop/build_pyinstaller.sh

Output:

src-tauri/bin/eventradar-server-<target-triple>

Build the .app and .dmg installer:

bash packaging/desktop/build_tauri.sh

Output:

src-tauri/target/release/bundle/macos/EventRadar.app
src-tauri/target/release/bundle/dmg/EventRadar_*.dmg

The desktop app starts eventradar-server as a sidecar, waits for /api/health, opens /events.html in a native window, and stops the backend process when the app exits. Runtime data is stored in ~/Library/Application Support/EventRadar/.

Upload this file to GitHub Releases for one-click macOS installation:

src-tauri/target/release/bundle/dmg/EventRadar_1.0.0_aarch64.dmg

The .dmg, .app, PyInstaller output, Rust target directory, and generated sidecar binaries are intentionally ignored by Git. Keep them as Release assets instead of committing them to the repository.

For Intel Macs, build on an Intel macOS machine or configure a matching x86_64-apple-darwin build. The generated sidecar must be named with the matching target triple under src-tauri/bin/.

The older lightweight launcher scripts are still available in packaging/macos for local experiments.

API Reference

Group Entry points
🩺 Health /api/health
🔐 WeChat foundation /api/public/searchbiz, /api/article, /api/rss/*
🗓️ Event calendar /api/events/extract, /api/events/list, /api/events/calendar.ics, /api/events/settings

Health Check

curl http://localhost:5001/api/health

WeChat Article Foundation

Method Path Description
GET /api/public/searchbiz?query=keyword Search WeChat accounts and get fakeid
POST /api/article Parse one WeChat article
POST /api/rss/subscribe Add an account subscription
GET /api/rss/subscriptions List subscriptions
POST /api/rss/poll Manually poll account articles
POST /api/rss/archive/daily Create daily article archive
GET /api/rss/{fakeid} Serve RSS feed

Event Calendar

Method Path Description
POST /api/events/extract Extract events from daily archives
POST /api/events/run-account Subscribe, poll, archive, and extract for one account
POST /api/events/run-account-range Run extraction by account and date range
GET /api/events/list Query events by date, status, priority, and keyword
PATCH /api/events/{event_id} Edit event content, status, and priority
POST /api/events/{event_id}/favorite Favorite or unfavorite an event
GET /api/events/calendar.ics Long-lived ICS calendar subscription
GET /api/events/export.csv Export CSV
POST /api/events/cleanup Clean up old unfavorited events
POST /api/events/cleanup-duplicates Manually remove duplicates
GET /api/events/settings Read automation settings and progress
POST /api/events/settings Save automation settings

Deduplication

When content is imported repeatedly, EventRadar deduplicates at the storage, list, and ICS layers:

  • Records from the same source article, event title, or event date can reuse existing events.
  • Higher-quality extracted content can update the stored record while preserving status, favorite, and notes.
  • Favorite or confirmed state is migrated to the retained event.
  • Duplicate cleanup runs automatically after extraction saves.
  • Low-quality legacy records with empty time fields can be removed on startup or manual cleanup.

This means repeated daily imports should not produce multiple copies of the same calendar item.

Calendar Time Rules

The calendar does not simply use start_time; it sorts by the earliest actionable time:

  1. If signup start time exists, use it first.
  2. If there is no signup start but a deadline exists, use the deadline.
  3. Otherwise, use the event start time.
  4. Deadline-like May 10 24:00 is kept on May 10 instead of drifting to May 11.
  5. Timezone-aware ISO timestamps are displayed on the correct local date.

Configuration

Most deployments only need to touch four groups first: service address, WeChat credentials, MiniMax extraction, and automation cadence.

Common settings:

Key Description Default
PORT Service port 5000
HOST Bind host 0.0.0.0
SITE_URL Image proxy and external URL http://localhost:5000
PUBLIC_URL Optional fixed public URL empty
WECHAT_TOKEN / WECHAT_COOKIE WeChat credentials filled after QR login empty
RSS_FETCH_FULL_CONTENT Whether RSS fetches full content true
WECHAT_FETCH_CONCURRENCY Full-content fetch concurrency; lower is safer 1
WECHAT_FETCH_DELAY_MIN / WECHAT_FETCH_DELAY_MAX Random delay between full-content fetches, in seconds 8 / 18
WECHAT_ACCOUNT_DELAY Delay between accounts, in seconds 20
WECHAT_MAX_ARTICLES_PER_ACCOUNT Max full articles per account per poll 10
WECHAT_VERIFICATION_PAUSE_MINUTES Cooldown minutes after verification is triggered 60
WECHAT_VERIFICATION_STOP_THRESHOLD Verification threshold before cooldown 1
WECHAT_PROXY_REQUIRED Require proxy pool before fetching full content false
DAILY_ARCHIVE_DOWNLOAD_IMAGES Download images during daily archive true
MINIMAX_API_KEY MiniMax Token Plan Key empty
MINIMAX_API_STYLE Text model API style anthropic
MINIMAX_BASE_URL Text model base URL https://api.minimax.io/anthropic
MINIMAX_API_HOST Vision endpoint host https://api.minimaxi.com
MINIMAX_MODEL Text extraction model MiniMax-M2.7
MINIMAX_VISION_ENABLED Enable vision understanding true
EVENT_AUTOMATION_ENABLED Enable scheduled event automation false
EVENT_AUTOMATION_LOOKBACK_DAYS Automation lookback days 0
EVENT_RETENTION_DAYS Retention days for old unfavorited events 15
PROXY_URLS SOCKS5/HTTP proxy pool empty
CLOUDFLARE_TUNNEL_ENABLED Whether start.sh launches Cloudflare Tunnel false

Anti-risk suggestions:

  • When fetching full content, use 2-3 SOCKS5 proxies to reduce WeChat risk checks.
  • Example: PROXY_URLS=socks5://user:pass@ip1:1080,socks5://user:pass@ip2:1080
  • The default is a conservative free-mode setup: one scheduled run per day, 0-1 lookback days, and up to 10 full articles per account per poll.
  • Conservative settings: WECHAT_FETCH_CONCURRENCY=1, WECHAT_FETCH_DELAY_MIN=8, WECHAT_FETCH_DELAY_MAX=18, WECHAT_ACCOUNT_DELAY=20.
  • After proxies are stable, concurrency can be raised to 2; staying above 3 long term is not recommended.
  • If verification is triggered, the system enters a 60-minute cooldown, shows the remaining cooldown in settings, and stops the current scheduled run.

SOCKS5 Proxy Pool (Strongly Recommended)

When full-content fetching is enabled, a proxy pool is strongly recommended to reduce the chance of WeChat risk checks. Direct connections without proxies may lead to frequent verification prompts, account restrictions, or IP blocking. Using 2-3 proxy IPs helps distribute requests and lowers operational risk.

Purpose: distribute article full-content requests across multiple IPs while using Chrome TLS fingerprint simulation. EventRadar uses curl_cffi to mimic Chrome-like TLS fingerprints, so requests look closer to real browser traffic; a proxy pool makes this setup more robust.

Recommended setup: prepare 2-3 low-cost VPS instances and run one SOCKS5 proxy service on each. gost is recommended because it is a single Go binary with no extra runtime dependencies.

1. Install gost on each VPS

# Download the release package. This example uses Linux amd64.
# For other architectures, choose the matching file from GitHub Releases.
wget https://github.com/go-gost/gost/releases/download/v3.2.6/gost_3.2.6_linux_amd64.tar.gz

# If GitHub downloads are slow, use an acceleration mirror when available.
wget https://gh-proxy.com/https://github.com/go-gost/gost/releases/download/v3.2.6/gost_3.2.6_linux_amd64.tar.gz
# or
wget https://ghproxy.cc/https://github.com/go-gost/gost/releases/download/v3.2.6/gost_3.2.6_linux_amd64.tar.gz

# Extract and install
tar -xzf gost_3.2.6_linux_amd64.tar.gz
mv gost /usr/local/bin/
chmod +x /usr/local/bin/gost

# Verify installation
gost -V

2. Start the SOCKS5 proxy

# With username/password authentication (recommended; replace myuser / mypass / port)
gost -L socks5://myuser:mypass@:1080

# Without authentication (only for private networks or strict firewall rules)
gost -L socks5://:1080

3. Configure systemd for auto-start

cat > /etc/systemd/system/gost.service << 'EOF'
[Unit]
Description=GOST Proxy
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/gost -L socks5://myuser:mypass@:1080
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable gost
systemctl start gost

4. Open the firewall port

# Allow only your main server IP to connect. Replace with the real IP.
ufw allow from YOUR_MAIN_SERVER_IP to any port 1080

If you use a cloud security group, add an inbound rule in the provider console: port 1080 / TCP / source IP restricted to your main server.

5. Configure the proxy pool in the main server .env

PROXY_URLS=socks5://myuser:mypass@vps1-ip:1080,socks5://myuser:mypass@vps2-ip:1080,socks5://myuser:mypass@vps3-ip:1080

Restart the service after configuration. Article requests will rotate across proxy IPs. You can verify proxy-pool status with GET /api/health. Leaving PROXY_URLS empty uses direct connections, which is the default behavior.

Testing

PYTHONPYCACHEPREFIX=.pycache venv/bin/python -m unittest discover -s tests
PYTHONPYCACHEPREFIX=.pycache venv/bin/python -m compileall -q app.py routes utils tests

Data Directory

Path Description
data/rss.db Account subscriptions and article cache
data/events.db Event store
data/daily_archives/YYYY-MM-DD/articles.json Daily article archive
data/daily_archives/YYYY-MM-DD/images/ Daily image archive
data/events/YYYY-MM-DD/events.json Daily event export
data/events/YYYY-MM-DD/calendar.ics Daily ICS export
data/automation/ Automation run history

Notes

  • This project requires QR-code login with a WeChat official account administrator. Credentials usually expire after about 4 days.
  • Chrome TLS fingerprinting, proxy rotation, random delays, account-level spacing, verification detection, and cooldown are built in; for bulk full-content fetching, a proxy pool and low concurrency are still recommended.
  • Image-only articles depend on MiniMax Token Plan vision understanding. Without a key, only weak fallback rules are available.
  • Quick Tunnel public URLs are temporary and not ideal for production.
  • This project is for learning, research, and personal information organization. Please follow the relevant WeChat platform terms.

Acknowledgements

EventRadar is developed on top of the original open-source WeChat Download API project, which provides the essential WeChat login, article fetching, RSS, image proxy, anti-risk, and FastAPI foundation. This project adds event extraction, vision understanding, an event store, calendar UI, ICS subscription, automation progress, favorite protection, retention cleanup, and repeated-import dedupe.

Thanks to:

License

This project follows the original project's AGPL-3.0 license. If you modify it and provide it as a network service, please comply with AGPL-3.0 obligations.

About

EventRadar turns the chaotic flow of online activity information into a personal opportunity intelligence system, helping you discover, rank, and manage the events that truly matter.(可智能推荐的个人活动日历)

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors