This source did not publish a separate summary. Review SKILL.md before using the skill.
SKILL.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.
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:
Username strings are trimmed and @ prefix is automatically stripped.
5. Health Check
curl -s http://localhost:3848/health
Response:
{ "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)
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.
Same pattern applies when removing or editing an RSS feed — always send the complete updated array.
Remove an RSS feed
GET current list, remove the target, POST back the remaining array.
# Get current feeds, then POST without the one you want to remove
curl -s http://localhost:3848/api/config | jq '.rssFeeds'
# POST back the array minus the removed feed
curl -s -X POST http://localhost:3848/api/config \
-H "Content-Type: application/json" \
-d '{"rssFeeds": [
{"enabled": true, "name": "BlockTempo", "feedUrl": "https://www.blocktempo.com/feed/", "pollIntervalMs": 300000, "color": 16746496}
]}'
Add an item to any array field (general pattern)
When the user says "also add X", always follow GET → modify → POST:
# Step 1: GET current value
CURRENT=$(curl -s http://localhost:3848/api/config | jq '.polymarket.tagIds')
# Example result: [21, 120]
# Step 2: Append and POST back
# Adding Sports (100639) to existing [21, 120]
curl -s -X POST http://localhost:3848/api/config \
-H "Content-Type: application/json" \
-d '{"polymarket": {"tagIds": [21, 120, 100639]}}'
Same pattern applies to opennews.signals, opennews.coins, opennews.engineTypes, polymarket.excludeTagIds.
# Add
curl -s -X POST http://localhost:3848/api/kols \
-H "Content-Type: application/json" \
-d '{"action": "add", "username": "VitalikButerin"}'
# List all
curl -s -X POST http://localhost:3848/api/kols \
-H "Content-Type: application/json" \
-d '{"action": "list"}'
Important Rules
Array fields are REPLACED, never merged
The config deep-merge only merges plain objects. All array fields are completely replaced when you POST them. If the user wants to add an item to an existing list, you MUST GET the current config first, modify the array, then POST back.
Array fields that require GET-first when adding/removing items:
Field
Example "add" intent
rssFeeds
"Add CoinDesk RSS" — GET current feeds, append, POST full array
polymarket.tagIds
"Also track Sports" — GET current tagIds, append 100639, POST
polymarket.excludeTagIds
"Also exclude Culture" — same pattern
opennews.signals
"Also show long signals" — GET, append "long", POST
opennews.coins
"Also track SOL" — GET, append "SOL", POST
opennews.engineTypes
"Also include listings" — GET, append "listing", POST
Exception — KOLs have a safe endpoint: Use POST /api/kols with action: "add" or "remove". This does NOT require GET-first. Do NOT modify x6551.kols via POST /api/config — use the dedicated endpoint instead.
When the user says "set to" (replace entire list) instead of "add", you can POST directly without GET-first. Example: "I only want Crypto and Finance" → {"polymarket": {"tagIds": [21, 120]}} is fine.
Other rules
Object sections support partial update. You can POST just {"jin10": {"enabled": false}} without affecting other jin10 fields or other sections.
Sensitive fields are redacted in GET responses as "••••••". When POSTing, redacted values are automatically preserved (not overwritten).
All changes are hot-reloaded — no restart needed, except dashboard.port.
The x6551.token is shared between X tweet monitor and OpenNews.