@perk-net/perk-pushplus-sdk 1.2.0 → 1.2.2
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/README.md +60 -5
- package/dist/index.cjs +263 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +220 -15
- package/dist/index.d.ts +220 -15
- package/dist/index.global.js +263 -5
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +263 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/api/base.ts +27 -1
- package/src/api/doc-api.ts +24 -0
- package/src/api/excel-api.ts +29 -0
- package/src/api/form-api.ts +3 -0
- package/src/api/friend-api.ts +38 -1
- package/src/api/open-base.ts +40 -0
- package/src/api/qqbot-api.ts +75 -0
- package/src/api/topic-user-api.ts +40 -1
- package/src/client.ts +3 -0
- package/src/config.ts +1 -1
- package/src/enums.ts +2 -0
- package/src/index.ts +10 -0
- package/src/models.ts +123 -13
- package/src/multipart.ts +62 -0
package/package.json
CHANGED
package/src/api/base.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ResolvedPushPlusConfig } from '../config';
|
|
2
2
|
import { PushPlusError } from '../exception';
|
|
3
|
-
import { HttpRequester, HttpResponse, isSuccessfulHttpStatus } from '../http';
|
|
3
|
+
import { HttpRequester, HttpResponse, callExecuteRaw, isSuccessfulHttpStatus } from '../http';
|
|
4
4
|
import { ApiResponse } from '../models';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -62,6 +62,32 @@ export abstract class AbstractApi {
|
|
|
62
62
|
return parseApiResponse<T>(resp);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* 执行带二进制请求体的请求并返回原始 ApiResponse(不进行 code 校验)。
|
|
67
|
+
* 用于 multipart 上传等场景。
|
|
68
|
+
*/
|
|
69
|
+
protected async executeRaw<T>(
|
|
70
|
+
method: string,
|
|
71
|
+
path: string,
|
|
72
|
+
headers: Record<string, string> | undefined | null,
|
|
73
|
+
body: Uint8Array,
|
|
74
|
+
): Promise<ApiResponse<T>> {
|
|
75
|
+
const url = this.resolveUrl(path);
|
|
76
|
+
const resp = await callExecuteRaw(this.http, {
|
|
77
|
+
method,
|
|
78
|
+
url,
|
|
79
|
+
headers: headers ?? undefined,
|
|
80
|
+
body,
|
|
81
|
+
});
|
|
82
|
+
if (!isSuccessfulHttpStatus(resp.statusCode)) {
|
|
83
|
+
throw new PushPlusError(
|
|
84
|
+
`PushPlus 接口 HTTP 调用失败: status=${resp.statusCode}, body=${resp.body}`,
|
|
85
|
+
resp.statusCode,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
return parseApiResponse<T>(resp);
|
|
89
|
+
}
|
|
90
|
+
|
|
65
91
|
/** 执行请求并直接返回 data;非 200 抛出异常。 */
|
|
66
92
|
protected async executeForData<T>(
|
|
67
93
|
method: string,
|
package/src/api/doc-api.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AccessKeyManager } from '../access-key-manager';
|
|
2
2
|
import { ResolvedPushPlusConfig } from '../config';
|
|
3
3
|
import { HttpRequester } from '../http';
|
|
4
|
+
import { FileInput, buildFileMultipart, toFileBytes } from '../multipart';
|
|
4
5
|
import { DocContent, DocListItem, DocListQuery, DocVo, PageResult } from '../models';
|
|
5
6
|
import { OpenAbstractApi } from './open-base';
|
|
6
7
|
|
|
@@ -9,6 +10,9 @@ import { OpenAbstractApi } from './open-base';
|
|
|
9
10
|
*
|
|
10
11
|
* 文档:https://www.pushplus.plus/doc/ecosystem/doc/
|
|
11
12
|
* 基础路径:`/push/api/open/doc`
|
|
13
|
+
*
|
|
14
|
+
* 文档开放接口不单独提供推送接口。发布后请通过 `client.send` 推送分享页:
|
|
15
|
+
* `template=doc`,`pushId=docCode`。
|
|
12
16
|
*/
|
|
13
17
|
export class DocApi extends OpenAbstractApi {
|
|
14
18
|
constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {
|
|
@@ -29,6 +33,20 @@ export class DocApi extends OpenAbstractApi {
|
|
|
29
33
|
return this.executeOpen<DocVo>('POST', '/push/api/open/doc/create', { title });
|
|
30
34
|
}
|
|
31
35
|
|
|
36
|
+
/**
|
|
37
|
+
* 导入 Word(.docx)创建文档。
|
|
38
|
+
*
|
|
39
|
+
* 标题默认取文件名;创建后默认关闭分享,需再调用 publish 才会同步到分享页。
|
|
40
|
+
*/
|
|
41
|
+
async importWord(file: FileInput, fileName = 'document.docx'): Promise<DocVo> {
|
|
42
|
+
const bytes = await toFileBytes(file);
|
|
43
|
+
const name = fileName && fileName.trim() ? fileName : 'document.docx';
|
|
44
|
+
return this.executeOpenMultipart<DocVo>(
|
|
45
|
+
'/push/api/open/doc/import',
|
|
46
|
+
buildFileMultipart(name, guessDocxContentType(name), bytes),
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
32
50
|
/** 获取文档元信息与 HTML 草稿正文。 */
|
|
33
51
|
content(docCode: string): Promise<DocContent> {
|
|
34
52
|
return this.executeOpen<DocContent>(
|
|
@@ -75,3 +93,9 @@ export class DocApi extends OpenAbstractApi {
|
|
|
75
93
|
return this.executeOpen<DocVo>('POST', '/push/api/open/doc/updateShare', body);
|
|
76
94
|
}
|
|
77
95
|
}
|
|
96
|
+
|
|
97
|
+
function guessDocxContentType(name: string): string {
|
|
98
|
+
return name.toLowerCase().endsWith('.docx')
|
|
99
|
+
? 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
|
|
100
|
+
: 'application/octet-stream';
|
|
101
|
+
}
|
package/src/api/excel-api.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { AccessKeyManager } from '../access-key-manager';
|
|
|
2
2
|
import { ResolvedPushPlusConfig } from '../config';
|
|
3
3
|
import { PushPlusError } from '../exception';
|
|
4
4
|
import { HttpRequester } from '../http';
|
|
5
|
+
import { FileInput, buildFileMultipart, toFileBytes } from '../multipart';
|
|
5
6
|
import { DocListItem, DocListQuery, ExcelContent, ExcelVo, PageResult } from '../models';
|
|
6
7
|
import { OpenAbstractApi } from './open-base';
|
|
7
8
|
|
|
@@ -10,6 +11,9 @@ import { OpenAbstractApi } from './open-base';
|
|
|
10
11
|
*
|
|
11
12
|
* 文档:https://www.pushplus.plus/doc/ecosystem/sheet/
|
|
12
13
|
* 基础路径:`/push/api/open/excel`
|
|
14
|
+
*
|
|
15
|
+
* 表格开放接口不单独提供推送接口。发布后请通过 `client.send` 推送分享页:
|
|
16
|
+
* `template=excel`,`pushId=docCode`。
|
|
13
17
|
*/
|
|
14
18
|
export class ExcelApi extends OpenAbstractApi {
|
|
15
19
|
constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {
|
|
@@ -30,6 +34,20 @@ export class ExcelApi extends OpenAbstractApi {
|
|
|
30
34
|
return this.executeOpen<ExcelVo>('POST', '/push/api/open/excel/create', { title });
|
|
31
35
|
}
|
|
32
36
|
|
|
37
|
+
/**
|
|
38
|
+
* 导入 Excel(.xlsx / .xls)创建表格。
|
|
39
|
+
*
|
|
40
|
+
* 标题默认取文件名;创建后默认关闭分享,需再调用 publish 才会同步到分享页。
|
|
41
|
+
*/
|
|
42
|
+
async importExcel(file: FileInput, fileName = 'workbook.xlsx'): Promise<ExcelVo> {
|
|
43
|
+
const bytes = await toFileBytes(file);
|
|
44
|
+
const name = fileName && fileName.trim() ? fileName : 'workbook.xlsx';
|
|
45
|
+
return this.executeOpenMultipart<ExcelVo>(
|
|
46
|
+
'/push/api/open/excel/import',
|
|
47
|
+
buildFileMultipart(name, guessExcelContentType(name), bytes),
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
33
51
|
/** 获取表格元信息与整表 JSON 草稿。 */
|
|
34
52
|
content(docCode: string): Promise<ExcelContent> {
|
|
35
53
|
return this.executeOpen<ExcelContent>(
|
|
@@ -112,3 +130,14 @@ function stringifyJsonContent(content: string | object): string {
|
|
|
112
130
|
throw new PushPlusError(`序列化表格内容失败: ${(e as Error).message}`, -1, { cause: e });
|
|
113
131
|
}
|
|
114
132
|
}
|
|
133
|
+
|
|
134
|
+
function guessExcelContentType(name: string): string {
|
|
135
|
+
const lower = name.toLowerCase();
|
|
136
|
+
if (lower.endsWith('.xlsx')) {
|
|
137
|
+
return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
|
|
138
|
+
}
|
|
139
|
+
if (lower.endsWith('.xls')) {
|
|
140
|
+
return 'application/vnd.ms-excel';
|
|
141
|
+
}
|
|
142
|
+
return 'application/octet-stream';
|
|
143
|
+
}
|
package/src/api/form-api.ts
CHANGED
|
@@ -17,6 +17,9 @@ import { OpenAbstractApi } from './open-base';
|
|
|
17
17
|
*
|
|
18
18
|
* 文档:https://www.pushplus.plus/doc/ecosystem/form/
|
|
19
19
|
* 基础路径:`/push/api/open/form`
|
|
20
|
+
*
|
|
21
|
+
* 表单开放接口不单独提供推送接口。发布后请通过 `client.send` 推送填写页:
|
|
22
|
+
* `template=form`,`pushId=formCode`。
|
|
20
23
|
*/
|
|
21
24
|
export class FormApi extends OpenAbstractApi {
|
|
22
25
|
constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {
|
package/src/api/friend-api.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AccessKeyManager } from '../access-key-manager';
|
|
2
2
|
import { ResolvedPushPlusConfig } from '../config';
|
|
3
3
|
import { HttpRequester } from '../http';
|
|
4
|
-
import { FriendItem, FriendQrCode, PageQuery, PageResult } from '../models';
|
|
4
|
+
import { FriendBlacklistItem, FriendItem, FriendQrCode, PageQuery, PageResult } from '../models';
|
|
5
5
|
import { OpenAbstractApi } from './open-base';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -44,4 +44,41 @@ export class FriendApi extends OpenAbstractApi {
|
|
|
44
44
|
async editRemark(id: number, remark: string): Promise<void> {
|
|
45
45
|
await this.executeOpen<unknown>('POST', '/api/open/friend/editRemark', { id, remark });
|
|
46
46
|
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 5. 将好友加入黑名单。
|
|
50
|
+
*
|
|
51
|
+
* 加入后将解除双方好友关系,对方无法再添加你。不能将自己加入黑名单,仅可将已有好友加入黑名单。
|
|
52
|
+
*
|
|
53
|
+
* @param friendId 好友 id(好友列表中的 friendId 字段)
|
|
54
|
+
*/
|
|
55
|
+
async addBlacklist(friendId: number): Promise<void> {
|
|
56
|
+
await this.executeOpen<unknown>(
|
|
57
|
+
'POST',
|
|
58
|
+
this.appendQuery('/api/open/friend/addBlacklist', { friendId }),
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** 6. 好友黑名单列表。 */
|
|
63
|
+
blacklistList(query?: PageQuery): Promise<PageResult<FriendBlacklistItem>> {
|
|
64
|
+
return this.executeOpen<PageResult<FriendBlacklistItem>>(
|
|
65
|
+
'POST',
|
|
66
|
+
'/api/open/friend/blacklistList',
|
|
67
|
+
query ?? {},
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* 7. 解除好友黑名单。
|
|
73
|
+
*
|
|
74
|
+
* 解除后不会自动恢复好友关系,需重新扫码添加。
|
|
75
|
+
*
|
|
76
|
+
* @param id 黑名单记录 ID(黑名单列表中的 id 字段)
|
|
77
|
+
*/
|
|
78
|
+
async removeBlacklist(id: number): Promise<void> {
|
|
79
|
+
await this.executeOpen<unknown>(
|
|
80
|
+
'POST',
|
|
81
|
+
this.appendQuery('/api/open/friend/removeBlacklist', { id }),
|
|
82
|
+
);
|
|
83
|
+
}
|
|
47
84
|
}
|
package/src/api/open-base.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { AccessKeyManager } from '../access-key-manager';
|
|
|
2
2
|
import { ResolvedPushPlusConfig } from '../config';
|
|
3
3
|
import { PushPlusError } from '../exception';
|
|
4
4
|
import { HttpRequester } from '../http';
|
|
5
|
+
import { FileMultipart } from '../multipart';
|
|
5
6
|
import { AbstractApi, isApiSuccess } from './base';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -51,4 +52,43 @@ export abstract class OpenAbstractApi extends AbstractApi {
|
|
|
51
52
|
resp.code ?? -1,
|
|
52
53
|
);
|
|
53
54
|
}
|
|
55
|
+
|
|
56
|
+
/** 以 multipart 上传文件(自动携带 access-key;code=401 时刷新后重试一次)。 */
|
|
57
|
+
protected executeOpenMultipart<T>(path: string, multipart: FileMultipart): Promise<T> {
|
|
58
|
+
return this.executeOpenRaw<T>('POST', path, multipart.body, {
|
|
59
|
+
'Content-Type': multipart.contentType,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 执行带二进制 body 的开放接口请求;当返回 code=401 时自动刷新 key 并重试一次。
|
|
65
|
+
*/
|
|
66
|
+
protected async executeOpenRaw<T>(
|
|
67
|
+
method: string,
|
|
68
|
+
path: string,
|
|
69
|
+
body: Uint8Array,
|
|
70
|
+
extraHeaders?: Record<string, string>,
|
|
71
|
+
): Promise<T> {
|
|
72
|
+
const headers = { ...(await this.headersWithAccessKey()), ...(extraHeaders ?? {}) };
|
|
73
|
+
const resp = await this.executeRaw<T>(method, path, headers, body);
|
|
74
|
+
if (isApiSuccess(resp)) {
|
|
75
|
+
return resp.data as T;
|
|
76
|
+
}
|
|
77
|
+
if (resp.code === OpenAbstractApi.CODE_ACCESS_KEY_INVALID) {
|
|
78
|
+
this.accessKeyManager.invalidate();
|
|
79
|
+
const retryHeaders = { ...(await this.headersWithAccessKey()), ...(extraHeaders ?? {}) };
|
|
80
|
+
const retry = await this.executeRaw<T>(method, path, retryHeaders, body);
|
|
81
|
+
if (isApiSuccess(retry)) {
|
|
82
|
+
return retry.data as T;
|
|
83
|
+
}
|
|
84
|
+
throw new PushPlusError(
|
|
85
|
+
`PushPlus 开放接口业务失败(重试后): code=${retry.code}, msg=${retry.msg}`,
|
|
86
|
+
retry.code ?? -1,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
throw new PushPlusError(
|
|
90
|
+
`PushPlus 开放接口业务失败: code=${resp.code}, msg=${resp.msg}`,
|
|
91
|
+
resp.code ?? -1,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
54
94
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { AccessKeyManager } from '../access-key-manager';
|
|
2
|
+
import { ResolvedPushPlusConfig } from '../config';
|
|
3
|
+
import { HttpRequester } from '../http';
|
|
4
|
+
import {
|
|
5
|
+
PageQuery,
|
|
6
|
+
PageResult,
|
|
7
|
+
QqBotBindInfo,
|
|
8
|
+
QqBotBindLink,
|
|
9
|
+
QqBotItem,
|
|
10
|
+
QqBotSaveRequest,
|
|
11
|
+
QqGroupItem,
|
|
12
|
+
} from '../models';
|
|
13
|
+
import { OpenAbstractApi } from './open-base';
|
|
14
|
+
|
|
15
|
+
/** 发送到 QQ 群,目前渠道配置仅支持该类型。 */
|
|
16
|
+
const SEND_TYPE_QQ_GROUP = 2;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 开放接口 - QQ 机器人(文档「九. QQ机器人接口」)。
|
|
20
|
+
*/
|
|
21
|
+
export class QqBotApi extends OpenAbstractApi {
|
|
22
|
+
constructor(config: ResolvedPushPlusConfig, http: HttpRequester, mgr: AccessKeyManager) {
|
|
23
|
+
super(config, http, mgr);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** 1. 获取绑定链接与绑定码;refresh 为 true 时旧绑定码失效并重新生成。 */
|
|
27
|
+
getBindLink(refresh = false): Promise<QqBotBindLink> {
|
|
28
|
+
const path = refresh
|
|
29
|
+
? this.appendQuery('/api/open/qqBot/getBindLink', { refresh: true })
|
|
30
|
+
: '/api/open/qqBot/getBindLink';
|
|
31
|
+
return this.executeOpen<QqBotBindLink>('GET', path);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** 2. 查询绑定状态。 */
|
|
35
|
+
botInfo(): Promise<QqBotBindInfo> {
|
|
36
|
+
return this.executeOpen<QqBotBindInfo>('GET', '/api/open/qqBot/botInfo');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** 3. 解绑 QQ 机器人。 */
|
|
40
|
+
async unbind(): Promise<void> {
|
|
41
|
+
await this.executeOpen<unknown>('GET', '/api/open/qqBot/unbind');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** 4. 获取机器人已加入的 QQ 群列表。 */
|
|
45
|
+
async groupList(): Promise<QqGroupItem[]> {
|
|
46
|
+
return (await this.executeOpen<QqGroupItem[]>('GET', '/api/open/qqBot/groupList')) ?? [];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** 5. 获取 QQ 机器人渠道配置列表。 */
|
|
50
|
+
list(q?: PageQuery): Promise<PageResult<QqBotItem>> {
|
|
51
|
+
return this.executeOpen<PageResult<QqBotItem>>('POST', '/api/open/qqBot/list', q ?? {});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** 6. 新增渠道配置,用于把消息发送到指定 QQ 群;发给自己无需创建配置。 */
|
|
55
|
+
async add(req: QqBotSaveRequest): Promise<void> {
|
|
56
|
+
await this.executeOpen<unknown>('POST', '/api/open/qqBot/add', withDefaultSendType(req));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** 7. 修改渠道配置;配置编码不可修改。 */
|
|
60
|
+
async edit(req: QqBotSaveRequest): Promise<void> {
|
|
61
|
+
await this.executeOpen<unknown>('POST', '/api/open/qqBot/edit', withDefaultSendType(req));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** 8. 删除渠道配置。 */
|
|
65
|
+
async delete(id: number): Promise<void> {
|
|
66
|
+
await this.executeOpen<unknown>(
|
|
67
|
+
'DELETE',
|
|
68
|
+
this.appendQuery('/api/open/qqBot/delete', { id }),
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function withDefaultSendType(req: QqBotSaveRequest): QqBotSaveRequest {
|
|
74
|
+
return { ...req, sendType: req.sendType ?? SEND_TYPE_QQ_GROUP };
|
|
75
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AccessKeyManager } from '../access-key-manager';
|
|
2
2
|
import { ResolvedPushPlusConfig } from '../config';
|
|
3
3
|
import { HttpRequester } from '../http';
|
|
4
|
-
import { PageResult, TopicUserItem, TopicUserListQuery } from '../models';
|
|
4
|
+
import { PageResult, TopicUserBlacklistItem, TopicUserItem, TopicUserListQuery } from '../models';
|
|
5
5
|
import { OpenAbstractApi } from './open-base';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -27,4 +27,43 @@ export class TopicUserApi extends OpenAbstractApi {
|
|
|
27
27
|
async editRemark(id: number, remark: string): Promise<void> {
|
|
28
28
|
await this.executeOpen<unknown>('POST', '/api/open/topicUser/editRemark', { id, remark });
|
|
29
29
|
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 4. 将订阅人加入黑名单。
|
|
33
|
+
*
|
|
34
|
+
* 加入后将移出群组,对方无法再加入该群组。积分群组不支持黑名单。不能将自己加入黑名单。
|
|
35
|
+
*
|
|
36
|
+
* @param topicRelationId 用户编号(订阅人列表中的 id 字段)
|
|
37
|
+
*/
|
|
38
|
+
async addBlacklist(topicRelationId: number): Promise<void> {
|
|
39
|
+
const path = this.appendQuery('/api/open/topicUser/addBlacklist', { topicRelationId });
|
|
40
|
+
await this.executeOpen<unknown>('POST', path);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 5. 订阅人黑名单列表。
|
|
45
|
+
*
|
|
46
|
+
* `query.params.topicId` 必填。
|
|
47
|
+
*/
|
|
48
|
+
blacklistList(query: TopicUserListQuery): Promise<PageResult<TopicUserBlacklistItem>> {
|
|
49
|
+
return this.executeOpen<PageResult<TopicUserBlacklistItem>>(
|
|
50
|
+
'POST',
|
|
51
|
+
'/api/open/topicUser/blacklistList',
|
|
52
|
+
query,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 6. 解除订阅人黑名单。
|
|
58
|
+
*
|
|
59
|
+
* 解除后不会自动恢复群组订阅,对方可重新加入该群组。
|
|
60
|
+
*
|
|
61
|
+
* @param id 黑名单记录 ID(黑名单列表中的 id 字段)
|
|
62
|
+
*/
|
|
63
|
+
async removeBlacklist(id: number): Promise<void> {
|
|
64
|
+
await this.executeOpen<unknown>(
|
|
65
|
+
'POST',
|
|
66
|
+
this.appendQuery('/api/open/topicUser/removeBlacklist', { id }),
|
|
67
|
+
);
|
|
68
|
+
}
|
|
30
69
|
}
|
package/src/client.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { MessageApi } from './api/message-api';
|
|
|
11
11
|
import { MessageTokenApi } from './api/message-token-api';
|
|
12
12
|
import { OpenMessageApi } from './api/open-message-api';
|
|
13
13
|
import { PreApi } from './api/pre-api';
|
|
14
|
+
import { QqBotApi } from './api/qqbot-api';
|
|
14
15
|
import { SettingApi } from './api/setting-api';
|
|
15
16
|
import { TopicApi } from './api/topic-api';
|
|
16
17
|
import { TopicUserApi } from './api/topic-user-api';
|
|
@@ -67,6 +68,7 @@ export class PushPlusClient {
|
|
|
67
68
|
readonly webhook: WebhookApi;
|
|
68
69
|
readonly channel: ChannelApi;
|
|
69
70
|
readonly clawBot: ClawBotApi;
|
|
71
|
+
readonly qqBot: QqBotApi;
|
|
70
72
|
readonly setting: SettingApi;
|
|
71
73
|
readonly pre: PreApi;
|
|
72
74
|
readonly image: ImageApi;
|
|
@@ -92,6 +94,7 @@ export class PushPlusClient {
|
|
|
92
94
|
this.webhook = new WebhookApi(this.config, this.httpRequester, this.accessKeyManager);
|
|
93
95
|
this.channel = new ChannelApi(this.config, this.httpRequester, this.accessKeyManager);
|
|
94
96
|
this.clawBot = new ClawBotApi(this.config, this.httpRequester, this.accessKeyManager);
|
|
97
|
+
this.qqBot = new QqBotApi(this.config, this.httpRequester, this.accessKeyManager);
|
|
95
98
|
this.setting = new SettingApi(this.config, this.httpRequester, this.accessKeyManager);
|
|
96
99
|
this.pre = new PreApi(this.config, this.httpRequester, this.accessKeyManager);
|
|
97
100
|
this.image = new ImageApi(this.config, this.httpRequester, this.accessKeyManager);
|
package/src/config.ts
CHANGED
|
@@ -87,6 +87,6 @@ export function resolveConfig(input: PushPlusConfig | undefined | null): Resolve
|
|
|
87
87
|
logRequest: cfg.logRequest ?? false,
|
|
88
88
|
rateLimitGuardEnabled: cfg.rateLimitGuardEnabled ?? true,
|
|
89
89
|
rateLimitCooldownMs: cfg.rateLimitCooldownMs ?? 0,
|
|
90
|
-
userAgent: cfg.userAgent ?? `@perk-net/perk-pushplus-sdk/1.2.
|
|
90
|
+
userAgent: cfg.userAgent ?? `@perk-net/perk-pushplus-sdk/1.2.1`,
|
|
91
91
|
};
|
|
92
92
|
}
|
package/src/enums.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -79,13 +79,21 @@ export type {
|
|
|
79
79
|
TopicItem,
|
|
80
80
|
TopicUserItem,
|
|
81
81
|
TopicUserListQuery,
|
|
82
|
+
TopicUserBlacklistItem,
|
|
82
83
|
WebhookItem,
|
|
83
84
|
WebhookSaveRequest,
|
|
84
85
|
FriendItem,
|
|
85
86
|
FriendQrCode,
|
|
87
|
+
FriendBlacklistItem,
|
|
86
88
|
ClawBotInfo,
|
|
87
89
|
ClawBotMessage,
|
|
88
90
|
ClawBotQrCode,
|
|
91
|
+
QqBotBindLink,
|
|
92
|
+
QqBotBindInfo,
|
|
93
|
+
QqBotInfo,
|
|
94
|
+
QqBotItem,
|
|
95
|
+
QqBotSaveRequest,
|
|
96
|
+
QqGroupItem,
|
|
89
97
|
MpItem,
|
|
90
98
|
CpItem,
|
|
91
99
|
MailItem,
|
|
@@ -140,6 +148,7 @@ export { FriendApi } from './api/friend-api';
|
|
|
140
148
|
export { WebhookApi } from './api/webhook-api';
|
|
141
149
|
export { ChannelApi } from './api/channel-api';
|
|
142
150
|
export { ClawBotApi } from './api/clawbot-api';
|
|
151
|
+
export { QqBotApi } from './api/qqbot-api';
|
|
143
152
|
export { SettingApi } from './api/setting-api';
|
|
144
153
|
export { PreApi } from './api/pre-api';
|
|
145
154
|
export {
|
|
@@ -150,3 +159,4 @@ export {
|
|
|
150
159
|
export { FormApi } from './api/form-api';
|
|
151
160
|
export { DocApi } from './api/doc-api';
|
|
152
161
|
export { ExcelApi } from './api/excel-api';
|
|
162
|
+
export { type FileInput } from './multipart';
|
package/src/models.ts
CHANGED
|
@@ -270,6 +270,7 @@ export interface SendCount {
|
|
|
270
270
|
cpSendCount?: number;
|
|
271
271
|
webhookSendCount?: number;
|
|
272
272
|
mailSendCount?: number;
|
|
273
|
+
qqBotSendCount?: number;
|
|
273
274
|
}
|
|
274
275
|
|
|
275
276
|
export interface UserLimitTime {
|
|
@@ -426,6 +427,19 @@ export interface TopicUserListQuery {
|
|
|
426
427
|
params?: Record<string, unknown>;
|
|
427
428
|
}
|
|
428
429
|
|
|
430
|
+
/** 群组订阅人黑名单列表项。 */
|
|
431
|
+
export interface TopicUserBlacklistItem {
|
|
432
|
+
/** 黑名单记录 ID;解除黑名单时使用。 */
|
|
433
|
+
id?: number;
|
|
434
|
+
/** 被拉黑用户 ID。 */
|
|
435
|
+
userId?: number;
|
|
436
|
+
nickName?: string;
|
|
437
|
+
openId?: string;
|
|
438
|
+
headImgUrl?: string;
|
|
439
|
+
/** 拉黑时间。 */
|
|
440
|
+
createTime?: string;
|
|
441
|
+
}
|
|
442
|
+
|
|
429
443
|
/* ============================== 开放接口 - webhook ============================== */
|
|
430
444
|
|
|
431
445
|
export interface WebhookItem {
|
|
@@ -474,6 +488,18 @@ export interface FriendQrCode {
|
|
|
474
488
|
qrCodeImgUrl?: string;
|
|
475
489
|
}
|
|
476
490
|
|
|
491
|
+
/** 好友黑名单列表项。 */
|
|
492
|
+
export interface FriendBlacklistItem {
|
|
493
|
+
/** 黑名单记录 ID;解除黑名单时使用。 */
|
|
494
|
+
id?: number;
|
|
495
|
+
/** 被拉黑好友 ID。 */
|
|
496
|
+
friendId?: number;
|
|
497
|
+
nickName?: string;
|
|
498
|
+
headImgUrl?: string;
|
|
499
|
+
/** 拉黑时间。 */
|
|
500
|
+
createTime?: string;
|
|
501
|
+
}
|
|
502
|
+
|
|
477
503
|
/* ============================== 开放接口 - clawbot ============================== */
|
|
478
504
|
|
|
479
505
|
export interface ClawBotInfo {
|
|
@@ -493,6 +519,82 @@ export interface ClawBotQrCode {
|
|
|
493
519
|
qrcode?: string;
|
|
494
520
|
}
|
|
495
521
|
|
|
522
|
+
/* ============================== 开放接口 - QQ 机器人 ============================== */
|
|
523
|
+
|
|
524
|
+
export interface QqBotBindLink {
|
|
525
|
+
/** 带参分享链接,用于生成扫码二维码;已绑定用户再次获取时可能为空。 */
|
|
526
|
+
url?: string;
|
|
527
|
+
/** 绑定码。已是好友时扫码收不到加好友事件,需私聊发送该码;认领 QQ 群也用此码。 */
|
|
528
|
+
bindCode?: string;
|
|
529
|
+
/** 有效期秒数,默认 300。 */
|
|
530
|
+
expireSeconds?: number;
|
|
531
|
+
/** 为当前用户分配的官方机器人 appId。 */
|
|
532
|
+
botAppId?: string;
|
|
533
|
+
botName?: string;
|
|
534
|
+
botAvatar?: string;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
export interface QqBotInfo {
|
|
538
|
+
botId?: string;
|
|
539
|
+
username?: string;
|
|
540
|
+
avatar?: string;
|
|
541
|
+
appId?: string;
|
|
542
|
+
/** 官方分享链接,可用于拉机器人进群。 */
|
|
543
|
+
shareUrl?: string;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
export interface QqBotBindInfo {
|
|
547
|
+
/** 0-未绑定,1-已绑定。 */
|
|
548
|
+
isBind?: number;
|
|
549
|
+
/** 1-可接收,0-用户已关闭单聊接收。 */
|
|
550
|
+
receiveStatus?: number;
|
|
551
|
+
createTime?: string;
|
|
552
|
+
botInfo?: QqBotInfo;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
export interface QqGroupItem {
|
|
556
|
+
/** 群编号;新增渠道配置时作为 qqGroupId 使用。 */
|
|
557
|
+
id?: number;
|
|
558
|
+
groupOpenId?: string;
|
|
559
|
+
groupRemark?: string;
|
|
560
|
+
/** 1-在群,2-群消息接收关闭。 */
|
|
561
|
+
status?: number;
|
|
562
|
+
/** 群名称,接口未授权时为空。 */
|
|
563
|
+
groupName?: string;
|
|
564
|
+
groupFingerMemo?: string;
|
|
565
|
+
groupClassText?: string;
|
|
566
|
+
groupTags?: string[];
|
|
567
|
+
groupMemberNum?: number;
|
|
568
|
+
createTime?: string;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
export interface QqBotItem {
|
|
572
|
+
id?: number;
|
|
573
|
+
qqName?: string;
|
|
574
|
+
/** 配置编码;发送消息时作为 option 传入。 */
|
|
575
|
+
qqCode?: string;
|
|
576
|
+
/** 2-发到 QQ 群。 */
|
|
577
|
+
sendType?: number;
|
|
578
|
+
qqGroupId?: number;
|
|
579
|
+
groupRemark?: string;
|
|
580
|
+
groupOpenId?: string;
|
|
581
|
+
groupName?: string;
|
|
582
|
+
updateTime?: string;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
export interface QqBotSaveRequest {
|
|
586
|
+
/** 修改时必填。 */
|
|
587
|
+
id?: number;
|
|
588
|
+
/** 配置名称,必填,最多 64 个字符。 */
|
|
589
|
+
qqName?: string;
|
|
590
|
+
/** 配置编码,新增必填;仅支持字母、数字、下划线和中划线,创建后不可修改。 */
|
|
591
|
+
qqCode?: string;
|
|
592
|
+
/** 发送类型;留空时 SDK 自动填 2(发到 QQ 群)。 */
|
|
593
|
+
sendType?: number;
|
|
594
|
+
/** QQ 群编号,必填,取自 groupList 返回的 id。 */
|
|
595
|
+
qqGroupId?: number;
|
|
596
|
+
}
|
|
597
|
+
|
|
496
598
|
/* ============================== 开放接口 - channel ============================== */
|
|
497
599
|
|
|
498
600
|
export interface MpItem {
|
|
@@ -661,16 +763,19 @@ export interface ImageItem {
|
|
|
661
763
|
|
|
662
764
|
/* ============================== 开放接口 - form(push 表单) ============================== */
|
|
663
765
|
|
|
664
|
-
/**
|
|
766
|
+
/** 我的表单分页查询。官方结构为 `{current, pageSize, params:{keyword, status}}`。 */
|
|
665
767
|
export interface FormListQuery {
|
|
666
|
-
/**
|
|
667
|
-
|
|
668
|
-
/**
|
|
768
|
+
/** 当前所在分页数,默认 1。 */
|
|
769
|
+
current?: number;
|
|
770
|
+
/** 每页大小,默认 20,最大 50。 */
|
|
669
771
|
pageSize?: number;
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
772
|
+
params?: {
|
|
773
|
+
/** 按标题关键词搜索。 */
|
|
774
|
+
keyword?: string;
|
|
775
|
+
/** 表单状态:0草稿 / 1收集中 / 2已停止。 */
|
|
776
|
+
status?: number;
|
|
777
|
+
[key: string]: unknown;
|
|
778
|
+
};
|
|
674
779
|
}
|
|
675
780
|
|
|
676
781
|
/** 表单封面页配置。 */
|
|
@@ -786,13 +891,18 @@ export interface FormPublishResult {
|
|
|
786
891
|
|
|
787
892
|
/* ============================== 开放接口 - doc / excel 共用查询 ============================== */
|
|
788
893
|
|
|
789
|
-
/** 文档 /
|
|
894
|
+
/** 文档 / 表格分页查询。官方结构为 `{current, pageSize, params:{keyword, shareEnabled}}`。 */
|
|
790
895
|
export interface DocListQuery {
|
|
791
|
-
|
|
896
|
+
/** 当前所在分页数,默认 1。 */
|
|
897
|
+
current?: number;
|
|
898
|
+
/** 每页大小,默认 20,最大 50。 */
|
|
792
899
|
pageSize?: number;
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
900
|
+
params?: {
|
|
901
|
+
keyword?: string;
|
|
902
|
+
/** true 时仅返回已开启分享的记录。 */
|
|
903
|
+
shareEnabled?: boolean;
|
|
904
|
+
[key: string]: unknown;
|
|
905
|
+
};
|
|
796
906
|
}
|
|
797
907
|
|
|
798
908
|
/** 文档 / 表格列表项。 */
|