☰
google-api-nodejs-client 中的 reseller 模块:Google Workspace Reseller API 的 Node.js 落地指南
2026/10/15 5:46:49 网站建设 项目流程
  • 后端

【免费下载链接】google-api-nodejs-client

Google's officially supported Node.js client library for accessing Google APIs. Support for authorization and authentication with OAuth 2.0, API Keys and JWT (Service Tokens) is included.

项目地址:https://gitcode.com/gh_mirrors/go/google-api-nodejs-client
点击查看免费下载

导读

本文以 reseller 模块文档 为核心,系统讲解如何在 google-api-nodejs-client 中安装、初始化并使用@googleapis/reseller客户端,规模化完成 Google Workspace(原 G Suite)分销场景下的下单、客户信息查看、订阅生命周期管理等操作。读完本文,你将掌握 reseller API v1 的完整方法清单、核心数据模型、OAuth 2.0 权限范围,以及从"查询客户"到"下单、升级套餐、变更席位、暂停/恢复订阅"的端到端实战代码。


1. reseller 模块是什么

根据 reseller 模块文档 的定义,该模块封装的是Google Workspace Reseller API(v1),其使命是:

Perform common functions that are available on the Channel Services console at scale, like placing orders and viewing customer information

即在 Google 渠道服务(Channel Services)控制台之外,以编程方式规模化地完成常见运营操作——典型场景包括:

  • 下单订购 Google Workspace 订阅(placing orders);
  • 查看和管理客户信息(viewing customer information);
  • 管理订阅的套餐、席位(seats)、续订与暂停/恢复。

从代码结构上看,v1.ts 中Reseller类聚合了三大资源子类:

export class Reseller { context: APIRequestContext; customers: Resource$Customers; resellernotify: Resource$Resellernotify; subscriptions: Resource$Subscriptions; constructor(options: GlobalOptions, google?: GoogleConfigurable) { this.context = {_options: options || {}, google}; this.customers = new Resource$Customers(this.context); this.resellernotify = new Resource$Resellernotify(this.context); this.subscriptions = new Resource$Subscriptions(this.context); } }

即所有操作都收敛在reseller.customers、reseller.resellernotify、reseller.subscriptions三个命名空间下,分别对应客户账户管理、Pub/Sub 事件通知与订阅生命周期管理三大主题。

2. 安装与依赖

2.1 独立子包安装

reseller 模块既可以在整体包googleapis中使用,也可以作为独立的子包安装(这是 reseller 模块文档 推荐的安装方式):

$ npm install @googleapis/reseller

根据 package.json,该子包当前版本为13.0.1,许可证为Apache-2.0,运行时要求Node.js >= 22.0.0,核心依赖为googleapis-common ^9.0.0(提供createAPIRequest、AuthPlus、GoogleConfigurable等基础设施)。

2.2 在整体包中使用

也可以直接安装googleapis并通过顶层命名空间访问:

const {google} = require('googleapis'); const reseller = google.reseller('v1');

无论哪种方式,最终都会经由 index.ts 中导出的reseller()工厂函数完成实例化:

export const VERSIONS = { v1: reseller_v1.Reseller, }; export function reseller(version: 'v1'): reseller_v1.Reseller; export function reseller(options: reseller_v1.Options): reseller_v1.Reseller;

从 index.ts 可以看出,目前该模块仅支持 v1 一个版本,调用形式为reseller('v1'),或在需要覆盖默认选项时传入reseller({version: 'v1', auth: ...})。

3. 认证与权限范围(OAuth 2.0)

Reseller API 属于面向渠道分销商的受控 API,必须使用OAuth 2.0授权(支持 API Key 的只读场景有限,官方建议使用服务账户 + 域内委派或 OAuth 客户端)。v1.ts 中StandardParameters声明了通用的鉴权入口:

  • auth:可传入OAuth2Client、JWT、Compute、UserRefreshClient、BaseExternalAccountClient或GoogleAuth;
  • 亦可通过access_token、key、oauth_token等标准参数直接传递凭证。

整个模块涉及两个 OAuth 2.0 范围(见各方法示例代码):

