Integrate with news APIs (GNews, NewsAPI, etc.) for aggregated news feeds. Covers headline fetching, search, and category filtering.
复制下面这句话,粘贴给 Claude Code、Codex、Cursor 等 AI 编程工具,它会读取安装说明并在你确认后完成安装。
请阅读 https://ai.atlankj.com/install/asset/gh-news-api-integration-2cdafadd84a9 ,按照其中的说明把「news-api-integration」安装到你(当前 AI 工具)中。执行前先告诉我将运行的命令和写入的位置,等我确认。
查看 AI 将读取的安装说明正在读取 GitHub 原文…
内容来自 GitHub 原始文件,由原作者维护。在 GitHub 查看
Multiple news APIs available. GNews is recommended for free tier usability.
https://gnews.io/api/v4token=API_KEYGET /top-headlines?category=general&lang=en&max=10&token=API_KEY
Categories: general, world, nation, business, technology, entertainment, sports, science, health
GET /search?q=artificial+intelligence&lang=en&max=10&token=API_KEY
{
"totalArticles": 1234,
"articles": [
{
"title": "Article Title",
"description": "Short description...",
"content": "Full article content (truncated)...",
"url": "https://example.com/article",
"image": "https://example.com/image.jpg",
"publishedAt": "2024-01-15T12:00:00Z",
"source": {
"name": "CNN",
"url": "https://cnn.com"
}
}
]
}
GET /v2/top-headlines?country=us&apiKey=API_KEY
GET /v2/everything?q=bitcoin&apiKey=API_KEY
| API | Free Tier | Best For |
|---|---|---|
| GNews | 100 req/day | General news, good free tier |
| Currents API | 600 req/day | Real-time news, good rate |
| NewsData.io | 200 req/day | News + crypto news |
| The Guardian | Unlimited (rate limited) | UK/international news |
| New York Times | 500 req/day | US news, archives |
| Mediastack | 500 req/month | Multi-source aggregation |
| TheNews API | 100 req/day | Simple aggregation |
| MarketAux | 100 req/day | Financial news with sentiment |
| HackerNews | No limit | Tech/startup news (no key needed) |
// src/services/news.ts
import { createCircuitBreaker } from '@/utils/circuit-breaker';
export interface NewsArticle {
title: string;
description: string;
url: string;
source: string;
publishedAt: string;
image?: string;
}
const newsBreaker = createCircuitBreaker<NewsArticle[]>({
name: 'News',
cacheTtlMs: 5 * 60_000, // 5 minutes
});
export async function fetchNews(category = 'general'): Promise<NewsArticle[]> {
return newsBreaker.execute(async () => {
const resp = await fetch(`/api/news?category=${category}`);
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
const data = await resp.json();
return data.articles || [];
}, []);
}
export async function searchNews(query: string): Promise<NewsArticle[]> {
const resp = await fetch(`/api/news?q=${encodeURIComponent(query)}`);
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
const data = await resp.json();
return data.articles || [];
}
For tech news, HackerNews API is free and unlimited:
// Fetch top 30 stories
const topIds = await fetch('https://hacker-news.firebaseio.com/v0/topstories.json').then(r => r.json());
const stories = await Promise.all(
topIds.slice(0, 30).map((id: number) =>
fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`).then(r => r.json())
)
);
// Each story: { title, url, score, by, time, descendants }
private render(articles: NewsArticle[]): void {
const rows = articles.map(a => `
<div class="news-item">
<a href="${a.url}" target="_blank" rel="noopener" class="news-title">${escapeHtml(a.title)}</a>
<div class="news-meta">
<span class="news-source">${escapeHtml(a.source)}</span>
<span class="news-time">${formatTime(new Date(a.publishedAt))}</span>
</div>
</div>
`).join('');
this.setContent(`<div class="news-list">${rows}</div>`);
}
Always escape user-controlled strings with escapeHtml() to prevent XSS.