@perk-net/perk-pushplus-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/enums.ts","../src/exception.ts","../src/access-key-manager.ts","../src/http.ts","../src/api/base.ts","../src/api/access-key-api.ts","../src/api/open-base.ts","../src/api/channel-api.ts","../src/api/clawbot-api.ts","../src/api/friend-api.ts","../src/api/message-api.ts","../src/api/message-token-api.ts","../src/api/open-message-api.ts","../src/api/pre-api.ts","../src/api/setting-api.ts","../src/api/topic-api.ts","../src/api/topic-user-api.ts","../src/api/user-api.ts","../src/api/webhook-api.ts","../src/config.ts","../src/rate-limit.ts","../src/client.ts","../src/callback.ts","../src/models.ts"],"names":["Channel","Template","SendStatus","CallbackEvent","WebhookType","ErrorCode"],"mappings":"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","file":"index.global.js","sourcesContent":["/**\n * PushPlus 发送渠道枚举。\n *\n * 对应官方文档「发送渠道(channel)枚举」。\n */\nexport enum Channel {\n /** 微信公众号(默认)。 */\n WECHAT = 'wechat',\n /** 第三方 webhook(企业微信/钉钉/飞书/bark/Gotify/Server酱/IFTTT/WxPusher 等)。 */\n WEBHOOK = 'webhook',\n /** 企业微信应用。 */\n CP = 'cp',\n /** 邮箱。 */\n MAIL = 'mail',\n /** 短信(收费)。 */\n SMS = 'sms',\n /** 语音(收费)。 */\n VOICE = 'voice',\n /** 浏览器扩展插件 / 桌面应用程序。 */\n EXTENSION = 'extension',\n /** App 渠道(安卓/鸿蒙/iOS)。 */\n APP = 'app',\n /** 微信 ClawBot。 */\n CLAWBOT = 'clawbot',\n}\n\n/**\n * PushPlus 消息模板枚举。\n */\nexport enum Template {\n /** 默认模板,支持 HTML 文本。 */\n HTML = 'html',\n /** 纯文本,不转义 HTML。 */\n TXT = 'txt',\n /** 基于 JSON 格式展示。 */\n JSON = 'json',\n /** Markdown 格式。 */\n MARKDOWN = 'markdown',\n /** 阿里云监控报警定制模板。 */\n CLOUD_MONITOR = 'cloudMonitor',\n /** Jenkins 插件定制模板。 */\n JENKINS = 'jenkins',\n /** 路由器插件定制模板。 */\n ROUTE = 'route',\n /** 支付成功通知模板。 */\n PAY = 'pay',\n}\n\n/**\n * 消息投递状态。\n *\n * 0-未发送/未投递,1-发送中,2-发送成功,3-发送失败。\n */\nexport enum SendStatus {\n NOT_SENT = 0,\n SENDING = 1,\n SUCCESS = 2,\n FAILED = 3,\n}\n\nexport const SendStatusDescription: Record<SendStatus, string> = {\n [SendStatus.NOT_SENT]: '未发送',\n [SendStatus.SENDING]: '发送中',\n [SendStatus.SUCCESS]: '发送成功',\n [SendStatus.FAILED]: '发送失败',\n};\n\n/**\n * 回调事件类型。\n */\nexport enum CallbackEvent {\n /** 消息发送完成。 */\n MESSAGE_COMPLETE = 'message_complate',\n /** 群组新增用户。 */\n ADD_TOPIC_USER = 'add_topic_user',\n /** 新增好友。 */\n ADD_FRIEND = 'add_friend',\n}\n\n/**\n * Webhook 渠道类型。\n *\n * 对应开放接口文档「webhook 列表」中的 webhookType 枚举值。\n */\nexport enum WebhookType {\n WORK_WECHAT_BOT = 1,\n DING_TALK_BOT = 2,\n FEISHU_BOT = 3,\n SERVER_CHAN = 4,\n BARK = 50,\n WORK_WECHAT_APP = 6,\n TENCENT_LIGHT_LINK = 7,\n IFTTT = 8,\n JI_JIAN_YUN = 9,\n GOTIFY = 10,\n WX_PUSHER = 11,\n CUSTOM = 12,\n}\n\nexport const WebhookTypeDescription: Record<number, string> = {\n [WebhookType.WORK_WECHAT_BOT]: '企业微信机器人',\n [WebhookType.DING_TALK_BOT]: '钉钉机器人',\n [WebhookType.FEISHU_BOT]: '飞书机器人',\n [WebhookType.SERVER_CHAN]: 'Server酱',\n [WebhookType.BARK]: 'bark',\n [WebhookType.WORK_WECHAT_APP]: '企业微信应用',\n [WebhookType.TENCENT_LIGHT_LINK]: '腾讯轻联',\n [WebhookType.IFTTT]: 'IFTTT',\n [WebhookType.JI_JIAN_YUN]: '集简云',\n [WebhookType.GOTIFY]: 'Gotify',\n [WebhookType.WX_PUSHER]: 'WxPusher',\n [WebhookType.CUSTOM]: '自定义',\n};\n\n/**\n * PushPlus 接口业务返回码语义。\n *\n * 对应官方文档「接口返回码说明」:https://www.pushplus.plus/doc/guide/code.html\n */\nexport enum ErrorCode {\n /** 200 执行成功。 */\n OK = 200,\n /** 302 未登录。 */\n NOT_LOGIN = 302,\n /** 401 请求未授权(开放接口未启用)。 */\n UNAUTHORIZED = 401,\n /** 403 请求 IP 未授权(白名单未配置)。 */\n IP_FORBIDDEN = 403,\n /** 500 系统异常,请稍后再试。 */\n SERVER_ERROR = 500,\n /** 600 数据异常,操作失败。 */\n DATA_ERROR = 600,\n /** 805 无权查看。 */\n FORBIDDEN_VIEW = 805,\n /** 888 积分不足,需要充值。 */\n INSUFFICIENT_POINTS = 888,\n /** 900 用户账号使用受限(请求次数过多)。 */\n RATE_LIMITED = 900,\n /** 905 账户未进行实名认证。 */\n NOT_VERIFIED = 905,\n /** 903 无效的用户令牌。 */\n INVALID_TOKEN = 903,\n /** 999 服务端验证错误。 */\n VALIDATION_ERROR = 999,\n /** 其它未在文档中列出的 code。 */\n UNKNOWN = -1,\n}\n\nexport function errorCodeFromValue(code: number | null | undefined): ErrorCode {\n if (code == null) return ErrorCode.UNKNOWN;\n const known = [\n ErrorCode.OK,\n ErrorCode.NOT_LOGIN,\n ErrorCode.UNAUTHORIZED,\n ErrorCode.IP_FORBIDDEN,\n ErrorCode.SERVER_ERROR,\n ErrorCode.DATA_ERROR,\n ErrorCode.FORBIDDEN_VIEW,\n ErrorCode.INSUFFICIENT_POINTS,\n ErrorCode.RATE_LIMITED,\n ErrorCode.NOT_VERIFIED,\n ErrorCode.INVALID_TOKEN,\n ErrorCode.VALIDATION_ERROR,\n ];\n return known.includes(code as ErrorCode) ? (code as ErrorCode) : ErrorCode.UNKNOWN;\n}\n\nexport function isRateLimitedCode(code: number | null | undefined): boolean {\n return code != null && code === ErrorCode.RATE_LIMITED;\n}\n","import { ErrorCode, errorCodeFromValue, isRateLimitedCode } from './enums';\n\n/**\n * PushPlus SDK 统一运行时异常。\n *\n * 该异常会在以下场景抛出:\n * - HTTP 请求失败(网络异常、非 2xx 状态码)\n * - PushPlus 业务接口返回 code != 200\n * - JSON 序列化/反序列化异常\n * - SDK 参数校验失败\n * - 本地限流守卫命中(code=900 后被短路),不会真正发起 HTTP 请求\n */\nexport class PushPlusError extends Error {\n /** PushPlus 接口返回的业务 code。HTTP 错误时为对应的 HTTP 状态码;其他为 -1。 */\n public readonly code: number;\n\n /** 同 message。便于和其它语言 SDK 风格一致。 */\n public get businessMessage(): string {\n return this.message;\n }\n\n constructor(message: string, code: number = -1, options?: { cause?: unknown }) {\n super(message);\n this.name = 'PushPlusError';\n this.code = code;\n if (options?.cause !== undefined) {\n // Node 16+ 支持 Error cause\n (this as any).cause = options.cause;\n }\n // 修复部分环境下 instanceof 失效问题\n Object.setPrototypeOf(this, PushPlusError.prototype);\n }\n\n /** 把数值 code 映射为 ErrorCode 枚举(未知为 UNKNOWN)。 */\n get errorCode(): ErrorCode {\n return errorCodeFromValue(this.code);\n }\n\n /** 是否为 PushPlus 限流(code=900)。命中后建议当天停止继续调用发送消息接口。 */\n isRateLimited(): boolean {\n return isRateLimitedCode(this.code);\n }\n}\n\n/**\n * 兼容 Java SDK 命名(PushPlusException)的别名导出。\n */\nexport const PushPlusException = PushPlusError;\n","import { AccessKeyApi } from './api/access-key-api';\nimport { ResolvedPushPlusConfig } from './config';\nimport { PushPlusError } from './exception';\n\n/**\n * AccessKey 管理器。\n *\n * 提供线程/异步并发安全的 AccessKey 缓存 + 过期前自动刷新能力。\n *\n * 在调用任意需要 access-key 的开放接口前,OpenAbstractApi 会自动通过本类拿到一个有效的 AccessKey。\n *\n * 刷新策略:在 expiresIn 到期前 `accessKeyRefreshAheadSeconds` 秒视为过期。\n * 文档说明老 key 在新 key 生成后 5 分钟内仍可用,因此默认 300 秒提前量足够安全。\n */\nexport class AccessKeyManager {\n private readonly config: ResolvedPushPlusConfig;\n private readonly api: AccessKeyApi;\n\n private cachedKey: string | null = null;\n /** 最早过期时间戳(毫秒,含提前量);到达此刻必须刷新。 */\n private expireAtMs = 0;\n\n /** 并发刷新去重。 */\n private inflight: Promise<string> | null = null;\n\n constructor(config: ResolvedPushPlusConfig, api: AccessKeyApi) {\n this.config = config;\n this.api = api;\n }\n\n /** 获取有效的 AccessKey。如已缓存且未过期则直接返回;否则触发刷新。 */\n async getAccessKey(): Promise<string> {\n if (this.isValid()) return this.cachedKey as string;\n return this.refresh();\n }\n\n /** 强制刷新。多次并发调用时仅会真正发起一次刷新请求。 */\n refresh(): Promise<string> {\n if (this.isValid()) return Promise.resolve(this.cachedKey as string);\n if (this.inflight) return this.inflight;\n this.inflight = this.doRefresh().finally(() => {\n this.inflight = null;\n });\n return this.inflight;\n }\n\n /** 失效缓存。下次调用 getAccessKey() 时会重新拉取。 */\n invalidate(): void {\n this.cachedKey = null;\n this.expireAtMs = 0;\n }\n\n private async doRefresh(): Promise<string> {\n const result = await this.api.getAccessKey();\n if (!result || !result.accessKey) {\n throw new PushPlusError('获取 AccessKey 失败:返回为空');\n }\n this.cachedKey = result.accessKey;\n const ttlSec = result.expiresIn ?? 7200;\n const aheadSec = Math.max(0, this.config.accessKeyRefreshAheadSeconds);\n const effectiveTtlSec = Math.max(1, ttlSec - aheadSec);\n this.expireAtMs = Date.now() + effectiveTtlSec * 1000;\n return this.cachedKey;\n }\n\n private isValid(): boolean {\n return this.cachedKey != null && Date.now() < this.expireAtMs;\n }\n}\n","import { ResolvedPushPlusConfig } from './config';\nimport { PushPlusError } from './exception';\n\nexport interface HttpRequestOptions {\n method: string;\n url: string;\n headers?: Record<string, string>;\n body?: string | null;\n}\n\nexport interface HttpResponse {\n statusCode: number;\n body: string;\n}\n\n/**\n * HTTP 请求执行器抽象。\n *\n * SDK 默认提供基于 `fetch` 的实现(Node 18+ 内置 / 浏览器原生)。\n * 调用方也可以自行实现并通过 `PushPlusClient` 注入以使用其它客户端(如 axios/undici/got)。\n */\nexport interface HttpRequester {\n execute(options: HttpRequestOptions): Promise<HttpResponse>;\n}\n\n/**\n * 基于 fetch 的请求执行器。\n *\n * - Node.js:18+ 自带全局 fetch;< 18 需要使用 polyfill 或自定义 HttpRequester。\n * - 浏览器:所有现代浏览器原生支持。\n *\n * 实现是无状态的,可作为 SDK 单例长期复用。\n */\nexport class FetchHttpRequester implements HttpRequester {\n private readonly readTimeoutMs: number;\n private readonly logRequest: boolean;\n private readonly userAgent: string;\n private readonly fetchImpl: typeof fetch;\n\n constructor(config: ResolvedPushPlusConfig, fetchImpl?: typeof fetch) {\n this.readTimeoutMs = config.readTimeoutMs;\n this.logRequest = config.logRequest;\n this.userAgent = config.userAgent;\n const resolved = fetchImpl ?? (typeof fetch !== 'undefined' ? fetch.bind(globalThis) : undefined);\n if (!resolved) {\n throw new PushPlusError(\n '当前运行环境没有可用的 fetch 实现。请在 Node.js 18+ 中运行,' +\n '或自行注入 HttpRequester 实例。',\n );\n }\n this.fetchImpl = resolved;\n }\n\n async execute(options: HttpRequestOptions): Promise<HttpResponse> {\n const { method, url, headers, body } = options;\n const finalHeaders: Record<string, string> = {};\n\n let hasContentType = false;\n if (headers) {\n for (const [k, v] of Object.entries(headers)) {\n if (k == null || v == null) continue;\n finalHeaders[k] = v;\n if (k.toLowerCase() === 'content-type') hasContentType = true;\n }\n }\n if (body != null && !hasContentType) {\n finalHeaders['Content-Type'] = 'application/json;charset=UTF-8';\n }\n // 浏览器中不允许设置 User-Agent,仅在非浏览器环境下添加\n if (typeof window === 'undefined' && !finalHeaders['User-Agent'] && !finalHeaders['user-agent']) {\n finalHeaders['User-Agent'] = this.userAgent;\n }\n\n if (this.logRequest) {\n // eslint-disable-next-line no-console\n console.debug('[pushplus] >>>', method, url, 'body=', body);\n }\n\n const controller = new AbortController();\n const timer = this.readTimeoutMs > 0 ? setTimeout(() => controller.abort(), this.readTimeoutMs) : null;\n\n try {\n const init: RequestInit = {\n method: method.toUpperCase(),\n headers: finalHeaders,\n signal: controller.signal,\n };\n if (body != null) {\n init.body = body;\n }\n const resp = await this.fetchImpl(url, init);\n const respBody = await resp.text();\n if (this.logRequest) {\n // eslint-disable-next-line no-console\n console.debug('[pushplus] <<< status=', resp.status, 'body=', respBody);\n }\n return { statusCode: resp.status, body: respBody };\n } catch (e: unknown) {\n const err = e as { name?: string; message?: string };\n if (err && err.name === 'AbortError') {\n throw new PushPlusError(`调用 PushPlus 接口超时(${this.readTimeoutMs}ms): ${err.message ?? ''}`, -1, {\n cause: e,\n });\n }\n throw new PushPlusError(`调用 PushPlus 接口失败: ${err?.message ?? String(e)}`, -1, { cause: e });\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n}\n\n/**\n * 是否处于成功的 HTTP 状态码区间(2xx)。\n */\nexport function isSuccessfulHttpStatus(status: number): boolean {\n return status >= 200 && status < 300;\n}\n","import { ResolvedPushPlusConfig } from '../config';\nimport { PushPlusError } from '../exception';\nimport { HttpRequester, HttpResponse, isSuccessfulHttpStatus } from '../http';\nimport { ApiResponse } from '../models';\n\n/**\n * API 基类,提供请求执行与统一错误处理。\n */\nexport abstract class AbstractApi {\n protected readonly config: ResolvedPushPlusConfig;\n protected readonly http: HttpRequester;\n\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester) {\n this.config = config;\n this.http = http;\n }\n\n /** 拼接绝对 URL。 */\n protected resolveUrl(path: string): string {\n if (path.startsWith('http://') || path.startsWith('https://')) {\n return path;\n }\n return this.config.baseUrl + (path.startsWith('/') ? path : '/' + path);\n }\n\n /** 把对象拼成 query string。 */\n protected buildQuery(params: Record<string, unknown> | undefined | null): string {\n if (!params) return '';\n const parts: string[] = [];\n for (const [k, v] of Object.entries(params)) {\n if (v == null) continue;\n parts.push(`${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);\n }\n return parts.join('&');\n }\n\n /** 在 path 上追加 query string。 */\n protected appendQuery(path: string, params: Record<string, unknown> | undefined | null): string {\n const q = this.buildQuery(params);\n if (!q) return path;\n return path + (path.includes('?') ? '&' : '?') + q;\n }\n\n /**\n * 执行请求并返回原始 ApiResponse(不进行 code 校验)。\n */\n protected async execute<T>(\n method: string,\n path: string,\n headers: Record<string, string> | undefined | null,\n body: unknown,\n ): Promise<ApiResponse<T>> {\n const url = this.resolveUrl(path);\n const json = body == null ? null : safeStringify(body);\n const resp = await this.http.execute({ method, url, headers: headers ?? undefined, body: json });\n if (!isSuccessfulHttpStatus(resp.statusCode)) {\n throw new PushPlusError(\n `PushPlus 接口 HTTP 调用失败: status=${resp.statusCode}, body=${resp.body}`,\n resp.statusCode,\n );\n }\n return parseApiResponse<T>(resp);\n }\n\n /** 执行请求并直接返回 data;非 200 抛出异常。 */\n protected async executeForData<T>(\n method: string,\n path: string,\n headers: Record<string, string> | undefined | null,\n body: unknown,\n ): Promise<T> {\n const resp = await this.execute<T>(method, path, headers, body);\n if (!isApiSuccess(resp)) {\n throw new PushPlusError(\n buildBusinessErrorMessage('PushPlus 接口业务失败', resp),\n resp.code ?? -1,\n );\n }\n return resp.data as T;\n }\n}\n\nexport function isApiSuccess<T>(resp: ApiResponse<T>): boolean {\n return resp.code === 200;\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch (e) {\n throw new PushPlusError(`序列化请求体失败: ${(e as Error).message}`, -1, { cause: e });\n }\n}\n\nfunction parseApiResponse<T>(resp: HttpResponse): ApiResponse<T> {\n if (!resp.body || resp.body.length === 0) {\n throw new PushPlusError('PushPlus 接口返回为空');\n }\n let raw: ApiResponse<unknown>;\n try {\n raw = JSON.parse(resp.body) as ApiResponse<unknown>;\n } catch (e) {\n throw new PushPlusError(\n `解析 PushPlus 响应失败: ${(e as Error).message}, payload=${resp.body}`,\n -1,\n { cause: e },\n );\n }\n if (raw == null || typeof raw !== 'object') {\n throw new PushPlusError(`PushPlus 接口返回结构异常: ${resp.body}`);\n }\n const result: ApiResponse<T> = {\n code: raw.code,\n msg: raw.msg,\n data: raw.data as T,\n };\n if (!isApiSuccess(result)) {\n // 业务失败场景:把 data 中的字符串/简单值附加到 msg,方便使用者直接拿到错误描述。\n const dataText = extractDataText(raw.data);\n if (dataText && (!result.msg || result.msg.length === 0)) {\n result.msg = dataText;\n } else if (dataText && result.msg && !result.msg.includes(dataText)) {\n result.msg = result.msg + ': ' + dataText;\n }\n }\n return result;\n}\n\nfunction extractDataText(data: unknown): string | null {\n if (data == null) return null;\n const t = typeof data;\n if (t === 'string') return data as string;\n if (t === 'number' || t === 'boolean') return String(data);\n try {\n return JSON.stringify(data);\n } catch {\n return null;\n }\n}\n\nfunction buildBusinessErrorMessage(prefix: string, resp: ApiResponse<unknown>): string {\n return `${prefix}: code=${resp.code}, msg=${resp.msg}`;\n}\n","import { ResolvedPushPlusConfig } from '../config';\nimport { PushPlusError } from '../exception';\nimport { HttpRequester } from '../http';\nimport { AccessKeyResult } from '../models';\nimport { AbstractApi } from './base';\n\n/**\n * AccessKey 接口。对应文档「一. 获取 AccessKey」。\n */\nexport class AccessKeyApi extends AbstractApi {\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester) {\n super(config, http);\n }\n\n /** 使用配置中的 token + secretKey 获取 AccessKey。 */\n getAccessKey(): Promise<AccessKeyResult>;\n /** 使用指定 token + secretKey 获取 AccessKey。 */\n getAccessKey(token: string, secretKey: string): Promise<AccessKeyResult>;\n async getAccessKey(token?: string, secretKey?: string): Promise<AccessKeyResult> {\n const t = token ?? this.config.token;\n const sk = secretKey ?? this.config.secretKey;\n if (!t || t.trim().length === 0) {\n throw new PushPlusError('获取 AccessKey 需要 token');\n }\n if (!sk || sk.trim().length === 0) {\n throw new PushPlusError('获取 AccessKey 需要 secretKey');\n }\n return this.executeForData<AccessKeyResult>(\n 'POST',\n '/api/common/openApi/getAccessKey',\n null,\n { token: t, secretKey: sk },\n );\n }\n}\n","import { AccessKeyManager } from '../access-key-manager';\nimport { ResolvedPushPlusConfig } from '../config';\nimport { PushPlusError } from '../exception';\nimport { HttpRequester } from '../http';\nimport { AbstractApi, isApiSuccess } from './base';\n\n/**\n * 开放接口基类。会自动在 header 中带上 access-key,\n * 并在收到 401 类业务错误时尝试重试一次(刷新 AccessKey 后重试)。\n */\nexport abstract class OpenAbstractApi extends AbstractApi {\n static readonly HEADER_ACCESS_KEY = 'access-key';\n /** PushPlus AccessKey 失效相关的业务码(用于触发自动重试)。 */\n private static readonly CODE_ACCESS_KEY_INVALID = 401;\n\n protected readonly accessKeyManager: AccessKeyManager;\n\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester, accessKeyManager: AccessKeyManager) {\n super(config, http);\n this.accessKeyManager = accessKeyManager;\n }\n\n private async headersWithAccessKey(): Promise<Record<string, string>> {\n const key = await this.accessKeyManager.getAccessKey();\n return { [OpenAbstractApi.HEADER_ACCESS_KEY]: key };\n }\n\n /**\n * 执行带 access-key 的请求;当返回 code=401 时自动刷新 key 并重试一次。\n */\n protected async executeOpen<T>(method: string, path: string, body?: unknown): Promise<T> {\n const headers = await this.headersWithAccessKey();\n const resp = await this.execute<T>(method, path, headers, body);\n if (isApiSuccess(resp)) {\n return resp.data as T;\n }\n if (resp.code === OpenAbstractApi.CODE_ACCESS_KEY_INVALID) {\n this.accessKeyManager.invalidate();\n const retryHeaders = await this.headersWithAccessKey();\n const retry = await this.execute<T>(method, path, retryHeaders, body);\n if (isApiSuccess(retry)) {\n return retry.data as T;\n }\n throw new PushPlusError(\n `PushPlus 开放接口业务失败(重试后): code=${retry.code}, msg=${retry.msg}`,\n retry.code ?? -1,\n );\n }\n throw new PushPlusError(\n `PushPlus 开放接口业务失败: code=${resp.code}, msg=${resp.msg}`,\n resp.code ?? -1,\n );\n }\n}\n","import { AccessKeyManager } from '../access-key-manager';\nimport { ResolvedPushPlusConfig } from '../config';\nimport { HttpRequester } from '../http';\nimport { CpItem, MailDetail, MailItem, MpItem, PageQuery, PageResult } from '../models';\nimport { OpenAbstractApi } from './open-base';\n\n/**\n * 开放接口 - 微信公众号/企业微信/邮箱渠道列表(文档「七. 渠道配置接口」 5-8)。\n */\nexport class ChannelApi extends OpenAbstractApi {\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {\n super(config, http, mgr);\n }\n\n /** 5. 微信公众号渠道列表。 */\n mpList(q?: PageQuery): Promise<PageResult<MpItem>> {\n return this.executeOpen<PageResult<MpItem>>('POST', '/api/open/mp/list', q ?? {});\n }\n\n /** 6. 企业微信应用渠道列表。 */\n cpList(q?: PageQuery): Promise<PageResult<CpItem>> {\n return this.executeOpen<PageResult<CpItem>>('POST', '/api/open/cp/list', q ?? {});\n }\n\n /** 7. 邮箱渠道列表。 */\n mailList(q?: PageQuery): Promise<PageResult<MailItem>> {\n return this.executeOpen<PageResult<MailItem>>('POST', '/api/open/mail/list', q ?? {});\n }\n\n /** 8. 邮箱渠道详情。 */\n mailDetail(mailId: number): Promise<MailDetail> {\n return this.executeOpen<MailDetail>(\n 'GET',\n this.appendQuery('/api/open/mail/detail', { mailId }),\n );\n }\n}\n","import { AccessKeyManager } from '../access-key-manager';\nimport { ResolvedPushPlusConfig } from '../config';\nimport { HttpRequester } from '../http';\nimport { ClawBotInfo, ClawBotMessage, ClawBotQrCode } from '../models';\nimport { OpenAbstractApi } from './open-base';\n\n/**\n * 开放接口 - 微信 ClawBot(文档「八. 微信ClawBot接口」)。\n */\nexport class ClawBotApi extends OpenAbstractApi {\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {\n super(config, http, mgr);\n }\n\n /** 1. 获取二维码。 */\n getBotQrcode(): Promise<ClawBotQrCode> {\n return this.executeOpen<ClawBotQrCode>('GET', '/api/open/clawBot/getBotQrcode');\n }\n\n /** 2. 扫码结果查询。 */\n async getQrcodeStatus(qrcode: string): Promise<void> {\n await this.executeOpen<unknown>(\n 'GET',\n this.appendQuery('/api/open/clawBot/getQrcodeStatus', { getQrcodeStatus: qrcode }),\n );\n }\n\n /** 3. 绑定详情。 */\n botInfo(): Promise<ClawBotInfo> {\n return this.executeOpen<ClawBotInfo>('GET', '/api/open/clawBot/botInfo');\n }\n\n /** 4. 解绑。 */\n async unbind(): Promise<void> {\n await this.executeOpen<unknown>('GET', '/api/open/clawBot/unbind');\n }\n\n /** 5. 获取发送消息。 */\n getMsg(): Promise<ClawBotMessage[]> {\n return this.executeOpen<ClawBotMessage[]>('GET', '/api/open/clawBot/getMsg');\n }\n}\n","import { AccessKeyManager } from '../access-key-manager';\nimport { ResolvedPushPlusConfig } from '../config';\nimport { HttpRequester } from '../http';\nimport { FriendItem, FriendQrCode, PageQuery, PageResult } from '../models';\nimport { OpenAbstractApi } from './open-base';\n\n/**\n * 开放接口 - 好友功能(文档「十. 好友功能接口」)。\n */\nexport class FriendApi extends OpenAbstractApi {\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {\n super(config, http, mgr);\n }\n\n /** 1. 获取个人二维码。 */\n getQrCode(options: {\n appId?: string;\n content?: string;\n second?: number;\n scanCount?: number;\n }): Promise<FriendQrCode> {\n const p: Record<string, unknown> = {};\n if (options.appId != null) p.appId = options.appId;\n if (options.content != null) p.content = options.content;\n if (options.second != null) p.second = options.second;\n if (options.scanCount != null) p.scanCount = options.scanCount;\n return this.executeOpen<FriendQrCode>('GET', this.appendQuery('/api/open/friend/getQrCode', p));\n }\n\n /** 2. 获取好友列表。 */\n list(query?: PageQuery): Promise<PageResult<FriendItem>> {\n return this.executeOpen<PageResult<FriendItem>>('POST', '/api/open/friend/list', query ?? {});\n }\n\n /** 3. 删除好友。 */\n async delete(friendId: number): Promise<void> {\n await this.executeOpen<unknown>(\n 'GET',\n this.appendQuery('/api/open/friend/deleteFriend', { friendId }),\n );\n }\n\n /** 4. 修改好友备注。 */\n async editRemark(id: number, remark: string): Promise<void> {\n await this.executeOpen<unknown>('POST', '/api/open/friend/editRemark', { id, remark });\n }\n}\n","import { ResolvedPushPlusConfig } from '../config';\nimport { PushPlusError } from '../exception';\nimport { HttpRequester } from '../http';\nimport { BatchSendRequest, BatchSendResult, SendRequest } from '../models';\nimport { RateLimitGuard } from '../rate-limit';\nimport { AbstractApi } from './base';\n\n/**\n * 发送消息接口。\n *\n * 对应 PushPlus 文档「二. 发送消息接口」与「三. 多渠道发送消息接口」。\n *\n * 内置本地限流守卫:当上游返回 ErrorCode.RATE_LIMITED(code=900)时,\n * 后续对同一 token 的发送调用会在 SDK 内被直接短路抛 PushPlusError,\n * 不再发起 HTTP,直到守卫到期自动解除。\n */\nexport class MessageApi extends AbstractApi {\n private readonly rateLimitGuard: RateLimitGuard;\n\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester, rateLimitGuard: RateLimitGuard) {\n super(config, http);\n this.rateLimitGuard = rateLimitGuard;\n }\n\n /** 暴露限流守卫,便于运维场景手动 clear 或观察解禁时间。 */\n getRateLimitGuard(): RateLimitGuard {\n return this.rateLimitGuard;\n }\n\n /**\n * 发送单条消息。\n *\n * @returns 消息流水号\n */\n async send(request: SendRequest): Promise<string> {\n const req = this.withDefaultToken(request);\n validateSend(req);\n this.rateLimitGuard.check(req.token);\n return this.executeWithGuard(req.token, () =>\n this.executeForData<string>('POST', '/send', null, req),\n );\n }\n\n /**\n * 多渠道发送消息。\n */\n async batchSend(request: BatchSendRequest): Promise<BatchSendResult[]> {\n const req = this.withDefaultBatchToken(request);\n validateBatch(req);\n this.rateLimitGuard.check(req.token);\n return this.executeWithGuard(req.token, () =>\n this.executeForData<BatchSendResult[]>('POST', '/batchSend', null, req),\n );\n }\n\n /** 便捷方法:以默认渠道、默认模板发送一条简单消息。 */\n sendSimple(title: string | undefined, content: string): Promise<string> {\n return this.send({ title, content });\n }\n\n /* ============================== 内部辅助 ============================== */\n\n private async executeWithGuard<T>(token: string | undefined, call: () => Promise<T>): Promise<T> {\n try {\n return await call();\n } catch (e) {\n if (e instanceof PushPlusError && e.isRateLimited()) {\n this.rateLimitGuard.markBlocked(token);\n }\n throw e;\n }\n }\n\n private withDefaultToken(req: SendRequest): SendRequest {\n if (req == null) throw new PushPlusError('SendRequest 不能为空');\n if (!req.token || req.token.trim().length === 0) {\n return { ...req, token: this.requireToken() };\n }\n return req;\n }\n\n private withDefaultBatchToken(req: BatchSendRequest): BatchSendRequest {\n if (req == null) throw new PushPlusError('BatchSendRequest 不能为空');\n if (!req.token || req.token.trim().length === 0) {\n return { ...req, token: this.requireToken() };\n }\n return req;\n }\n\n private requireToken(): string {\n const t = this.config.token;\n if (!t || t.trim().length === 0) {\n throw new PushPlusError('发送消息需要 token,但 PushPlusConfig.token 为空');\n }\n return t;\n }\n}\n\nfunction validateSend(req: SendRequest): void {\n if (!req.content || req.content.trim().length === 0) {\n throw new PushPlusError('发送消息 content 不能为空');\n }\n}\n\nfunction validateBatch(req: BatchSendRequest): void {\n if (!req.content || req.content.trim().length === 0) {\n throw new PushPlusError('批量发送消息 content 不能为空');\n }\n}\n","import { AccessKeyManager } from '../access-key-manager';\nimport { ResolvedPushPlusConfig } from '../config';\nimport { HttpRequester } from '../http';\nimport {\n MessageTokenAddRequest,\n MessageTokenEditRequest,\n MessageTokenItem,\n MessageTokenOption,\n PageQuery,\n PageResult,\n} from '../models';\nimport { OpenAbstractApi } from './open-base';\n\n/**\n * 开放接口 - 消息 token(文档「四. 消息token接口」)。\n */\nexport class MessageTokenApi extends OpenAbstractApi {\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {\n super(config, http, mgr);\n }\n\n /** 获取消息 token 列表。 */\n list(query?: PageQuery): Promise<PageResult<MessageTokenItem>> {\n return this.executeOpen<PageResult<MessageTokenItem>>('POST', '/api/open/token/list', query ?? {});\n }\n\n /** 新增消息 token,返回新建的 token 字符串。 */\n add(req: MessageTokenAddRequest): Promise<string> {\n return this.executeOpen<string>('POST', '/api/open/token/add', req);\n }\n\n /** 修改消息 token。 */\n edit(req: MessageTokenEditRequest): Promise<string> {\n return this.executeOpen<string>('POST', '/api/open/token/edit', req);\n }\n\n /** 删除消息 token。 */\n delete(id: number): Promise<string> {\n const path = this.appendQuery('/api/open/token/deleteToken', { id });\n return this.executeOpen<string>('DELETE', path);\n }\n\n /**\n * 消息 token 下拉选择列表。\n *\n * @param type 0-返回所有;1-返回未配置默认推送渠道的消息 token\n */\n selectList(type?: number): Promise<MessageTokenOption[]> {\n const path = this.appendQuery('/api/open/token/selectTokenList', { type: type ?? 0 });\n return this.executeOpen<MessageTokenOption[]>('GET', path);\n }\n}\n","import { AccessKeyManager } from '../access-key-manager';\nimport { ResolvedPushPlusConfig } from '../config';\nimport { PushPlusError } from '../exception';\nimport { HttpRequester } from '../http';\nimport { MessageItem, PageQuery, PageResult, SendMessageResult } from '../models';\nimport { OpenAbstractApi } from './open-base';\n\n/**\n * 开放接口 - 消息接口(文档「二. 消息接口」)。\n */\nexport class OpenMessageApi extends OpenAbstractApi {\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {\n super(config, http, mgr);\n }\n\n /** 1. 消息列表。 */\n list(query?: PageQuery): Promise<PageResult<MessageItem>> {\n return this.executeOpen<PageResult<MessageItem>>('POST', '/api/open/message/list', query ?? {});\n }\n\n /** 2. 查询消息发送结果。 */\n queryResult(shortCode: string): Promise<SendMessageResult> {\n if (!shortCode || shortCode.trim().length === 0) {\n throw new PushPlusError('shortCode 不能为空');\n }\n const path = this.appendQuery('/api/open/message/sendMessageResult', { shortCode });\n return this.executeOpen<SendMessageResult>('GET', path);\n }\n\n /** 3. 删除消息。 */\n delete(shortCode: string): Promise<string> {\n if (!shortCode || shortCode.trim().length === 0) {\n throw new PushPlusError('shortCode 不能为空');\n }\n const path = this.appendQuery('/api/open/message/deleteMessage', { shortCode });\n return this.executeOpen<string>('DELETE', path);\n }\n\n /**\n * 4. 消息详情(HTML 页面 URL)。\n *\n * 该接口直接返回 HTML 内容,SDK 仅返回访问 URL,调用方自行决定是否拉取页面内容。\n */\n detailUrl(shortCode: string): string {\n if (!shortCode || shortCode.trim().length === 0) {\n throw new PushPlusError('shortCode 不能为空');\n }\n return this.resolveUrl('/shortMessage/' + shortCode);\n }\n}\n","import { AccessKeyManager } from '../access-key-manager';\nimport { ResolvedPushPlusConfig } from '../config';\nimport { HttpRequester } from '../http';\nimport { PageQuery, PageResult, PreDetail, PreItem, PreSaveRequest, PreTestRequest } from '../models';\nimport { OpenAbstractApi } from './open-base';\n\n/**\n * 开放接口 - 预处理信息(文档「十一. 预处理信息接口」)。注:需开通会员。\n */\nexport class PreApi extends OpenAbstractApi {\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {\n super(config, http, mgr);\n }\n\n list(q?: PageQuery): Promise<PageResult<PreItem>> {\n return this.executeOpen<PageResult<PreItem>>('POST', '/api/open/pre/list', q ?? {});\n }\n\n detail(preId: number): Promise<PreDetail> {\n return this.executeOpen<PreDetail>('GET', this.appendQuery('/api/open/pre/detail', { preId }));\n }\n\n add(req: PreSaveRequest): Promise<number> {\n return this.executeOpen<number>('POST', '/api/open/pre/add', req);\n }\n\n edit(req: PreSaveRequest): Promise<string> {\n return this.executeOpen<string>('POST', '/api/open/pre/edit', req);\n }\n\n delete(preId: number): Promise<string> {\n return this.executeOpen<string>(\n 'DELETE',\n this.appendQuery('/api/open/pre/delete', { preId }),\n );\n }\n\n /** 测试预处理代码,返回处理后的消息。 */\n test(req: PreTestRequest): Promise<string> {\n return this.executeOpen<string>('POST', '/api/open/pre/test', req);\n }\n}\n","import { AccessKeyManager } from '../access-key-manager';\nimport { ResolvedPushPlusConfig } from '../config';\nimport { HttpRequester } from '../http';\nimport {\n PageQuery,\n PageResult,\n UserDefaultDetail,\n UserDefaultItem,\n UserDefaultSaveRequest,\n} from '../models';\nimport { OpenAbstractApi } from './open-base';\n\n/**\n * 开放接口 - 功能设置(文档「九. 功能设置接口」)。\n */\nexport class SettingApi extends OpenAbstractApi {\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {\n super(config, http, mgr);\n }\n\n /** 1. 获取默认配置列表。 */\n listUserDefault(q?: PageQuery): Promise<PageResult<UserDefaultItem>> {\n return this.executeOpen<PageResult<UserDefaultItem>>('POST', '/api/open/setting/listUserDefault', q ?? {});\n }\n\n /** 2. 默认配置详情。 */\n detailUserDefault(id: number): Promise<UserDefaultDetail> {\n return this.executeOpen<UserDefaultDetail>(\n 'GET',\n this.appendQuery('/api/open/setting/detailUserDefault', { id }),\n );\n }\n\n /** 3. 新增默认配置。 */\n async addUserDefault(req: UserDefaultSaveRequest): Promise<void> {\n await this.executeOpen<unknown>('POST', '/api/open/setting/addUserDefault', req);\n }\n\n /** 4. 修改默认配置。 */\n async editUserDefault(req: UserDefaultSaveRequest): Promise<void> {\n await this.executeOpen<unknown>('POST', '/api/open/setting/editUserDefault', req);\n }\n\n /** 5. 删除默认配置。 */\n async deleteUserDefault(id: number): Promise<void> {\n await this.executeOpen<unknown>(\n 'DELETE',\n this.appendQuery('/api/open/setting/deleteUserDefault', { id }),\n );\n }\n\n /**\n * 6. 修改接收消息限制。\n *\n * @param recevieLimit 0-接收全部,1-不接收消息\n */\n async changeReceiveLimit(recevieLimit: number): Promise<void> {\n await this.executeOpen<unknown>(\n 'GET',\n this.appendQuery('/api/open/setting/changeRecevieLimit', { recevieLimit }),\n );\n }\n\n /**\n * 7. 开启/关闭发送消息功能。\n *\n * @param isSend 0-禁用,1-启用\n */\n async changeIsSend(isSend: number): Promise<void> {\n await this.executeOpen<unknown>(\n 'GET',\n this.appendQuery('/api/open/setting/changeIsSend', { isSend }),\n );\n }\n\n /**\n * 8. 修改打开消息方式。\n *\n * @param openMessageType 0:H5,1:小程序\n */\n async changeOpenMessageType(openMessageType: number): Promise<void> {\n await this.executeOpen<unknown>(\n 'GET',\n this.appendQuery('/api/open/setting/changeOpenMessageType', { openMessageType }),\n );\n }\n\n /**\n * 9. 修改插件渠道转发。\n *\n * @param forward 0:否,1:是\n */\n async changeExtensionForward(forward: number): Promise<void> {\n await this.executeOpen<unknown>(\n 'GET',\n this.appendQuery('/api/open/setting/extension', { forward }),\n );\n }\n}\n","import { AccessKeyManager } from '../access-key-manager';\nimport { ResolvedPushPlusConfig } from '../config';\nimport { HttpRequester } from '../http';\nimport {\n PageResult,\n TopicAddRequest,\n TopicDetail,\n TopicEditRequest,\n TopicItem,\n TopicListQuery,\n TopicQrCode,\n} from '../models';\nimport { OpenAbstractApi } from './open-base';\n\n/**\n * 开放接口 - 群组接口(文档「五. 群组接口」)。\n */\nexport class TopicApi extends OpenAbstractApi {\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {\n super(config, http, mgr);\n }\n\n /** 1. 群组列表。 */\n list(query?: TopicListQuery): Promise<PageResult<TopicItem>> {\n return this.executeOpen<PageResult<TopicItem>>('POST', '/api/open/topic/list', query ?? {});\n }\n\n /** 2. 获取我创建的群组详情。 */\n detail(topicId: number): Promise<TopicDetail> {\n return this.executeOpen<TopicDetail>('GET', this.appendQuery('/api/open/topic/detail', { topicId }));\n }\n\n /** 3. 获取我加入的群详情。 */\n joinDetail(topicId: number): Promise<TopicDetail> {\n return this.executeOpen<TopicDetail>(\n 'GET',\n this.appendQuery('/api/open/topic/joinTopicDetail', { topicId }),\n );\n }\n\n /** 4. 新增群组,返回新建群组编号。 */\n add(req: TopicAddRequest): Promise<number> {\n return this.executeOpen<number>('POST', '/api/open/topic/add', req);\n }\n\n /** 5. 修改群组。 */\n edit(req: TopicEditRequest): Promise<string> {\n return this.executeOpen<string>('POST', '/api/open/topic/editTopic', req);\n }\n\n /** 6. 获取群组二维码。 */\n qrCode(topicId: number, second?: number, scanCount?: number): Promise<TopicQrCode> {\n const params: Record<string, unknown> = { topicId };\n if (second != null) params.second = second;\n if (scanCount != null) params.scanCount = scanCount;\n return this.executeOpen<TopicQrCode>('GET', this.appendQuery('/api/open/topic/qrCode', params));\n }\n\n /** 7. 退出群组。 */\n exit(topicId: number): Promise<string> {\n return this.executeOpen<string>(\n 'GET',\n this.appendQuery('/api/open/topic/exitTopic', { topicId }),\n );\n }\n\n /** 8. 删除群组。 */\n delete(topicId: number): Promise<string> {\n return this.executeOpen<string>('GET', this.appendQuery('/api/open/topic/delete', { topicId }));\n }\n\n /**\n * 9. 上下架积分群组。\n *\n * @param isOpen 1-上架,0-下架\n */\n setOpen(topicId: number, isOpen: number): Promise<string> {\n return this.executeOpen<string>('POST', '/api/open/topic/isOpen', { topic: topicId, isOpen });\n }\n}\n","import { AccessKeyManager } from '../access-key-manager';\nimport { ResolvedPushPlusConfig } from '../config';\nimport { HttpRequester } from '../http';\nimport { PageResult, TopicUserItem, TopicUserListQuery } from '../models';\nimport { OpenAbstractApi } from './open-base';\n\n/**\n * 开放接口 - 群组用户(文档「六. 群组用户接口」)。\n */\nexport class TopicUserApi extends OpenAbstractApi {\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {\n super(config, http, mgr);\n }\n\n /** 1. 获取群组内用户。 */\n subscriberList(query: TopicUserListQuery): Promise<PageResult<TopicUserItem>> {\n return this.executeOpen<PageResult<TopicUserItem>>('POST', '/api/open/topicUser/subscriberList', query);\n }\n\n /** 2. 删除群组内用户。 */\n deleteUser(topicRelationId: number): Promise<string> {\n const path = this.appendQuery('/api/open/topicUser/deleteTopicUser', { topicRelationId });\n return this.executeOpen<string>('POST', path);\n }\n\n /** 3. 修改订阅人备注。 */\n async editRemark(id: number, remark: string): Promise<void> {\n await this.executeOpen<unknown>('POST', '/api/open/topicUser/editRemark', { id, remark });\n }\n}\n","import { AccessKeyManager } from '../access-key-manager';\nimport { ResolvedPushPlusConfig } from '../config';\nimport { HttpRequester } from '../http';\nimport { SendCount, UserInfo, UserLimitTime } from '../models';\nimport { OpenAbstractApi } from './open-base';\n\n/**\n * 开放接口 - 用户接口(文档「三. 用户接口」)。\n */\nexport class UserApi extends OpenAbstractApi {\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {\n super(config, http, mgr);\n }\n\n /** 获取用户 token。 */\n getToken(): Promise<string> {\n return this.executeOpen<string>('GET', '/api/open/user/token');\n }\n\n /** 个人资料详情。 */\n myInfo(): Promise<UserInfo> {\n return this.executeOpen<UserInfo>('GET', '/api/open/user/myInfo');\n }\n\n /** 获取解封剩余时间。 */\n getLimitTime(): Promise<UserLimitTime> {\n return this.executeOpen<UserLimitTime>('GET', '/api/open/user/userLimitTime');\n }\n\n /** 查询当日消息接口请求次数。 */\n getSendCount(): Promise<SendCount> {\n return this.executeOpen<SendCount>('GET', '/api/open/user/sendCount');\n }\n}\n","import { AccessKeyManager } from '../access-key-manager';\nimport { ResolvedPushPlusConfig } from '../config';\nimport { HttpRequester } from '../http';\nimport { PageQuery, PageResult, WebhookItem, WebhookSaveRequest } from '../models';\nimport { OpenAbstractApi } from './open-base';\n\n/**\n * 开放接口 - webhook 渠道配置(文档「七. 渠道配置接口」 1-4)。\n */\nexport class WebhookApi extends OpenAbstractApi {\n constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {\n super(config, http, mgr);\n }\n\n list(q?: PageQuery): Promise<PageResult<WebhookItem>> {\n return this.executeOpen<PageResult<WebhookItem>>('POST', '/api/open/webhook/list', q ?? {});\n }\n\n detail(webhookId: number): Promise<WebhookItem> {\n return this.executeOpen<WebhookItem>(\n 'GET',\n this.appendQuery('/api/open/webhook/detail', { webhookId }),\n );\n }\n\n /** 新增 webhook,返回新 id。 */\n add(req: WebhookSaveRequest): Promise<number> {\n return this.executeOpen<number>('POST', '/api/open/webhook/add', req);\n }\n\n edit(req: WebhookSaveRequest): Promise<string> {\n return this.executeOpen<string>('POST', '/api/open/webhook/edit', req);\n }\n}\n","/**\n * PushPlus SDK 全局配置。\n *\n * 通过 `PushPlusClient.builder()` 或直接 `new PushPlusClient(config)` 构建实例。\n * 所有字段都有合理默认值,仅 `token` 是发送消息接口必填、`secretKey` 是开放接口必填。\n */\nexport interface PushPlusConfig {\n /**\n * 用户 token 或消息 token,发送消息接口默认使用。\n * 注意:获取 AccessKey 必须使用用户 token。\n */\n token?: string;\n\n /**\n * 用户 secretKey,调用开放接口(获取 AccessKey)必填。\n * 在 pushplus 个人中心 -> 开发设置 中配置。\n */\n secretKey?: string;\n\n /**\n * 服务器基础地址。默认:https://www.pushplus.plus\n */\n baseUrl?: string;\n\n /** 连接超时(毫秒)。默认 10000。 */\n connectTimeoutMs?: number;\n\n /** 请求/读超时(毫秒)。默认 30000。 */\n readTimeoutMs?: number;\n\n /**\n * 在 AccessKey 过期前提前多少秒刷新。默认提前 5 分钟(300 秒),\n * 文档中提到老 AccessKey 在新 AccessKey 生成后 5 分钟内仍可用。\n */\n accessKeyRefreshAheadSeconds?: number;\n\n /** 是否启用请求/响应详细日志。默认关闭。 */\n logRequest?: boolean;\n\n /**\n * 是否启用本地限流守卫。默认开启。\n *\n * 开启后,当任意一次发送消息接口返回 code=900(请求次数过多)时,\n * 后续对同一 token 的发送调用会被 SDK 直接短路,不再发起 HTTP,\n * 直到 `rateLimitCooldownMs`(默认次日 0 点)到期。\n */\n rateLimitGuardEnabled?: boolean;\n\n /**\n * 命中 code=900 后的本地禁推时长(毫秒)。\n * 不传或 <=0 表示使用默认策略:到「次日 0 点」。\n *\n * 注意:服务端实际禁推时长可能更长(文档示例为 2 天)。\n */\n rateLimitCooldownMs?: number;\n\n /** 自定义 User-Agent。 */\n userAgent?: string;\n}\n\n/** PushPlus 默认服务地址。 */\nexport const DEFAULT_BASE_URL = 'https://www.pushplus.plus';\n\nexport interface ResolvedPushPlusConfig {\n token: string;\n secretKey: string;\n baseUrl: string;\n connectTimeoutMs: number;\n readTimeoutMs: number;\n accessKeyRefreshAheadSeconds: number;\n logRequest: boolean;\n rateLimitGuardEnabled: boolean;\n rateLimitCooldownMs: number;\n userAgent: string;\n}\n\nexport function resolveConfig(input: PushPlusConfig | undefined | null): ResolvedPushPlusConfig {\n const cfg = input ?? {};\n const baseUrl = (cfg.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '');\n return {\n token: cfg.token ?? '',\n secretKey: cfg.secretKey ?? '',\n baseUrl: baseUrl || DEFAULT_BASE_URL,\n connectTimeoutMs: cfg.connectTimeoutMs ?? 10000,\n readTimeoutMs: cfg.readTimeoutMs ?? 30000,\n accessKeyRefreshAheadSeconds: cfg.accessKeyRefreshAheadSeconds ?? 300,\n logRequest: cfg.logRequest ?? false,\n rateLimitGuardEnabled: cfg.rateLimitGuardEnabled ?? true,\n rateLimitCooldownMs: cfg.rateLimitCooldownMs ?? 0,\n userAgent: cfg.userAgent ?? `@perk-net/perk-pushplus-sdk/1.0.0`,\n };\n}\n","import { ResolvedPushPlusConfig } from './config';\nimport { ErrorCode } from './enums';\nimport { PushPlusError } from './exception';\n\n/**\n * 本地限流守卫:当 PushPlus 服务端返回 ErrorCode.RATE_LIMITED(code=900)时,\n * 在内存里按 token 维度记录\"解禁时间\",期间任何发送类调用都会直接抛 PushPlusError,\n * 不再发起 HTTP,避免继续打到上游浪费请求并加重账号限制。\n *\n * 对应官方文档建议:https://www.pushplus.plus/doc/guide/code.html\n *\n * 默认禁推到「次日 0 点」自动解禁;也可以通过 rateLimitCooldownMs 配置一个固定时长。\n *\n * 仅本地视角:服务端实际禁推时长可能与本地估算不同(文档示例为 2 天)。\n */\nexport class RateLimitGuard {\n private readonly enabled: boolean;\n private readonly cooldownMs: number;\n private readonly blockedUntil = new Map<string, number>();\n\n constructor(config: ResolvedPushPlusConfig) {\n this.enabled = config.rateLimitGuardEnabled;\n this.cooldownMs = config.rateLimitCooldownMs;\n }\n\n /**\n * 在发起发送类请求前调用:若当前 token 处于限流期,直接抛 PushPlusError\n * (code = ErrorCode.RATE_LIMITED),不会发起 HTTP。\n */\n check(token: string | undefined | null): void {\n if (!this.enabled) return;\n const key = this.normalize(token);\n if (!key) return;\n const until = this.blockedUntil.get(key);\n if (until == null) return;\n const now = Date.now();\n if (now < until) {\n throw new PushPlusError(\n `PushPlus 本地限流守卫:当前 token 已命中 code=900,` +\n `在 ${new Date(until).toISOString()} 之前不再发起请求(请参考官方文档减少无用请求)`,\n ErrorCode.RATE_LIMITED,\n );\n }\n this.blockedUntil.delete(key);\n }\n\n /**\n * 在收到服务端 code=900 后调用:登记限流状态,直到 cooldownUntil 到期。\n */\n markBlocked(token: string | undefined | null): void {\n if (!this.enabled) return;\n const key = this.normalize(token);\n if (!key) return;\n const until = this.cooldownUntil(Date.now());\n this.blockedUntil.set(key, until);\n }\n\n /** 仅供测试或运维手动清除(例如已确认服务端解禁)。 */\n clear(token: string | undefined | null): void {\n const key = this.normalize(token);\n if (key) this.blockedUntil.delete(key);\n }\n\n /** 返回该 token 的解禁时间(毫秒时间戳);未被限流则为 null。 */\n blockedUntilAt(token: string | undefined | null): number | null {\n const key = this.normalize(token);\n if (!key) return null;\n const until = this.blockedUntil.get(key);\n return until ?? null;\n }\n\n /**\n * 计算解禁时间:\n * - cooldownMs > 0 时使用 now + cooldownMs;\n * - 否则使用「系统默认时区的次日 0 点」。\n */\n private cooldownUntil(now: number): number {\n if (this.cooldownMs && this.cooldownMs > 0) {\n return now + this.cooldownMs;\n }\n const d = new Date(now);\n d.setHours(0, 0, 0, 0);\n d.setDate(d.getDate() + 1);\n return d.getTime();\n }\n\n private normalize(token: string | undefined | null): string | null {\n if (token == null) return null;\n const t = String(token).trim();\n return t.length === 0 ? null : t;\n }\n}\n","import { AccessKeyManager } from './access-key-manager';\nimport { AccessKeyApi } from './api/access-key-api';\nimport { ChannelApi } from './api/channel-api';\nimport { ClawBotApi } from './api/clawbot-api';\nimport { FriendApi } from './api/friend-api';\nimport { MessageApi } from './api/message-api';\nimport { MessageTokenApi } from './api/message-token-api';\nimport { OpenMessageApi } from './api/open-message-api';\nimport { PreApi } from './api/pre-api';\nimport { SettingApi } from './api/setting-api';\nimport { TopicApi } from './api/topic-api';\nimport { TopicUserApi } from './api/topic-user-api';\nimport { UserApi } from './api/user-api';\nimport { WebhookApi } from './api/webhook-api';\nimport { PushPlusConfig, ResolvedPushPlusConfig, resolveConfig } from './config';\nimport { PushPlusError } from './exception';\nimport { FetchHttpRequester, HttpRequester } from './http';\nimport { BatchSendRequest, BatchSendResult, SendRequest } from './models';\nimport { RateLimitGuard } from './rate-limit';\n\nexport interface PushPlusClientOptions extends PushPlusConfig {\n /** 自定义 HTTP 客户端实现。 */\n httpRequester?: HttpRequester;\n}\n\n/**\n * PushPlus SDK 统一入口。\n *\n * 兼容 Node.js(>=18 内置 fetch)与浏览器环境。\n *\n * @example 快速开始\n * ```ts\n * import { PushPlusClient } from '@perk-net/perk-pushplus-sdk';\n *\n * const client = new PushPlusClient({\n * token: 'your_user_token',\n * secretKey: 'your_secret_key', // 调用开放接口才需要\n * });\n *\n * // 发送消息\n * const shortCode = await client.sendSimple('标题', 'Hello PushPlus');\n *\n * // 调用开放接口(无需手动管理 AccessKey)\n * const info = await client.user.myInfo();\n * ```\n */\nexport class PushPlusClient {\n /** 已解析的不可变配置。 */\n readonly config: ResolvedPushPlusConfig;\n readonly httpRequester: HttpRequester;\n readonly accessKeyManager: AccessKeyManager;\n readonly rateLimitGuard: RateLimitGuard;\n\n /* ---------------- 各 API ---------------- */\n readonly message: MessageApi;\n readonly accessKey: AccessKeyApi;\n readonly openMessage: OpenMessageApi;\n readonly user: UserApi;\n readonly messageToken: MessageTokenApi;\n readonly topic: TopicApi;\n readonly topicUser: TopicUserApi;\n readonly friend: FriendApi;\n readonly webhook: WebhookApi;\n readonly channel: ChannelApi;\n readonly clawBot: ClawBotApi;\n readonly setting: SettingApi;\n readonly pre: PreApi;\n\n constructor(options: PushPlusClientOptions = {}) {\n this.config = resolveConfig(options);\n this.httpRequester = options.httpRequester ?? new FetchHttpRequester(this.config);\n this.rateLimitGuard = new RateLimitGuard(this.config);\n\n this.message = new MessageApi(this.config, this.httpRequester, this.rateLimitGuard);\n this.accessKey = new AccessKeyApi(this.config, this.httpRequester);\n this.accessKeyManager = new AccessKeyManager(this.config, this.accessKey);\n\n this.openMessage = new OpenMessageApi(this.config, this.httpRequester, this.accessKeyManager);\n this.user = new UserApi(this.config, this.httpRequester, this.accessKeyManager);\n this.messageToken = new MessageTokenApi(this.config, this.httpRequester, this.accessKeyManager);\n this.topic = new TopicApi(this.config, this.httpRequester, this.accessKeyManager);\n this.topicUser = new TopicUserApi(this.config, this.httpRequester, this.accessKeyManager);\n this.friend = new FriendApi(this.config, this.httpRequester, this.accessKeyManager);\n this.webhook = new WebhookApi(this.config, this.httpRequester, this.accessKeyManager);\n this.channel = new ChannelApi(this.config, this.httpRequester, this.accessKeyManager);\n this.clawBot = new ClawBotApi(this.config, this.httpRequester, this.accessKeyManager);\n this.setting = new SettingApi(this.config, this.httpRequester, this.accessKeyManager);\n this.pre = new PreApi(this.config, this.httpRequester, this.accessKeyManager);\n }\n\n /** 与 Java SDK 风格一致的 Builder 入口。 */\n static builder(): PushPlusClientBuilder {\n return new PushPlusClientBuilder();\n }\n\n /** 工厂方法。 */\n static of(options: PushPlusClientOptions): PushPlusClient {\n return new PushPlusClient(options);\n }\n\n /* ============================== 便捷转发方法 ============================== */\n\n /** 发送一条简单消息(默认 wechat / html)。 */\n sendSimple(title: string | undefined, content: string): Promise<string> {\n return this.message.sendSimple(title, content);\n }\n\n /** 发送消息。 */\n send(req: SendRequest): Promise<string> {\n return this.message.send(req);\n }\n\n /** 多渠道发送消息。 */\n batchSend(req: BatchSendRequest): Promise<BatchSendResult[]> {\n return this.message.batchSend(req);\n }\n}\n\n/**\n * 链式 Builder,与 Java/Python SDK 风格保持一致。\n */\nexport class PushPlusClientBuilder {\n private readonly opt: PushPlusClientOptions = {};\n\n token(v?: string): this { this.opt.token = v; return this; }\n secretKey(v?: string): this { this.opt.secretKey = v; return this; }\n baseUrl(v?: string): this { this.opt.baseUrl = v; return this; }\n connectTimeoutMs(v: number): this { this.opt.connectTimeoutMs = v; return this; }\n readTimeoutMs(v: number): this { this.opt.readTimeoutMs = v; return this; }\n accessKeyRefreshAheadSeconds(v: number): this { this.opt.accessKeyRefreshAheadSeconds = v; return this; }\n logRequest(v: boolean): this { this.opt.logRequest = v; return this; }\n rateLimitGuardEnabled(v: boolean): this { this.opt.rateLimitGuardEnabled = v; return this; }\n rateLimitCooldownMs(v: number): this { this.opt.rateLimitCooldownMs = v; return this; }\n userAgent(v: string): this { this.opt.userAgent = v; return this; }\n httpRequester(req: HttpRequester): this { this.opt.httpRequester = req; return this; }\n\n build(): PushPlusClient {\n if (this.opt.token != null && this.opt.token.trim().length === 0) {\n throw new PushPlusError('token 不能为空字符串');\n }\n return new PushPlusClient(this.opt);\n }\n}\n","import { PushPlusError } from './exception';\nimport { CallbackPayload } from './models';\n\n/**\n * PushPlus 回调请求体解析工具。\n *\n * 用法:在你的回调接口中拿到原始 JSON body,直接传入 `parseCallback(body)` 即可。\n *\n * @example\n * ```ts\n * import { parseCallback, CallbackEvent } from '@perk-net/perk-pushplus-sdk';\n *\n * function onPushPlusCallback(rawBody: string) {\n * const payload = parseCallback(rawBody);\n * switch (payload.event) {\n * case CallbackEvent.MESSAGE_COMPLETE:\n * // payload.messageInfo\n * break;\n * case CallbackEvent.ADD_TOPIC_USER:\n * // payload.topicUserInfo\n * break;\n * case CallbackEvent.ADD_FRIEND:\n * // payload.friendInfo, payload.qrCode\n * break;\n * }\n * return 'ok';\n * }\n * ```\n */\nexport function parseCallback(json: string | object): CallbackPayload {\n if (json == null) {\n throw new PushPlusError('回调请求体不能为空');\n }\n if (typeof json === 'string') {\n try {\n return JSON.parse(json) as CallbackPayload;\n } catch (e) {\n throw new PushPlusError(`解析 PushPlus 回调失败: ${(e as Error).message}`, -1, { cause: e });\n }\n }\n return json as CallbackPayload;\n}\n\nexport const CallbackParser = {\n parse: parseCallback,\n};\n","import { CallbackEvent, Channel, SendStatus, Template, WebhookType } from './enums';\n\n/**\n * PushPlus 接口统一响应。所有接口都遵循 `{code, msg, data}` 结构。\n */\nexport interface ApiResponse<T = unknown> {\n code?: number;\n msg?: string;\n data?: T;\n}\n\n/** 通用分页请求参数。 */\nexport interface PageQuery {\n /** 当前所在分页数,默认 1。 */\n current?: number;\n /** 每页大小,默认 20,最大 50。 */\n pageSize?: number;\n}\n\n/** 分页响应结构。 */\nexport interface PageResult<T> {\n pageNum?: number;\n pageSize?: number;\n total?: number;\n pages?: number;\n list?: T[];\n}\n\n/* ============================== 发送消息 ============================== */\n\n/**\n * 发送消息请求。对应 `/send` 接口。\n *\n * 推荐使用 `SendRequestBuilder`(`SendRequest.builder()`)链式构建。\n */\nexport interface SendRequest {\n /** 用户 token 或消息 token。可不填,由 SDK 从 PushPlusConfig 自动注入。 */\n token?: string;\n /** 消息标题。 */\n title?: string;\n /** 消息内容;必填。 */\n content?: string;\n /** 群组编码。不填仅发送给自己;channel 为 webhook 时无效。 */\n topic?: string;\n /** 发送模板,默认 html。 */\n template?: Template | string;\n /** 发送渠道,默认 wechat。 */\n channel?: Channel | string;\n /** 渠道配置参数(cp/webhook/mail 渠道使用渠道编码)。 */\n option?: string;\n /** 异步回调地址。 */\n callbackUrl?: string;\n /** 毫秒时间戳;服务器时间大于此时间戳消息不会发送。 */\n timestamp?: number;\n /** 好友令牌;多个用逗号分隔。 */\n to?: string;\n /** 预处理编码(仅会员)。 */\n pre?: string;\n}\n\nexport class SendRequestBuilder {\n private req: SendRequest = {};\n\n token(v?: string): this { this.req.token = v; return this; }\n title(v?: string): this { this.req.title = v; return this; }\n content(v?: string): this { this.req.content = v; return this; }\n topic(v?: string): this { this.req.topic = v; return this; }\n template(v?: Template | string): this { this.req.template = v; return this; }\n channel(v?: Channel | string): this { this.req.channel = v; return this; }\n option(v?: string): this { this.req.option = v; return this; }\n callbackUrl(v?: string): this { this.req.callbackUrl = v; return this; }\n timestamp(v?: number): this { this.req.timestamp = v; return this; }\n to(v?: string): this { this.req.to = v; return this; }\n pre(v?: string): this { this.req.pre = v; return this; }\n\n build(): SendRequest {\n return { ...this.req };\n }\n}\n\n/**\n * 创建 SendRequest 链式构造器。\n */\nexport function sendRequest(): SendRequestBuilder {\n return new SendRequestBuilder();\n}\n\n/* ============================== 多渠道发送 ============================== */\n\n/**\n * 多渠道发送消息请求。对应 `/batchSend` 接口。\n */\nexport interface BatchSendRequest {\n token?: string;\n title?: string;\n content?: string;\n topic?: string;\n template?: Template | string;\n /** 多渠道,逗号分隔。 */\n channel?: string;\n /** 多渠道 option,逗号分隔;与 channel 一一对应。 */\n option?: string;\n callbackUrl?: string;\n timestamp?: number;\n to?: string;\n pre?: string;\n}\n\n/**\n * 链式 Builder:支持以 `channel(Channel)` / `option(string)` 形式累积调用,\n * 内部自动用逗号拼接并按顺序一一对应。\n *\n * 也可以通过 `channelString`/`optionString` 直接指定 CSV 字符串。\n * 累积式优先级高于 CSV 字符串。\n */\nexport class BatchSendRequestBuilder {\n private req: BatchSendRequest = {};\n private readonly channelList: string[] = [];\n private readonly optionList: string[] = [];\n\n token(v?: string): this { this.req.token = v; return this; }\n title(v?: string): this { this.req.title = v; return this; }\n content(v?: string): this { this.req.content = v; return this; }\n topic(v?: string): this { this.req.topic = v; return this; }\n template(v?: Template | string): this { this.req.template = v; return this; }\n callbackUrl(v?: string): this { this.req.callbackUrl = v; return this; }\n timestamp(v?: number): this { this.req.timestamp = v; return this; }\n to(v?: string): this { this.req.to = v; return this; }\n pre(v?: string): this { this.req.pre = v; return this; }\n\n /** 追加一个 channel。 */\n channel(ch: Channel | string): this {\n this.channelList.push(typeof ch === 'string' ? ch : (ch as string));\n return this;\n }\n\n /** 追加一个 option,与最近一次 channel() 配对;可传空串。 */\n option(opt?: string): this {\n this.optionList.push(opt ?? '');\n return this;\n }\n\n /** 直接以 CSV 形式指定多渠道字符串(与累积式 channel(Channel) 互斥)。 */\n channelString(csv?: string): this { this.req.channel = csv; return this; }\n\n /** 直接以 CSV 形式指定 option 字符串。 */\n optionString(csv?: string): this { this.req.option = csv; return this; }\n\n build(): BatchSendRequest {\n const finalChannel = this.channelList.length > 0 ? this.channelList.join(',') : this.req.channel;\n const finalOption = this.optionList.length > 0 ? this.optionList.join(',') : this.req.option;\n return { ...this.req, channel: finalChannel, option: finalOption };\n }\n}\n\n/**\n * 创建 BatchSendRequest 链式构造器。\n */\nexport function batchSendRequest(): BatchSendRequestBuilder {\n return new BatchSendRequestBuilder();\n}\n\n/** 批量发送的单条渠道结果。 */\nexport interface BatchSendResult {\n /** 消息流水号;可用于查询发送结果。 */\n shortCode?: string;\n /** 业务消息。 */\n message?: string;\n /** 业务 code。 */\n code?: number;\n /** 渠道。 */\n channel?: Channel | string;\n}\n\n/* ============================== 回调 ============================== */\n\nexport interface MessageCompleteInfo {\n /** 推送错误内容(如有)。 */\n message?: string;\n /** 消息流水号。 */\n shortCode?: string;\n /** 发送状态:0-未发送,1-发送中,2-发送成功,3-发送失败。 */\n sendStatus?: SendStatus | number;\n}\n\nexport interface TopicUserInfo {\n id?: number;\n openId?: string;\n topicId?: number;\n userSex?: number;\n isFollow?: number;\n nickName?: string;\n havePhone?: number;\n topicCode?: string;\n topicName?: string;\n headImgUrl?: string;\n emailStatus?: number;\n}\n\nexport interface FriendInfo {\n token?: string;\n friendId?: number;\n isFollow?: number;\n nickName?: string;\n havePhone?: number;\n createTime?: string;\n emailStatus?: number;\n}\n\n/**\n * PushPlus 回调统一载体。\n *\n * 使用 `parseCallback(json)` 解析回调请求体后,\n * 根据 `event` 判断事件类型并取对应的字段。\n */\nexport interface CallbackPayload {\n event?: CallbackEvent | string;\n messageInfo?: MessageCompleteInfo;\n topicUserInfo?: TopicUserInfo;\n friendInfo?: FriendInfo;\n /** 自定义二维码参数(仅 add_friend 事件有值)。 */\n qrCode?: string;\n}\n\n/* ============================== 开放接口 - access ============================== */\n\nexport interface AccessKeyResult {\n /** 访问令牌,后续请求需加到 header 中。 */\n accessKey?: string;\n /** 过期时间(单位秒)。 */\n expiresIn?: number;\n}\n\n/* ============================== 开放接口 - user ============================== */\n\nexport interface UserInfo {\n openId?: string;\n unionId?: string;\n nickName?: string;\n headImgUrl?: string;\n userSex?: number;\n token?: string;\n phoneNumber?: string;\n email?: string;\n emailStatus?: number;\n birthday?: string;\n points?: number;\n}\n\nexport interface SendCount {\n wechatSendCount?: number;\n cpSendCount?: number;\n webhookSendCount?: number;\n mailSendCount?: number;\n}\n\nexport interface UserLimitTime {\n /** 1-无限制,2-短期限制,3-永久限制。 */\n sendLimit?: number;\n userLimitTime?: string;\n}\n\n/* ============================== 开放接口 - message ============================== */\n\nexport interface MessageItem {\n topicName?: string;\n /** 消息类型:1-一对一消息,2-一对多消息。 */\n messageType?: number;\n title?: string;\n shortCode?: string;\n channel?: Channel | string;\n updateTime?: string;\n}\n\nexport interface SendMessageResult {\n /** 0-未投递,1-发送中,2-已发送,3-发送失败。 */\n status?: SendStatus | number;\n errorMessage?: string;\n updateTime?: string;\n}\n\n/* ============================== 开放接口 - message token ============================== */\n\nexport interface MessageTokenAddRequest {\n /** 令牌名称;必填。 */\n name: string;\n /** 过期时间,格式 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss;不填默认 2999-12-31。 */\n expireTime?: string;\n}\n\nexport interface MessageTokenEditRequest {\n id: number;\n name?: string;\n expireTime?: string;\n}\n\nexport interface MessageTokenItem {\n id?: number;\n name?: string;\n expireTime?: string;\n token?: string;\n}\n\nexport interface MessageTokenOption {\n id?: number;\n name?: string;\n}\n\n/* ============================== 开放接口 - topic ============================== */\n\nexport interface TopicListQuery {\n current?: number;\n pageSize?: number;\n /** 例如 { topicType: 0 };0-我创建的,1-我加入的。 */\n params?: Record<string, unknown>;\n}\n\nexport interface TopicQrCode {\n qrCodeImgUrl?: string;\n /** 0-临时二维码,1-永久二维码。 */\n forever?: number;\n}\n\nexport interface TopicAddRequest {\n topicCode?: string;\n topicName?: string;\n contact?: string;\n introduction?: string;\n receiptMessage?: string;\n appId?: string;\n icon?: string;\n /** 0普通;1积分;2公开。默认 0。 */\n topicType?: number;\n price?: number | string;\n topicDescribe?: string;\n}\n\nexport interface TopicEditRequest {\n /** 群组编号,必填。 */\n topic: number;\n topicCode?: string;\n topicName?: string;\n contact?: string;\n introduction?: string;\n receiptMessage?: string;\n icon?: string;\n price?: number | string;\n topicDescribe?: string;\n}\n\nexport interface TopicDetail {\n topicId?: number;\n topicName?: string;\n topicCode?: string;\n qrCodeImgUrl?: string;\n contact?: string;\n introduction?: string;\n receiptMessage?: string;\n nickName?: string;\n createTime?: string;\n topicUserCount?: number;\n icon?: string;\n appId?: string;\n topicType?: number;\n price?: number | string;\n topicDescribe?: string;\n userNickName?: string;\n isApproved?: number;\n firstIsApproved?: number;\n approveReason?: string;\n isOpen?: number;\n}\n\nexport interface TopicItem {\n icon?: string;\n topicId?: number;\n topicCode?: string;\n topicName?: string;\n nickName?: string;\n createTime?: string;\n topicUserCount?: number;\n /** 0普通群组;1积分群组;2公开群组。 */\n topicType?: number;\n isApproved?: number;\n firstIsApproved?: number;\n approveReason?: string;\n /** 0否,1是。 */\n isOpen?: number;\n}\n\nexport interface TopicUserItem {\n id?: number;\n nickName?: string;\n openId?: string;\n headImgUrl?: string;\n userSex?: number;\n havePhone?: number;\n isFollow?: number;\n emailStatus?: number;\n followTime?: string;\n remark?: string;\n}\n\nexport interface TopicUserListQuery {\n current?: number;\n pageSize?: number;\n /** 例如 { topicId }。 */\n params?: Record<string, unknown>;\n}\n\n/* ============================== 开放接口 - webhook ============================== */\n\nexport interface WebhookItem {\n id?: number;\n webhookCode?: string;\n webhookName?: string;\n webhookType?: WebhookType | number;\n webhookTypeName?: string;\n webhookUrl?: string;\n createTime?: string;\n /** 自定义类型才返回。 */\n httpMethod?: string;\n headers?: string;\n body?: string;\n}\n\nexport interface WebhookSaveRequest {\n /** 仅修改时使用。 */\n id?: number;\n webhookCode?: string;\n webhookName?: string;\n webhookType?: WebhookType | number;\n webhookUrl?: string;\n /** 自定义类型时使用。 */\n httpMethod?: string;\n headers?: string;\n body?: string;\n}\n\n/* ============================== 开放接口 - friend ============================== */\n\nexport interface FriendItem {\n id?: number;\n friendId?: number;\n token?: string;\n headImgUrl?: string;\n nickName?: string;\n emailStatus?: number;\n havePhone?: number;\n isFollow?: number;\n remark?: string;\n createTime?: string;\n}\n\nexport interface FriendQrCode {\n qrCodeImgUrl?: string;\n}\n\n/* ============================== 开放接口 - clawbot ============================== */\n\nexport interface ClawBotInfo {\n createTime?: string;\n /** 是否有对话令牌(文档为字符串/数字混用,统一用 number 兼容)。 */\n haveContextToken?: number;\n}\n\nexport interface ClawBotMessage {\n /** 1-文字,3-语音。 */\n type?: number;\n text?: string;\n}\n\nexport interface ClawBotQrCode {\n url?: string;\n qrcode?: string;\n}\n\n/* ============================== 开放接口 - channel ============================== */\n\nexport interface MpItem {\n id?: number;\n nickName?: string;\n headImg?: string;\n principalName?: string;\n authorizationAppid?: string;\n funcInfo?: string;\n serviceType?: number;\n verifyType?: number;\n alias?: string;\n updateTime?: string;\n}\n\nexport interface CpItem {\n id?: number;\n cpName?: string;\n cpCode?: string;\n}\n\nexport interface MailItem {\n id?: number;\n mailName?: string;\n mailCode?: string;\n}\n\nexport interface MailDetail {\n id?: number;\n mailName?: string;\n mailCode?: string;\n account?: string;\n password?: string;\n smtpServer?: string;\n smtpSsl?: number;\n smtpPort?: number;\n createTime?: string;\n}\n\n/* ============================== 开放接口 - setting ============================== */\n\nexport interface UserDefaultDetail {\n id?: number;\n channel?: Channel | string;\n option?: string;\n pre?: string;\n updateTime?: string;\n name?: string;\n tokenId?: number;\n}\n\nexport interface UserDefaultItem {\n id?: number;\n channel?: Channel | string;\n channelTxt?: string;\n updateTime?: string;\n name?: string;\n}\n\nexport interface UserDefaultSaveRequest {\n /** 默认配置编号(修改时必填)。 */\n id?: number;\n channel?: Channel | string;\n option?: string;\n pre?: string;\n /** 消息令牌 id;用户令牌为 0。 */\n tokenId?: number;\n}\n\n/* ============================== 开放接口 - pre ============================== */\n\nexport interface PreItem {\n id?: number;\n preName?: string;\n preCode?: string;\n /** 1-JavaScript。 */\n contentType?: number;\n createTime?: string;\n}\n\nexport interface PreDetail {\n id?: number;\n preName?: string;\n preCode?: string;\n contentType?: number;\n content?: string;\n}\n\nexport interface PreSaveRequest {\n /** 修改时必填。 */\n id?: number;\n content?: string;\n preName?: string;\n preCode?: string;\n /** 1-JavaScript。 */\n contentType?: number;\n}\n\nexport interface PreTestRequest {\n content?: string;\n contentType?: number;\n message?: string;\n}\n"]}