buzz
Real-time news aggregator with Discord & Telegram push. Manage Jin10, BlockBeats, RSS, X KOLs, Polymarket, OpenNews via REST API.
安装 / 下载方式
TotalClaw CLI推荐
totalclaw skills install shop:github:LeoYeAI~openclaw-master-skills~buzzcURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/github%3ALeoYeAI~openclaw-master-skills~buzz/file -o buzz.md# Buzz Skill
Install, run, and manage a real-time news aggregator with Discord & Telegram push notifications. All configuration is done via REST API with hot-reload — no restarts needed.
**Base URL**: `http://localhost:3848` (default, configurable via `dashboard.port`)
## Security Notice
- `config.json` stores API keys, bot tokens, and webhook URLs locally. **Never commit it to version control** (it is gitignored by default).
- If `dashboard.password` is empty, the REST API is **unauthenticated**. Always set a password when the dashboard is exposed beyond localhost.
- The server binds to `0.0.0.0` by default. Use a reverse proxy or firewall to restrict access in production.
- Review the source code at [github.com/zxcnny930/buzz](https://github.com/zxcnny930/buzz) before running.
## Quick Setup
```bash
git clone https://github.com/zxcnny930/buzz.git
cd buzz
npm install
cp config.example.json config.json # Edit config.json and set dashboard.password before starting
npm start
```
The dashboard is at `http://localhost:3848`, settings page at `/settings.html?lang=en`.
## Authentication
If a dashboard password is set, all `/api/*` endpoints require `?pw=PASSWORD`:
```bash
curl -s "http://localhost:3848/api/config?pw=YOUR_PASSWORD"
```
If password is empty string, no authentication is needed.
**IMPORTANT: All curl examples below omit `?pw=` for brevity. If the server has a password configured, append `?pw=PASSWORD` to every URL.**
Auth failure response (HTTP 401):
```json
{ "ok": false, "error": "Unauthorized" }
```
---
## API Endpoints
### 1. Get Current Config
```bash
curl -s http://localhost:3848/api/config
```
Returns the full configuration JSON. Sensitive fields (apiKey, token, botToken, password) are redacted as `"••••••"` in the response.
### 2. Update Config (Partial, Hot-Reload)
`POST /api/config` accepts partial updates. Only send the sections you want to change.
**Enable Jin10 with 10-second polling:**
```bash
curl -s -X POST http://localhost:3848/api/config \
-H "Content-Type: application/json" \
-d '{"jin10": {"enabled": true, "pollIntervalMs": 10000}}'
```
**Disable Polymarket:**
```bash
curl -s -X POST http://localhost:3848/api/config \
-H "Content-Type: application/json" \
-d '{"polymarket": {"enabled": false}}'
```
**Set Discord webhook:**
```bash
curl -s -X POST http://localhost:3848/api/config \
-H "Content-Type: application/json" \
-d '{"discord": {"webhookUrl": "https://discord.com/api/webhooks/..."}}'
```
**Enable Telegram:**
```bash
curl -s -X POST http://localhost:3848/api/config \
-H "Content-Type: application/json" \
-d '{"telegram": {"enabled": true, "botToken": "123456:ABC-DEF", "chatId": "-1001234567890"}}'
```
**Add an RSS source:**
```bash
curl -s -X POST http://localhost:3848/api/config \
-H "Content-Type: application/json" \
-d '{"rssFeeds": [{"enabled": true, "name": "CoinDesk", "feedUrl": "https://www.coindesk.com/arc/outboundfeeds/rss/?outputType=xml", "pollIntervalMs": 300000, "color": 3447003}]}'
```
> Note: `rssFeeds` is an array — sending it replaces the entire array, not appends.
**Configure OpenNews AI filtering:**
```bash
curl -s -X POST http://localhost:3848/api/config \
-H "Content-Type: application/json" \
-d '{"opennews": {"enabled": true, "pollIntervalMs": 60000, "minScore": 70, "signals": ["long"], "coins": ["BTC", "ETH"], "engineTypes": ["news", "listing"]}}'
```
**Configure Polymarket alerts:**
```bash
curl -s -X POST http://localhost:3848/api/config \
-H "Content-Type: application/json" \
-d '{"polymarket": {"enabled": true, "minChangePp": 5, "zThreshold": 2.5, "volSpikeThreshold": 2.0, "minLiquidity": 10000, "tagIds": [21, 120], "excludeTagIds": [100639]}}'
```
**Set translation engine and AI model:**
```bash
# Use Google Translate (free, default)
curl -s -X POST http://localhost:3848/api/config \
-H "Content-Type: application/json" \
-d '{"translator": "google"}'
# Use AI translation (OpenAI-compatible API)
curl -s -X POST http://localhost:3848/api/config \
-H "Content-Type: application/json" \
-d '{"translator": "ai", "ai": {"apiKey": "xai-...", "model": "grok-4.1-fast", "baseUrl": "https://api.x.ai/v1"}}'
```
**Success response:**
```json
{ "ok": true }
```
**Validation error response:**
```json
{
"ok": false,
"errors": ["polymarket.zThreshold must be > 0", "dashboard.port must be 1024-65535"]
}
```
### 3. Get Source Status
```bash
curl -s http://localhost:3848/api/status
```
**Response:**
```json
{
"jin10": { "active": true, "interval": 15000 },
"blockbeats": { "active": true, "interval": 30000 },
"polymarket": { "active": true, "interval": 180000 },
"x6551": { "active": true, "interval": 3600000 },
"opennews": { "active": false, "interval": 60000 },
"rss:https://www.blocktempo.com/feed/": { "active": true, "interval": 300000 }
}
```
Each key is a source identifier. RSS sources are prefixed with `rss:` followed by their feed URL.
### 4. Manage KOL Tracking List
**List all tracked accounts:**
```bash
curl -s -X POST http://localhost:3848/api/kols \
-H "Content-Type: application/json" \
-d '{"action": "list"}'
```
Response:
```json
{ "ok": true, "kols": ["elonmusk", "VitalikButerin"] }
```
**Add a KOL:**
```bash
curl -s -X POST http://localhost:3848/api/kols \
-H "Content-Type: application/json" \
-d '{"action": "add", "username": "caboronli"}'
```
Response:
```json
{ "ok": true, "kols": ["elonmusk", "VitalikButerin", "caboronli"] }
```
If already exists:
```json
{ "ok": true, "message": "already exists", "kols": ["elonmusk", "VitalikButerin", "caboronli"] }
```
**Remove a KOL:**
```bash
curl -s -X POST http://localhost:3848/api/kols \
-H "Content-Type: application/json" \
-d '{"action": "remove", "username": "elonmusk"}'
```
Response:
```json
{ "ok": true, "kols": ["VitalikButerin", "caboronli"] }
```
If username not found:
```json
{ "ok": false, "error": "not found", "kols": ["VitalikButerin", "caboronli"] }
```
> Username strings are trimmed and `@` prefix is automatically stripped.
### 5. Health Check
```bash
curl -s http://localhost:3848/health
```
Response:
```json
{ "ok": true, "clients": 2, "history": 150 }
```
- `clients`: number of active SSE connections
- `history`: number of events in memory
No authentication required.
### 6. Server-Sent Events (Live Stream)
```bash
curl -s -N http://localhost:3848/sse
```
Streams real-time news events as SSE. On connection, all historical events are sent first, then new events arrive in real-time. Heartbeat every 15 seconds.
---
## Full Configuration Schema
### jin10
| Field | Type | Default | Validation | Description |
|-------|------|---------|------------|-------------|
| `enabled` | boolean | `true` | | Enable Jin10 flash news |
| `pollIntervalMs` | number | `15000` | >= 5000 | Poll interval in milliseconds |
| `onlyImportant` | boolean | `true` | | Only push important items |
### blockbeats
| Field | Type | Default | Validation | Description |
|-------|------|---------|------------|-------------|
| `enabled` | boolean | `true` | | Enable BlockBeats |
| `pollIntervalMs` | number | `30000` | >= 5000 | Poll interval |
| `onlyImportant` | boolean | `true` | | Only push important items |
| `lang` | string | `"cht"` | | Language: `cht` (Trad. Chinese), `en`, `cn` (Simp. Chinese) |
### rssFeeds (array)
| Field | Type | Default | Validation | Description |
|-------|------|---------|------------|-------------|
| `enabled` | boolean | `true` | | Enable this feed |
| `name` | string | | | Display name |
| `feedUrl` | string | | must start with `http(s)://` | RSS/Atom feed URL |
| `pollIntervalMs` | number | `300000` | >= 5000 | Poll interval |