chatboty 0.1.0 → 0.2.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/README.md +31 -11
- package/dist/cjs/src/chatboty.d.ts +15 -6
- package/dist/cjs/src/chatboty.d.ts.map +1 -1
- package/dist/cjs/src/chatboty.js +37 -5
- package/dist/cjs/src/chatboty.js.map +1 -1
- package/dist/cjs/src/entity/contact.d.ts +10 -2
- package/dist/cjs/src/entity/contact.d.ts.map +1 -1
- package/dist/cjs/src/entity/contact.js +11 -4
- package/dist/cjs/src/entity/contact.js.map +1 -1
- package/dist/cjs/src/entity/friendship.d.ts +6 -1
- package/dist/cjs/src/entity/friendship.d.ts.map +1 -1
- package/dist/cjs/src/entity/friendship.js +6 -1
- package/dist/cjs/src/entity/friendship.js.map +1 -1
- package/dist/cjs/src/entity/message.d.ts +21 -16
- package/dist/cjs/src/entity/message.d.ts.map +1 -1
- package/dist/cjs/src/entity/message.js +23 -20
- package/dist/cjs/src/entity/message.js.map +1 -1
- package/dist/cjs/src/entity/received-file.d.ts +25 -0
- package/dist/cjs/src/entity/received-file.d.ts.map +1 -0
- package/dist/cjs/src/entity/received-file.js +35 -0
- package/dist/cjs/src/entity/received-file.js.map +1 -0
- package/dist/cjs/src/entity/room.d.ts +18 -8
- package/dist/cjs/src/entity/room.d.ts.map +1 -1
- package/dist/cjs/src/entity/room.js +20 -15
- package/dist/cjs/src/entity/room.js.map +1 -1
- package/dist/cjs/src/mod.d.ts +1 -0
- package/dist/cjs/src/mod.d.ts.map +1 -1
- package/dist/cjs/src/mod.js +3 -1
- package/dist/cjs/src/mod.js.map +1 -1
- package/dist/cjs/src/types.d.ts +6 -1
- package/dist/cjs/src/types.d.ts.map +1 -1
- package/dist/cjs/src/types.js.map +1 -1
- package/dist/esm/src/chatboty.d.ts +15 -6
- package/dist/esm/src/chatboty.d.ts.map +1 -1
- package/dist/esm/src/chatboty.js +37 -5
- package/dist/esm/src/chatboty.js.map +1 -1
- package/dist/esm/src/entity/contact.d.ts +10 -2
- package/dist/esm/src/entity/contact.d.ts.map +1 -1
- package/dist/esm/src/entity/contact.js +11 -4
- package/dist/esm/src/entity/contact.js.map +1 -1
- package/dist/esm/src/entity/friendship.d.ts +6 -1
- package/dist/esm/src/entity/friendship.d.ts.map +1 -1
- package/dist/esm/src/entity/friendship.js +6 -1
- package/dist/esm/src/entity/friendship.js.map +1 -1
- package/dist/esm/src/entity/message.d.ts +21 -16
- package/dist/esm/src/entity/message.d.ts.map +1 -1
- package/dist/esm/src/entity/message.js +23 -20
- package/dist/esm/src/entity/message.js.map +1 -1
- package/dist/esm/src/entity/received-file.d.ts +25 -0
- package/dist/esm/src/entity/received-file.d.ts.map +1 -0
- package/dist/esm/src/entity/received-file.js +31 -0
- package/dist/esm/src/entity/received-file.js.map +1 -0
- package/dist/esm/src/entity/room.d.ts +18 -8
- package/dist/esm/src/entity/room.d.ts.map +1 -1
- package/dist/esm/src/entity/room.js +20 -15
- package/dist/esm/src/entity/room.js.map +1 -1
- package/dist/esm/src/mod.d.ts +1 -0
- package/dist/esm/src/mod.d.ts.map +1 -1
- package/dist/esm/src/mod.js +1 -0
- package/dist/esm/src/mod.js.map +1 -1
- package/dist/esm/src/types.d.ts +6 -1
- package/dist/esm/src/types.d.ts.map +1 -1
- package/dist/esm/src/types.js.map +1 -1
- package/package.json +2 -1
- package/src/chatboty.ts +42 -9
- package/src/entity/contact.ts +16 -5
- package/src/entity/friendship.ts +6 -1
- package/src/entity/message.ts +32 -27
- package/src/entity/received-file.ts +44 -0
- package/src/entity/room.ts +26 -16
- package/src/mod.ts +1 -0
- package/src/types.ts +6 -1
|
@@ -1,18 +1,28 @@
|
|
|
1
|
-
import type { BotApi, MessagePayload, Sayable
|
|
1
|
+
import type { BotApi, MessagePayload, Sayable } from '../types.js';
|
|
2
2
|
import { MessageType } from '../types.js';
|
|
3
3
|
import { Contact } from './contact.js';
|
|
4
4
|
import { Room } from './room.js';
|
|
5
|
-
|
|
5
|
+
import { ReceivedFile } from './received-file.js';
|
|
6
|
+
/**
|
|
7
|
+
* 消息实体。
|
|
8
|
+
*
|
|
9
|
+
* 【同步 vs 异步约定】实体已持有的数据(来自事件 payload / 缓存)用【同步】方法直接读取;
|
|
10
|
+
* 任何需要回连接器/企微(下载、拉通讯录、发送)的操作一律 async。
|
|
11
|
+
* - 同步(缓存): id / type() / text() / self() / talker() / room() / mentionSelf() / timestamp()
|
|
12
|
+
* - 异步(round-trip/动作): say() / toFileBox() / download() / mentionList()
|
|
13
|
+
*/
|
|
6
14
|
export declare class Message {
|
|
7
15
|
private readonly bot;
|
|
8
16
|
readonly payload: MessagePayload;
|
|
17
|
+
/** 消息 id(来自事件 payload; 同步只读属性)。未知时为空串。 */
|
|
18
|
+
readonly id: string;
|
|
9
19
|
constructor(bot: BotApi, payload: MessagePayload);
|
|
10
|
-
id(): string | undefined;
|
|
11
20
|
type(): MessageType;
|
|
12
21
|
text(): string;
|
|
13
22
|
self(): boolean;
|
|
14
23
|
timestamp(): number | undefined;
|
|
15
|
-
|
|
24
|
+
/** 随事件附带的媒体(若探针已下载); 无则 undefined。取字节请用 {@link toFileBox}。 */
|
|
25
|
+
file(): ReceivedFile | null | undefined;
|
|
16
26
|
miniProgram(): Record<string, any> | null | undefined;
|
|
17
27
|
urlLink(): Record<string, any> | null | undefined;
|
|
18
28
|
/** 发送者(完整 Contact; 群消息识别客户用)。 */
|
|
@@ -30,7 +40,7 @@ export declare class Message {
|
|
|
30
40
|
/**
|
|
31
41
|
* 消息中被 @ 的联系人列表(best-effort)。
|
|
32
42
|
* 先从正文解析出 @显示名, 再用一次 contactList 拉全量通讯录按 name/alias 就近解析成完整 Contact;
|
|
33
|
-
* 未在已加载通讯录中的成员回退为仅含名字的 Contact(其 id
|
|
43
|
+
* 未在已加载通讯录中的成员回退为仅含名字的 Contact(其 id 为空串)。
|
|
34
44
|
* @returns 被 @ 的 Contact 数组(无 @ 时为空数组)。
|
|
35
45
|
*/
|
|
36
46
|
mentionList(): Promise<Contact[]>;
|
|
@@ -40,22 +50,17 @@ export declare class Message {
|
|
|
40
50
|
* (纯本机文本判定, 不发起网络请求; 依赖 bot 已知 self 名。)
|
|
41
51
|
*/
|
|
42
52
|
mentionSelf(): boolean;
|
|
43
|
-
private
|
|
53
|
+
private toFileFromResult;
|
|
44
54
|
/**
|
|
45
|
-
* 取本条消息的媒体/文件字节(图片/文件/音视频), 返回 {@link
|
|
55
|
+
* 取本条消息的媒体/文件字节(图片/文件/音视频), 返回 {@link ReceivedFile}(含 base64 data URL,
|
|
56
|
+
* 并带 toBuffer()/save() 便捷方法)。
|
|
46
57
|
* - 收到的图片/文件事件通常已附带 file(探针后台已下载解密) → 直接返回。
|
|
47
58
|
* - 否则按类型冷调探针下载: 图片走 downloadImage, 文件/音视频走 downloadFile(按 msgid+会话+文件名定位缓存)。
|
|
48
|
-
* @returns
|
|
59
|
+
* @returns ReceivedFile; 非媒体消息或下载失败返回 null。
|
|
49
60
|
*/
|
|
50
|
-
toFileBox(): Promise<
|
|
61
|
+
toFileBox(): Promise<ReceivedFile | null>;
|
|
51
62
|
/** {@link toFileBox} 的别名(下载本条消息的媒体字节)。 */
|
|
52
|
-
download(): Promise<
|
|
53
|
-
/**
|
|
54
|
-
* 转发本条消息到另一会话(群/单聊 conversationId, 或 Room/Contact)。
|
|
55
|
-
* ⚠️ 未实现: 企微转发需逆向定位并冷调"转发消息"服务(见 puppet-wework 交付说明的 RE 计划)。
|
|
56
|
-
* 当前会抛错, 以免静默失败。
|
|
57
|
-
*/
|
|
58
|
-
forward(_to: string | Room | Contact): Promise<never>;
|
|
63
|
+
download(): Promise<ReceivedFile | null>;
|
|
59
64
|
toString(): string;
|
|
60
65
|
}
|
|
61
66
|
//# sourceMappingURL=message.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../../src/entity/message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../../src/entity/message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD;;;;;;;GAOG;AACH,qBAAa,OAAO;IAIL,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAU,QAAQ,CAAC,OAAO,EAAE,cAAc;IAH3E,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;gBAEW,GAAG,EAAE,MAAM,EAAW,OAAO,EAAE,cAAc;IAI3E,IAAI,IAAK,WAAW;IACpB,IAAI,IAAK,MAAM;IACf,IAAI,IAAK,OAAO;IAChB,SAAS,IAAK,MAAM,GAAG,SAAS;IAChC,8DAA8D;IAC9D,IAAI,IAAK,YAAY,GAAG,IAAI,GAAG,SAAS;IAGxC,WAAW,IAAK,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS;IACtD,OAAO,IAAK,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS;IAElD,iCAAiC;IACjC,MAAM,IAAK,OAAO,GAAG,SAAS;IAM9B,0BAA0B;IAC1B,IAAI,IAAK,IAAI,GAAG,SAAS;IAIzB,4BAA4B;IACtB,GAAG,CAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC;IAO1C;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAapB;;;;;OAKG;IACG,WAAW,IAAK,OAAO,CAAC,OAAO,EAAE,CAAC;IAoBxC;;;;OAIG;IACH,WAAW,IAAK,OAAO;IAUvB,OAAO,CAAC,gBAAgB;IAOxB;;;;;;OAMG;IACG,SAAS,IAAK,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAqBhD,0CAA0C;IACpC,QAAQ,IAAK,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAE/C,QAAQ,IAAK,MAAM;CACpB"}
|
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
import { MessageType } from '../types.js';
|
|
2
2
|
import { Contact } from './contact.js';
|
|
3
3
|
import { Room } from './room.js';
|
|
4
|
-
|
|
4
|
+
import { ReceivedFile } from './received-file.js';
|
|
5
|
+
/**
|
|
6
|
+
* 消息实体。
|
|
7
|
+
*
|
|
8
|
+
* 【同步 vs 异步约定】实体已持有的数据(来自事件 payload / 缓存)用【同步】方法直接读取;
|
|
9
|
+
* 任何需要回连接器/企微(下载、拉通讯录、发送)的操作一律 async。
|
|
10
|
+
* - 同步(缓存): id / type() / text() / self() / talker() / room() / mentionSelf() / timestamp()
|
|
11
|
+
* - 异步(round-trip/动作): say() / toFileBox() / download() / mentionList()
|
|
12
|
+
*/
|
|
5
13
|
export class Message {
|
|
6
14
|
constructor(bot, payload) {
|
|
7
15
|
this.bot = bot;
|
|
8
16
|
this.payload = payload;
|
|
17
|
+
this.id = payload.id ?? '';
|
|
9
18
|
}
|
|
10
|
-
id() { return this.payload.id; }
|
|
11
19
|
type() { return this.payload.type; }
|
|
12
20
|
text() { return this.payload.text ?? ''; }
|
|
13
21
|
self() { return !!this.payload.self; }
|
|
14
22
|
timestamp() { return this.payload.timestamp; }
|
|
15
|
-
|
|
23
|
+
/** 随事件附带的媒体(若探针已下载); 无则 undefined。取字节请用 {@link toFileBox}。 */
|
|
24
|
+
file() {
|
|
25
|
+
return this.payload.file ? new ReceivedFile(this.payload.file) : this.payload.file;
|
|
26
|
+
}
|
|
16
27
|
miniProgram() { return this.payload.miniProgram; }
|
|
17
28
|
urlLink() { return this.payload.urlLink; }
|
|
18
29
|
/** 发送者(完整 Contact; 群消息识别客户用)。 */
|
|
@@ -55,7 +66,7 @@ export class Message {
|
|
|
55
66
|
/**
|
|
56
67
|
* 消息中被 @ 的联系人列表(best-effort)。
|
|
57
68
|
* 先从正文解析出 @显示名, 再用一次 contactList 拉全量通讯录按 name/alias 就近解析成完整 Contact;
|
|
58
|
-
* 未在已加载通讯录中的成员回退为仅含名字的 Contact(其 id
|
|
69
|
+
* 未在已加载通讯录中的成员回退为仅含名字的 Contact(其 id 为空串)。
|
|
59
70
|
* @returns 被 @ 的 Contact 数组(无 @ 时为空数组)。
|
|
60
71
|
*/
|
|
61
72
|
async mentionList() {
|
|
@@ -94,30 +105,31 @@ export class Message {
|
|
|
94
105
|
return !!selfName && this.mentionNames().includes(selfName);
|
|
95
106
|
}
|
|
96
107
|
/* ---------------- 媒体下载 ---------------- */
|
|
97
|
-
|
|
108
|
+
toFileFromResult(r) {
|
|
98
109
|
if (!r)
|
|
99
110
|
return null;
|
|
100
111
|
const dataUrl = r.dataUrl || r.base64;
|
|
101
112
|
if (!dataUrl)
|
|
102
113
|
return null;
|
|
103
|
-
return { dataUrl, mime: r.mime, name: r.name, size: r.size };
|
|
114
|
+
return new ReceivedFile({ dataUrl, mime: r.mime, name: r.name, size: r.size });
|
|
104
115
|
}
|
|
105
116
|
/**
|
|
106
|
-
* 取本条消息的媒体/文件字节(图片/文件/音视频), 返回 {@link
|
|
117
|
+
* 取本条消息的媒体/文件字节(图片/文件/音视频), 返回 {@link ReceivedFile}(含 base64 data URL,
|
|
118
|
+
* 并带 toBuffer()/save() 便捷方法)。
|
|
107
119
|
* - 收到的图片/文件事件通常已附带 file(探针后台已下载解密) → 直接返回。
|
|
108
120
|
* - 否则按类型冷调探针下载: 图片走 downloadImage, 文件/音视频走 downloadFile(按 msgid+会话+文件名定位缓存)。
|
|
109
|
-
* @returns
|
|
121
|
+
* @returns ReceivedFile; 非媒体消息或下载失败返回 null。
|
|
110
122
|
*/
|
|
111
123
|
async toFileBox() {
|
|
112
124
|
if (this.payload.file)
|
|
113
|
-
return this.payload.file;
|
|
125
|
+
return new ReceivedFile(this.payload.file);
|
|
114
126
|
const msgid = this.payload.id;
|
|
115
127
|
if (!msgid)
|
|
116
128
|
return null;
|
|
117
129
|
const t = this.payload.type;
|
|
118
130
|
if (t === MessageType.Image) {
|
|
119
131
|
const r = await this.bot.command('downloadImage', { msgid });
|
|
120
|
-
return this.
|
|
132
|
+
return this.toFileFromResult(r);
|
|
121
133
|
}
|
|
122
134
|
if (t === MessageType.File || t === MessageType.Video || t === MessageType.Audio) {
|
|
123
135
|
const r = await this.bot.command('downloadFile', {
|
|
@@ -126,21 +138,12 @@ export class Message {
|
|
|
126
138
|
timestamp: this.payload.timestamp,
|
|
127
139
|
name: this.payload.text,
|
|
128
140
|
});
|
|
129
|
-
return this.
|
|
141
|
+
return this.toFileFromResult(r);
|
|
130
142
|
}
|
|
131
143
|
return null;
|
|
132
144
|
}
|
|
133
145
|
/** {@link toFileBox} 的别名(下载本条消息的媒体字节)。 */
|
|
134
146
|
async download() { return this.toFileBox(); }
|
|
135
|
-
/* ---------------- 转发(RE 待定) ---------------- */
|
|
136
|
-
/**
|
|
137
|
-
* 转发本条消息到另一会话(群/单聊 conversationId, 或 Room/Contact)。
|
|
138
|
-
* ⚠️ 未实现: 企微转发需逆向定位并冷调"转发消息"服务(见 puppet-wework 交付说明的 RE 计划)。
|
|
139
|
-
* 当前会抛错, 以免静默失败。
|
|
140
|
-
*/
|
|
141
|
-
async forward(_to) {
|
|
142
|
-
throw new Error('Message.forward 未实现: 需逆向定位企微转发消息服务(ForwardMessage), 见 RE 计划');
|
|
143
|
-
}
|
|
144
147
|
toString() { return `Message<${MessageType[this.type()]}:${this.text().slice(0, 30)}>`; }
|
|
145
148
|
}
|
|
146
149
|
//# sourceMappingURL=message.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../../../src/entity/message.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../../../src/entity/message.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { FileBox } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 收到的媒体/文件(图片/文件/音视频)。自包含, 零外部依赖。
|
|
4
|
+
*
|
|
5
|
+
* 除原始字段(dataUrl/mime/name/size)外, 额外提供便捷方法:
|
|
6
|
+
* - toBuffer(): 同步, 把 dataUrl/base64 解码成原始字节(Buffer)。
|
|
7
|
+
* - save(path): 异步, 把字节写到磁盘。
|
|
8
|
+
*/
|
|
9
|
+
export declare class ReceivedFile {
|
|
10
|
+
/** base64 data URL(形如 `data:<mime>;base64,<...>`)。 */
|
|
11
|
+
readonly dataUrl?: string;
|
|
12
|
+
/** MIME 类型(如 image/png)。 */
|
|
13
|
+
readonly mime?: string;
|
|
14
|
+
/** 文件名(若探针可解析)。 */
|
|
15
|
+
readonly name?: string;
|
|
16
|
+
/** 字节数(若已知)。 */
|
|
17
|
+
readonly size?: number;
|
|
18
|
+
constructor(init: FileBox);
|
|
19
|
+
/** 解出原始字节(从 dataUrl / 裸 base64 解码)。同步。 */
|
|
20
|
+
toBuffer(): Buffer;
|
|
21
|
+
/** 写盘到指定路径(需 round-trip 到磁盘, 故为 async)。 */
|
|
22
|
+
save(path: string): Promise<void>;
|
|
23
|
+
toString(): string;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=received-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"received-file.d.ts","sourceRoot":"","sources":["../../../../src/entity/received-file.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,sDAAsD;IACtD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,4BAA4B;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,mBAAmB;IACnB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,gBAAgB;IAChB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;gBAET,IAAI,EAAE,OAAO;IAO1B,0CAA0C;IAC1C,QAAQ,IAAK,MAAM;IAOnB,2CAA2C;IACrC,IAAI,CAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxC,QAAQ,IAAK,MAAM;CACpB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
2
|
+
/**
|
|
3
|
+
* 收到的媒体/文件(图片/文件/音视频)。自包含, 零外部依赖。
|
|
4
|
+
*
|
|
5
|
+
* 除原始字段(dataUrl/mime/name/size)外, 额外提供便捷方法:
|
|
6
|
+
* - toBuffer(): 同步, 把 dataUrl/base64 解码成原始字节(Buffer)。
|
|
7
|
+
* - save(path): 异步, 把字节写到磁盘。
|
|
8
|
+
*/
|
|
9
|
+
export class ReceivedFile {
|
|
10
|
+
constructor(init) {
|
|
11
|
+
this.dataUrl = init.dataUrl;
|
|
12
|
+
this.mime = init.mime;
|
|
13
|
+
this.name = init.name;
|
|
14
|
+
this.size = init.size;
|
|
15
|
+
}
|
|
16
|
+
/** 解出原始字节(从 dataUrl / 裸 base64 解码)。同步。 */
|
|
17
|
+
toBuffer() {
|
|
18
|
+
const s = this.dataUrl ?? '';
|
|
19
|
+
const comma = s.indexOf(',');
|
|
20
|
+
const b64 = s.startsWith('data:') && comma >= 0 ? s.slice(comma + 1) : s;
|
|
21
|
+
return Buffer.from(b64, 'base64');
|
|
22
|
+
}
|
|
23
|
+
/** 写盘到指定路径(需 round-trip 到磁盘, 故为 async)。 */
|
|
24
|
+
async save(path) {
|
|
25
|
+
// 用 Uint8Array 包一层: 新版 @types/node 的 writeFile 形参要求 Uint8Array<ArrayBuffer>,
|
|
26
|
+
// 而 Buffer 的底层可能是 SharedArrayBuffer(方差不兼容); 复制成纯 ArrayBuffer 视图即可。
|
|
27
|
+
await writeFile(path, new Uint8Array(this.toBuffer()));
|
|
28
|
+
}
|
|
29
|
+
toString() { return `ReceivedFile<${this.name ?? this.mime ?? 'unknown'}>`; }
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=received-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"received-file.js","sourceRoot":"","sources":["../../../../src/entity/received-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAG5C;;;;;;GAMG;AACH,MAAM,OAAO,YAAY;IAUvB,YAAa,IAAa;QACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;IACvB,CAAC;IAED,0CAA0C;IAC1C,QAAQ;QACN,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAA;QAC5B,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAC5B,MAAM,GAAG,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACxE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;IACnC,CAAC;IAED,2CAA2C;IAC3C,KAAK,CAAC,IAAI,CAAE,IAAY;QACtB,6EAA6E;QAC7E,mEAAmE;QACnE,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;IACxD,CAAC;IAED,QAAQ,KAAc,OAAO,gBAAgB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,SAAS,GAAG,CAAA,CAAC,CAAC;CACtF"}
|
|
@@ -1,21 +1,31 @@
|
|
|
1
1
|
import type { BotApi, RoomPayload, Sayable } from '../types.js';
|
|
2
2
|
import { Contact } from './contact.js';
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* 群实体。
|
|
5
|
+
*
|
|
6
|
+
* 【同步 vs 异步约定】实体已持有的数据(来自事件 payload / 缓存)用【同步】读取;
|
|
7
|
+
* 需要回连接器/企微(拉成员、改名、发送)的操作一律 async。
|
|
8
|
+
* - 同步(缓存): id / topic() / owner()
|
|
9
|
+
* - 异步(round-trip/动作): say() / rename() / memberAll()
|
|
10
|
+
*/
|
|
4
11
|
export declare class Room {
|
|
5
12
|
private readonly bot;
|
|
6
13
|
readonly payload: RoomPayload;
|
|
14
|
+
/** 群 id(R:..; 同步只读属性)。 */
|
|
15
|
+
readonly id: string;
|
|
7
16
|
constructor(bot: BotApi, payload: RoomPayload);
|
|
8
|
-
id(): string;
|
|
9
17
|
topic(): string | undefined;
|
|
10
|
-
|
|
11
|
-
|
|
18
|
+
/**
|
|
19
|
+
* 群主(同步; 由缓存的 ownerId 构造)。
|
|
20
|
+
* 事件/列表未携带 ownerId 时返回 undefined; 需完整群主资料请用 {@link memberAll} 定位。
|
|
21
|
+
*/
|
|
22
|
+
owner(): Contact | undefined;
|
|
23
|
+
/** 群发消息(动作)。 */
|
|
12
24
|
say(sayable: Sayable): Promise<any>;
|
|
13
|
-
/** 改群名(冷改,
|
|
25
|
+
/** 改群名(冷改, 内外群通用; round-trip)。 */
|
|
14
26
|
rename(topic: string): Promise<any>;
|
|
15
|
-
/** 群成员(完整 Contact 对象;
|
|
27
|
+
/** 群成员(完整 Contact 对象; 受探针成员枚举局限; round-trip)。 */
|
|
16
28
|
memberAll(): Promise<Contact[]>;
|
|
17
|
-
/** 群主(若可解析)。 */
|
|
18
|
-
owner(): Promise<Contact | undefined>;
|
|
19
29
|
toString(): string;
|
|
20
30
|
}
|
|
21
31
|
//# sourceMappingURL=room.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room.d.ts","sourceRoot":"","sources":["../../../../src/entity/room.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC
|
|
1
|
+
{"version":3,"file":"room.d.ts","sourceRoot":"","sources":["../../../../src/entity/room.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC;;;;;;;GAOG;AACH,qBAAa,IAAI;IAIF,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAU,QAAQ,CAAC,OAAO,EAAE,WAAW;IAHxE,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;gBAEW,GAAG,EAAE,MAAM,EAAW,OAAO,EAAE,WAAW;IAIxE,KAAK,IAAK,MAAM,GAAG,SAAS;IAE5B;;;OAGG;IACH,KAAK,IAAK,OAAO,GAAG,SAAS;IAI7B,gBAAgB;IACV,GAAG,CAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC;IAI1C,kCAAkC;IAC5B,MAAM,CAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAI1C,iDAAiD;IAC3C,SAAS,IAAK,OAAO,CAAC,OAAO,EAAE,CAAC;IAUtC,QAAQ,IAAK,MAAM;CACpB"}
|
|
@@ -1,22 +1,35 @@
|
|
|
1
1
|
import { Contact } from './contact.js';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* 群实体。
|
|
4
|
+
*
|
|
5
|
+
* 【同步 vs 异步约定】实体已持有的数据(来自事件 payload / 缓存)用【同步】读取;
|
|
6
|
+
* 需要回连接器/企微(拉成员、改名、发送)的操作一律 async。
|
|
7
|
+
* - 同步(缓存): id / topic() / owner()
|
|
8
|
+
* - 异步(round-trip/动作): say() / rename() / memberAll()
|
|
9
|
+
*/
|
|
3
10
|
export class Room {
|
|
4
11
|
constructor(bot, payload) {
|
|
5
12
|
this.bot = bot;
|
|
6
13
|
this.payload = payload;
|
|
14
|
+
this.id = payload.id;
|
|
7
15
|
}
|
|
8
|
-
id() { return this.payload.id; }
|
|
9
16
|
topic() { return this.payload.topic; }
|
|
10
|
-
|
|
11
|
-
|
|
17
|
+
/**
|
|
18
|
+
* 群主(同步; 由缓存的 ownerId 构造)。
|
|
19
|
+
* 事件/列表未携带 ownerId 时返回 undefined; 需完整群主资料请用 {@link memberAll} 定位。
|
|
20
|
+
*/
|
|
21
|
+
owner() {
|
|
22
|
+
return this.payload.ownerId ? new Contact(this.bot, { id: this.payload.ownerId }) : undefined;
|
|
23
|
+
}
|
|
24
|
+
/** 群发消息(动作)。 */
|
|
12
25
|
async say(sayable) {
|
|
13
26
|
return this.bot.sayTo(this.payload.id, sayable);
|
|
14
27
|
}
|
|
15
|
-
/** 改群名(冷改,
|
|
28
|
+
/** 改群名(冷改, 内外群通用; round-trip)。 */
|
|
16
29
|
async rename(topic) {
|
|
17
30
|
return this.bot.command('roomTopic', { conversationId: this.payload.id, topic });
|
|
18
31
|
}
|
|
19
|
-
/** 群成员(完整 Contact 对象;
|
|
32
|
+
/** 群成员(完整 Contact 对象; 受探针成员枚举局限; round-trip)。 */
|
|
20
33
|
async memberAll() {
|
|
21
34
|
const r = await this.bot.command('roomMembers', { conversationId: this.payload.id });
|
|
22
35
|
const list = (r && (r.memberList || []));
|
|
@@ -26,14 +39,6 @@ export class Room {
|
|
|
26
39
|
conversationId: u.conversationId,
|
|
27
40
|
}));
|
|
28
41
|
}
|
|
29
|
-
|
|
30
|
-
async owner() {
|
|
31
|
-
const r = await this.bot.command('roomMembers', { conversationId: this.payload.id });
|
|
32
|
-
const u = r && r.ownerUser;
|
|
33
|
-
if (!u || !u.userId)
|
|
34
|
-
return undefined;
|
|
35
|
-
return new Contact(this.bot, { id: u.userId, name: u.name, alias: u.alias, avatar: u.avatar, conversationId: u.conversationId });
|
|
36
|
-
}
|
|
37
|
-
toString() { return `Room<${this.topic() || this.id()}>`; }
|
|
42
|
+
toString() { return `Room<${this.topic() || this.id}>`; }
|
|
38
43
|
}
|
|
39
44
|
//# sourceMappingURL=room.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"room.js","sourceRoot":"","sources":["../../../../src/entity/room.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC
|
|
1
|
+
{"version":3,"file":"room.js","sourceRoot":"","sources":["../../../../src/entity/room.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC;;;;;;;GAOG;AACH,MAAM,OAAO,IAAI;IAIf,YAA8B,GAAW,EAAW,OAAoB;QAA1C,QAAG,GAAH,GAAG,CAAQ;QAAW,YAAO,GAAP,OAAO,CAAa;QACtE,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAA;IACtB,CAAC;IAED,KAAK,KAA0B,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAA,CAAC,CAAC;IAE1D;;;OAGG;IACH,KAAK;QACH,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC/F,CAAC;IAED,gBAAgB;IAChB,KAAK,CAAC,GAAG,CAAE,OAAgB;QACzB,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IACjD,CAAC;IAED,kCAAkC;IAClC,KAAK,CAAC,MAAM,CAAE,KAAa;QACzB,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;IAClF,CAAC;IAED,iDAAiD;IACjD,KAAK,CAAC,SAAS;QACb,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAA;QACpF,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAU,CAAA;QACjD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE;YAC3C,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM;YAC5D,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO;YACpE,cAAc,EAAE,CAAC,CAAC,cAAc;SACjC,CAAC,CAAC,CAAA;IACL,CAAC;IAED,QAAQ,KAAc,OAAO,QAAQ,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,EAAE,GAAG,CAAA,CAAC,CAAC;CAClE"}
|
package/dist/esm/src/mod.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export { Message } from './entity/message.js';
|
|
|
12
12
|
export { Contact } from './entity/contact.js';
|
|
13
13
|
export { Room } from './entity/room.js';
|
|
14
14
|
export { Friendship } from './entity/friendship.js';
|
|
15
|
+
export { ReceivedFile } from './entity/received-file.js';
|
|
15
16
|
export * from './types.js';
|
|
16
17
|
export { Chatboty as default } from './chatboty.js';
|
|
17
18
|
//# sourceMappingURL=mod.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../src/mod.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAC9D,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AAE3F,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../src/mod.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAC9D,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AAE3F,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAExD,cAAc,YAAY,CAAA;AAE1B,OAAO,EAAE,QAAQ,IAAI,OAAO,EAAE,MAAM,eAAe,CAAA"}
|
package/dist/esm/src/mod.js
CHANGED
|
@@ -12,6 +12,7 @@ export { Message } from './entity/message.js';
|
|
|
12
12
|
export { Contact } from './entity/contact.js';
|
|
13
13
|
export { Room } from './entity/room.js';
|
|
14
14
|
export { Friendship } from './entity/friendship.js';
|
|
15
|
+
export { ReceivedFile } from './entity/received-file.js';
|
|
15
16
|
export * from './types.js';
|
|
16
17
|
export { Chatboty as default } from './chatboty.js';
|
|
17
18
|
//# sourceMappingURL=mod.js.map
|
package/dist/esm/src/mod.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../../src/mod.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,QAAQ,EAAwB,MAAM,eAAe,CAAA;AAC9D,OAAO,EAAE,cAAc,EAAiD,MAAM,aAAa,CAAA;AAE3F,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../../src/mod.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,QAAQ,EAAwB,MAAM,eAAe,CAAA;AAC9D,OAAO,EAAE,cAAc,EAAiD,MAAM,aAAa,CAAA;AAE3F,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAExD,cAAc,YAAY,CAAA;AAE1B,OAAO,EAAE,QAAQ,IAAI,OAAO,EAAE,MAAM,eAAe,CAAA"}
|
package/dist/esm/src/types.d.ts
CHANGED
|
@@ -37,12 +37,17 @@ export interface ContactPayload {
|
|
|
37
37
|
conversationId?: string;
|
|
38
38
|
type?: ContactType;
|
|
39
39
|
}
|
|
40
|
-
/**
|
|
40
|
+
/** contactFind/contactFindAll 查询条件: 关键词字符串, 或按字段精确匹配。 */
|
|
41
41
|
export type ContactQueryFilter = string | {
|
|
42
42
|
name?: string;
|
|
43
43
|
alias?: string;
|
|
44
44
|
id?: string;
|
|
45
45
|
};
|
|
46
|
+
/** roomFind/roomFindAll 查询条件: 关键词字符串(匹配 topic/id 子串), 或按字段精确匹配。 */
|
|
47
|
+
export type RoomQueryFilter = string | {
|
|
48
|
+
topic?: string;
|
|
49
|
+
id?: string;
|
|
50
|
+
};
|
|
46
51
|
/** 群。 */
|
|
47
52
|
export interface RoomPayload {
|
|
48
53
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY;AACZ,oBAAY,WAAW;IACrB,OAAO,IAAI;IACX,IAAI,IAAA;IACJ,KAAK,IAAA;IACL,KAAK,IAAA;IACL,KAAK,IAAA;IACL,IAAI,IAAA;IACJ,GAAG,IAAA,CAAS,OAAO;IACnB,WAAW,IAAA;IACX,MAAM,IAAA;CACP;AAED;;;GAGG;AACH,oBAAY,WAAW;IACrB,OAAO,IAAI;IACX,UAAU,IAAA,CAAI,uBAAuB;IACrC,QAAQ,IAAA,CAAM,wBAAwB;IACtC,WAAW,IAAA;CACZ;AAED,kBAAkB;AAClB,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,IAAI,CAAC,EAAE,WAAW,CAAA;CAEnB;AAED,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY;AACZ,MAAM,CAAN,IAAY,WAUX;AAVD,WAAY,WAAW;IACrB,mDAAW,CAAA;IACX,6CAAI,CAAA;IACJ,+CAAK,CAAA;IACL,+CAAK,CAAA;IACL,+CAAK,CAAA;IACL,6CAAI,CAAA;IACJ,2CAAG,CAAA;IACH,2DAAW,CAAA;IACX,iDAAM,CAAA;AACR,CAAC,EAVW,WAAW,KAAX,WAAW,QAUtB;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,mDAAW,CAAA;IACX,yDAAU,CAAA;IACV,qDAAQ,CAAA;IACR,2DAAW,CAAA;AACb,CAAC,EALW,WAAW,KAAX,WAAW,QAKtB;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY;AACZ,MAAM,CAAN,IAAY,WAUX;AAVD,WAAY,WAAW;IACrB,mDAAW,CAAA;IACX,6CAAI,CAAA;IACJ,+CAAK,CAAA;IACL,+CAAK,CAAA;IACL,+CAAK,CAAA;IACL,6CAAI,CAAA;IACJ,2CAAG,CAAA;IACH,2DAAW,CAAA;IACX,iDAAM,CAAA;AACR,CAAC,EAVW,WAAW,KAAX,WAAW,QAUtB;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,mDAAW,CAAA;IACX,yDAAU,CAAA;IACV,qDAAQ,CAAA;IACR,2DAAW,CAAA;AACb,CAAC,EALW,WAAW,KAAX,WAAW,QAKtB;AAoGD,qCAAqC;AACrC,MAAM,UAAU,QAAQ,CAAE,cAAuB;IAC/C,OAAO,CAAC,CAAC,cAAc,IAAI,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;AAC5D,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,aAAa,CAAE,OAAgB,EAAE,OAAgB;IAC/D,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,CAAC,OAAO,WAAW,CAAC,IAAI,CAAA;QACpC,KAAK,OAAO,CAAC,CAAC,OAAO,WAAW,CAAC,KAAK,CAAA;QACtC,KAAK,YAAY,CAAC,CAAC,OAAO,WAAW,CAAC,KAAK,CAAA;QAC3C,KAAK,OAAO,CAAC;QAAC,KAAK,OAAO,CAAC,CAAC,OAAO,WAAW,CAAC,KAAK,CAAA;QACpD,KAAK,OAAO,CAAC,CAAC,OAAO,WAAW,CAAC,KAAK,CAAA;QACtC,KAAK,MAAM,CAAC,CAAC,OAAO,WAAW,CAAC,IAAI,CAAA;QACpC,KAAK,KAAK,CAAC,CAAC,OAAO,WAAW,CAAC,GAAG,CAAA;QAClC,KAAK,aAAa,CAAC,CAAC,OAAO,WAAW,CAAC,WAAW,CAAA;QAClD,KAAK,KAAK,CAAC;QAAC,KAAK,QAAQ,CAAC,CAAC,OAAO,WAAW,CAAC,MAAM,CAAA;QACpD,OAAO,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAA;IACrE,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chatboty",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "chatboty — 企业微信(WeCom)IM 自动化 SDK。自研全生态框架, 收发消息/群管理/群事件/联系人, 经云网关连接你的探针实例。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cjs/src/mod.js",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"ws": "^8.18.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
+
"@types/node": "^20.11.0",
|
|
48
49
|
"@types/ws": "^8.5.10",
|
|
49
50
|
"typescript": "^5.4.0"
|
|
50
51
|
},
|
package/src/chatboty.ts
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { ChatbotyClient, type ChatbotyClientOptions } from './client.js'
|
|
7
7
|
import {
|
|
8
|
-
type BotApi, type Sayable, type MessagePayload, type ContactPayload,
|
|
8
|
+
type BotApi, type Sayable, type MessagePayload, type ContactPayload,
|
|
9
|
+
type ContactQueryFilter, type RoomQueryFilter,
|
|
9
10
|
toMessageType, isRoomId,
|
|
10
11
|
} from './types.js'
|
|
11
12
|
import { Message } from './entity/message.js'
|
|
@@ -47,12 +48,13 @@ export class Chatboty implements BotApi {
|
|
|
47
48
|
on (event: 'friendship', l: (f: Friendship) => void): this
|
|
48
49
|
on (event: 'room-join' | 'room-leave', l: (p: { room: Room, contactList: Contact[], idList: string[], timestamp?: number }) => void): this
|
|
49
50
|
on (event: 'room-topic', l: (p: { room: Room, topic?: string, oldTopic?: string, timestamp?: number }) => void): this
|
|
50
|
-
|
|
51
|
+
// 登录成功: 回调收到 typed 的当前登录者 Contact(已从 payload 构造并缓存到 bot.self)。
|
|
52
|
+
on (event: 'login', l: (self: Contact) => void): this
|
|
51
53
|
on (event: 'scan', l: (p: { qrcode?: string, status?: any }) => void): this
|
|
52
54
|
// 登录阶段(扫码/验证码全流程): phase = scan|scanned|need-verify|verifying|verify-ok|verify-fail|online...
|
|
53
55
|
on (event: 'login-phase', l: (p: { phase: string, label?: string }) => void): this
|
|
54
|
-
// 探针/代理侧错误信号(不中断运行, 仅上报):
|
|
55
|
-
on (event: 'error', l: (
|
|
56
|
+
// 探针/代理侧错误信号(不中断运行, 仅上报): 回调收到一个真正的 Error 对象。
|
|
57
|
+
on (event: 'error', l: (err: Error) => void): this
|
|
56
58
|
// 探针心跳(~30s 一次), 供上层做存活/掉线判定: { state }。
|
|
57
59
|
on (event: 'heartbeat', l: (p: { state?: string }) => void): this
|
|
58
60
|
on (event: 'logout' | 'ready' | 'stop' | 'disconnected', l: () => void): this
|
|
@@ -74,12 +76,17 @@ export class Chatboty implements BotApi {
|
|
|
74
76
|
room: new Room(this, { id: w.roomId, topic: w.topic }), topic: w.topic, oldTopic: w.oldTopic, timestamp: w.timestamp,
|
|
75
77
|
}))
|
|
76
78
|
this.client.on('friendship', (w) => this.emit('friendship', this.toFriendship(w)))
|
|
77
|
-
this.client.on('login', (w) =>
|
|
79
|
+
this.client.on('login', (w) => {
|
|
80
|
+
// 把 payload 构造成 typed self Contact, 缓存并向上抛(供 message.mentionSelf/self 判定)。
|
|
81
|
+
const self = new Contact(this, this.toContactPayload(w.self ?? w))
|
|
82
|
+
this._self = self
|
|
83
|
+
this.emit('login', self)
|
|
84
|
+
})
|
|
78
85
|
this.client.on('logout', () => { this._self = undefined; this.emit('logout') })
|
|
79
86
|
this.client.on('scan', (w) => this.emit('scan', { qrcode: w.qrcode, status: w.status }))
|
|
80
87
|
this.client.on('login-phase', (w) => this.emit('login-phase', { phase: w.phase, label: w.label }))
|
|
81
88
|
this.client.on('disconnected', () => this.emit('disconnected'))
|
|
82
|
-
this.client.on('error', (w) => this.emit('error',
|
|
89
|
+
this.client.on('error', (w) => this.emit('error', new Error(w.error ?? '未知错误')))
|
|
83
90
|
this.client.on('heartbeat', (w) => this.emit('heartbeat', { state: w.state }))
|
|
84
91
|
}
|
|
85
92
|
|
|
@@ -177,10 +184,36 @@ export class Chatboty implements BotApi {
|
|
|
177
184
|
}
|
|
178
185
|
|
|
179
186
|
/* ---------------- 查询/工厂 ---------------- */
|
|
180
|
-
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* 查找群列表。无 query 时返回全部已加载群; 传 query 则在其上本地过滤。
|
|
190
|
+
* @param query 关键词字符串(匹配 topic/id 子串), 或 { topic?, id? } 精确匹配。
|
|
191
|
+
* @returns 命中的 Room 列表(可能为空)。
|
|
192
|
+
*/
|
|
193
|
+
async roomFindAll (query?: RoomQueryFilter): Promise<Room[]> {
|
|
181
194
|
const r = await this.command('roomList')
|
|
182
195
|
const arr = (r && (r.rooms || r.list || (Array.isArray(r) ? r : []))) || []
|
|
183
|
-
|
|
196
|
+
let list: Room[] = arr.map((x: any) => new Room(this, { id: x.conversationId || x.id, topic: x.name || x.topic }))
|
|
197
|
+
if (query !== undefined) {
|
|
198
|
+
if (typeof query === 'string') {
|
|
199
|
+
const kw = query.toLowerCase()
|
|
200
|
+
list = list.filter((rm) => (rm.topic() ?? '').toLowerCase().includes(kw) || rm.id.toLowerCase().includes(kw))
|
|
201
|
+
} else {
|
|
202
|
+
if (query.id) list = list.filter((rm) => rm.id === query.id)
|
|
203
|
+
if (query.topic) list = list.filter((rm) => rm.topic() === query.topic)
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return list
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* 查找单个群(取 {@link roomFindAll} 第一个命中)。
|
|
211
|
+
* @param query 关键词字符串或 { topic?, id? }。
|
|
212
|
+
* @returns 命中的第一个 Room; 无则 undefined。
|
|
213
|
+
*/
|
|
214
|
+
async roomFind (query: RoomQueryFilter): Promise<Room | undefined> {
|
|
215
|
+
const all = await this.roomFindAll(query)
|
|
216
|
+
return all[0]
|
|
184
217
|
}
|
|
185
218
|
|
|
186
219
|
async contactList (): Promise<Contact[]> {
|
|
@@ -202,7 +235,7 @@ export class Chatboty implements BotApi {
|
|
|
202
235
|
const arr = (r && (r.contacts || r.list || (Array.isArray(r) ? r : []))) || []
|
|
203
236
|
let list = arr.map((u: any) => new Contact(this, this.toContactPayload(u)))
|
|
204
237
|
if (query && typeof query !== 'string') { // 对象条件: 在子串命中基础上再做精确收窄
|
|
205
|
-
if (query.id) list = list.filter((c: Contact) => c.id
|
|
238
|
+
if (query.id) list = list.filter((c: Contact) => c.id === query.id)
|
|
206
239
|
if (query.alias) list = list.filter((c: Contact) => c.alias() === query.alias)
|
|
207
240
|
if (query.name) list = list.filter((c: Contact) => c.name() === query.name)
|
|
208
241
|
}
|
package/src/entity/contact.ts
CHANGED
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import type { BotApi, ContactPayload, Sayable } from '../types.js'
|
|
2
2
|
import { ContactType } from '../types.js'
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* 联系人实体(含外部客户)。
|
|
6
|
+
*
|
|
7
|
+
* 【同步 vs 异步约定】实体已持有的数据(来自事件 payload / 缓存)用【同步】读取;
|
|
8
|
+
* 需要回连接器/企微的操作一律 async。
|
|
9
|
+
* - 同步(缓存): id / name() / alias() / avatar() / phone() / title() / type() / conversationId()
|
|
10
|
+
* - 异步(动作): say()
|
|
11
|
+
*/
|
|
5
12
|
export class Contact {
|
|
6
|
-
|
|
13
|
+
/** 联系人 id(vid; 同步只读属性)。 */
|
|
14
|
+
readonly id: string
|
|
15
|
+
|
|
16
|
+
constructor (private readonly bot: BotApi, readonly payload: ContactPayload) {
|
|
17
|
+
this.id = payload.id
|
|
18
|
+
}
|
|
7
19
|
|
|
8
|
-
id (): string { return this.payload.id }
|
|
9
20
|
name (): string { return this.payload.name ?? '' }
|
|
10
21
|
alias (): string | undefined { return this.payload.alias }
|
|
11
22
|
avatar (): string | undefined { return this.payload.avatar }
|
|
@@ -24,9 +35,9 @@ export class Contact {
|
|
|
24
35
|
/** 给该联系人发消息(单聊)。 */
|
|
25
36
|
async say (sayable: Sayable): Promise<any> {
|
|
26
37
|
const conv = this.payload.conversationId
|
|
27
|
-
if (!conv) throw new Error(`Contact ${this.id
|
|
38
|
+
if (!conv) throw new Error(`Contact ${this.id} 无单聊会话 id, 无法发送`)
|
|
28
39
|
return this.bot.sayTo(conv, sayable)
|
|
29
40
|
}
|
|
30
41
|
|
|
31
|
-
toString (): string { return `Contact<${this.name() || this.id
|
|
42
|
+
toString (): string { return `Contact<${this.name() || this.id}>` }
|
|
32
43
|
}
|