# @crvouga/mockingbird-service-fitbit 中文文档

规范地址：https://npmcn.com/package/%40crvouga/mockingbird-service-fitbit/

版本：0\.5\.0
npm 元数据更新时间：2026-11-11T02:11:10.050Z
中文译文更新时间：2026-11-11T09:41:12.827Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40crvouga/mockingbird-service-fitbit
原文对照：https://npmcn.com/package/%40crvouga/mockingbird-service-fitbit/?lang=original
项目主页：https://github.com/crvouga/mockingbird/tree/main/packages/service/fitbit#readme
源码仓库：https://github.com/crvouga/mockingbird

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

- 包体积（解压后）：4.3 MB，18 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：2 个
- 首次发布：2026-10-21T17:02:50.542Z
- 最新版本发布：2026-11-11T02:11:09.609Z
- 近 30 天下载量：2388（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：14（近 12 个月 14 个）

## 中文简介

Stateful Fitbit 遗留的Web API模拟器:OAuth PKCE和撤销,活性日志,睡眠和有合成数据的每日摘要.

## 安装

```sh
npm install @crvouga/mockingbird-service-fitbit
```

也可以使用：`pnpm add @crvouga/mockingbird-service-fitbit`、`yarn add @crvouga/mockingbird-service-fitbit`、`bun add @crvouga/mockingbird-service-fitbit`

## README

# @crvouga/mockingbird-service-fitbit (英语)

