---
title: "新闻事件与 History"
canonical_url: "https://tweetstream.io/zh-cn/docs/news"
last_updated: 2026-09-24
---

# 新闻事件与 History

选择媒体，实时接收 `news/article`，并通过独立的游标式新闻 History API 获取已存文章。

Canonical URL: https://tweetstream.io/zh-cn/docs/news

## 选择媒体

使用控制台或 `GET` 和 `PATCH /api/news/sources` 查看并修改已启用的媒体。

- `GET /api/news/sources`
- `PATCH /api/news/sources`

### 新闻来源响应

```json
{
  "sources": [
    {
      "id": "bbc-news",
      "name": "BBC News",
      "icon": "/news-sources/bbc.png",
      "available": true,
      "enabled": true
    },
    {
      "id": "dexerto",
      "name": "Dexerto",
      "icon": "/news-sources/dexerto.png",
      "available": true,
      "enabled": false
    }
  ]
}
```

## news/article

已启用媒体的文章会通过其他 TweetStream 事件所用的同一 WebSocket 发送。

### 新闻文章类型

```typescript
type NewsSource = {
  id: string;
  name: string;
};

type NewsMedia = {
  url: string;
  type?: 'image' | 'video';
  caption?: string;
};

type NewsArticle = {
  source: NewsSource;
  url: string;
  title: string;
  publishedAt: string;
  receivedAt: number;
  modifiedAt?: string;
  primaryCategory?: string;
  categories: string[];
  author?: string;
  keywords: string[];
  description?: string;
  summary?: string;
  media: NewsMedia[];
  content?: string;
  language?: string;
  copyright?: string;
};
```

### 新闻文章事件

```json
{
  "v": 1,
  "t": "news",
  "op": "article",
  "id": "news_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "ts": 1787786858123,
  "d": {
    "source": {
      "id": "bbc-news",
      "name": "BBC News"
    },
    "url": "https://www.bbc.com/news/articles/example",
    "title": "Markets open after the holiday",
    "publishedAt": "2026-08-26T23:27:38.000Z",
    "receivedAt": 1787786858123,
    "primaryCategory": "Business",
    "categories": ["Business"],
    "author": "BBC News",
    "keywords": ["markets"],
    "description": "A brief description supplied by the publication.",
    "summary": "Markets reopened after the holiday.",
    "media": [
      {
        "url": "https://ichef.bbci.co.uk/news/example.jpg",
        "type": "image",
        "caption": "A market floor"
      }
    ],
    "content": "The stored article text, when available.",
    "language": "en",
    "copyright": "BBC"
  }
}
```

## 新闻 History API

`GET /api/news/history` 按 `(receivedAt DESC, id DESC)` 顺序返回已启用媒体的已存文章。`limit` 默认为 50，取值范围为 1 至 100。

使用 `nextCursor` 继续翻页。达到响应大小限制时，一页可能少于指定数量。这不代表任何保留期限或历史完整性保证。

- `GET /api/news/history`

### 新闻 History 类型

```typescript
type NewsSource = {
  id: string;
  name: string;
};

type NewsMedia = {
  url: string;
  type?: 'image' | 'video';
  caption?: string;
};

type NewsArticle = {
  source: NewsSource;
  url: string;
  title: string;
  publishedAt: string;
  receivedAt: number;
  modifiedAt?: string;
  primaryCategory?: string;
  categories: string[];
  author?: string;
  keywords: string[];
  description?: string;
  summary?: string;
  media: NewsMedia[];
  content?: string;
  language?: string;
  copyright?: string;
};

type HistoricalNewsArticle = {
  id: string;
  source: NewsSource;
  url: string;
  title: string;
  publishedAt: string;
  receivedAt: string;
  modifiedAt: string | null;
  primaryCategory: string | null;
  categories: string[];
  author: string | null;
  keywords: string[];
  description: string | null;
  summary: string | null;
  media: NewsMedia[];
  content: string | null;
  language: string | null;
  copyright: string | null;
};

type NewsHistoryResult = {
  data: HistoricalNewsArticle[];
  metadata: {
    count: number;
    nextCursor: string | null;
    sourceId?: string;
  };
};
```

### 获取新闻 History

```typescript
const apiKey = process.env.TWEETSTREAM_API_KEY;
if (!apiKey) throw new Error("Missing TWEETSTREAM_API_KEY");

const url = new URL(
  "https://api.tweetstream.io/api/news/history",
);
url.searchParams.set("sourceId", "bbc-news");
url.searchParams.set("limit", "1");

const response = await fetch(url, {
  headers: {
    Authorization: `Bearer ${apiKey}`,
  },
});

if (!response.ok) {
  const detail = await response.text();
  throw new Error(`News history failed (${response.status}): ${detail}`);
}

const page = await response.json();
console.log(page.data);

if (page.metadata.nextCursor) {
  url.searchParams.set("before", page.metadata.nextCursor);
}
```

### 新闻 History 响应

```json
{
  "data": [
    {
      "id": "news_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
      "source": {
        "id": "bbc-news",
        "name": "BBC News"
      },
      "url": "https://www.bbc.com/news/articles/example",
      "title": "Markets open after the holiday",
      "publishedAt": "2026-08-26T23:27:38.000Z",
      "receivedAt": "2026-08-26T23:27:38.123Z",
      "modifiedAt": null,
      "primaryCategory": "Business",
      "categories": ["Business"],
      "author": "BBC News",
      "keywords": ["markets"],
      "description": "A brief description supplied by the publication.",
      "summary": "Markets reopened after the holiday.",
      "media": [
        {
          "url": "https://ichef.bbci.co.uk/news/example.jpg",
          "type": "image",
          "caption": "A market floor"
        }
      ],
      "content": "The stored article text, when available.",
      "language": "en",
      "copyright": "BBC"
    }
  ],
  "metadata": {
    "count": 1,
    "nextCursor": "v1.MTc4Nzc4Njg1ODEyMwpuZXdzXzAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY",
    "sourceId": "bbc-news"
  }
}
```
