# @crvouga/mockingbird-service-google-calendar 中文文档

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

版本：3\.11\.0
npm 元数据更新时间：2026-11-11T02:17:11.788Z
中文译文更新时间：2026-11-11T04:08:39.797Z
软件包许可：MIT

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

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

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

- 包体积（解压后）：4.5 MB，18 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：2 个
- 首次发布：2026-09-22T23:54:22.165Z
- 最新版本发布：2026-11-11T02:17:11.305Z
- 近 30 天下载量：3214（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：42（近 12 个月 42 个）

## 中文简介

Google Calendar v3 API 和 Google OAuth 我们的EMR 呼叫的状态模拟器: 事件列表/插入/更新/删除/watch, channel.stop, calendarList/calendars, sorders exchange/refresh/revoke and userinfo,并附有逐个签名的推进通知.

## 安装

```sh
npm install @crvouga/mockingbird-service-google-calendar
```

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

## README

# @crvouga/mockingbird-service-google-日历

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

状态模拟器 **谷歌日历 v3** 财务报告和审定财务报表 **Google OAuth 2.0 (英语)** 测试套房,涵盖什么 我们的EMR后端呼叫: `calendarList.list`, (中文(简体) ), `calendars.insert`, (中文(简体) ), `events.list` (时间窗口, `q`, (中文(简体) ), `orderBy`,呼号,与 410 同步递增 `fullSyncRequired`, (中文(简体) ), `events.get/insert/ update/delete`, (中文(简体) ), `events.watch` 将通知推到频道的地址 `channels.stop`;加符号终点(授权代码和刷新赠款),撤销,以及 OpenID 用户信息 。 从业人员连接、同步EMR任命并接受日历推 没有谷歌的账户.

-   行动范围: [支助](https://github.com/crvouga/mockingbird/blob/main/packages/service/google-calendar/SUPPORT.md)
-   合同`openapi.yaml`从Google的日历 v3 发现文档中修剪 OAuth 文档到什么 `google-calendar-service.ts`, (中文(简体) ), `authorize.business.ts` 和网络 控制器的使用.

## 安装

```bash
npm install -D @crvouga/mockingbird-service-google-calendar
```

仅限无害环境管理。 节点 22或 Bun 1.2. 无土生属地. 给它服务 `npx mockingbird-google-calendar serve`, (中文(简体) ), `createServer` 从 `./server` (节点),或 `createRuntime` 与任何获取服务器.

## 使用量

接合( 应用程序的硬码今天 Google ): 给日历客户端一个 `rootUrl` (单位:千美元)`google.calendar({version: "v3", auth, rootUrl: "<emulator>/"})`),给出 `OAuth2Client` `endpoints: {oauth2TokenUrl: "<emulator>/token", oauth2RevokeUrl: "<emulator>/revoke"}`,并点 用户信息获取到 `<emulator>/oauth2/v3/userinfo`。 。 。 . `GOOGLE_WEBHOOK_URL` 可以保持原样:仿真者 帖子推向任何东西 `address` 应用程序注册(允许http,除非 `--require-https-webhooks`) (中文(简体) ).

```bash
npx mockingbird-google-calendar serve --port 8820 --client "$GOOGLE_CLIENT_ID:$GOOGLE_CLIENT_SECRET"
```

```ts
import { auth, calendar } from "@googleapis/calendar"
import { OAuth2Client } from "google-auth-library"
import { createServer } from "@crvouga/mockingbird-service-google-calendar/server"

const google = await createServer()

// The application's OAuth and Calendar clients. Only their URLs change.
const oauth = new OAuth2Client({
  clientId: "c",
  clientSecret: "s",
  redirectUri: "postmessage",
  endpoints: { oauth2TokenUrl: `${google.url}/token`, oauth2RevokeUrl: `${google.url}/revoke` },
})
// Authorization code "4/mock-<name>" signs in <name>@example.com ("4/mock-<email>" for others).
const { tokens } = await oauth.getToken("4/mock-dr.house")
const client = new auth.OAuth2()
client.setCredentials({ access_token: tokens.access_token ?? null })
const cal = calendar({ version: "v3", auth: client, rootUrl: `${google.url}/` })
await cal.events.insert({
  calendarId: "primary",
  requestBody: { summary: "Rounds", start: { dateTime: "2026-10-01T15:00:00Z" }, end: { dateTime: "2026-10-01T16:00:00Z" } },
})

await google.close()
```

在Google的UI(admin路由)中创建的事件

```ts
import { auth, calendar } from "@googleapis/calendar"
import { OAuth2Client } from "google-auth-library"
import { createServer } from "@crvouga/mockingbird-service-google-calendar/server"

const google = await createServer()

// Test control: the practitioner adds an event in Google's UI.
await fetch(`${google.url}/__admin/events`, {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    email: "dr.house@example.com",
    event: { summary: "Rounds", start: { dateTime: "2026-10-01T15:00:00Z" }, end: { dateTime: "2026-10-01T16:00:00Z" } },
  }),
})

// The application lists it through the Calendar client.
const oauth = new OAuth2Client({
  clientId: "c",
  clientSecret: "s",
  redirectUri: "postmessage",
  endpoints: { oauth2TokenUrl: `${google.url}/token` },
})
const { tokens } = await oauth.getToken("4/mock-dr.house")
const client = new auth.OAuth2()
client.setCredentials({ access_token: tokens.access_token ?? null })
const cal = calendar({ version: "v3", auth: client, rootUrl: `${google.url}/` })
const { data } = await cal.events.list({ calendarId: "primary" })
console.log(data.items?.map((event) => event.summary)) // ["Rounds"]

await google.close()
```

### 路线

| 路线 | 行为 |
| --- | --- |
| `POST /token` | 格式编码( E)`client_secret_post` 或基础). `authorization_code`数字 : `4/mock-<name or email>` → `{access_token, expires_in: 3599, refresh_token, scope, token_type, id_token}`; 代码是单用; 其他的都是400 `invalid_grant`。 。 。 . `refresh_token` + 一个新的访问标志(+ `id_token`); 被吊销或外国令牌 `invalid_grant`。未知客户端(与 `clients` 套) 401 (简体中文) `invalid_client`。 。 。 . |
| `POST /revoke?token=` | 撤销访问或刷新令牌; 未知 / 已取消 400 `invalid_token`。 。 。 . |
| `GET /oauth2/v3/userinfo` | `{sub, email, email_verified, name, given_name, family_name, picture}` (来自电子邮件,或与 `PUT /__admin/users/:email`) (中文(简体) ). |
| `GET /calendar/v3/users/me/calendarList` | 该账户的主要日历(id = mail)及其次要日历. |
| `POST /calendar/v3/calendars` | 创建次要日历( N)`…@group.calendar.google.com`) (中文(简体) ). |
| `GET /calendar/v3/calendars/{id}/events` | `timeMin`编号 :`timeMax` (重叠), `q`, (中文(简体) ), `showDeleted`, (中文(简体) ), `singleEvents`, (中文(简体) ), `orderBy` (单位:千美元)`startTime` 需求 `singleEvents`, (中文(简体) ), `updatedMin`, (中文(简体) ), `maxResults` ( `nextPageToken`; 最后一页带有 `nextSyncToken` (不与 `q`编号 :`orderBy`编号 :`updatedMin`) (中文(简体) ). `syncToken` 返回后仅更改,删除为 `{id, status: "cancelled"}`; 与窗口或 `q` 400;无效或无效是410 `fullSyncRequired`。 。 。 . |
| `POST …/events`, (中文(简体) ), `GET/PUT/DELETE …/events/{eventId}` | Base32hex ids(允许客户身份;重复409). 缺少起始/结束 400, 空区域 400 `timeRangeEmpty`。 。 。 . `PUT` 替换(时间移动时序列+1). `DELETE` 204,还是410 `deleted`。 。 。 . |
| `POST …/events/watch` | `{id, type: "web_hook", address, token?, expiration?}` → `{kind: "api#channel", id, resourceId, resourceUri, expiration}` (封顶30天). A 类 `sync` 立即推进 复制活道ids为400. |
| `POST /calendar/v3/channels/stop` | `{id, resourceId}` ^ 204;未知为404. |

错误使用 Google 的信封 `{error: {errors: [{domain, reason, message}], code, message, status?}}`。 。 。 . 无效或过期的访问令牌为 401 `authError` (用户信息 : `invalid_request`) (中文(简体) ).

### 推动通知

每次更改日历事件( 通过 API 或 管理员平面) 都会张贴到每个直播 该日历上的频道: 空正文 `X-Goog-Channel-ID`, (中文(简体) ), `X-Goog-Channel-Token` (当 设定), `X-Goog-Channel-Expiration` (RFC 1123), (中文(简体) ), `X-Goog-Message-Number` (1个) `sync`,然后为+1, `X-Goog-Resource-ID`, (中文(简体) ), `X-Goog-Resource-URI` 财务报告和审定财务报表 `X-Goog-Resource-State` (单位:千美元)`sync`,则 `exists`。停止或过期的(模拟时钟)频道获得什么也没有。 非-2xx 答案被重审 (一等会,一等会,一等会,一等会,一等会). `GET /__admin/webhooks` \* 清单交付,以及 `/__admin/webhooks/events`, (中文(简体) ), `…/replay`, (中文(简体) ), `…/flush` 工作如常.

### 管理员(超过标准合同)

| 路线 | 效果 |
| --- | --- |
| `POST /__admin/events` | `{email, calendarId?, event}`:创建一个事件,因为账户会出现在Google的UI(pushes)中. |
| `PUT /__admin/events/:id` | `{email, calendarId?, event}`:替换(pushes). |
| `DELETE /__admin/events/:id?email=&calendarId=` | 删除(pushes). |
| `GET /__admin/events?email=` | 被存储的事件(带有更改序列). |
| `PUT /__admin/users/:email` | 设置用户信息配置 . |
| `GET /__admin/channels` | 每道有其消息号,已失效并停旗. |
| `POST /__admin/sync-tokens/invalidate` | 至今为止所有发行的同步符号都回答410. |
| `GET/PUT /__admin/settings` | `{clients?, tokenTtlSeconds?, requireHttpsWebhooks?, maxChannelTtlSeconds?, scope?}`。 。 。 . |

错误预设( E)`POST /__admin/faults {"preset": "<name>", "count"?: n}`: `invalid_grant`, (中文(简体) ), `token_expired`, (中文(简体) ), `rate_limited` (403个上限), `too_many_requests` (429个), `calendar_api_disabled` (403次访问未配置), `insufficient_scopes`, (中文(简体) ), `sync_token_gone`, (中文(简体) ), `backend_error` (503个), `connection_drop`, (中文(简体) ), `push_duplicate`, (中文(简体) ), `push_drop`. gaxios 重试 429 和 5xx本身,所以通过一个 `count` 超过其预算(三次检讨).

### 命名空间

由账号: 访问符携带他们的电子邮件,所以 `PUT /__admin/credentials {"credentials": {"dr.house@example.com": "<namespace>"}}` 路径 日历和用户信息呼叫. `x-mockingbird-namespace` 和往常一样 A 类 `/__admin/ns/<name>` 前缀 用于符号、撤销和用户信息 URL (它们是完整的 URL) 但不用于日历 客户端: googleapis 解析路径与 `rootUrl`'来源并放下路径前缀.

### SDK 软件

测试驱动真正的客户端堆栈 `googleapis@149`数字 : `@googleapis/calendar@9.8.0` (中文(简体) ) 在 googleapis- common 7 / gaxios 6 上生成日历模块; 完整 `googleapis` 软件包是 ~125 MB已解开,因此只安装了模块)并 `google-auth-library@9.15.0`。 。 。 .