> 本地模拟器。 真正的API合同. 部分 [嘲笑鸟](https://github.com/crvouga/mockingbird)。 。 。 .

WIP Fitbit遗留的Web API模拟器:OAuth 2.0授权代码与PKCE,刷新旋转并撤销,配置,活动日志列表,睡眠日志按日期和日常活动摘要,超过合成数据. Fitbit于2026-09-30宣布终止对遗产Web API的支持并停用于2026-10-30 (移民目标:Google Health API);此仿真器在此后保留了被记录下来的遗产合同可以测试.

## 安装

`bun add @crvouga/mockingbird-service-fitbit`

## 使用量

```ts
import { createServer } from "@crvouga/mockingbird-service-fitbit/server"

// Test setup: a local Fitbit. One origin serves the API, token, revoke and authorize routes, so it
// replaces https://api.fitbit.com and https://www.fitbit.com in the application.
const server = await createServer({
  activityLogs: [
    {
      userId: "ABC123",
      log: { logId: 1, activityName: "Walk", startTime: "2026-09-02T06:00:00.000-07:00", steps: 3000 },
    },
  ],
})
const baseUrl = server.url

// Application code: the requests it sends to Fitbit (default synthetic user ABC123 and its token).
const response = await fetch(
  `${baseUrl}/1/user/-/activities/list.json?afterDate=2026-09-01&sort=asc&limit=20&offset=0`,
  { headers: { authorization: "Bearer mock_fitbit_token", accept: "application/json" } },
)
const { activities, pagination } = await response.json()

await server.close()
```

运行 `mockingbird-fitbit serve --port 12141`Fitbit没有发布JS SDK,消费者使用原始的HTTP,因此将模拟源作为API源,代号源,撤销源和授权页源(一个本地源服务于全部4个)注入. 浏览器或模拟器在 HTTP 上到达授权页面, 因此使用已服务模拟器而不是在进程内 `fetch` 同意步骤.

## 路线

| 路线 | 它会做什么 |
| --- | --- |
| `GET /oauth2/authorize` | 同意页. 验证 `client_id`, (中文(简体) ), `redirect_uri`, (中文(简体) ), `response_type=code`, (中文(简体) ), `scope`和S256号 `code_challenge`,然后将(302)重定向到重新定向的URI上 `code` 财务报告和审定财务报表 `state`,或与 `error`, (中文(简体) ), `error_description` 财务报告和审定财务报表 `state`。未注册的客户端或重定向 URI 无法重定向并回答 400 HTML . |
| `POST /oauth2/token` | 基本客户验证、形式机构(a) `type: "client"` 应用程序发送 `client_id` 而不是在体内,没有授权头. `authorization_code` (与 `redirect_uri` 财务报告和审定财务报表 `code_verifier`和 `refresh_token` 赠款。 答复 `access_token`, (中文(简体) ), `refresh_token`, (中文(简体) ), `expires_in: 28800`, (中文(简体) ), `token_type: "Bearer"`, (中文(简体) ), `scope`, (中文(简体) ), `user_id`。 。 。 . |
| `POST /oauth2/revoke` | 基本客户端认证(或,用于 `type: "client"` 应用程序,可选机构 `client_id`),表单 `token=<access or refresh token>`. 200; 用户给客户的每个符号都不见了. |
| `GET /1/user/{-|encodedId}/profile.json` | `{ user: { encodedId, displayName, ... } }`1\. 范围 `profile`。 。 。 . |
| `GET /1/user/-/activities/list.json` | `afterDate` (与 `sort=asc`)或(或) `beforeDate` (与 `sort=desc`, (中文(简体) ), `limit` (1至100个), `offset`1\. 范围 `activity`。 。 。 . |
| `GET /1/user/-/activities/date/{date}.json` | `{ activities, goals, summary }`1\. 范围 `activity`。 。 。 . |
| `GET /1/user/-/sleep/date/{date}.json` 财务报告和审定财务报表 `/1.2/...` | `{ sleep, summary }`1\. 范围 `sleep`。两个路径版本服务于相同的数据. |

授权代码是单用并持续了10分钟;访问令牌在模拟器时钟上持续了28800秒. 刷新为同一用户和范围发布新访问并刷新令牌,并去除前一对(单用旋转,所以旧访问令牌回答401和旧刷新令牌回答) `invalid_grant`) (中文(简体) ). 一个失败的代码交换(错误的校验器,错误的重定向URI)不会消耗代码. 默认客户端是 `mock_client` 编号 : `mock_client_secret` (任何方向调整的URI,除非 `redirectUris` 种子; 种子客户端 `type: "client"` 以模拟 Fitbit “ client”( 公用) app, 以认证 `client_id` 单独([Fitbit 文档](https://dev.fitbit.com/build/reference/web-api/authorization/oauth2-token/)),并且应当使用 PKCE;默认用户是 `ABC123` 无记名者 `mock_fitbit_token` 并刷新标志 `mock_fitbit_refresh`所有瞄准镜,直到2100年的时钟.

数据语义:活动日志被过滤并由本地墙钟部分命令 `startTime` (单位:千美元)`afterDate` 包括:, `beforeDate` 除外); `pagination.next` 是一个完整的 URL 在模拟器源头上的下一个 `offset` 是最后一页的空字符串; `previous` 同样的。 睡眠记录属于白天 `dateOfSleep` (自 `endTime`因此,在前一天晚上开始的日志,在它结束的那天被归还; `summary` 总计 `minutesAsleep` 财务报告和审定财务报表 `timeInBed` 数额 `levels.summary.{deep,light,rem,wake}.minutes` 输入 `summary.stages` 当任何木材携带的时候, 没有睡眠记录的一天是200 `{ sleep: [], summary: { totalMinutesAsleep: 0, totalSleepRecords: 0, totalTimeInBed: 0 } }`; 无活动数据的一天为 200 个零 `summary`默认值 `goals` 财务报告和审定财务报表 `activities: []`日期为 `YYYY-MM-DD` (实际日历日期)或 `today`. 日志是传递的:种子的每一个字段都会回来.

## 测试控制

种子与 `createRuntime`编号 :`createServer` 选项(`users`, (中文(简体) ), `clients`, (中文(简体) ), `grants`, (中文(简体) ), `codes`, (中文(简体) ), `activityLogs`, (中文(简体) ), `sleepLogs`, (中文(简体) ), `dailySummaries`, (中文(简体) ), `consent`)或下面的管理员路线(均相对于 `/__admin`,可通过 `adminPrefix`:

| 管理路线 | 对 |
| --- | --- |
| `PUT /consent` `{ mode: "approve" | "deny" | "error", userId? }` 编号 : `GET /consent` | 授权页面下一步要做什么, 以及该代码属于哪个种子用户 . |
| `POST /users` `{ encodedId, profile? }` | 种子用户; `profile` 字段返回配置路径. |
| `POST /activity-logs` 编号 : `POST /sleep-logs` `{ userId?, logs: [...] }` | 种子原木(`logId` 财务报告和审定财务报表 `startTime` 需要睡觉 `endTime`) (中文(简体) ). 重复 `logId` 替换日志. |
| `POST /daily-summaries` `{ userId?, date, activities?, goals?, summary? }` | 种子一天; 字段在默认情况下合并 . |
| `POST /tokens/expire` `{ userId }` | 将用户的访问符号过期, 不移动时钟; 刷新符号仍然有效 . |
| `POST /tokens/revoke` `{ userId }` | 撤销用户的每个符号, 所以下一个刷新是 `invalid_grant`。 。 。 . |

`POST /clock {"advance": ms}` 移动命名空间时钟:一个超过28800秒的访问符,然后回答401 `expired_token`,而超过10分钟的代码被拒绝。 标准 `/__admin/health`, (中文(简体) ), `/state` (会费) `users`, (中文(简体) ), `clients`, (中文(简体) ), `grants`, (中文(简体) ), `codes`, (中文(简体) ), `activity_logs`, (中文(简体) ), `sleep_logs`, (中文(简体) ), `daily_summaries`, (中文(简体) ), `settings`, (中文(简体) ), `/reset`, (中文(简体) ), `/requests`,有时间线检查站和故障。 标题 `x-mockingbird-namespace`, (中文(简体) ), `/__admin/ns/<name>` 路径和证书映射(持有者令牌或 Basic client id) 隔离数据。 期刊中包含元数据,从不表示或健康有效载荷.

预设`POST /__admin/faults {"preset": "<name>", "count": n}`: `unauthorized` (401美元) `expired_token`, (中文(简体) ), `forbidden` (403) (中文(简体) ) `insufficient_scope`, (中文(简体) ), `rate_limited` (429处) `Retry-After: 2` 财务报告和审定财务报表 `fitbit-rate-limit-*` 信头, `rate_limited_no_retry_after`, (中文(简体) ), `server_error` (500个), `connection_drop`。没有webhooks:订阅 API 不是模拟.

## 证据和最佳猜测

这里没有观察到任何针对一个活的Fitbit账户(遗留的API没有沙盒,需要一个同意的用户). 合同遵循供应商参考书目 [https://dev.fitbit.com/building/reference/web-api/ 页面存档备份,存于互联网档案馆](https://dev.fitbit.com/build/reference/web-api/) (授权,令牌,刷新,撤销,活动清单,按日期入睡,简介). 下方所有的东西都是 **最好猜,不是甲骨文验证** 并被跟踪到本议题 `needs-oracle-check`数字 :

-   页:1 `{"errors":[{"errorType","message","fieldName"?}],"success":false}` 信封和密码 `errorType` 名称 (`invalid_client`, (中文(简体) ), `invalid_grant`, (中文(简体) ), `invalid_request`, (中文(简体) ), `unsupported_grant_type`, (中文(简体) ), `invalid_token`, (中文(简体) ), `expired_token`, (中文(简体) ), `insufficient_scope`, (中文(简体) ), `insufficient_permissions`, (中文(简体) ), `validation`, (中文(简体) ), `too_many_requests`• 其信息和状况(401份客户资格差和坏或过期的无记名信使,400份赠款和参数差,403份范围或另一个用户的代号);
-   单用途刷新旋转会杀死先前的访问令牌,而不在失败的交换上消耗授权代码;
-   `offset` 0以上者,享有荣誉(参考文件) `Supported: 0` 和建设 `next` ,下页), `next` 作为最后一页的空字符串,并且 `next` 使用下一个 `offset` 而不是移动 `afterDate`· ;
-   页:1 `afterDate`编号 :`sort` 配对规则和 `limit` 1至100 约束为400 `validation`· ;
-   `/1/` 财务报告和审定财务报表 `/1.2/` 睡眠服务于相同的数据,包括 `levels.summary` 阶段总计;
-   撤销回答 200 `{}` 和一个未知的代号,还有200(RFC 7009),一个未知的用户代号,在回答403的路径中;
-   429个正文和标题集, 以及配置文件、目标和一个空日的默认值.

## 甲骨文和测试

`bun test` 运行接受测试(服务请求的每个编号行为一次,通过 `test/consumer.ts`,消费者的 httpx 客户端的端口)和每一次操作的自平并有差异检测. `bun run parity` 需求 `FITBIT_ACCESS_TOKEN`,进行安全的只读配置和活性清单信封检查,并永远不打印健康数据或证书.

## 故意不模拟

内部时间序列、心率和SpO2时间序列、设备、朋友、订阅和网络用户、写作(创建日志、目标)、隐性赠款和客户证书赠款, `GET /1/user/-/activities/{id}.json` (没有记录每个用户的路由),TCX下载,Google Health API,同意UI(同意由W `consent` 控件和浏览器仅重定向) `#_=_` 将销售商附件分解到重定向、费率限制(限制仅通过预设脚本)、真实的健康数据和设备配对.

## API 密码

根运行时间导出 : `FitbitAPI`, (中文(简体) ), `FITBIT_NAMESPACE`, (中文(简体) ), `FITBIT_SCOPES`, (中文(简体) ), `ACCESS_TOKEN_SECONDS`, (中文(简体) ), `CODE_SECONDS`, (中文(简体) ), `fitbitError`, (中文(简体) ), `createRuntime`, (中文(简体) ), `FITBIT_PRESETS`, (中文(简体) ), `document`, (中文(简体) ), `operationIds`, (中文(简体) ), `supportedOperationIds`类型包括: `FitbitAPIOptions`, (中文(简体) ), `Client`, (中文(简体) ), `User`, (中文(简体) ), `Grant`, (中文(简体) ), `OAuthCode`, (中文(简体) ), `ActivityLog`, (中文(简体) ), `ActivityLogEntry`, (中文(简体) ), `SleepLog`, (中文(简体) ), `SleepLogEntry`, (中文(简体) ), `DailySummary`, (中文(简体) ), `Consent`, (中文(简体) ), `FitbitRuntimeOptions`, (中文(简体) ), `FitbitRuntime`, (中文(简体) ), `OperationId`, (中文(简体) ), `SupportedOperationId`。 。 。 .

`/server` 出口 `createServer`, (中文(简体) ), `serveTarget`, (中文(简体) ), `DEFAULT_PORT` 类型 `FitbitServerOptions`, (中文(简体) ), `FitbitServer`。 。 。 .

## 常见问题

### @crvouga/mockingbird-service-fitbit 是什么？

Stateful Fitbit 遗留的Web API模拟器:OAuth PKCE和撤销,活性日志,睡眠和有合成数据的每日摘要\.

### 如何安装 @crvouga/mockingbird-service-fitbit？

在项目目录运行 npm install @crvouga/mockingbird-service-fitbit，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 mockingbird-fitbit，可以用 npx mockingbird-fitbit 直接运行。

### @crvouga/mockingbird-service-fitbit 支持 TypeScript 吗？

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

### @crvouga/mockingbird-service-fitbit 支持 ESM 还是 CommonJS？

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

### @crvouga/mockingbird-service-fitbit 可以商用吗？

@crvouga/mockingbird-service-fitbit 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @crvouga/mockingbird-service-fitbit 的下载量有多少？

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

### @crvouga/mockingbird-service-fitbit 还在维护吗？

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

