chatboty 0.1.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/LICENSE +162 -0
- package/README.md +119 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/src/chatboty.d.ts +93 -0
- package/dist/cjs/src/chatboty.d.ts.map +1 -0
- package/dist/cjs/src/chatboty.js +204 -0
- package/dist/cjs/src/chatboty.js.map +1 -0
- package/dist/cjs/src/client.d.ts +84 -0
- package/dist/cjs/src/client.d.ts.map +1 -0
- package/dist/cjs/src/client.js +298 -0
- package/dist/cjs/src/client.js.map +1 -0
- package/dist/cjs/src/entity/contact.d.ts +25 -0
- package/dist/cjs/src/entity/contact.d.ts.map +1 -0
- package/dist/cjs/src/entity/contact.js +34 -0
- package/dist/cjs/src/entity/contact.js.map +1 -0
- package/dist/cjs/src/entity/friendship.d.ts +13 -0
- package/dist/cjs/src/entity/friendship.d.ts.map +1 -0
- package/dist/cjs/src/entity/friendship.js +19 -0
- package/dist/cjs/src/entity/friendship.js.map +1 -0
- package/dist/cjs/src/entity/message.d.ts +61 -0
- package/dist/cjs/src/entity/message.d.ts.map +1 -0
- package/dist/cjs/src/entity/message.js +150 -0
- package/dist/cjs/src/entity/message.js.map +1 -0
- package/dist/cjs/src/entity/room.d.ts +21 -0
- package/dist/cjs/src/entity/room.d.ts.map +1 -0
- package/dist/cjs/src/entity/room.js +43 -0
- package/dist/cjs/src/entity/room.js.map +1 -0
- package/dist/cjs/src/mod.d.ts +17 -0
- package/dist/cjs/src/mod.d.ts.map +1 -0
- package/dist/cjs/src/mod.js +41 -0
- package/dist/cjs/src/mod.js.map +1 -0
- package/dist/cjs/src/types.d.ts +122 -0
- package/dist/cjs/src/types.d.ts.map +1 -0
- package/dist/cjs/src/types.js +55 -0
- package/dist/cjs/src/types.js.map +1 -0
- package/dist/esm/src/chatboty.d.ts +93 -0
- package/dist/esm/src/chatboty.d.ts.map +1 -0
- package/dist/esm/src/chatboty.js +200 -0
- package/dist/esm/src/chatboty.js.map +1 -0
- package/dist/esm/src/client.d.ts +84 -0
- package/dist/esm/src/client.d.ts.map +1 -0
- package/dist/esm/src/client.js +291 -0
- package/dist/esm/src/client.js.map +1 -0
- package/dist/esm/src/entity/contact.d.ts +25 -0
- package/dist/esm/src/entity/contact.d.ts.map +1 -0
- package/dist/esm/src/entity/contact.js +30 -0
- package/dist/esm/src/entity/contact.js.map +1 -0
- package/dist/esm/src/entity/friendship.d.ts +13 -0
- package/dist/esm/src/entity/friendship.d.ts.map +1 -0
- package/dist/esm/src/entity/friendship.js +15 -0
- package/dist/esm/src/entity/friendship.js.map +1 -0
- package/dist/esm/src/entity/message.d.ts +61 -0
- package/dist/esm/src/entity/message.d.ts.map +1 -0
- package/dist/esm/src/entity/message.js +146 -0
- package/dist/esm/src/entity/message.js.map +1 -0
- package/dist/esm/src/entity/room.d.ts +21 -0
- package/dist/esm/src/entity/room.d.ts.map +1 -0
- package/dist/esm/src/entity/room.js +39 -0
- package/dist/esm/src/entity/room.js.map +1 -0
- package/dist/esm/src/mod.d.ts +17 -0
- package/dist/esm/src/mod.d.ts.map +1 -0
- package/dist/esm/src/mod.js +17 -0
- package/dist/esm/src/mod.js.map +1 -0
- package/dist/esm/src/types.d.ts +122 -0
- package/dist/esm/src/types.d.ts.map +1 -0
- package/dist/esm/src/types.js +50 -0
- package/dist/esm/src/types.js.map +1 -0
- package/package.json +52 -0
- package/src/chatboty.ts +228 -0
- package/src/client.ts +310 -0
- package/src/entity/contact.ts +32 -0
- package/src/entity/friendship.ts +16 -0
- package/src/entity/message.ts +147 -0
- package/src/entity/room.ts +42 -0
- package/src/mod.ts +19 -0
- package/src/types.ts +142 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export interface ChatbotyClientOptions {
|
|
2
|
+
/**
|
|
3
|
+
* 长期订阅 token(cbt_...), 由售卖端签发给用户。
|
|
4
|
+
* 直连/发证模式(fallback)必填; 使用服务发现(serviceToken+serviceAuthority)时可省略。
|
|
5
|
+
*/
|
|
6
|
+
token?: string;
|
|
7
|
+
/** 售卖端基址(发证/服务发现)。默认 http://127.0.0.1:8080 */
|
|
8
|
+
atlasUrl?: string;
|
|
9
|
+
/** 命令回包超时(ms)。默认 25000 */
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
/** 调试直连: 跳过发证, 直接给网关地址 */
|
|
12
|
+
endpoint?: string;
|
|
13
|
+
/** 调试直连: 直接给接入 JWT(配合 endpoint) */
|
|
14
|
+
accessToken?: string;
|
|
15
|
+
/**
|
|
16
|
+
* 【推荐】服务发现: 长期服务令牌。配合 serviceAuthority 使用。
|
|
17
|
+
* SDK 会带 `Authorization: Bearer <serviceToken>` POST 到 serviceAuthority,
|
|
18
|
+
* 换取 { endpoint, accessToken(短TTL RS256), expiresIn }, 用 accessToken 连网关(?access=)。
|
|
19
|
+
*/
|
|
20
|
+
serviceToken?: string;
|
|
21
|
+
/**
|
|
22
|
+
* 【推荐】服务发现端点(权威 URL)。给定时优先走服务发现流程(而非 token 直连/发证)。
|
|
23
|
+
*/
|
|
24
|
+
serviceAuthority?: string;
|
|
25
|
+
/** accessToken 过期前提前刷新的秒数。默认 30 */
|
|
26
|
+
refreshSkewSec?: number;
|
|
27
|
+
}
|
|
28
|
+
export type EventHandler = (payload: Record<string, any>) => void;
|
|
29
|
+
export declare class ChatbotyClient {
|
|
30
|
+
private readonly opts;
|
|
31
|
+
private ws?;
|
|
32
|
+
private accountId?;
|
|
33
|
+
private reqId;
|
|
34
|
+
private readonly pending;
|
|
35
|
+
private readonly handlers;
|
|
36
|
+
private readyResolve?;
|
|
37
|
+
private readonly discoveryMode;
|
|
38
|
+
private stopped;
|
|
39
|
+
private autoReconnect;
|
|
40
|
+
private currentAccessToken?;
|
|
41
|
+
private currentEndpoint?;
|
|
42
|
+
private refreshTimer?;
|
|
43
|
+
private reconnectTimer?;
|
|
44
|
+
private reconnectAttempt;
|
|
45
|
+
constructor(options: ChatbotyClientOptions);
|
|
46
|
+
/** 该接入授权的探针实例 id(发证后可知)。 */
|
|
47
|
+
get account(): string | undefined;
|
|
48
|
+
/** 服务发现 + 连接网关。resolve 于网关 gateway-ready。 */
|
|
49
|
+
start(): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* 服务发现: POST serviceAuthority(带 Bearer serviceToken)换取接入凭据。
|
|
52
|
+
* 期望响应 { endpoint, accessToken, expiresIn }(可选 accountId/seatId)。
|
|
53
|
+
*/
|
|
54
|
+
private discover;
|
|
55
|
+
/** 应用一次发现结果: 缓存 endpoint/accessToken, 并安排到期前刷新。 */
|
|
56
|
+
private applyDiscovery;
|
|
57
|
+
/** 在 accessToken 过期前(提前 refreshSkewSec)重新发现, 刷新缓存的 accessToken。 */
|
|
58
|
+
private scheduleRefresh;
|
|
59
|
+
/** 刷新 accessToken; 失败按指数退避重试(封顶 30s)。刷新后的 token 供下次(重)连使用。 */
|
|
60
|
+
private refresh;
|
|
61
|
+
/** discovery 模式下断线自愈: 重新发现取新 accessToken 后重连; 失败指数退避。 */
|
|
62
|
+
private scheduleReconnect;
|
|
63
|
+
private reconnect;
|
|
64
|
+
/** 用订阅 token 向售卖端换接入 JWT(发证/服务发现)。 */
|
|
65
|
+
private grant;
|
|
66
|
+
/**
|
|
67
|
+
* 连接网关。queryKey='token' 为直连/发证 fallback(既有行为不变);
|
|
68
|
+
* queryKey='access' 为服务发现流程(网关验 RS256 accessToken → seatId)。
|
|
69
|
+
*/
|
|
70
|
+
private connect;
|
|
71
|
+
private onFrame;
|
|
72
|
+
/** 订阅事件: message / room-join / room-leave / room-topic / friendship / login / logout / disconnected ... */
|
|
73
|
+
on(event: string, handler: EventHandler): this;
|
|
74
|
+
off(event: string, handler: EventHandler): this;
|
|
75
|
+
private emit;
|
|
76
|
+
/** 通用命令: 发到网关 → 路由到本接入授权的探针。 */
|
|
77
|
+
command(cmd: string, args?: Record<string, any>): Promise<any>;
|
|
78
|
+
roomList(): Promise<any>;
|
|
79
|
+
contactList(limit?: number): Promise<any>;
|
|
80
|
+
say(conversationId: string, text: string): Promise<any>;
|
|
81
|
+
/** 断开。停止刷新/重连定时器。 */
|
|
82
|
+
stop(): void;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/client.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,mCAAmC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAA;AAQjE,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CACE;IACvB,OAAO,CAAC,EAAE,CAAC,CAAW;IACtB,OAAO,CAAC,SAAS,CAAC,CAAQ;IAC1B,OAAO,CAAC,KAAK,CAAI;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuC;IAChE,OAAO,CAAC,YAAY,CAAC,CAAY;IAEjC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,kBAAkB,CAAC,CAAQ;IACnC,OAAO,CAAC,eAAe,CAAC,CAAQ;IAChC,OAAO,CAAC,YAAY,CAAC,CAA+B;IACpD,OAAO,CAAC,cAAc,CAAC,CAA+B;IACtD,OAAO,CAAC,gBAAgB,CAAI;gBAEf,OAAO,EAAE,qBAAqB;IAgB3C,4BAA4B;IAC5B,IAAI,OAAO,IAAK,MAAM,GAAG,SAAS,CAA0B;IAE5D,6CAA6C;IACvC,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;IAqB7B;;;OAGG;YACW,QAAQ;IAsBtB,mDAAmD;IACnD,OAAO,CAAC,cAAc;IAOtB,mEAAmE;IACnE,OAAO,CAAC,eAAe;IAOvB,8DAA8D;YAChD,OAAO;IAarB,yDAAyD;IACzD,OAAO,CAAC,iBAAiB;YASX,SAAS;IAyBvB,sCAAsC;YACxB,KAAK;IAkBnB;;;OAGG;IACH,OAAO,CAAC,OAAO;IAuBf,OAAO,CAAC,OAAO;IAoBf,2GAA2G;IAC3G,EAAE,CAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAM/C,GAAG,CAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IAKhD,OAAO,CAAC,IAAI;IAIZ,gCAAgC;IAChC,OAAO,CAAE,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAcnE,QAAQ,IAAK,OAAO,CAAC,GAAG,CAAC;IACzB,WAAW,CAAE,KAAK,SAAI,GAAG,OAAO,CAAC,GAAG,CAAC;IACrC,GAAG,CAAE,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAExD,qBAAqB;IACrB,IAAI,IAAK,IAAI;CAOd"}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ChatbotyClient = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* ChatbotyClient — P1 身份主线的"薄壳"接入客户端。
|
|
9
|
+
*
|
|
10
|
+
* 自研、零外部框架依赖(仅 ws)。职责:
|
|
11
|
+
* 1) 服务发现+发证: 用长期订阅 token 调售卖端 /api/access/grant 换取
|
|
12
|
+
* {endpoint(网关地址), accessToken(短TTL接入JWT), accountId}。
|
|
13
|
+
* 2) 连网关: endpoint + `/client?token=<accessToken>`; 网关公钥验签后按 accountId 路由+隔离。
|
|
14
|
+
* 3) 收发: 命令请求/回包关联(带超时) + 事件订阅(message/room-join/room-leave/room-topic/friendship/...)。
|
|
15
|
+
*
|
|
16
|
+
* 这是 P2 自研全生态框架(Contact/Room/Message/插件)的传输地基。
|
|
17
|
+
*/
|
|
18
|
+
const ws_1 = __importDefault(require("ws"));
|
|
19
|
+
class ChatbotyClient {
|
|
20
|
+
constructor(options) {
|
|
21
|
+
this.reqId = 1;
|
|
22
|
+
this.pending = new Map();
|
|
23
|
+
this.handlers = new Map();
|
|
24
|
+
this.stopped = false;
|
|
25
|
+
this.autoReconnect = false;
|
|
26
|
+
this.reconnectAttempt = 0;
|
|
27
|
+
const hasDiscovery = !!(options && options.serviceToken && options.serviceAuthority);
|
|
28
|
+
const hasDirect = !!(options && (options.token || (options.endpoint && options.accessToken)));
|
|
29
|
+
if (!hasDiscovery && !hasDirect) {
|
|
30
|
+
throw new Error('ChatbotyClient: 需提供 { serviceToken, serviceAuthority } 或 { token, endpoint }');
|
|
31
|
+
}
|
|
32
|
+
this.discoveryMode = hasDiscovery;
|
|
33
|
+
this.opts = {
|
|
34
|
+
atlasUrl: 'http://127.0.0.1:8080',
|
|
35
|
+
timeoutMs: 25000,
|
|
36
|
+
refreshSkewSec: 30,
|
|
37
|
+
token: '',
|
|
38
|
+
...options,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** 该接入授权的探针实例 id(发证后可知)。 */
|
|
42
|
+
get account() { return this.accountId; }
|
|
43
|
+
/** 服务发现 + 连接网关。resolve 于网关 gateway-ready。 */
|
|
44
|
+
async start() {
|
|
45
|
+
this.stopped = false;
|
|
46
|
+
// 【推荐】服务发现流程: serviceToken/serviceAuthority → 短TTL accessToken → 连网关(?access=) + 到期前刷新。
|
|
47
|
+
if (this.discoveryMode) {
|
|
48
|
+
const d = await this.discover();
|
|
49
|
+
this.applyDiscovery(d);
|
|
50
|
+
await this.connect(d.endpoint, d.accessToken, 'access');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// 直连/发证 fallback: 保持既有 `?token=<accessToken>` 行为不变。
|
|
54
|
+
let endpoint = this.opts.endpoint;
|
|
55
|
+
let accessToken = this.opts.accessToken;
|
|
56
|
+
if (!endpoint || !accessToken) {
|
|
57
|
+
const g = await this.grant();
|
|
58
|
+
endpoint = g.endpoint;
|
|
59
|
+
accessToken = g.accessToken;
|
|
60
|
+
this.accountId = g.accountId;
|
|
61
|
+
}
|
|
62
|
+
await this.connect(endpoint, accessToken);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 服务发现: POST serviceAuthority(带 Bearer serviceToken)换取接入凭据。
|
|
66
|
+
* 期望响应 { endpoint, accessToken, expiresIn }(可选 accountId/seatId)。
|
|
67
|
+
*/
|
|
68
|
+
async discover() {
|
|
69
|
+
const url = this.opts.serviceAuthority;
|
|
70
|
+
const httpFetch = globalThis.fetch;
|
|
71
|
+
if (!httpFetch)
|
|
72
|
+
throw new Error('运行环境无 fetch(需 Node>=18)');
|
|
73
|
+
const resp = await httpFetch(url, {
|
|
74
|
+
method: 'POST',
|
|
75
|
+
headers: {
|
|
76
|
+
'content-type': 'application/json',
|
|
77
|
+
authorization: `Bearer ${this.opts.serviceToken ?? ''}`,
|
|
78
|
+
},
|
|
79
|
+
body: JSON.stringify({ token: this.opts.serviceToken }),
|
|
80
|
+
});
|
|
81
|
+
if (!resp.ok) {
|
|
82
|
+
const txt = await resp.text().catch(() => '');
|
|
83
|
+
throw new Error(`服务发现失败 ${resp.status}: ${txt.slice(0, 200)}`);
|
|
84
|
+
}
|
|
85
|
+
const j = await resp.json();
|
|
86
|
+
if (!j.endpoint || !j.accessToken)
|
|
87
|
+
throw new Error('服务发现响应缺少 endpoint/accessToken');
|
|
88
|
+
const expiresIn = Number(j.expiresIn) > 0 ? Number(j.expiresIn) : 300;
|
|
89
|
+
return { endpoint: j.endpoint, accessToken: j.accessToken, expiresIn, accountId: j.accountId ?? j.seatId };
|
|
90
|
+
}
|
|
91
|
+
/** 应用一次发现结果: 缓存 endpoint/accessToken, 并安排到期前刷新。 */
|
|
92
|
+
applyDiscovery(d) {
|
|
93
|
+
this.currentEndpoint = d.endpoint;
|
|
94
|
+
this.currentAccessToken = d.accessToken;
|
|
95
|
+
if (d.accountId)
|
|
96
|
+
this.accountId = d.accountId;
|
|
97
|
+
this.scheduleRefresh(d.expiresIn);
|
|
98
|
+
}
|
|
99
|
+
/** 在 accessToken 过期前(提前 refreshSkewSec)重新发现, 刷新缓存的 accessToken。 */
|
|
100
|
+
scheduleRefresh(expiresIn) {
|
|
101
|
+
if (this.refreshTimer)
|
|
102
|
+
clearTimeout(this.refreshTimer);
|
|
103
|
+
if (this.stopped)
|
|
104
|
+
return;
|
|
105
|
+
const delayMs = Math.max(1000, (expiresIn - this.opts.refreshSkewSec) * 1000);
|
|
106
|
+
this.refreshTimer = setTimeout(() => { void this.refresh(0); }, delayMs);
|
|
107
|
+
}
|
|
108
|
+
/** 刷新 accessToken; 失败按指数退避重试(封顶 30s)。刷新后的 token 供下次(重)连使用。 */
|
|
109
|
+
async refresh(attempt) {
|
|
110
|
+
if (this.stopped)
|
|
111
|
+
return;
|
|
112
|
+
try {
|
|
113
|
+
const d = await this.discover();
|
|
114
|
+
this.applyDiscovery(d); // 内部会重新 scheduleRefresh
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
if (this.stopped)
|
|
118
|
+
return;
|
|
119
|
+
const backoff = Math.min(30000, 1000 * 2 ** attempt);
|
|
120
|
+
if (this.refreshTimer)
|
|
121
|
+
clearTimeout(this.refreshTimer);
|
|
122
|
+
this.refreshTimer = setTimeout(() => { void this.refresh(attempt + 1); }, backoff);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/** discovery 模式下断线自愈: 重新发现取新 accessToken 后重连; 失败指数退避。 */
|
|
126
|
+
scheduleReconnect() {
|
|
127
|
+
if (this.stopped || this.reconnectTimer)
|
|
128
|
+
return;
|
|
129
|
+
const backoff = Math.min(30000, 1000 * 2 ** this.reconnectAttempt);
|
|
130
|
+
this.reconnectTimer = setTimeout(() => {
|
|
131
|
+
this.reconnectTimer = undefined;
|
|
132
|
+
void this.reconnect();
|
|
133
|
+
}, backoff);
|
|
134
|
+
}
|
|
135
|
+
async reconnect() {
|
|
136
|
+
if (this.stopped)
|
|
137
|
+
return;
|
|
138
|
+
try {
|
|
139
|
+
// 优先用刷新循环维护的最新 accessToken(“on reconnect use the fresh one”);
|
|
140
|
+
// 无缓存(如刚被失败清空)则强制重新发现。
|
|
141
|
+
let endpoint = this.currentEndpoint;
|
|
142
|
+
let accessToken = this.currentAccessToken;
|
|
143
|
+
if (!endpoint || !accessToken) {
|
|
144
|
+
const d = await this.discover();
|
|
145
|
+
this.applyDiscovery(d);
|
|
146
|
+
endpoint = d.endpoint;
|
|
147
|
+
accessToken = d.accessToken;
|
|
148
|
+
}
|
|
149
|
+
await this.connect(endpoint, accessToken, 'access');
|
|
150
|
+
this.reconnectAttempt = 0;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
if (this.stopped)
|
|
154
|
+
return;
|
|
155
|
+
this.reconnectAttempt++;
|
|
156
|
+
// 缓存 token 可能已失效, 清掉 → 下次重连强制重新发现。
|
|
157
|
+
this.currentAccessToken = undefined;
|
|
158
|
+
this.currentEndpoint = undefined;
|
|
159
|
+
this.scheduleReconnect();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/** 用订阅 token 向售卖端换接入 JWT(发证/服务发现)。 */
|
|
163
|
+
async grant() {
|
|
164
|
+
const url = this.opts.atlasUrl.replace(/\/$/, '') + '/api/access/grant';
|
|
165
|
+
const httpFetch = globalThis.fetch;
|
|
166
|
+
if (!httpFetch)
|
|
167
|
+
throw new Error('运行环境无 fetch(需 Node>=18)');
|
|
168
|
+
const resp = await httpFetch(url, {
|
|
169
|
+
method: 'POST',
|
|
170
|
+
headers: { 'content-type': 'application/json' },
|
|
171
|
+
body: JSON.stringify({ token: this.opts.token }),
|
|
172
|
+
});
|
|
173
|
+
if (!resp.ok) {
|
|
174
|
+
const txt = await resp.text().catch(() => '');
|
|
175
|
+
throw new Error(`发证失败 ${resp.status}: ${txt.slice(0, 200)}`);
|
|
176
|
+
}
|
|
177
|
+
const j = await resp.json();
|
|
178
|
+
if (!j.endpoint || !j.accessToken)
|
|
179
|
+
throw new Error('发证响应缺少 endpoint/accessToken');
|
|
180
|
+
return { endpoint: j.endpoint, accessToken: j.accessToken, accountId: j.accountId };
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* 连接网关。queryKey='token' 为直连/发证 fallback(既有行为不变);
|
|
184
|
+
* queryKey='access' 为服务发现流程(网关验 RS256 accessToken → seatId)。
|
|
185
|
+
*/
|
|
186
|
+
connect(endpoint, accessToken, queryKey = 'token') {
|
|
187
|
+
const sep = endpoint.includes('/client') ? '' : '/client';
|
|
188
|
+
const wsUrl = `${endpoint}${sep}?${queryKey}=${encodeURIComponent(accessToken)}`;
|
|
189
|
+
return new Promise((resolve, reject) => {
|
|
190
|
+
const ws = new ws_1.default(wsUrl);
|
|
191
|
+
this.ws = ws;
|
|
192
|
+
this.readyResolve = resolve;
|
|
193
|
+
const onErr = (e) => reject(new Error('连接网关失败: ' + e.message));
|
|
194
|
+
ws.once('error', onErr);
|
|
195
|
+
ws.on('open', () => {
|
|
196
|
+
ws.removeListener('error', onErr);
|
|
197
|
+
// 首次成功连上后才开启断线自愈, 避免首连失败时把错误吞进后台重连。
|
|
198
|
+
if (queryKey === 'access')
|
|
199
|
+
this.autoReconnect = true;
|
|
200
|
+
});
|
|
201
|
+
ws.on('message', (raw) => this.onFrame(raw));
|
|
202
|
+
ws.on('close', () => {
|
|
203
|
+
if (this.ws === ws)
|
|
204
|
+
this.ws = undefined;
|
|
205
|
+
this.emit('disconnected', {});
|
|
206
|
+
if (this.autoReconnect && !this.stopped)
|
|
207
|
+
this.scheduleReconnect();
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
onFrame(raw) {
|
|
212
|
+
let m;
|
|
213
|
+
try {
|
|
214
|
+
m = JSON.parse(raw.toString());
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (typeof m.id === 'number' && this.pending.has(m.id)) { // 命令回包
|
|
220
|
+
const p = this.pending.get(m.id);
|
|
221
|
+
this.pending.delete(m.id);
|
|
222
|
+
clearTimeout(p.timer);
|
|
223
|
+
if (m.ok)
|
|
224
|
+
p.resolve(m.result);
|
|
225
|
+
else
|
|
226
|
+
p.reject(new Error(m.error || 'command failed'));
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (m.ev) { // 事件
|
|
230
|
+
if (m.ev === 'gateway-ready') {
|
|
231
|
+
if (!this.accountId && Array.isArray(m.accounts) && m.accounts.length)
|
|
232
|
+
this.accountId = m.accounts[0];
|
|
233
|
+
if (this.readyResolve) {
|
|
234
|
+
this.readyResolve();
|
|
235
|
+
this.readyResolve = undefined;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
this.emit(m.ev, m);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/** 订阅事件: message / room-join / room-leave / room-topic / friendship / login / logout / disconnected ... */
|
|
242
|
+
on(event, handler) {
|
|
243
|
+
if (!this.handlers.has(event))
|
|
244
|
+
this.handlers.set(event, new Set());
|
|
245
|
+
this.handlers.get(event).add(handler);
|
|
246
|
+
return this;
|
|
247
|
+
}
|
|
248
|
+
off(event, handler) {
|
|
249
|
+
this.handlers.get(event)?.delete(handler);
|
|
250
|
+
return this;
|
|
251
|
+
}
|
|
252
|
+
emit(event, payload) {
|
|
253
|
+
this.handlers.get(event)?.forEach((h) => { try {
|
|
254
|
+
h(payload);
|
|
255
|
+
}
|
|
256
|
+
catch { /* 隔离回调异常 */ } });
|
|
257
|
+
}
|
|
258
|
+
/** 通用命令: 发到网关 → 路由到本接入授权的探针。 */
|
|
259
|
+
command(cmd, args = {}) {
|
|
260
|
+
const ws = this.ws;
|
|
261
|
+
if (!ws || ws.readyState !== ws_1.default.OPEN)
|
|
262
|
+
return Promise.reject(new Error('未连接'));
|
|
263
|
+
const id = this.reqId++;
|
|
264
|
+
return new Promise((resolve, reject) => {
|
|
265
|
+
const timer = setTimeout(() => {
|
|
266
|
+
if (this.pending.has(id)) {
|
|
267
|
+
this.pending.delete(id);
|
|
268
|
+
reject(new Error('命令超时: ' + cmd));
|
|
269
|
+
}
|
|
270
|
+
}, this.opts.timeoutMs);
|
|
271
|
+
this.pending.set(id, { resolve, reject, timer });
|
|
272
|
+
ws.send(JSON.stringify({ id, accountId: this.accountId, cmd, ...args }));
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
// —— 便捷方法(P2 框架前的最小集; 完整 Contact/Room/Message 对象模型见 P2) ——
|
|
276
|
+
roomList() { return this.command('roomList'); }
|
|
277
|
+
contactList(limit = 0) { return this.command('contactList', { limit }); }
|
|
278
|
+
say(conversationId, text) { return this.command('sendText', { conversationId, text }); }
|
|
279
|
+
/** 断开。停止刷新/重连定时器。 */
|
|
280
|
+
stop() {
|
|
281
|
+
this.stopped = true;
|
|
282
|
+
this.autoReconnect = false;
|
|
283
|
+
if (this.refreshTimer) {
|
|
284
|
+
clearTimeout(this.refreshTimer);
|
|
285
|
+
this.refreshTimer = undefined;
|
|
286
|
+
}
|
|
287
|
+
if (this.reconnectTimer) {
|
|
288
|
+
clearTimeout(this.reconnectTimer);
|
|
289
|
+
this.reconnectTimer = undefined;
|
|
290
|
+
}
|
|
291
|
+
try {
|
|
292
|
+
this.ws?.close();
|
|
293
|
+
}
|
|
294
|
+
catch { /* noop */ }
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
exports.ChatbotyClient = ChatbotyClient;
|
|
298
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { BotApi, ContactPayload, Sayable } from '../types.js';
|
|
2
|
+
import { ContactType } from '../types.js';
|
|
3
|
+
/** 联系人实体(含外部客户)。 */
|
|
4
|
+
export declare class Contact {
|
|
5
|
+
private readonly bot;
|
|
6
|
+
readonly payload: ContactPayload;
|
|
7
|
+
constructor(bot: BotApi, payload: ContactPayload);
|
|
8
|
+
id(): string;
|
|
9
|
+
name(): string;
|
|
10
|
+
alias(): string | undefined;
|
|
11
|
+
avatar(): string | undefined;
|
|
12
|
+
phone(): string | undefined;
|
|
13
|
+
title(): string | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* 联系人类别。企微通讯录成员/外部客户都是真人 → 默认 {@link ContactType.Individual}。
|
|
16
|
+
* (企微不存在微信式"公众号/服务号", 且探针未采集"应用号/机器人"标志, 故不臆造 Official。)
|
|
17
|
+
*/
|
|
18
|
+
type(): ContactType;
|
|
19
|
+
/** 单聊会话 id(发消息目标)。 */
|
|
20
|
+
conversationId(): string | undefined;
|
|
21
|
+
/** 给该联系人发消息(单聊)。 */
|
|
22
|
+
say(sayable: Sayable): Promise<any>;
|
|
23
|
+
toString(): string;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=contact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contact.d.ts","sourceRoot":"","sources":["../../../../src/entity/contact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,oBAAoB;AACpB,qBAAa,OAAO;IACL,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAU,QAAQ,CAAC,OAAO,EAAE,cAAc;gBAA7C,GAAG,EAAE,MAAM,EAAW,OAAO,EAAE,cAAc;IAE3E,EAAE,IAAK,MAAM;IACb,IAAI,IAAK,MAAM;IACf,KAAK,IAAK,MAAM,GAAG,SAAS;IAC5B,MAAM,IAAK,MAAM,GAAG,SAAS;IAC7B,KAAK,IAAK,MAAM,GAAG,SAAS;IAC5B,KAAK,IAAK,MAAM,GAAG,SAAS;IAE5B;;;OAGG;IACH,IAAI,IAAK,WAAW;IAEpB,sBAAsB;IACtB,cAAc,IAAK,MAAM,GAAG,SAAS;IAErC,oBAAoB;IACd,GAAG,CAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC;IAM1C,QAAQ,IAAK,MAAM;CACpB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Contact = void 0;
|
|
4
|
+
const types_js_1 = require("../types.js");
|
|
5
|
+
/** 联系人实体(含外部客户)。 */
|
|
6
|
+
class Contact {
|
|
7
|
+
constructor(bot, payload) {
|
|
8
|
+
this.bot = bot;
|
|
9
|
+
this.payload = payload;
|
|
10
|
+
}
|
|
11
|
+
id() { return this.payload.id; }
|
|
12
|
+
name() { return this.payload.name ?? ''; }
|
|
13
|
+
alias() { return this.payload.alias; }
|
|
14
|
+
avatar() { return this.payload.avatar; }
|
|
15
|
+
phone() { return this.payload.phone; }
|
|
16
|
+
title() { return this.payload.title; }
|
|
17
|
+
/**
|
|
18
|
+
* 联系人类别。企微通讯录成员/外部客户都是真人 → 默认 {@link ContactType.Individual}。
|
|
19
|
+
* (企微不存在微信式"公众号/服务号", 且探针未采集"应用号/机器人"标志, 故不臆造 Official。)
|
|
20
|
+
*/
|
|
21
|
+
type() { return this.payload.type ?? types_js_1.ContactType.Individual; }
|
|
22
|
+
/** 单聊会话 id(发消息目标)。 */
|
|
23
|
+
conversationId() { return this.payload.conversationId; }
|
|
24
|
+
/** 给该联系人发消息(单聊)。 */
|
|
25
|
+
async say(sayable) {
|
|
26
|
+
const conv = this.payload.conversationId;
|
|
27
|
+
if (!conv)
|
|
28
|
+
throw new Error(`Contact ${this.id()} 无单聊会话 id, 无法发送`);
|
|
29
|
+
return this.bot.sayTo(conv, sayable);
|
|
30
|
+
}
|
|
31
|
+
toString() { return `Contact<${this.name() || this.id()}>`; }
|
|
32
|
+
}
|
|
33
|
+
exports.Contact = Contact;
|
|
34
|
+
//# sourceMappingURL=contact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contact.js","sourceRoot":"","sources":["../../../../src/entity/contact.ts"],"names":[],"mappings":";;;AACA,0CAAyC;AAEzC,oBAAoB;AACpB,MAAa,OAAO;IAClB,YAA8B,GAAW,EAAW,OAAuB;QAA7C,QAAG,GAAH,GAAG,CAAQ;QAAW,YAAO,GAAP,OAAO,CAAgB;IAAG,CAAC;IAE/E,EAAE,KAAc,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA,CAAC,CAAC;IACxC,IAAI,KAAc,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAA,CAAC,CAAC;IAClD,KAAK,KAA0B,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAA,CAAC,CAAC;IAC1D,MAAM,KAA0B,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAA,CAAC,CAAC;IAC5D,KAAK,KAA0B,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAA,CAAC,CAAC;IAC1D,KAAK,KAA0B,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAA,CAAC,CAAC;IAE1D;;;OAGG;IACH,IAAI,KAAmB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,sBAAW,CAAC,UAAU,CAAA,CAAC,CAAC;IAE3E,sBAAsB;IACtB,cAAc,KAA0B,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAA,CAAC,CAAC;IAE5E,oBAAoB;IACpB,KAAK,CAAC,GAAG,CAAE,OAAgB;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAA;QACxC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAA;QACjE,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACtC,CAAC;IAED,QAAQ,KAAc,OAAO,WAAW,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,EAAE,GAAG,CAAA,CAAC,CAAC;CACtE;AA3BD,0BA2BC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BotApi, FriendshipPayload, FriendshipKind } from '../types.js';
|
|
2
|
+
import { Contact } from './contact.js';
|
|
3
|
+
/** 好友关系事件实体。 */
|
|
4
|
+
export declare class Friendship {
|
|
5
|
+
private readonly bot;
|
|
6
|
+
readonly payload: FriendshipPayload;
|
|
7
|
+
constructor(bot: BotApi, payload: FriendshipPayload);
|
|
8
|
+
kind(): FriendshipKind;
|
|
9
|
+
hello(): string | undefined;
|
|
10
|
+
contact(): Contact;
|
|
11
|
+
toString(): string;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=friendship.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"friendship.d.ts","sourceRoot":"","sources":["../../../../src/entity/friendship.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,gBAAgB;AAChB,qBAAa,UAAU;IACR,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAU,QAAQ,CAAC,OAAO,EAAE,iBAAiB;gBAAhD,GAAG,EAAE,MAAM,EAAW,OAAO,EAAE,iBAAiB;IAE9E,IAAI,IAAK,cAAc;IACvB,KAAK,IAAK,MAAM,GAAG,SAAS;IAE5B,OAAO,IAAK,OAAO;IAInB,QAAQ,IAAK,MAAM;CACpB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Friendship = void 0;
|
|
4
|
+
const contact_js_1 = require("./contact.js");
|
|
5
|
+
/** 好友关系事件实体。 */
|
|
6
|
+
class Friendship {
|
|
7
|
+
constructor(bot, payload) {
|
|
8
|
+
this.bot = bot;
|
|
9
|
+
this.payload = payload;
|
|
10
|
+
}
|
|
11
|
+
kind() { return this.payload.kind; }
|
|
12
|
+
hello() { return this.payload.hello; }
|
|
13
|
+
contact() {
|
|
14
|
+
return new contact_js_1.Contact(this.bot, this.payload.contact ?? { id: this.payload.contactId });
|
|
15
|
+
}
|
|
16
|
+
toString() { return `Friendship<${this.kind()}:${this.payload.contactId}>`; }
|
|
17
|
+
}
|
|
18
|
+
exports.Friendship = Friendship;
|
|
19
|
+
//# sourceMappingURL=friendship.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"friendship.js","sourceRoot":"","sources":["../../../../src/entity/friendship.ts"],"names":[],"mappings":";;;AACA,6CAAsC;AAEtC,gBAAgB;AAChB,MAAa,UAAU;IACrB,YAA8B,GAAW,EAAW,OAA0B;QAAhD,QAAG,GAAH,GAAG,CAAQ;QAAW,YAAO,GAAP,OAAO,CAAmB;IAAG,CAAC;IAElF,IAAI,KAAsB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAA,CAAC,CAAC;IACpD,KAAK,KAA0B,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAA,CAAC,CAAC;IAE1D,OAAO;QACL,OAAO,IAAI,oBAAO,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;IACtF,CAAC;IAED,QAAQ,KAAc,OAAO,cAAc,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,CAAA,CAAC,CAAC;CACtF;AAXD,gCAWC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { BotApi, MessagePayload, Sayable, FileBox } from '../types.js';
|
|
2
|
+
import { MessageType } from '../types.js';
|
|
3
|
+
import { Contact } from './contact.js';
|
|
4
|
+
import { Room } from './room.js';
|
|
5
|
+
/** 消息实体。 */
|
|
6
|
+
export declare class Message {
|
|
7
|
+
private readonly bot;
|
|
8
|
+
readonly payload: MessagePayload;
|
|
9
|
+
constructor(bot: BotApi, payload: MessagePayload);
|
|
10
|
+
id(): string | undefined;
|
|
11
|
+
type(): MessageType;
|
|
12
|
+
text(): string;
|
|
13
|
+
self(): boolean;
|
|
14
|
+
timestamp(): number | undefined;
|
|
15
|
+
file(): FileBox | null | undefined;
|
|
16
|
+
miniProgram(): Record<string, any> | null | undefined;
|
|
17
|
+
urlLink(): Record<string, any> | null | undefined;
|
|
18
|
+
/** 发送者(完整 Contact; 群消息识别客户用)。 */
|
|
19
|
+
talker(): Contact | undefined;
|
|
20
|
+
/** 所在群(单聊为 undefined)。 */
|
|
21
|
+
room(): Room | undefined;
|
|
22
|
+
/** 回复到原会话(群消息回群, 单聊回该人)。 */
|
|
23
|
+
say(sayable: Sayable): Promise<any>;
|
|
24
|
+
/**
|
|
25
|
+
* 从消息正文解析出的 @ 提及显示名(不含 "@所有人"/"@all")。
|
|
26
|
+
* 说明: 企微群 @ 消息正文形如 `@张三 内容`, 名字后接普通空格或 U+2005(four-per-em space)分隔。
|
|
27
|
+
* 这是"从消息 payload 解析"的诚实实现——只用真实的正文文本; 结构化的被@ vid 需进一步逆向(见 RE 计划)。
|
|
28
|
+
*/
|
|
29
|
+
private mentionNames;
|
|
30
|
+
/**
|
|
31
|
+
* 消息中被 @ 的联系人列表(best-effort)。
|
|
32
|
+
* 先从正文解析出 @显示名, 再用一次 contactList 拉全量通讯录按 name/alias 就近解析成完整 Contact;
|
|
33
|
+
* 未在已加载通讯录中的成员回退为仅含名字的 Contact(其 id() 为空串)。
|
|
34
|
+
* @returns 被 @ 的 Contact 数组(无 @ 时为空数组)。
|
|
35
|
+
*/
|
|
36
|
+
mentionList(): Promise<Contact[]>;
|
|
37
|
+
/**
|
|
38
|
+
* 本条消息是否 @ 了当前登录者(self)或 @所有人。
|
|
39
|
+
* 判定: 正文含 `@所有人`/`@all`(全体含自己) → true; 或含 `@{self 显示名}` → true。
|
|
40
|
+
* (纯本机文本判定, 不发起网络请求; 依赖 bot 已知 self 名。)
|
|
41
|
+
*/
|
|
42
|
+
mentionSelf(): boolean;
|
|
43
|
+
private toFileBoxFromResult;
|
|
44
|
+
/**
|
|
45
|
+
* 取本条消息的媒体/文件字节(图片/文件/音视频), 返回 {@link FileBox}(含 base64 data URL)。
|
|
46
|
+
* - 收到的图片/文件事件通常已附带 file(探针后台已下载解密) → 直接返回。
|
|
47
|
+
* - 否则按类型冷调探针下载: 图片走 downloadImage, 文件/音视频走 downloadFile(按 msgid+会话+文件名定位缓存)。
|
|
48
|
+
* @returns FileBox(dataUrl/mime/name/size); 非媒体消息或下载失败返回 null。
|
|
49
|
+
*/
|
|
50
|
+
toFileBox(): Promise<FileBox | null>;
|
|
51
|
+
/** {@link toFileBox} 的别名(下载本条消息的媒体字节)。 */
|
|
52
|
+
download(): Promise<FileBox | null>;
|
|
53
|
+
/**
|
|
54
|
+
* 转发本条消息到另一会话(群/单聊 conversationId, 或 Room/Contact)。
|
|
55
|
+
* ⚠️ 未实现: 企微转发需逆向定位并冷调"转发消息"服务(见 puppet-wework 交付说明的 RE 计划)。
|
|
56
|
+
* 当前会抛错, 以免静默失败。
|
|
57
|
+
*/
|
|
58
|
+
forward(_to: string | Room | Contact): Promise<never>;
|
|
59
|
+
toString(): string;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=message.d.ts.map
|
|
@@ -0,0 +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,OAAO,EAAE,MAAM,aAAa,CAAA;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,YAAY;AACZ,qBAAa,OAAO;IACL,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAU,QAAQ,CAAC,OAAO,EAAE,cAAc;gBAA7C,GAAG,EAAE,MAAM,EAAW,OAAO,EAAE,cAAc;IAE3E,EAAE,IAAK,MAAM,GAAG,SAAS;IACzB,IAAI,IAAK,WAAW;IACpB,IAAI,IAAK,MAAM;IACf,IAAI,IAAK,OAAO;IAChB,SAAS,IAAK,MAAM,GAAG,SAAS;IAChC,IAAI,IAAK,OAAO,GAAG,IAAI,GAAG,SAAS;IACnC,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,mBAAmB;IAO3B;;;;;OAKG;IACG,SAAS,IAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAqB3C,0CAA0C;IACpC,QAAQ,IAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI1C;;;;OAIG;IACG,OAAO,CAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC;IAI5D,QAAQ,IAAK,MAAM;CACpB"}
|