Install
openclaw skills install @lgy2020/info-streamDaily tech news collection and distribution system. Automated methodology for collecting, curating, and distributing industry news via scheduled cron jobs. Use when setting up automated daily news digests, creating tech news roundups, or building scheduled content delivery workflows. Triggers on "daily news", "news digest", "tech roundup", "industry news collection", "automated newsletter", "news cron".
openclaw skills install @lgy2020/info-streamAutomated methodology for collecting, curating, and distributing industry news.
Separate collection (slow) from distribution (fast) using a file cache.
07:00 Collect news → Write to weekly file (slow, ~3-5 min)
08:00 Read file → Push to chat (instant, <10 sec)
Key insight: Collection and distribution happen the same morning. News is at most ~1 hour old when delivered, not 9+ hours.
Create a markdown file for the current week: weekly-news-YYYY-WNN.md
Schedule an isolated agentTurn cron job that:
Schedule an isolated agentTurn cron job that:
Timing: 1 hour gap between collection and distribution ensures collection completes before push.
Use Tavily API (or similar) with keyword groups tailored to your domain. Example for browser/AI news (7 groups, ~27 candidates):
browser Chrome Firefox Safari Edge news 2026 (5 results, topic: news)AI machine learning LLM technology news March 2026 (5 results, topic: news)中国科技 AI 浏览器 最新消息 (5 results, topic: news)Web standards W3C WHATWG V8 JavaScript new features 2026 (3 results, topic: news)Android Chrome mobile browser development 2026 (3 results, topic: news)APPSO 机器之心 量子位 AI 人工智能 最新 (3 results, topic: news)虎嗅 雷科技 科技行业 消费电子 (3 results, topic: news)See references/tavily-setup.md for Tavily API setup.
Use web_fetch to directly crawl authoritative blogs. These guarantee coverage of domain-specific news that AI search might miss.
Example sources for browser/AI domain:
https://webkit.org/blog/https://v8.dev/bloghttps://hacks.mozilla.org/https://blog.chromium.org/Check community aggregators for trending discussions:
https://news.ycombinator.com| Layer | Weight | Purpose | Speed | Depth |
|---|---|---|---|---|
| AI Search API | ~80% | Broad discovery | Fast (1-3s/query) | Medium |
| Core blogs | ~20% | Domain authority | Slow (5-10s/source) | Deep |
| Aggregators | Optional | Community trends | Fast | Shallow |
Each layer should contribute 2-3 stories minimum to ensure balanced coverage.
## YYYY.M.D Report Title | Day N
Use domain-specific categories. Examples:
### 🔧 Browser Engine & Web Standards### 🦊 Firefox / Mozilla### 🤖 AI & Browser Tech### 🇨🇳 Regional Tech### 📱 Mobile / Web DevN. emoji **Title** — Description (2-3 sentences with specific details like version numbers, data, impact)
- Source: full clickable URL
#### 💡 Analyst Insights
💡 **Insight Title** — Analysis (2-3 sentences with actionable perspective)
*Sources: Source1 · Source2 · Source3*
*Collected: YYYY-MM-DD HH:MM TZ*
Critical: Multiple cron sessions may run simultaneously and cause conflicts.
Save this as tavily-search.js and run with: node tavily-search.js "query" [max_results] [topic] [search_depth]
Requires TAVILY_API_KEY environment variable.
#!/usr/bin/env node
/**
* Tavily Search — AI-optimized search API wrapper for news collection
* Usage: node scripts/tavily-search.js "query" [max_results] [topic] [search_depth]
*
* Env: TAVILY_API_KEY required
* Output: JSON with results array (title, url, content, score)
*/
const https = require('https');
const API_KEY = process.env.TAVILY_API_KEY;
if (!API_KEY) {
console.error('Error: TAVILY_API_KEY environment variable not set');
process.exit(1);
}
const query = process.argv[2];
const maxResults = parseInt(process.argv[3]) || 5;
const topic = process.argv[4] || 'general';
const searchDepth = process.argv[5] || 'basic';
if (!query) {
console.error('Usage: node tavily-search.js "query" [max_results] [topic] [search_depth]');
process.exit(1);
}
const payload = JSON.stringify({
query,
max_results: maxResults,
topic,
search_depth: searchDepth,
include_answer: true,
include_raw_content: false,
});
const req = https.request({
hostname: 'api.tavily.com',
path: '/search',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`,
},
}, (res) => {
let body = '';
res.on('data', (chunk) => body += chunk);
res.on('end', () => {
try {
const data = JSON.parse(body);
const output = {
query: data.query,
answer: data.answer || null,
results: (data.results || []).map(r => ({
title: r.title,
url: r.url,
content: r.content?.substring(0, 500),
score: r.score,
})),
};
console.log(JSON.stringify(output, null, 2));
} catch (e) {
console.error('Parse error:', e.message);
console.error('Raw:', body.substring(0, 500));
process.exit(1);
}
});
});
req.on('error', (e) => {
console.error('Request error:', e.message);
process.exit(1);
});
req.write(payload);
req.end();