---
title: "账号与设置"
canonical_url: "https://tweetstream.io/zh-cn/docs/account-management"
last_updated: 2026-09-24
---

# 账号与设置

通过已认证的 REST 端点和账号设置管理监控账号及可选事件来源。

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

## 端点

将每个请求发送到 `https://api.tweetstream.io`，并附带 `Authorization: Bearer <API_KEY>`。

| 方法 | 路径 | 用途 |
| --- | --- | --- |
| `POST` | `/api/add-account` | 添加监控账号 |
| `DELETE` | `/api/remove-account` | 移除监控账号 |
| `GET` | `/api/me` | 读取套餐限制和用量 |
| `POST`, `DELETE` | `/api/affiliate-alerts` | 开启或关闭关联账号列表提醒 |
| `GET`, `POST`, `DELETE` | `/api/binance-square` | 列出币安广场账号，或开启、关闭某个账号 |

## 添加和移除账号

从后端调用 REST 端点来修改监控列表。

### 发送账号 handle

在 `accounts` 中发送一个 handle 或 handle 数组。开头的 @ 可以省略，匹配不区分大小写。

- `POST /api/add-account`
- `DELETE /api/remove-account`

#### 添加账号

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

const response = await fetch("https://api.tweetstream.io/api/add-account", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${apiKey}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    accounts: ["marketdesk", "realDonaldTrump"],
  }),
});

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

console.log(await response.json());
```

#### 移除账号

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

const response = await fetch("https://api.tweetstream.io/api/remove-account", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${apiKey}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    accounts: "marketdesk",
  }),
});

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

console.log(await response.json());
```

### 选择凭证范围

标准 API 密钥更新标准监控账号列表。有效的 Ultra 密钥更新 Ultra 选择，并执行其已付费账号上限。

### 读取每条结果

响应包含每个 handle 的处理结果，以及带有 `total`、`succeeded` 和 `failed` 计数的 `summary`。重试前应读取每行状态，而不能只看 HTTP 状态。

#### 添加结果

```json
{
  "action": "follow",
  "requestId": "8b4f9c9c-9e7b-4a0c-9c7d-2d4d6f0a9a25",
  "error": null,
  "results": [
    {
      "input": "marketdesk",
      "state": "added"
    },
    {
      "input": "realDonaldTrump",
      "state": "added"
    }
  ],
  "summary": {
    "failed": 0,
    "succeeded": 2,
    "total": 2
  }
}
```

#### 移除结果

```json
{
  "action": "unfollow",
  "requestId": "3f1c7d2e-5a4b-4c8d-9e0f-1a2b3c4d5e6f",
  "error": null,
  "results": [
    {
      "input": "marketdesk",
      "state": "removed"
    }
  ],
  "summary": {
    "failed": 0,
    "succeeded": 1,
    "total": 1
  }
}
```

## 检查当前用量

使用标准或 Ultra API 密钥调用 `/api/me`。此私有响应不会缓存。

- `GET /api/me`

### 读取套餐和用量字段

响应包含基础套餐用量和附加的 Ultra Speed 详情。

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `credentialScope` | `standard` 或 `ultra_speed` | 本次 Bearer 密钥的权限范围 |
| `plan` | `BASIC`、`ELITE` 或 `ENTERPRISE` | 运行时套餐值：`BASIC` 为 Minimum，`ELITE` 为 Pro，`ENTERPRISE` 为 Scale |
| `trackedAccounts` | object | 数量、限制和规范化 handles |
| `websocket` | object | 当前活跃连接数和套餐限制 |
| `stripe` | object | 订阅状态和账期字段；标识符应视为私有 |
| `ultraSpeed` | `object` 或 `null` | Ultra 状态、账期、限制、监控 handles（可能与顶层 `trackedAccounts` 重复）、独立 WebSocket 用量和取消时间 |

### 查看响应

#### 账号用量请求

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

const response = await fetch("https://api.tweetstream.io/api/me", {
  headers: {
    Authorization: `Bearer ${apiKey}`,
  },
});

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

