@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.
package/src/index.ts ADDED
@@ -0,0 +1,116 @@
1
+ /**
2
+ * PushPlus(推送加) JavaScript/TypeScript SDK
3
+ *
4
+ * - Node.js 18+:使用内置 fetch;< 18 请自定义 HttpRequester。
5
+ * - 浏览器:原生 fetch。
6
+ * - TypeScript:完整类型定义。
7
+ */
8
+
9
+ export {
10
+ PushPlusClient,
11
+ PushPlusClientBuilder,
12
+ type PushPlusClientOptions,
13
+ } from './client';
14
+ export {
15
+ type PushPlusConfig,
16
+ type ResolvedPushPlusConfig,
17
+ DEFAULT_BASE_URL,
18
+ resolveConfig,
19
+ } from './config';
20
+ export {
21
+ Channel,
22
+ Template,
23
+ SendStatus,
24
+ SendStatusDescription,
25
+ CallbackEvent,
26
+ WebhookType,
27
+ WebhookTypeDescription,
28
+ ErrorCode,
29
+ errorCodeFromValue,
30
+ isRateLimitedCode,
31
+ } from './enums';
32
+ export { PushPlusError, PushPlusException } from './exception';
33
+ export {
34
+ type HttpRequester,
35
+ type HttpRequestOptions,
36
+ type HttpResponse,
37
+ FetchHttpRequester,
38
+ isSuccessfulHttpStatus,
39
+ } from './http';
40
+ export { RateLimitGuard } from './rate-limit';
41
+ export { AccessKeyManager } from './access-key-manager';
42
+ export { parseCallback, CallbackParser } from './callback';
43
+
44
+ /* models */
45
+ export type {
46
+ ApiResponse,
47
+ PageQuery,
48
+ PageResult,
49
+ SendRequest,
50
+ BatchSendRequest,
51
+ BatchSendResult,
52
+ CallbackPayload,
53
+ MessageCompleteInfo,
54
+ TopicUserInfo,
55
+ FriendInfo,
56
+ AccessKeyResult,
57
+ UserInfo,
58
+ SendCount,
59
+ UserLimitTime,
60
+ MessageItem,
61
+ SendMessageResult,
62
+ MessageTokenAddRequest,
63
+ MessageTokenEditRequest,
64
+ MessageTokenItem,
65
+ MessageTokenOption,
66
+ TopicListQuery,
67
+ TopicQrCode,
68
+ TopicAddRequest,
69
+ TopicEditRequest,
70
+ TopicDetail,
71
+ TopicItem,
72
+ TopicUserItem,
73
+ TopicUserListQuery,
74
+ WebhookItem,
75
+ WebhookSaveRequest,
76
+ FriendItem,
77
+ FriendQrCode,
78
+ ClawBotInfo,
79
+ ClawBotMessage,
80
+ ClawBotQrCode,
81
+ MpItem,
82
+ CpItem,
83
+ MailItem,
84
+ MailDetail,
85
+ UserDefaultDetail,
86
+ UserDefaultItem,
87
+ UserDefaultSaveRequest,
88
+ PreItem,
89
+ PreDetail,
90
+ PreSaveRequest,
91
+ PreTestRequest,
92
+ } from './models';
93
+
94
+ export {
95
+ SendRequestBuilder,
96
+ BatchSendRequestBuilder,
97
+ sendRequest,
98
+ batchSendRequest,
99
+ } from './models';
100
+
101
+ /* APIs(一般通过 client.xxx 访问,但也允许单独导入便于扩展) */
102
+ export { AbstractApi } from './api/base';
103
+ export { OpenAbstractApi } from './api/open-base';
104
+ export { AccessKeyApi } from './api/access-key-api';
105
+ export { MessageApi } from './api/message-api';
106
+ export { OpenMessageApi } from './api/open-message-api';
107
+ export { UserApi } from './api/user-api';
108
+ export { MessageTokenApi } from './api/message-token-api';
109
+ export { TopicApi } from './api/topic-api';
110
+ export { TopicUserApi } from './api/topic-user-api';
111
+ export { FriendApi } from './api/friend-api';
112
+ export { WebhookApi } from './api/webhook-api';
113
+ export { ChannelApi } from './api/channel-api';
114
+ export { ClawBotApi } from './api/clawbot-api';
115
+ export { SettingApi } from './api/setting-api';
116
+ export { PreApi } from './api/pre-api';
package/src/models.ts ADDED
@@ -0,0 +1,580 @@
1
+ import { CallbackEvent, Channel, SendStatus, Template, WebhookType } from './enums';
2
+
3
+ /**
4
+ * PushPlus 接口统一响应。所有接口都遵循 `{code, msg, data}` 结构。
5
+ */
6
+ export interface ApiResponse<T = unknown> {
7
+ code?: number;
8
+ msg?: string;
9
+ data?: T;
10
+ }
11
+
12
+ /** 通用分页请求参数。 */
13
+ export interface PageQuery {
14
+ /** 当前所在分页数,默认 1。 */
15
+ current?: number;
16
+ /** 每页大小,默认 20,最大 50。 */
17
+ pageSize?: number;
18
+ }
19
+
20
+ /** 分页响应结构。 */
21
+ export interface PageResult<T> {
22
+ pageNum?: number;
23
+ pageSize?: number;
24
+ total?: number;
25
+ pages?: number;
26
+ list?: T[];
27
+ }
28
+
29
+ /* ============================== 发送消息 ============================== */
30
+
31
+ /**
32
+ * 发送消息请求。对应 `/send` 接口。
33
+ *
34
+ * 推荐使用 `SendRequestBuilder`(`SendRequest.builder()`)链式构建。
35
+ */
36
+ export interface SendRequest {
37
+ /** 用户 token 或消息 token。可不填,由 SDK 从 PushPlusConfig 自动注入。 */
38
+ token?: string;
39
+ /** 消息标题。 */
40
+ title?: string;
41
+ /** 消息内容;必填。 */
42
+ content?: string;
43
+ /** 群组编码。不填仅发送给自己;channel 为 webhook 时无效。 */
44
+ topic?: string;
45
+ /** 发送模板,默认 html。 */
46
+ template?: Template | string;
47
+ /** 发送渠道,默认 wechat。 */
48
+ channel?: Channel | string;
49
+ /** 渠道配置参数(cp/webhook/mail 渠道使用渠道编码)。 */
50
+ option?: string;
51
+ /** 异步回调地址。 */
52
+ callbackUrl?: string;
53
+ /** 毫秒时间戳;服务器时间大于此时间戳消息不会发送。 */
54
+ timestamp?: number;
55
+ /** 好友令牌;多个用逗号分隔。 */
56
+ to?: string;
57
+ /** 预处理编码(仅会员)。 */
58
+ pre?: string;
59
+ }
60
+
61
+ export class SendRequestBuilder {
62
+ private req: SendRequest = {};
63
+
64
+ token(v?: string): this { this.req.token = v; return this; }
65
+ title(v?: string): this { this.req.title = v; return this; }
66
+ content(v?: string): this { this.req.content = v; return this; }
67
+ topic(v?: string): this { this.req.topic = v; return this; }
68
+ template(v?: Template | string): this { this.req.template = v; return this; }
69
+ channel(v?: Channel | string): this { this.req.channel = v; return this; }
70
+ option(v?: string): this { this.req.option = v; return this; }
71
+ callbackUrl(v?: string): this { this.req.callbackUrl = v; return this; }
72
+ timestamp(v?: number): this { this.req.timestamp = v; return this; }
73
+ to(v?: string): this { this.req.to = v; return this; }
74
+ pre(v?: string): this { this.req.pre = v; return this; }
75
+
76
+ build(): SendRequest {
77
+ return { ...this.req };
78
+ }
79
+ }
80
+
81
+ /**
82
+ * 创建 SendRequest 链式构造器。
83
+ */
84
+ export function sendRequest(): SendRequestBuilder {
85
+ return new SendRequestBuilder();
86
+ }
87
+
88
+ /* ============================== 多渠道发送 ============================== */
89
+
90
+ /**
91
+ * 多渠道发送消息请求。对应 `/batchSend` 接口。
92
+ */
93
+ export interface BatchSendRequest {
94
+ token?: string;
95
+ title?: string;
96
+ content?: string;
97
+ topic?: string;
98
+ template?: Template | string;
99
+ /** 多渠道,逗号分隔。 */
100
+ channel?: string;
101
+ /** 多渠道 option,逗号分隔;与 channel 一一对应。 */
102
+ option?: string;
103
+ callbackUrl?: string;
104
+ timestamp?: number;
105
+ to?: string;
106
+ pre?: string;
107
+ }
108
+
109
+ /**
110
+ * 链式 Builder:支持以 `channel(Channel)` / `option(string)` 形式累积调用,
111
+ * 内部自动用逗号拼接并按顺序一一对应。
112
+ *
113
+ * 也可以通过 `channelString`/`optionString` 直接指定 CSV 字符串。
114
+ * 累积式优先级高于 CSV 字符串。
115
+ */
116
+ export class BatchSendRequestBuilder {
117
+ private req: BatchSendRequest = {};
118
+ private readonly channelList: string[] = [];
119
+ private readonly optionList: string[] = [];
120
+
121
+ token(v?: string): this { this.req.token = v; return this; }
122
+ title(v?: string): this { this.req.title = v; return this; }
123
+ content(v?: string): this { this.req.content = v; return this; }
124
+ topic(v?: string): this { this.req.topic = v; return this; }
125
+ template(v?: Template | string): this { this.req.template = v; return this; }
126
+ callbackUrl(v?: string): this { this.req.callbackUrl = v; return this; }
127
+ timestamp(v?: number): this { this.req.timestamp = v; return this; }
128
+ to(v?: string): this { this.req.to = v; return this; }
129
+ pre(v?: string): this { this.req.pre = v; return this; }
130
+
131
+ /** 追加一个 channel。 */
132
+ channel(ch: Channel | string): this {
133
+ this.channelList.push(typeof ch === 'string' ? ch : (ch as string));
134
+ return this;
135
+ }
136
+
137
+ /** 追加一个 option,与最近一次 channel() 配对;可传空串。 */
138
+ option(opt?: string): this {
139
+ this.optionList.push(opt ?? '');
140
+ return this;
141
+ }
142
+
143
+ /** 直接以 CSV 形式指定多渠道字符串(与累积式 channel(Channel) 互斥)。 */
144
+ channelString(csv?: string): this { this.req.channel = csv; return this; }
145
+
146
+ /** 直接以 CSV 形式指定 option 字符串。 */
147
+ optionString(csv?: string): this { this.req.option = csv; return this; }
148
+
149
+ build(): BatchSendRequest {
150
+ const finalChannel = this.channelList.length > 0 ? this.channelList.join(',') : this.req.channel;
151
+ const finalOption = this.optionList.length > 0 ? this.optionList.join(',') : this.req.option;
152
+ return { ...this.req, channel: finalChannel, option: finalOption };
153
+ }
154
+ }
155
+
156
+ /**
157
+ * 创建 BatchSendRequest 链式构造器。
158
+ */
159
+ export function batchSendRequest(): BatchSendRequestBuilder {
160
+ return new BatchSendRequestBuilder();
161
+ }
162
+
163
+ /** 批量发送的单条渠道结果。 */
164
+ export interface BatchSendResult {
165
+ /** 消息流水号;可用于查询发送结果。 */
166
+ shortCode?: string;
167
+ /** 业务消息。 */
168
+ message?: string;
169
+ /** 业务 code。 */
170
+ code?: number;
171
+ /** 渠道。 */
172
+ channel?: Channel | string;
173
+ }
174
+
175
+ /* ============================== 回调 ============================== */
176
+
177
+ export interface MessageCompleteInfo {
178
+ /** 推送错误内容(如有)。 */
179
+ message?: string;
180
+ /** 消息流水号。 */
181
+ shortCode?: string;
182
+ /** 发送状态:0-未发送,1-发送中,2-发送成功,3-发送失败。 */
183
+ sendStatus?: SendStatus | number;
184
+ }
185
+
186
+ export interface TopicUserInfo {
187
+ id?: number;
188
+ openId?: string;
189
+ topicId?: number;
190
+ userSex?: number;
191
+ isFollow?: number;
192
+ nickName?: string;
193
+ havePhone?: number;
194
+ topicCode?: string;
195
+ topicName?: string;
196
+ headImgUrl?: string;
197
+ emailStatus?: number;
198
+ }
199
+
200
+ export interface FriendInfo {
201
+ token?: string;
202
+ friendId?: number;
203
+ isFollow?: number;
204
+ nickName?: string;
205
+ havePhone?: number;
206
+ createTime?: string;
207
+ emailStatus?: number;
208
+ }
209
+
210
+ /**
211
+ * PushPlus 回调统一载体。
212
+ *
213
+ * 使用 `parseCallback(json)` 解析回调请求体后,
214
+ * 根据 `event` 判断事件类型并取对应的字段。
215
+ */
216
+ export interface CallbackPayload {
217
+ event?: CallbackEvent | string;
218
+ messageInfo?: MessageCompleteInfo;
219
+ topicUserInfo?: TopicUserInfo;
220
+ friendInfo?: FriendInfo;
221
+ /** 自定义二维码参数(仅 add_friend 事件有值)。 */
222
+ qrCode?: string;
223
+ }
224
+
225
+ /* ============================== 开放接口 - access ============================== */
226
+
227
+ export interface AccessKeyResult {
228
+ /** 访问令牌,后续请求需加到 header 中。 */
229
+ accessKey?: string;
230
+ /** 过期时间(单位秒)。 */
231
+ expiresIn?: number;
232
+ }
233
+
234
+ /* ============================== 开放接口 - user ============================== */
235
+
236
+ export interface UserInfo {
237
+ openId?: string;
238
+ unionId?: string;
239
+ nickName?: string;
240
+ headImgUrl?: string;
241
+ userSex?: number;
242
+ token?: string;
243
+ phoneNumber?: string;
244
+ email?: string;
245
+ emailStatus?: number;
246
+ birthday?: string;
247
+ points?: number;
248
+ }
249
+
250
+ export interface SendCount {
251
+ wechatSendCount?: number;
252
+ cpSendCount?: number;
253
+ webhookSendCount?: number;
254
+ mailSendCount?: number;
255
+ }
256
+
257
+ export interface UserLimitTime {
258
+ /** 1-无限制,2-短期限制,3-永久限制。 */
259
+ sendLimit?: number;
260
+ userLimitTime?: string;
261
+ }
262
+
263
+ /* ============================== 开放接口 - message ============================== */
264
+
265
+ export interface MessageItem {
266
+ topicName?: string;
267
+ /** 消息类型:1-一对一消息,2-一对多消息。 */
268
+ messageType?: number;
269
+ title?: string;
270
+ shortCode?: string;
271
+ channel?: Channel | string;
272
+ updateTime?: string;
273
+ }
274
+
275
+ export interface SendMessageResult {
276
+ /** 0-未投递,1-发送中,2-已发送,3-发送失败。 */
277
+ status?: SendStatus | number;
278
+ errorMessage?: string;
279
+ updateTime?: string;
280
+ }
281
+
282
+ /* ============================== 开放接口 - message token ============================== */
283
+
284
+ export interface MessageTokenAddRequest {
285
+ /** 令牌名称;必填。 */
286
+ name: string;
287
+ /** 过期时间,格式 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss;不填默认 2999-12-31。 */
288
+ expireTime?: string;
289
+ }
290
+
291
+ export interface MessageTokenEditRequest {
292
+ id: number;
293
+ name?: string;
294
+ expireTime?: string;
295
+ }
296
+
297
+ export interface MessageTokenItem {
298
+ id?: number;
299
+ name?: string;
300
+ expireTime?: string;
301
+ token?: string;
302
+ }
303
+
304
+ export interface MessageTokenOption {
305
+ id?: number;
306
+ name?: string;
307
+ }
308
+
309
+ /* ============================== 开放接口 - topic ============================== */
310
+
311
+ export interface TopicListQuery {
312
+ current?: number;
313
+ pageSize?: number;
314
+ /** 例如 { topicType: 0 };0-我创建的,1-我加入的。 */
315
+ params?: Record<string, unknown>;
316
+ }
317
+
318
+ export interface TopicQrCode {
319
+ qrCodeImgUrl?: string;
320
+ /** 0-临时二维码,1-永久二维码。 */
321
+ forever?: number;
322
+ }
323
+
324
+ export interface TopicAddRequest {
325
+ topicCode?: string;
326
+ topicName?: string;
327
+ contact?: string;
328
+ introduction?: string;
329
+ receiptMessage?: string;
330
+ appId?: string;
331
+ icon?: string;
332
+ /** 0普通;1积分;2公开。默认 0。 */
333
+ topicType?: number;
334
+ price?: number | string;
335
+ topicDescribe?: string;
336
+ }
337
+
338
+ export interface TopicEditRequest {
339
+ /** 群组编号,必填。 */
340
+ topic: number;
341
+ topicCode?: string;
342
+ topicName?: string;
343
+ contact?: string;
344
+ introduction?: string;
345
+ receiptMessage?: string;
346
+ icon?: string;
347
+ price?: number | string;
348
+ topicDescribe?: string;
349
+ }
350
+
351
+ export interface TopicDetail {
352
+ topicId?: number;
353
+ topicName?: string;
354
+ topicCode?: string;
355
+ qrCodeImgUrl?: string;
356
+ contact?: string;
357
+ introduction?: string;
358
+ receiptMessage?: string;
359
+ nickName?: string;
360
+ createTime?: string;
361
+ topicUserCount?: number;
362
+ icon?: string;
363
+ appId?: string;
364
+ topicType?: number;
365
+ price?: number | string;
366
+ topicDescribe?: string;
367
+ userNickName?: string;
368
+ isApproved?: number;
369
+ firstIsApproved?: number;
370
+ approveReason?: string;
371
+ isOpen?: number;
372
+ }
373
+
374
+ export interface TopicItem {
375
+ icon?: string;
376
+ topicId?: number;
377
+ topicCode?: string;
378
+ topicName?: string;
379
+ nickName?: string;
380
+ createTime?: string;
381
+ topicUserCount?: number;
382
+ /** 0普通群组;1积分群组;2公开群组。 */
383
+ topicType?: number;
384
+ isApproved?: number;
385
+ firstIsApproved?: number;
386
+ approveReason?: string;
387
+ /** 0否,1是。 */
388
+ isOpen?: number;
389
+ }
390
+
391
+ export interface TopicUserItem {
392
+ id?: number;
393
+ nickName?: string;
394
+ openId?: string;
395
+ headImgUrl?: string;
396
+ userSex?: number;
397
+ havePhone?: number;
398
+ isFollow?: number;
399
+ emailStatus?: number;
400
+ followTime?: string;
401
+ remark?: string;
402
+ }
403
+
404
+ export interface TopicUserListQuery {
405
+ current?: number;
406
+ pageSize?: number;
407
+ /** 例如 { topicId }。 */
408
+ params?: Record<string, unknown>;
409
+ }
410
+
411
+ /* ============================== 开放接口 - webhook ============================== */
412
+
413
+ export interface WebhookItem {
414
+ id?: number;
415
+ webhookCode?: string;
416
+ webhookName?: string;
417
+ webhookType?: WebhookType | number;
418
+ webhookTypeName?: string;
419
+ webhookUrl?: string;
420
+ createTime?: string;
421
+ /** 自定义类型才返回。 */
422
+ httpMethod?: string;
423
+ headers?: string;
424
+ body?: string;
425
+ }
426
+
427
+ export interface WebhookSaveRequest {
428
+ /** 仅修改时使用。 */
429
+ id?: number;
430
+ webhookCode?: string;
431
+ webhookName?: string;
432
+ webhookType?: WebhookType | number;
433
+ webhookUrl?: string;
434
+ /** 自定义类型时使用。 */
435
+ httpMethod?: string;
436
+ headers?: string;
437
+ body?: string;
438
+ }
439
+
440
+ /* ============================== 开放接口 - friend ============================== */
441
+
442
+ export interface FriendItem {
443
+ id?: number;
444
+ friendId?: number;
445
+ token?: string;
446
+ headImgUrl?: string;
447
+ nickName?: string;
448
+ emailStatus?: number;
449
+ havePhone?: number;
450
+ isFollow?: number;
451
+ remark?: string;
452
+ createTime?: string;
453
+ }
454
+
455
+ export interface FriendQrCode {
456
+ qrCodeImgUrl?: string;
457
+ }
458
+
459
+ /* ============================== 开放接口 - clawbot ============================== */
460
+
461
+ export interface ClawBotInfo {
462
+ createTime?: string;
463
+ /** 是否有对话令牌(文档为字符串/数字混用,统一用 number 兼容)。 */
464
+ haveContextToken?: number;
465
+ }
466
+
467
+ export interface ClawBotMessage {
468
+ /** 1-文字,3-语音。 */
469
+ type?: number;
470
+ text?: string;
471
+ }
472
+
473
+ export interface ClawBotQrCode {
474
+ url?: string;
475
+ qrcode?: string;
476
+ }
477
+
478
+ /* ============================== 开放接口 - channel ============================== */
479
+
480
+ export interface MpItem {
481
+ id?: number;
482
+ nickName?: string;
483
+ headImg?: string;
484
+ principalName?: string;
485
+ authorizationAppid?: string;
486
+ funcInfo?: string;
487
+ serviceType?: number;
488
+ verifyType?: number;
489
+ alias?: string;
490
+ updateTime?: string;
491
+ }
492
+
493
+ export interface CpItem {
494
+ id?: number;
495
+ cpName?: string;
496
+ cpCode?: string;
497
+ }
498
+
499
+ export interface MailItem {
500
+ id?: number;
501
+ mailName?: string;
502
+ mailCode?: string;
503
+ }
504
+
505
+ export interface MailDetail {
506
+ id?: number;
507
+ mailName?: string;
508
+ mailCode?: string;
509
+ account?: string;
510
+ password?: string;
511
+ smtpServer?: string;
512
+ smtpSsl?: number;
513
+ smtpPort?: number;
514
+ createTime?: string;
515
+ }
516
+
517
+ /* ============================== 开放接口 - setting ============================== */
518
+
519
+ export interface UserDefaultDetail {
520
+ id?: number;
521
+ channel?: Channel | string;
522
+ option?: string;
523
+ pre?: string;
524
+ updateTime?: string;
525
+ name?: string;
526
+ tokenId?: number;
527
+ }
528
+
529
+ export interface UserDefaultItem {
530
+ id?: number;
531
+ channel?: Channel | string;
532
+ channelTxt?: string;
533
+ updateTime?: string;
534
+ name?: string;
535
+ }
536
+
537
+ export interface UserDefaultSaveRequest {
538
+ /** 默认配置编号(修改时必填)。 */
539
+ id?: number;
540
+ channel?: Channel | string;
541
+ option?: string;
542
+ pre?: string;
543
+ /** 消息令牌 id;用户令牌为 0。 */
544
+ tokenId?: number;
545
+ }
546
+
547
+ /* ============================== 开放接口 - pre ============================== */
548
+
549
+ export interface PreItem {
550
+ id?: number;
551
+ preName?: string;
552
+ preCode?: string;
553
+ /** 1-JavaScript。 */
554
+ contentType?: number;
555
+ createTime?: string;
556
+ }
557
+
558
+ export interface PreDetail {
559
+ id?: number;
560
+ preName?: string;
561
+ preCode?: string;
562
+ contentType?: number;
563
+ content?: string;
564
+ }
565
+
566
+ export interface PreSaveRequest {
567
+ /** 修改时必填。 */
568
+ id?: number;
569
+ content?: string;
570
+ preName?: string;
571
+ preCode?: string;
572
+ /** 1-JavaScript。 */
573
+ contentType?: number;
574
+ }
575
+
576
+ export interface PreTestRequest {
577
+ content?: string;
578
+ contentType?: number;
579
+ message?: string;
580
+ }