This skill automatically aggregates Spotify-related news from 9+ sources (official Spotify blogs + media + community), deduplicates articles, ranks them by relevance, and delivers a formatted Chinese digest — one-sentence summary per article with the original link.
Key Features:
Read this before scheduling or running in any environment with internal network access.
verify=True on all HTTP requests. Do not add any ssl._create_default_https_context overrides.ALLOWED_DDG_DOMAINS (defined at the top of scripts/fetch_spotify_news.py). Only well-known public news domains pass; internal hostnames are rejected. Review and edit that list before running in sensitive environments.config/sources.json are official Spotify feeds and a few trusted media outlets. Do not add intranet or metadata-service URLs to sources.json.feedparser, beautifulsoup4, requests, python-dateutil, ddgs.agentTurn cron job. Confirm the target channel is a group/recipient you intend before confirming the job.bash
cd /projects/.openclaw/skills/spotify-news-digest
python3 scripts/generate_digest.py
bash
python3 scripts/generate_digest.py --hours 168
bash
python3 scripts/generate_digest.py --hours 24 --output /tmp/spotify_digest.md
SourceTypeURL / MethodCategorySpotify Engineering BlogRSSengineering.atspotify.com/feed/officialSpotify NewsroomRSSnewsroom.spotify.com/feed/officialSpotify ResearchRSSresearch.atspotify.com/feed/researchSpotify DesignRSSspotify.design/feeddesignTechCrunch SpotifyRSStechcrunch.com/tag/spotify/feed/mediaThe Verge (filtered)RSSVerge full feed + keyword filtermediaHacker News SpotifyAlgolia APIhn.algolia.com query=spotifycommunityDDG News SearchDDGS API5 queries × 8 resultsmedia/official
Note: Music Business Worldwide and Billboard RSS feeds have high latency and are disabled by default (
_disabled: trueinsources.json). Their articles are captured via DDG News Search instead.
Each digest is grouped by category with one-sentence Chinese summaries:
text
🎵 Spotify 新闻日报 · YYYY-MM-DD
共 N 条(去重后)
─────────────────────────────
🎵 官方动态(N 条)
· [一句话中文总结](Source Name)
🔗 https://...
📰 媒体报道(N 条)
· [一句话中文总结](Source Name)
🔗 https://...
🔬 技术研究(N 条)
· ...
─────────────────────────────
🤖 由 OpenClaw · spotify-news-digest 自动生成
Category KeyDisplay Labelofficial🎵 官方动态research🔬 技术研究design🎨 产品设计media📰 媒体报道community💬 社区讨论industry🏭 行业资讯
python
import sys
sys.path.insert(0, '/projects/.openclaw/skills/spotify-news-digest/scripts')
from fetch_spotify_news import SpotifyNewsFetcher
from process_spotify_news import SpotifyNewsProcessor, format_digest
# Fetch articles from the last 48 hours
articles = SpotifyNewsFetcher().fetch_all(hours=48)
print(f"Fetched {len(articles)} articles")
# Deduplicate, score, and group by category
result = SpotifyNewsProcessor().process(articles, max_output=20)
# Render Markdown digest
md = format_digest(result, date_str='2026-03-17')
print(md)
The format_digest() function outputs [English Title] placeholders when no zh_summary is set on an article. The calling LLM should:
generate_digest.py to get the raw structured resulttitle + summary and generate a one-sentence Chinese summaryitem['zh_summary'] before calling format_digest()This two-step flow keeps the scraping fast and the summarization accurate.
python
# Example: LLM fills zh_summary before formatting
for cat_items in result.values():
for item in cat_items:
item['zh_summary'] = llm_summarize_zh(item['title'], item['summary'])
digest = format_digest(result)
Ask OpenClaw to set up a daily cron job:
"每天上午 10 点发一份 Spotify 新闻日报到 [群/频道]"
OpenClaw will create an isolated agentTurn cron job that:
Edit config/sources.json:
json
{
"sources": [
{
"name": "My Custom Source",
"type": "rss",
"url": "https://example.com/feed/",
"language": "en",
"category": "media",
"keyword_filter": "spotify"
}
],
"settings": {
"max_news_per_source": 15,
"final_output_count": 20,
"similarity_threshold": 0.65,
"timeout": 12,
"keyword_filter_default": "spotify"
}
}
keyword_filter: When set, only articles containing this keyword (case-insensitive) in title or summary are included. Leave empty for official Spotify feeds that are already Spotify-only.
_disabled: true: Mark a source to skip it at runtime without deleting it.
Security: Only add public news domains to
sources.json. Do not add intranet, VPN, or cloud metadata URLs — they could be fetched directly via RSS without domain-allowlist filtering.
If you add sources that are reachable via DDG News search (not RSS), also add their domain to ALLOWED_DDG_DOMAINS near the top of scripts/fetch_spotify_news.py:
python
ALLOWED_DDG_DOMAINS: tuple = (
'atspotify.com',
'techcrunch.com',
...
'your-new-domain.com', # ← add here
)
In scripts/process_spotify_news.py:
python
processor = SpotifyNewsProcessor(similarity_threshold=0.65)
# 0.5 = aggressive dedup | 0.8 = loose dedup
In process_spotify_news.py, edit source_weight:
python
source_weight = {
'Spotify Engineering Blog': 90,
'Spotify Newsroom': 80,
'TechCrunch': 60,
# Add your custom sources here
}
text
python3 scripts/generate_digest.py [OPTIONS]
Options:
--hours N Time range in hours (default: 24)
--max N Max articles to output after dedup (default: 20)
--output PATH Save Markdown digest to file
text
python3 scripts/fetch_spotify_news.py [OPTIONS]
Options:
--hours N Fetch articles published within last N hours
Most likely a network restriction on RSS endpoints.
bash
# Test direct RSS access
curl -I https://engineering.atspotify.com/feed/
# Test DDG search fallback
python3 -c "
from ddgs import DDGS
with DDGS() as d:
r = list(d.news('spotify new feature', max_results=3, timelimit='w'))
print(r)
"
If RSS is blocked but DDG works, the skill will still return results via the search fallback. This is normal in restricted network environments.
ddgs not installed#bash
pip3 install ddgs
duckduckgo-search(older package name) is also supported as a fallback.
Sources with slow RSS feeds are marked _disabled: true in sources.json. To disable an additional slow source:
json
{ "name": "...", "_disabled": true, ... }
Lower the similarity threshold:
python
SpotifyNewsProcessor(similarity_threshold=0.5)
The format_digest() function wraps untranslated titles in [brackets]. This is intentional — the LLM caller should fill zh_summary before rendering. See Usage Examples → LLM-Enhanced Summaries above.
text
spotify-news-digest/
├── SKILL.md ← You are here
├── config/
│ └── sources.json ← News source definitions & settings
├── scripts/
│ ├── fetch_spotify_news.py ← Multi-source fetcher (RSS + DDG)
│ ├── process_spotify_news.py ← Dedup, scoring, formatting
│ └── generate_digest.py ← CLI entry point (fetch → process → print)
└── references/
└── (reserved for future API reference docs)
bash
pip3 install feedparser beautifulsoup4 requests python-dateutil ddgs
PackagePurposefeedparserRSS feed parsingbeautifulsoup4HTML summary cleanuprequestsHTTP requests for RSSpython-dateutilRobust date parsingddgsDuckDuckGo News search fallback
Python: 3.8+
timelimit for recency filtering.VersionDateChanges1.1.02026-07-14Security: remove SSL bypass, add domain allowlist for DDG results, explicit verify=True on all requests, updated security guidance1.0.02026-03-17Initial release: RSS + DDG, 9 sources, category grouping, Chinese summary support