Claude
Skills
Sign in
Back

buzz

Included with Lifetime
$97 forever

Real-time news aggregator with Discord & Telegram push. Manage Jin10, BlockBeats, RSS, X KOLs, Polymarket, OpenNews via REST API.

Backend & APIs

What this skill does

# 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
Files: 3
Size: 19.6 KB
Complexity: 30/100
Category: Backend & APIs

Related in Backend & APIs