Scope说明适用方法
https://www.googleapis.com/auth/apps.order读写权限,可下单、修改订阅全部写操作
https://www.googleapis.com/auth/apps.order.readonly只读权限customers.get、subscriptions.get、subscriptions.list、resellernotify.getwatchdetails

推荐的初始化方式是使用GoogleAuth并绑定默认客户端(与 v1.ts 中各方法的示例一致):

const {google} = require('googleapis'); async function main() { const auth = new google.auth.GoogleAuth({ scopes: [ 'https://www.googleapis.com/auth/apps.order', 'https://www.googleapis.com/auth/apps.order.readonly', ], }); // Acquire an auth client, and bind it to all future calls const authClient = await auth.getClient(); google.options({auth: authClient}); const reseller = google.reseller('v1'); // 后续所有 reseller 调用自动携带该客户端 } main().catch(e => { console.error(e); throw e; });

注意:若以子包@googleapis/reseller独立使用,认证方式一致,只是通过googleapis-common的AuthPlus获取 auth 客户端(index.ts 中同样导出了auth)。

4. customers:客户账户管理

customers资源用于管理分销客户账户,一个客户由主域名和物理地址描述(Schema$Customer)。它提供四个方法:

方法HTTP端点说明
customers.getGET/apps/reseller/v1/customers/{customerId}查询已有客户账户
customers.insertPOST/apps/reseller/v1/customers创建新客户账户(或转入已有客户的订阅)
customers.patchPATCH/apps/reseller/v1/customers/{customerId}局部更新客户设置
customers.updatePUT/apps/reseller/v1/customers/{customerId}整体更新客户设置

4.1 查询客户

const res = await reseller.customers.get({ // 可以是客户主域名或 Google 生成的唯一标识;域名变更后旧域名不可用,建议持久化存储 customerId customerId: 'example.com', }); console.log(res.data);

4.2 创建新客户

创建客户时,customerDomain、postalAddress为必填项,其中countryCode必须是经批准可转售 Google 产品的国家/地区代码(ISO 3166)。创建后还需为客户配置管理员,由管理员登录 Admin 控制台签署"G Suite via Reseller"协议后账户才激活——经销商不得代客户签署该协议(见 customers.insert 的 JSDoc)。

const res = await reseller.customers.insert({ // 可选:转移直客或他方经销商客户订阅时,必填十六进制鉴权令牌 customerAuthToken: 'd41d8cd98f00b204e9800998ecf8427e', requestBody: { customerDomain: 'example.com', // 必填,不要带 www 前缀 alternateEmail: 'admin@example.com', // 备用联系邮箱,须与主域不同 customerType: 'domain', // domain(默认)或 team postalAddress: { contactName: 'Jane Doe', organizationName: 'Example, Inc.', addressLine1: '1600 Amphitheatre Pkwy', locality: 'Mountain View', region: 'CA', postalCode: '94043', countryCode: 'US', }, }, }); console.log(res.data);

4.3 更新客户

  • patch:支持 patch 语义的局部更新;
  • update:整体覆盖式更新(PUT)。

需要注意:customerType无法通过 API 直接修改,但"team"类型客户可自行完成域名验证后自动变为"domain"(见 customers.patch 的 JSDoc)。

5. subscriptions:订阅生命周期管理

subscriptions是 reseller 模块的方法最丰富的资源,定义了一个客户支付方案(payment plan)、SKU、用户许可证(seats)、30 天试用与续订选项之间的完整关系(Schema$Subscriptions)。共提供9 个方法:

方法HTTP端点(相对 /apps/reseller/v1)说明
subscriptions.insertPOST/customers/{customerId}/subscriptions创建或转入订阅
subscriptions.getGET/customers/{customerId}/subscriptions/{subscriptionId}查询单个订阅
subscriptions.listGET/subscriptions列出经销商管理的全部/某客户的订阅
subscriptions.activatePOST/customers/{cid}/subscriptions/{sid}/activate恢复被经销商暂停的订阅
subscriptions.suspendPOST/customers/{cid}/subscriptions/{sid}/suspend暂停活跃订阅
subscriptions.changePlanPOST/customers/{cid}/subscriptions/{sid}/changePlan变更套餐(如试用/弹性转年度)
subscriptions.changeSeatsPOST/customers/{cid}/subscriptions/{sid}/changeSeats变更用户许可证数量
subscriptions.changeRenewalSettingsPOST/customers/{cid}/subscriptions/{sid}/changeRenewalSettings修改年度套餐续订设置
subscriptions.startPaidServicePOST/customers/{cid}/subscriptions/{sid}/startPaidService30 天试用立即转付费
subscriptions.deleteDELETE/customers/{cid}/subscriptions/{subscriptionId}取消/降级/暂停(由deletionType决定)

以上端点均来自 v1.ts 中各方法的rootUrl + url拼接实现,rootUrl统一为https://reseller.googleapis.com/(见 customers.get 实现 等)。

5.1 创建订阅

const res = await reseller.subscriptions.insert({ customerId: 'example.com', // 可选:已有同产品不同 SKU 订阅时的动作;SWITCH 时必须传 sourceSkuId action: 'SWITCH', sourceSkuId: 'Google-Apps-For-Business', requestBody: { skuId: 'Google-Apps-For-Business', plan: {planName: 'ANNUAL_MONTHLY_PAY'}, seats: {numberOfSeats: 10}, purchaseOrderId: 'PO-2026-001', // 可选,最多 80 字符,会显示在账单上 }, });

5.2 列出订阅

list支持按客户与名称前缀过滤,并支持分页(默认每页 20 条,maxResults可调,nextPageToken续页):

const res = await reseller.subscriptions.list({ customerId: 'example.com', customerNamePrefix: 'exa', // 匹配 exam.com、example20.com、example.com maxResults: 50, pageToken: '...', }); console.log(res.data.subscriptions);

5.3 变更套餐、席位与续订

  • changePlan:请求体使用 Schema$ChangePlanRequest,planName必填。可选值包括:
    • ANNUAL_MONTHLY_PAY:年度承诺、按月付款(注意:API 响应中返回为ANNUAL);
    • ANNUAL_YEARLY_PAY:年度承诺、按年付款;
    • FLEXIBLE:弹性套餐;
    • TRIAL:30 天免费试用。
    • dealCode(最多 100 字符)可选,用于享受折扣价;seats为必填。
  • changeSeats:请求体为 Schema$Seats,numberOfSeats仅适用于年度套餐且设定后到续订前不可减少,计费按该值进行;maximumNumberOfSeats仅适用于FLEXIBLE/TRIAL套餐。
  • changeRenewalSettings:请求体为 Schema$RenewalSettings,仅适用于年度承诺套餐,renewalType为必填。
// 变更套餐 await reseller.subscriptions.changePlan({ customerId: 'example.com', subscriptionId: 'subscription-id-123', requestBody: { planName: 'ANNUAL_YEARLY_PAY', seats: {numberOfSeats: 25}, purchaseOrderId: 'PO-2026-002', }, }); // 变更席位 await reseller.subscriptions.changeSeats({ customerId: 'example.com', subscriptionId: 'subscription-id-123', requestBody: {numberOfSeats: 30}, }); // 修改续订设置 await reseller.subscriptions.changeRenewalSettings({ customerId: 'example.com', subscriptionId: 'subscription-id-123', requestBody: {renewalType: 'RENEW_WITH_COMMITMENT'}, });

5.4 暂停、恢复、取消与转付费

  • suspend:仅适用于ACTIVE状态的付费订阅。FLEXIBLE套餐暂停后停止计费;年度套餐暂停不改变原承诺的续订日期、且不自动续订——若在原续订日之后才恢复,会从恢复当天起生成一个新的年度订阅。官方建议暂停不要超过 60 天,超期可能被取消(见 subscriptions.suspend 的 JSDoc)。
  • activate:仅能恢复由经销商主动暂停的订阅;因滥用、待接受 ToS 等原因被 Google 暂停的订阅无法通过此接口恢复。
  • startPaidService:将 30 天试用订阅立即转为付费服务(前提是已为该试用订阅设置好支付方案)。
  • delete:deletionType为必填查询参数,决定是取消(cancel)、降级(downgrade)还是转移为直客(transfer_to_direct)。
await reseller.subscriptions.suspend({ customerId: 'example.com', subscriptionId: 'subscription-id-123', }); await reseller.subscriptions.activate({ customerId: 'example.com', subscriptionId: 'subscription-id-123', }); await reseller.subscriptions.startPaidService({ customerId: 'example.com', subscriptionId: 'subscription-id-123', }); await reseller.subscriptions.delete({ customerId: 'example.com', subscriptionId: 'subscription-id-123', deletionType: 'cancel', // cancel | downgrade | transfer_to_direct });

6. resellernotify:基于 Pub/Sub 的事件通知

resellernotify资源负责让经销商订阅 Google Cloud Pub/Sub 事件通知,当订阅/客户发生变更时可实时感知。它提供 3 个方法(Resource$Resellernotify):

方法HTTP说明
resellernotify.registerPOST注册经销商,开始接收通知(需提供服务账号邮箱,该账号将拥有创建的 Pub/Sub topic)
resellernotify.unregisterPOST注销经销商的通知接收
resellernotify.getwatchdetailsGET查询当前 watch 详情
// 注册:serviceAccountEmailAddress 为将拥有 Pub/Sub topic 的服务账号 const res = await reseller.resellernotify.register({ serviceAccountEmailAddress: 'reseller-notify@my-project.iam.gserviceaccount.com', }); console.log(res.data); // { topicName: "projects/my-project/topics/..." } // 查询 const details = await reseller.resellernotify.getwatchdetails({}); console.log(details.data); // { // serviceAccountEmailAddresses: [...], // topicName: "..." // } // 注销 await reseller.resellernotify.unregister({ serviceAccountEmailAddress: 'reseller-notify@my-project.iam.gserviceaccount.com', });

对应响应模型为 Schema$ResellernotifyGetwatchdetailsResponse(返回serviceAccountEmailAddresses数组与topicName)和 Schema$ResellernotifyResource(仅返回topicName)。

7. 核心数据模型速查

以下 Schema 全部定义在 v1.ts 中,也是类型声明(TypeScript)直接导出的:

Schema位置关键字段
Schema$Addressv1.ts#L134addressLine1-3、contactName、countryCode、locality、organizationName、postalCode、region(各字段上限 255 字符)
Schema$Customerv1.ts#L204customerDomain、customerDomainVerified、customerId、customerType(domain/team)、alternateEmail、phoneNumber(须以+开头加国家码)、postalAddress、primaryAdmin、resourceUiUrl(只读)
Schema$PrimaryAdminv1.ts#L249primaryEmail(team 客户的首席管理员,创建时接收验证邮件)
Schema$Seatsv1.ts#L293licensedNumberOfSeats(只读)、maximumNumberOfSeats(FLEXIBLE/TRIAL 用)、numberOfSeats(年度套餐用,续订前不可减)
Schema$ChangePlanRequestv1.ts#L179dealCode、planName(必填)、purchaseOrderId、seats(必填)
Schema$RenewalSettingsv1.ts#L258renewalType(续订时必填)
Schema$Subscriptionv1.ts#L314skuId、skuName、plan、seats、renewalSettings、trialSettings、dealCode、status、suspensionReasons、transferInfo、creationTime(Epoch 毫秒)等
Schema$Subscriptionsv1.ts#L399subscriptions列表 +nextPageToken分页

关于订阅status,suspensionReasons只读字段枚举了常见暂停原因(v1.ts#L380):

  • PENDING_TOS_ACCEPTANCE:客户未登录并接受 G Suite 转售服务条款;
  • RENEWAL_WITH_TYPE_CANCEL:承诺期结束、服务被取消;
  • RESELLER_INITIATED:经销商手动暂停;
  • TRIAL_ENDED:试用到期未选择套餐;
  • OTHER:Google 内部原因(如滥用)。

只有全部暂停原因解除后,订阅状态才会从SUSPENDED恢复为ACTIVE。

8. 底层实现与调用链

8.1 请求是如何发出的

每个方法(如 customers.get 的实现)最终都会走统一模板:

const rootUrl = options.rootUrl || 'https://reseller.googleapis.com/'; const parameters = { options: Object.assign( { url: (rootUrl + '/apps/reseller/v1/customers/{customerId}').replace(/([^:]\/)\/+/g, '$1'), method: 'GET', apiVersion: '', }, options ), params, requiredParams: ['customerId'], pathParams: ['customerId'], context: this.context, }; return createAPIRequest<Schema$Customer>(parameters);

createAPIRequest来自googleapis-common,负责把params中的pathParams填充到 URL、合并查询参数与请求体,并挂载 auth 客户端。开发者也可以通过options覆盖rootUrl(如代理环境)、method或encoding等底层行为。

8.2 三种调用风格

所有方法都重载了三种调用形式(以 subscriptions.get 为例):

  1. Promise(async/await):await reseller.subscriptions.get({...}),返回GaxiosResponseWithHTTP2<Schema$Subscription>,响应数据在.data;
  2. 回调:reseller.subscriptions.get({...}, callback);
  3. 流式:传入StreamMethodOptions时返回Readable流,便于处理大响应或管道输出。

8.3 模块注册与版本

reseller 模块文档 中未展开的模块装配细节可从 index.ts 与 CHANGELOG.md 中读到:该子包由生成器(generator)自动生成,随 Discovery Document 更新而同步发布;13.0.1版本(2026-09 发布)修复了 API 更新问题,且近期版本将最低 Node 版本提升至 22。

9. 实战:一个完整的自动化运维脚本

将以上能力组合,即可写出一个典型的"经销商自动化"脚本——查询客户、检查订阅状态、为试用到期的订阅转付费并扩容:

const {google} = require('googleapis'); async function main() { const auth = new google.auth.GoogleAuth({ scopes: ['https://www.googleapis.com/auth/apps.order'], }); const authClient = await auth.getClient(); google.options({auth: authClient}); const reseller = google.reseller('v1'); // 1. 列出所有订阅(分页遍历) let pageToken; do { const res = await reseller.subscriptions.list({pageToken, maxResults: 100}); for (const sub of res.data.subscriptions || []) { console.log(sub.customerId, sub.skuName, sub.status); // 2. 试用中且临近到期 → 立即转付费 if (sub.trialSettings && sub.trialSettings.isInTrial) { await reseller.subscriptions.startPaidService({ customerId: sub.customerId, subscriptionId: sub.subscriptionId, }); console.log(`trial started to paid: ${sub.subscriptionId}`); } // 3. 扩容:年度套餐增加席位 await reseller.subscriptions.changeSeats({ customerId: sub.customerId, subscriptionId: sub.subscriptionId, requestBody: {numberOfSeats: 50}, }); } pageToken = res.data.nextPageToken; } while (pageToken); } main().catch(e => { console.error(e); throw e; });

10. 许可与社区约定

reseller 模块文档 明确该库基于Apache 2.0开源,完整许可文本见仓库根目录 LICENSE。仓库同时提供了 CODE_OF_CONDUCT.md 与 CONTRIBUTING.md 供参与贡献时参考;若在集成中发现缺陷,可到仓库 issue 区反馈,或在 Stack Overflow 上使用google-api-nodejs-client标签提问(详见 README.md)。

总结

  • 模块定位:@googleapis/reseller是 Google Workspace Reseller API v1 的官方 Node.js 客户端,聚焦客户、订阅、通知三大领域;
  • 能力边界:支持客户增删查改、订阅的全生命周期管理(下单/查询/变更套餐/变更席位/续订/暂停/恢复/转付费/取消)、基于 Pub/Sub 的通知注册与查询;
  • 约束要点:写操作需apps.order范围;numberOfSeats年度套餐续订前不可减;activate仅能恢复经销商主动暂停的订阅;customerType不可通过 API 修改;运行时要求 Node.js >= 22;
  • 进一步阅读:完整的类型定义与逐方法示例见 v1.ts,模块装配逻辑见 index.ts,版本演进见 CHANGELOG.md。
  • 后端

【免费下载链接】google-api-nodejs-client

Google's officially supported Node.js client library for accessing Google APIs. Support for authorization and authentication with OAuth 2.0, API Keys and JWT (Service Tokens) is included.

项目地址:https://gitcode.com/gh_mirrors/go/google-api-nodejs-client
点击查看免费下载
上一篇:Flutter Thrio 教程
下一篇:5分钟搞定XGBoost:机器学习新手的终极入门指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询