console.log(await response.json());
```

#### 账号用量响应

```json
{
  "credentialScope": "standard",
  "plan": "ELITE",
  "trackedAccounts": {
    "count": 2,
    "limit": 250,
    "handles": ["marketdesk", "realDonaldTrump"]
  },
  "websocket": {
    "count": 1,
    "limit": 10
  },
  "stripe": {
    "subscriptionStatus": "ACTIVE",
    "customerId": "[redacted]",
    "hasCustomer": true,
    "subscriptionId": "[redacted]",
    "currentPeriodStart": "2026-06-30T00:00:00.000Z",
    "currentPeriodEnd": "2026-07-30T00:00:00.000Z",
    "canceledAt": null
  },
  "ultraSpeed": {
    "active": true,
    "status": "ACTIVE",
    "billingCycle": "MONTHLY",
    "paymentRail": "STRIPE_CARD",
    "accountLimit": 25,
    "trackedAccounts": {
      "count": 1,
      "handles": ["realDonaldTrump"]
    },
    "websocket": {
      "count": 1,
      "limit": 5
    },
    "currentPeriodEnd": "2026-07-30T00:00:00.000Z",
    "cancelAtPeriodEnd": false,
    "canceledAt": null
  }
}
```

## 跟踪关联账号列表变更

已监控的企业账号在有效或试用中的 Pro、Scale 和 Ultra 套餐上默认关闭关联账号列表变更。

### 开启或关闭提醒

使用 `POST /api/affiliate-alerts`、`DELETE /api/affiliate-alerts` 或控制台。将已监控的 handle 作为 `account` 发送，开头的 @ 可以省略。重复请求是安全的。成功时返回 `{ account, affiliateAlertsEnabled }`。

- `POST /api/affiliate-alerts`
- `DELETE /api/affiliate-alerts`

#### 修改提醒设置

```typescript
async function setAffiliateAlerts(account: string, enabled: boolean) {
  const response = await fetch("https://api.tweetstream.io/api/affiliate-alerts", {
    method: enabled ? "POST" : "DELETE",
    headers: {
      Authorization: `Bearer ${process.env.TWEETSTREAM_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ account }),
  });

  if (!response.ok) {
    throw new Error(await response.text());
  }
  return await response.json();
}

console.log(await setAffiliateAlerts("marketdesk", true));
console.log(await setAffiliateAlerts("marketdesk", false));
```

### 处理设置错误

开启提醒时，TweetStream 会检查账号是否仍符合企业账号资格。检查失败时返回 `400` 和 `{ error: "This account is not a business account." }`。

| 状态 | 出现时机 | 处理方式 |
| --- | --- | --- |
| `200` | 已保存的设置与请求一致 | 读取 `affiliateAlertsEnabled` |
| `400` | 请求 body 无效或账号不是企业账号 | 修正请求 |
| `401` | Bearer 密钥缺失或无效 | 发送有效的 API 密钥 |
| `403` | 订阅或功能权限未生效 | 检查套餐权限 |
| `404` | 此 API 密钥未监控该 handle | 检查已监控 handle |
| `500` | TweetStream 无法确认资格 | 稍后重试 |

### 保存和回放变更

变更会发送到 WebSocket、控制台实时流和 Discord 通知路由。关键词过滤不适用。按 `(organization.id, member.id)` 保存关系，`eventId` 仅用于完全相同的重放去重。使用 `GET /api/history?type=AFFILIATE` 回放已记录变化。不提供当前列表快照或功能上线前回补。

## 接收币安广场帖子

币安广场账号默认关闭。可在控制台或通过此 API 开启。它们与 X 监控账号分开管理，不占用 X 账号额度。

### 列出和修改设置

`GET /api/binance-square` 返回已保存的设置，以及 `displayName`、`squareHandle`、`profileUrl`、`avatarUrl` 和 `enabled`。`POST /api/binance-square` 开启账号；`DELETE /api/binance-square` 关闭账号。将广场 handle 放在 `account` 中，开头的 @ 可以省略。重复请求是安全的。

- `GET /api/binance-square`
- `POST /api/binance-square`
- `DELETE /api/binance-square`

- `profileUrl` 是规范地址。没有头像时，`avatarUrl` 为 `null`。
- 设置属于 TweetStream 用户，因此生效的 Standard 和 Ultra 凭证会共享它们。
- 保存成功时返回 `{ account, binanceSquareEnabled }`，其中包含规范 handle。

#### 列出币安广场账号

```typescript
const response = await fetch(
  "https://api.tweetstream.io/api/binance-square",
  {
    headers: {
      Authorization: `Bearer ${process.env.TWEETSTREAM_API_KEY}`,
    },
  },
);

if (!response.ok) {
  throw new Error(await response.text());
}

const catalog = await response.json();
console.log(catalog);
// {
//   accounts: [{
//     avatarUrl: "https://bin.bnbstatic.com/static/content/live-admin-api/images/chVikg58jFQ6ScXcVmWNmj.png",
//     displayName: "币安Binance华语",
//     enabled: true,
//     profileUrl: "https://www.binance.com/en/square/profile/Vpo7Qwqy63rk7_Km3zYYaQ",
//     squareHandle: "binancezh"
//   }],
//   canManage: true
// }
```

#### 开启或关闭帖子

```typescript
async function setBinanceSquarePosts(account: string, enabled: boolean) {
  const response = await fetch("https://api.tweetstream.io/api/binance-square", {
    method: enabled ? "POST" : "DELETE",
    headers: {
      Authorization: `Bearer ${process.env.TWEETSTREAM_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ account }),
  });

  if (!response.ok) {
    throw new Error(await response.text());
  }
  return await response.json();
}

