# @bsky/sdk 中文文档

规范地址：https://npmcn.com/package/%40bsky/sdk/

版本：1\.3\.0
npm 元数据更新时间：2026-10-17T13:23:47.483Z
中文译文更新时间：2026-11-08T17:17:43.155Z
软件包许可：MIT OR Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40bsky/sdk
原文对照：https://npmcn.com/package/%40bsky/sdk/?lang=original
项目主页：https://bsky.app/
源码仓库：https://github.com/bluesky-social/bsky

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：4.3 MB，2800 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22\.12\.0
- 运行依赖：3 个
- peer 依赖：@atproto/lex ^0\.3\.0
- 首次发布：2026-08-05T06:37:08.478Z
- 最新版本发布：2026-10-17T13:23:47.110Z
- 近 30 天下载量：30960（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：12（近 12 个月 12 个）

## 中文简介

Bluesky SDK 与 @ atproto/ lex 一起使用

## 安装

```sh
npm install @bsky/sdk
```

也可以使用：`pnpm add @bsky/sdk`、`yarn add @bsky/sdk`、`bun add @bsky/sdk`

## README

# @bsky/ sdk (英语)

Bluesky SDK 创建于 [@ atproto/ lex (韩语)](https://github.com/bluesky-social/atproto/tree/main/packages/lex). 提供 Bluesky 词汇定义、打字动作、节制公用事业、丰富文本的助手和字符串公用事业.

## 安装

```sh
npm install @bsky/sdk @atproto/lex
```

`@atproto/lex` 提供 `Client` 给API拨打的电源. `@bsky/sdk` 提供布鲁斯基特有的词汇、行动和公用事业.

## 开始

```typescript
import { Client } from '@atproto/lex'
import { PasswordSession } from '@atproto/lex-password-session'
import { post } from '@bsky/sdk'

const session = await PasswordSession.login({
  service: 'https://bsky.social',
  identifier: 'your.bsky.social', // your handle
  password: 'xxxx-xxxx-xxxx-xxxx', // an app password, generated in the Bluesky app
})
const client = new Client(session)

await client.call(post, { text: 'Hello, world!' })
```

## 使用量

### 会话管理

大多数API的电话都需要经过认证的会话. 有两种方法 管理会议:

1.  [基于密码的 App 会话管理](https://npmcn.com/package/%40bsky/sdk/#readme-app-password-based-session-management)
2.  [基于 OAuth 会话管理](https://npmcn.com/package/%40bsky/sdk/#readme-oauth-based-session-management)

#### 基于密码的 App 会话管理

用户名/ 基于密码的认证可以使用 `PasswordSession` 课程从 `@atproto/lex-password-session`。 。 。 .

> \[叹息\]
> 
> 这种方法被贬值,有利于基于OAuth的会话管理. 没错 建议使用基于 OAuth 会话管理(通过 `@atproto/oauth-client-*` 软件包).

```typescript
import { Client } from '@atproto/lex'
import {
  PasswordSession,
  type SessionData,
} from '@atproto/lex-password-session'

const session = await PasswordSession.login({
  service: 'https://bsky.social',
  identifier: 'your.bsky.social', // your handle
  password: 'xxxx-xxxx-xxxx-xxxx', // an app password, generated in the Bluesky app
  onUpdated: (data: SessionData) => saveToStorage(data),
  onDeleted: (data: SessionData) => clearStorage(data.did),
})
const client = new Client(session)
console.log(`Authenticated as: ${client.assertDid}`)

// Next time, resume with the persisted session data to avoid storing
// user credentials:
const resumed = await PasswordSession.resume(loadFromStorage(), {
  onUpdated: (data: SessionData) => saveToStorage(data),
  onDeleted: (data: SessionData) => clearStorage(data.did),
})
```

#### 基于 OAuth 会话管理

根据应用程序所使用的环境, OAuth 客户端 备有:

-   [@atproto/oauth-客户端浏览器](https://www.npmjs.com/package/@atproto/oauth-client-browser)数字 : 用于浏览器.
-   [@atproto/oauth-客户端-节点](https://www.npmjs.com/package/@atproto/oauth-client-node): 用于 节点.js.
-   [@atproto/oauth-客户端](https://www.npmjs.com/package/@atproto/oauth-client)数字 : 下层;可兼容大多数JS引擎.

每个 `@atproto/oauth-client-*` 执行有另一种方式来获得 可用于即时 a `Client`这里有一个 实例恢复先前保存的会话 :

```typescript
import { Client } from '@atproto/lex'
import { OAuthClient } from '@atproto/oauth-client'

const oauthClient = new OAuthClient({
  // ...
})

const oauthSession = await oauthClient.restore('did:plc:123')

// Instantiate the lex Client using an OAuth session
const client = new Client(oauthSession)
```

### 经认证的公众客户

使用 `api.*` 用于处理 Bluesky 服务的常数 :

```typescript
import { Client } from '@atproto/lex'
import { api } from '@bsky/sdk'

// Bluesky API (authenticated queries, proxied through the account host;
// record writes and mutations automatically target the account host directly)
const bskyClient = new Client(session, { service: api.app.service })

// Bluesky API (unauthenticated public queries)
const publicBskyClient = new Client(api.app.urlPublic)
```

### API电话

SDK出口许多共同业务的行动. 起诉 客户端为 `client.call(action, input)`数字 :

```typescript
import {
  blockActor,
  blockActorList,
  deleteFollow,
  deleteLike,
  deletePost,
  deleteRepost,
  follow,
  getPreferences,
  like,
  muteActor,
  muteActorList,
  post,
  repost,
  unblockActor,
  unblockActorList,
  unmuteActor,
  unmuteActorList,
  updateSeenNotifications,
  upsertProfile,
} from '@bsky/sdk'

// The DID of the user currently authenticated (or undefined)
bskyClient.did
bskyClient.assertDid // Throws if the user is not authenticated

// Feeds and content
await bskyClient.call(post, { text: 'Hello, world!' })
await bskyClient.call(deletePost, postUri)
await bskyClient.call(like, { uri, cid })
await bskyClient.call(deleteLike, likeUri)
await bskyClient.call(repost, { uri, cid })
await bskyClient.call(deleteRepost, repostUri)

// Social graph
await bskyClient.call(follow, { did })
await bskyClient.call(deleteFollow, followUri)
await bskyClient.call(muteActor, { actor })
await bskyClient.call(unmuteActor, { actor })
await bskyClient.call(blockActor, { did })
await bskyClient.call(unblockActor, blockUri)
await bskyClient.call(muteActorList, { list })
await bskyClient.call(unmuteActorList, { list })
await bskyClient.call(blockActorList, { list })
await bskyClient.call(unblockActorList, { list })

// Actors
await bskyClient.call(upsertProfile, (existing) => ({
  ...existing,
  displayName: 'Alice',
}))

// Notifications
await bskyClient.call(updateSeenNotifications, seenAt)

// Preferences
const prefs = await bskyClient.call(getPreferences)
```

没有专门动作的查询是一个 `xrpc` 使用生成的调用 词汇表——见 [高级 API 呼叫](https://npmcn.com/package/%40bsky/sdk/#readme-advanced-api-calls)。 。 。 .

### 审定和类型

词典包括一个完整的类型系统,具有验证和类型护栏. 例如,为了验证邮政记录:

```typescript
import { app } from '@bsky/sdk/lexicons'

const post = { ... }
if (app.bsky.feed.post.$isTypeOf(post)) {
  // typescript now recognizes `post` may be an app.bsky.feed.post.Main
  // however -- we still need to validate it
  const res = app.bsky.feed.post.main.safeValidate(post)
  if (res.success) {
    // a valid record
  } else {
    // something is wrong
    console.log(res.error)
  }
}
```

### 丰富文本

一些记录(i)使用 `app.bsky.richtext` 词典. 目前richtext只用于链接和提及,但会随着时间推移被扩展以包括粗体,斜体等.

这是 **强烈的** 建议使用此软件包 `RichText` 图书馆。 Javascript在utf16中编码字符串,而协议(和大多数其他编程环境)则使用utf8. 二人之间的转换很困难,但是 `RichText` 帮你处理.

```typescript
import { currentDatetimeString } from '@atproto/lex'
import { RichText } from '@bsky/sdk/richtext'

// creating richtext — detects mentions and links, resolving mentions to DIDs
const rt = await RichText.resolve(
  'Hello @alice.com, check out this link: https://example.com',
  { resolver: client },
)
const postRecord = {
  $type: 'app.bsky.feed.post',
  text: rt.text,
  facets: rt.facets,
  createdAt: currentDatetimeString(),
}

// rendering as markdown
let markdown = ''
for (const segment of rt.segments()) {
  if (segment.isLink()) {
    markdown += `[${segment.text}](${segment.link?.uri})`
  } else if (segment.isMention()) {
    markdown += `[${segment.text}](https://my-bsky-app.com/user/${segment.mention?.did})`
  } else {
    markdown += segment.text
  }
}

// calculating string lengths
const rt2 = new RichText({ text: 'Hello' })
console.log(rt2.length) // => 5
console.log(rt2.graphemeLength) // => 5
const rt3 = new RichText({ text: '👨‍👩‍👧‍👧' })
console.log(rt3.length) // => 25
console.log(rt3.graphemeLength) // => 1
```

### 调和

运用节制制度是一项具有挑战性的任务,但我们已经尽力为您简化了. 调和API帮助处理一系列广泛的任务,包括:

-   主持人标签
-   用户变异(包括变异者)
-   用户屏蔽
-   哑词
-   隐藏员额

更多信息,请参见 [调和文档](https://npmcn.com/package/%40bsky/sdk/docs/moderation.md)。 。 。 .

```typescript
import { getPreferences } from '@bsky/sdk'
import { moderatePost } from '@bsky/sdk/moderation'

// First get the user's moderation prefs and their label definitions
// =

const prefs = await bskyClient.call(getPreferences)
const labelDefs = {
  /* see the Moderation Documentation for gathering labelDefs */
}

// We call the appropriate moderation function for the content
// =

const postMod = moderatePost(postView, {
  userDid: bskyClient.assertDid,
  prefs: prefs.moderationPrefs,
  labelDefs,
})

// We then use the output to decide how to affect rendering
// =

// in feeds
if (postMod.ui('contentList').filter) {
  // don't include in feeds
}
if (postMod.ui('contentList').blur) {
  // render the whole object behind a cover (use postMod.ui('contentList').blurs to explain)
  if (postMod.ui('contentList').noOverride) {
    // do not allow the cover the be removed
  }
}
if (postMod.ui('contentList').alert || postMod.ui('contentList').inform) {
  // render warnings on the post
  // find the warnings in postMod.ui('contentList').alerts and postMod.ui('contentList').informs
}

// viewed directly
if (postMod.ui('contentView').filter) {
  // don't render the view
}
if (postMod.ui('contentView').blur) {
  // render the whole object behind a cover (use postMod.ui('contentView').blurs to explain)
  if (postMod.ui('contentView').noOverride) {
    // do not allow the cover the be removed
  }
}
if (postMod.ui('contentView').alert || postMod.ui('contentView').inform) {
  // render warnings on the post
  // find the warnings in postMod.ui('contentView').alerts and postMod.ui('contentView').informs
}

// post embeds in all contexts
if (postMod.ui('contentMedia').blur) {
  // render the whole object behind a cover (use postMod.ui('contentMedia').blurs to explain)
  if (postMod.ui('contentMedia').noOverride) {
    // do not allow the cover the be removed
  }
}
```

## 高级

### 高级 API 呼叫

以上动作为便利包装. 它们覆盖了大部分,但不是全部 现有方法.

《AT议定书》确定了带有反向DNA名称的方法和记录。 你们可以 使用生成的词典和客户端的 `call` 财务报告和审定财务报表 记录助手 :

```typescript
import { currentDatetimeString } from '@atproto/lex'
import { app, com } from '@bsky/sdk/lexicons'

// Record helpers always target the user's account host
const res1 = await bskyClient.createRecord({
  $type: 'app.bsky.feed.post',
  text: 'Hello, world!',
  createdAt: currentDatetimeString(),
})
const res2 = await bskyClient.call(
  com.atproto.repo.listRecords,
  { repo: alice.did, collection: 'app.bsky.feed.post' },
  { service: null }, // target the account host rather than the Bluesky API
)
// or, using the typed record convenience helper:
const res2b = await bskyClient.list(app.bsky.feed.post, {
  repo: alice.did, // optional. Defaults to bskyClient.did (throws if unauthenticated)
})

const res3 = await bskyClient.call(app.bsky.feed.getTimeline, {
  limit: 20,
})
// res3: app.bsky.feed.getTimeline.OutputSchema
```

命名空间根导出自 `/lexicons`数字 : `app`, (中文(简体) ), `com`, (中文(简体) ), `chat`。 。 。 .

### 自己拿来

如果你想提供自己的 `fetch` 执行——用于伐木、嘲笑、, 复试,或没有内置环境 `fetch` 建筑时通过它 页:1 `Client`数字 :

```typescript
import { Client } from '@atproto/lex'

const myFetch: typeof globalThis.fetch = async (input, init) => {
  console.log('requesting', input)
  const response = await globalThis.fetch(input, init)
  console.log('got response', response)
  return response
}

const client = new Client({
  service: 'https://example.com',
  fetch: myFetch,
})
```

## 子路径

| 导入 | 目录 |
| --- | --- |
| `@bsky/sdk` | `api` 常数,动作, `DEFAULT_LABEL_SETTINGS` |
| `@bsky/sdk/lexicons` | 产生词典定义(`app`, (中文(简体) ), `com`, (中文(简体) ), `chat`(中文(简体) ) |
| `@bsky/sdk/moderation` | `moderatePost`, (中文(简体) ), `moderateProfile`和朋友; `ModerationDecision`, (中文(简体) ), `ModerationUI` |
| `@bsky/sdk/richtext` | `RichText` 构建器 |
| `@bsky/sdk/utils` | 年龄保障助手, `sanitizeMutedWordValue`, nux 验证 |

## 从@atproto/ api 升级

见 [技能/升级/升级](https://npmcn.com/package/skills/upgrade-from-atproto-api/SKILL.md) 包括所有删除的API及其替换.

## 许可证

根据麻省理工学院和Apache 2.0条款,这个项目具有双重许可证:

-   麻省理工学院许可证[LICENSE-MIT.txt (英语)](https://github.com/bluesky-social/atproto/blob/main/LICENSE-MIT.txt) 或者说 [http://opensource.org/licenses/MIT 互联网档案馆的存檔,存档日期2013-12-02](http://opensource.org/licenses/MIT)(中文(简体) )
-   Apache 许可证,2.0版本, ([(原始内容存档于2017-09-31) (英语). LICENSE-APACHE.txt](https://github.com/bluesky-social/atproto/blob/main/LICENSE-APACHE.txt) 或者说 [http://www.apache.org/licenses/LICENSE-2.0 (中文(简体) )](http://www.apache.org/licenses/LICENSE-2.0)(中文(简体) )

下游项目和终端用户可自行选择单独或共同发放许可证。 这种双重许可的动机是Apache 2.0提供的额外软件专利保证.

## 常见问题

### @bsky/sdk 是什么？

Bluesky SDK 与 @ atproto/ lex 一起使用

### 如何安装 @bsky/sdk？

在项目目录运行 npm install @bsky/sdk，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：@atproto/lex（^0\.3\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @bsky/sdk 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @bsky/sdk 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @bsky/sdk 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22\.12\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @bsky/sdk 可以商用吗？

@bsky/sdk 使用 MIT OR Apache-2\.0 许可。可在 MIT、Apache-2\.0 中任选其一遵守。选择 MIT 时，宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @bsky/sdk 的下载量有多少？

根据 npm 官方下载统计，@bsky/sdk 在 2026/10/09 – 2026/11/07 这 30 天内被下载 30,960 次，日均约 1,032 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @bsky/sdk 还在维护吗？

最新版本 1\.3\.0 发布于 2026/10/17（22 天前）；至今共发布 12 个版本，其中过去 12 个月发布了 12 个；首次发布于 2026/08/05。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