### 故意不模拟

-   经常性活动`recurrence` 、参与者的答复和电子邮件 请访问链接、 免费/ 繁忙、 ACL 、 颜色和设置 .
-   真实的谷歌身份 : `id_token`s是JWT形但与Google的密钥没有签名.
-   `X-Goog-Changed` (Google为日历事件频道省略)和 `not_exists` 各州.

## API 密码

| 导出 | 仁爱 | 说明 |
| --- | --- | --- |
| `GoogleCalendarAPI` | 类 | 进程模拟器 : `fetch(request)`, (中文(简体) ), `reset()`, (中文(简体) ), `user(email)`, (中文(简体) ), `ensurePrimary(email)`, (中文(简体) ), `resolveCalendar(email, id)`, (中文(简体) ), `createEvent`, (中文(简体) ), `updateEvent`, (中文(简体) ), `deleteEvent`, (中文(简体) ), `findEvent`, (中文(简体) ), `notify(calendarId)`, (中文(简体) ), `channels()`, (中文(简体) ), `events(email?)`, (中文(简体) ), `invalidateSyncTokens()`选项: `sqlite`, (中文(简体) ), `now`, (中文(简体) ), `namespace`, (中文(简体) ), `settings`, (中文(简体) ), `onPush`, (中文(简体) ), `onChannels`。 。 。 . |
| `createRuntime` | 函数 | 与全服务合同相仿并推送. 选项 : `settings`, (中文(简体) ), `push: {retryDelaysMs?, fetch?}`, (中文(简体) ), `clock`, (中文(简体) ), `seed`, (中文(简体) ), `adminKey`, (中文(简体) ), `onLog`, (中文(简体) ), `sqlite`。 。 。 . |
| `GOOGLE_CALENDAR_PRESETS` | 对象 | 每个命名的断层预设. |
| `GOOGLE_CALENDAR_NAMESPACE` | 字符串 | 服务名称, `"google-calendar"`。 。 。 . |
| `DEFAULT_SCOPE` | 字符串 | 标志性终点报告的范围 . |
| `pushHeaders` | 函数 | 这个 `X-Goog-*` 推车通知头. |
| `issueAccessToken` | 函数 | 仿真器接受电子邮件的 Mint 访问令牌 . |
| `parseToken` | 函数 | 解码仿真器访问或刷新令牌 . |
| `accessTokenCredential` | 函数 | 访问令牌所属的账户( 如何将证书映射到命名空间) . |
| `emailFromCode` | 函数 | 账户a `4/mock-…` 授权代码标志. |
| `googleError` | 函数 | 构建Google错误信封. |
| `document`, (中文(简体) ), `operationIds`, (中文(简体) ), `supportedOperationIds` | 数值 | OpenAPI合同及其操作代号. |
| `createServer`, (中文(简体) ), `serveTarget`, (中文(简体) ), `DEFAULT_PORT` (单位:千美元)`./server`(中文(简体) ) | 节点 | 服务过来 `node:http`; 数据 `serve` CLI目标(`--client`, (中文(简体) ), `--require-https-webhooks`; 第8820号口. |

部分 [嘲笑鸟](https://github.com/crvouga/mockingbird)。 。 。 .

## 常见问题

### @crvouga/mockingbird-service-google-calendar 是什么？

Google Calendar v3 API 和 Google OAuth 我们的EMR 呼叫的状态模拟器: 事件列表/插入/更新/删除/watch, channel\.stop, calendarList/calendars, sorders exchange/refresh/revoke and userinfo,并附有逐个签名的推进通知\.

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

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

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

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

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

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

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

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

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

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

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

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