console.log(await setBinanceSquarePosts("binancezh", true));
// { account: "binancezh", binanceSquareEnabled: true }
```

### 处理实时内容

已开启账号的帖子、回复和引用会通过 WebSocket 和适用的 Discord 路由发送。广场内容不会存入 History，因此重连后不会补发错过的帖子。关键词过滤仍然生效。Discord 默认使用全局 webhook，适用账号专属路由时除外。

- 内容使用 `tweet/content`，`author.platform` 为 `binance_square`，`kind` 为 `post`、`reply` 或 `quote`。
- 后续推文操作的 `d.platform` 为 `binance_square`；使用 `(platform, tweetId)` 作为帖子键。
- 有引用上下文时，回复和引用会包含 `ref`。帖子链接使用币安规范地址。广场作者没有 `author.url`，因为币安广场不提供账号网站。

#### 币安广场内容事件

```json
{
  "v": 1,
  "t": "tweet",
  "op": "content",
  "id": "358051617962575",
  "ts": 1772000001100,
  "d": {
    "tweetId": "358051617962575",
    "kind": "quote",
    "text": "Example Binance Square quote",
    "createdAt": 1772000001000,
    "receivedAt": 1772000001100,
    "link": "https://www.binance.com/en/square/post/358051617962575",
    "author": {
      "id": "Vpo7Qwqy63rk7_Km3zYYaQ",
      "handle": "@binancezh",
      "platform": "binance_square"
    },
    "ref": {
      "type": "quote",
      "tweetId": "358012920288073"
    }
  }
}
```

### 处理设置错误

| 状态 | 出现时机 | 处理方式 |
| --- | --- | --- |
| `200` | 已列出目录或保存设置 | 读取响应 body |
| `400` | 请求 body 无效或账号不在目录中 | 修正请求 |
| `401` | Bearer 密钥缺失或无效 | 发送有效的 API 密钥 |
| `403` | API 凭证未生效 | 检查订阅状态 |
| `500` | TweetStream 无法保存此设置 | 稍后重试 |

## 读取账号处理结果

| 状态 | 出现时机 | 推荐处理 |
| --- | --- | --- |
| `added` | 账号已加入监控列表 | 视为成功 |
| `already_following` | 账号已经在监控中 | 作为逐行幂等结果处理 |
| `removed` | 账号已移除 | 视为成功 |
| `not_following` | 账号原本没有被监控 | 作为逐行幂等结果处理 |
| `invalid_input`、`duplicate`、`not_found`、`failed` | 输入无效、输入重复、账号不存在或操作失败 | 展示逐行 message，仅在合适时重试 |

## 读取 REST 状态码

Add 和 remove 端点为每个 handle 返回一行结果。HTTP 状态说明批处理结果，每行 result 说明对应 handle 的结果。

| 状态 | 出现时机 | 说明 |
| --- | --- | --- |
| `200` | 没有任何行失败，包括幂等成功结果 | `summary.failed` 为 0；`already_following` 和 `not_following` 都属于成功结果 |
| `207` | 部分行成功，部分行失败 | 重试前读取 `results` 和 `summary` |
| `400` | 请求 body 无效，或每一行都因非临时原因失败 | 重试前先修正请求或逐行错误 |
| `429` | handle 请求过多 | 稍等后重试整批请求 |
| `503` | 每一行都因临时原因失败 | 使用退避策略重试整批请求 |

## 检查套餐限制

- Minimum：试用后 50 个监控账号和 3 个 WebSocket 连接。
- Trial：3 天内 5 个监控账号和 1 个 WebSocket 连接。
- Pro：250 个监控账号和 10 个 WebSocket 连接。
- Scale：可在定价页自助配置更高的监控账号和 WebSocket 限制。
- Pro、Scale 和 Ultra Speed 提供完整 History 回放。
