xabot-cli 1.4.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.
Files changed (116) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +126 -0
  3. package/README.zh-CN.md +126 -0
  4. package/dist/bridge/index.d.ts +93 -0
  5. package/dist/bridge/index.d.ts.map +1 -0
  6. package/dist/bridge/index.js +811 -0
  7. package/dist/bridge/index.js.map +1 -0
  8. package/dist/bridge/input-parser.d.ts +16 -0
  9. package/dist/bridge/input-parser.d.ts.map +1 -0
  10. package/dist/bridge/input-parser.js +20 -0
  11. package/dist/bridge/input-parser.js.map +1 -0
  12. package/dist/cli/chat.d.ts +38 -0
  13. package/dist/cli/chat.d.ts.map +1 -0
  14. package/dist/cli/chat.js +147 -0
  15. package/dist/cli/chat.js.map +1 -0
  16. package/dist/cli/feishu.d.ts +3 -0
  17. package/dist/cli/feishu.d.ts.map +1 -0
  18. package/dist/cli/feishu.js +79 -0
  19. package/dist/cli/feishu.js.map +1 -0
  20. package/dist/cli/health.d.ts +15 -0
  21. package/dist/cli/health.d.ts.map +1 -0
  22. package/dist/cli/health.js +26 -0
  23. package/dist/cli/health.js.map +1 -0
  24. package/dist/cli/index.d.ts +13 -0
  25. package/dist/cli/index.d.ts.map +1 -0
  26. package/dist/cli/index.js +43 -0
  27. package/dist/cli/index.js.map +1 -0
  28. package/dist/cli/run.d.ts +20 -0
  29. package/dist/cli/run.d.ts.map +1 -0
  30. package/dist/cli/run.js +43 -0
  31. package/dist/cli/run.js.map +1 -0
  32. package/dist/cli/wechat.d.ts +3 -0
  33. package/dist/cli/wechat.d.ts.map +1 -0
  34. package/dist/cli/wechat.js +86 -0
  35. package/dist/cli/wechat.js.map +1 -0
  36. package/dist/core/client.d.ts +31 -0
  37. package/dist/core/client.d.ts.map +1 -0
  38. package/dist/core/client.js +2 -0
  39. package/dist/core/client.js.map +1 -0
  40. package/dist/core/error.d.ts +11 -0
  41. package/dist/core/error.d.ts.map +1 -0
  42. package/dist/core/error.js +21 -0
  43. package/dist/core/error.js.map +1 -0
  44. package/dist/core/fs-utils.d.ts +17 -0
  45. package/dist/core/fs-utils.d.ts.map +1 -0
  46. package/dist/core/fs-utils.js +84 -0
  47. package/dist/core/fs-utils.js.map +1 -0
  48. package/dist/core/logger.d.ts +10 -0
  49. package/dist/core/logger.d.ts.map +1 -0
  50. package/dist/core/logger.js +44 -0
  51. package/dist/core/logger.js.map +1 -0
  52. package/dist/core/pairing.d.ts +10 -0
  53. package/dist/core/pairing.d.ts.map +1 -0
  54. package/dist/core/pairing.js +22 -0
  55. package/dist/core/pairing.js.map +1 -0
  56. package/dist/core/types.d.ts +50 -0
  57. package/dist/core/types.d.ts.map +1 -0
  58. package/dist/core/types.js +11 -0
  59. package/dist/core/types.js.map +1 -0
  60. package/dist/index.d.ts +13 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +9 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/platforms/feishu/client.d.ts +49 -0
  65. package/dist/platforms/feishu/client.d.ts.map +1 -0
  66. package/dist/platforms/feishu/client.js +296 -0
  67. package/dist/platforms/feishu/client.js.map +1 -0
  68. package/dist/platforms/feishu/message.d.ts +49 -0
  69. package/dist/platforms/feishu/message.d.ts.map +1 -0
  70. package/dist/platforms/feishu/message.js +131 -0
  71. package/dist/platforms/feishu/message.js.map +1 -0
  72. package/dist/platforms/feishu/upload.d.ts +11 -0
  73. package/dist/platforms/feishu/upload.d.ts.map +1 -0
  74. package/dist/platforms/feishu/upload.js +60 -0
  75. package/dist/platforms/feishu/upload.js.map +1 -0
  76. package/dist/platforms/wechat/client.d.ts +53 -0
  77. package/dist/platforms/wechat/client.d.ts.map +1 -0
  78. package/dist/platforms/wechat/client.js +301 -0
  79. package/dist/platforms/wechat/client.js.map +1 -0
  80. package/dist/platforms/wechat/crypto.d.ts +23 -0
  81. package/dist/platforms/wechat/crypto.d.ts.map +1 -0
  82. package/dist/platforms/wechat/crypto.js +46 -0
  83. package/dist/platforms/wechat/crypto.js.map +1 -0
  84. package/dist/platforms/wechat/login.d.ts +19 -0
  85. package/dist/platforms/wechat/login.d.ts.map +1 -0
  86. package/dist/platforms/wechat/login.js +71 -0
  87. package/dist/platforms/wechat/login.js.map +1 -0
  88. package/dist/platforms/wechat/message.d.ts +102 -0
  89. package/dist/platforms/wechat/message.d.ts.map +1 -0
  90. package/dist/platforms/wechat/message.js +212 -0
  91. package/dist/platforms/wechat/message.js.map +1 -0
  92. package/dist/platforms/wechat/upload.d.ts +10 -0
  93. package/dist/platforms/wechat/upload.d.ts.map +1 -0
  94. package/dist/platforms/wechat/upload.js +86 -0
  95. package/dist/platforms/wechat/upload.js.map +1 -0
  96. package/dist/xacpp/establish-handler.d.ts +58 -0
  97. package/dist/xacpp/establish-handler.d.ts.map +1 -0
  98. package/dist/xacpp/establish-handler.js +152 -0
  99. package/dist/xacpp/establish-handler.js.map +1 -0
  100. package/dist/xacpp/index.d.ts +3 -0
  101. package/dist/xacpp/index.d.ts.map +1 -0
  102. package/dist/xacpp/index.js +3 -0
  103. package/dist/xacpp/index.js.map +1 -0
  104. package/dist/xacpp/initiator-session-handler.d.ts +30 -0
  105. package/dist/xacpp/initiator-session-handler.d.ts.map +1 -0
  106. package/dist/xacpp/initiator-session-handler.js +233 -0
  107. package/dist/xacpp/initiator-session-handler.js.map +1 -0
  108. package/dist/xacpp/session-handler.d.ts +17 -0
  109. package/dist/xacpp/session-handler.d.ts.map +1 -0
  110. package/dist/xacpp/session-handler.js +27 -0
  111. package/dist/xacpp/session-handler.js.map +1 -0
  112. package/dist/xacpp/stdin-router.d.ts +23 -0
  113. package/dist/xacpp/stdin-router.d.ts.map +1 -0
  114. package/dist/xacpp/stdin-router.js +46 -0
  115. package/dist/xacpp/stdin-router.js.map +1 -0
  116. package/package.json +44 -0
@@ -0,0 +1,296 @@
1
+ import { Client, WSClient, EventDispatcher, Domain, LoggerLevel, } from '@larksuiteoapi/node-sdk';
2
+ import { StreamCapability, channelId, messageId, userId } from '../../core/types.js';
3
+ import { XabotError } from '../../core/error.js';
4
+ import { toStandardMessage, fromMessageContent } from './message.js';
5
+ import { uploadImage, uploadFile, downloadMessageResource } from './upload.js';
6
+ import { saveTemp } from '../../core/fs-utils.js';
7
+ import { createLogger } from '../../core/logger.js';
8
+ import { tmpdir } from 'node:os';
9
+ import { randomUUID } from 'node:crypto';
10
+ const log = createLogger('FeishuClient');
11
+ const DEFAULT_LOG_LEVEL = 'info';
12
+ /**
13
+ * Feishu platform client using WebSocket long connection.
14
+ *
15
+ * Uses @larksuiteoapi/node-sdk:
16
+ * - WSClient: receives incoming messages via WebSocket
17
+ * - Client: sends outgoing messages via REST API
18
+ */
19
+ export class FeishuClient {
20
+ platform = 'feishu';
21
+ config;
22
+ wsClient;
23
+ httpClient;
24
+ eventDispatcher;
25
+ messageBuffer = [];
26
+ messageResolve = null;
27
+ connected = false;
28
+ #abortCtrl = new AbortController();
29
+ activeReactions = new Map();
30
+ constructor(config) {
31
+ this.config = config;
32
+ const level = config.logLevel ?? DEFAULT_LOG_LEVEL;
33
+ const sdkLevel = level === 'trace' ? LoggerLevel.trace : level === 'debug' ? LoggerLevel.debug : LoggerLevel.info;
34
+ // Conditionally add loggerLevel – the SDK types use exactOptionalPropertyTypes
35
+ // which rejects implicit undefined, so we build the options object in two steps.
36
+ const wsBase = { appId: config.appId, appSecret: config.appSecret, domain: Domain.Feishu };
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ this.wsClient = new WSClient({
39
+ ...wsBase,
40
+ loggerLevel: sdkLevel,
41
+ onReady: () => { log.info('WSClient onReady: ws connected'); },
42
+ onError: (err) => { log.error('WSClient onError: %s', err instanceof Error ? err.message : String(err)); },
43
+ onReconnecting: () => { log.warn('WSClient onReconnecting'); },
44
+ onReconnected: () => { log.info('WSClient onReconnected'); },
45
+ });
46
+ const httpBase = { appId: config.appId, appSecret: config.appSecret, domain: Domain.Feishu };
47
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
+ this.httpClient = new Client({ ...httpBase, loggerLevel: sdkLevel });
49
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
+ this.eventDispatcher = new EventDispatcher({ loggerLevel: sdkLevel });
51
+ // Register the message receive handler — push events into a queue
52
+ // that messages() async generator will consume.
53
+ this.eventDispatcher.register({
54
+ 'im.message.receive_v1': async (data) => {
55
+ log.debug('im.message.receive_v1 received');
56
+ // If a reader is waiting, resolve immediately; otherwise buffer.
57
+ if (this.messageResolve) {
58
+ const resolve = this.messageResolve;
59
+ this.messageResolve = null;
60
+ resolve(data);
61
+ }
62
+ else {
63
+ this.messageBuffer.push(data);
64
+ }
65
+ },
66
+ });
67
+ }
68
+ // --------------------------------------------------------------------------
69
+ // PlatformClient implementation
70
+ // --------------------------------------------------------------------------
71
+ async connect() {
72
+ if (this.connected)
73
+ return;
74
+ await this.wsClient.start({ eventDispatcher: this.eventDispatcher });
75
+ this.connected = true;
76
+ // Resolve any iterator that was waiting before the connection was established.
77
+ // Pass a valid empty event so toStandardMessage() doesn't crash on undefined.
78
+ if (this.messageResolve) {
79
+ this.messageResolve({
80
+ sender: { sender_type: '' },
81
+ message: { message_id: '', chat_id: '', create_time: '', chat_type: '', message_type: '', content: '' },
82
+ });
83
+ this.messageResolve = null;
84
+ }
85
+ }
86
+ async send(chatId, content) {
87
+ if (content.type === 'text') {
88
+ return this._doSend(fromMessageContent(chatId, content));
89
+ }
90
+ const src = content.source;
91
+ if (src.localUri) {
92
+ try {
93
+ return await this._uploadAndSend(chatId, content, src.localUri);
94
+ }
95
+ catch (err) {
96
+ log.warn('upload failed (localUri), fallback to text: %s', err);
97
+ return this._doSend(fromMessageContent(chatId, { type: 'text', text: `[${content.type}]` }));
98
+ }
99
+ }
100
+ log.warn('send: %s has no localUri, sending placeholder', content.type);
101
+ return this._doSend(fromMessageContent(chatId, { type: 'text', text: `[${content.type} 无法发送]` }));
102
+ }
103
+ async _uploadAndSend(chatId, content, filePath) {
104
+ if (content.type === 'image') {
105
+ const key = await uploadImage(this.httpClient, filePath);
106
+ const effective = { ...content, source: { ...content.source, remoteUrl: key } };
107
+ return this._doSend(fromMessageContent(chatId, effective));
108
+ }
109
+ const result = await uploadFile(this.httpClient, filePath, content.source.mimeType, content.type === 'file' ? content.name : undefined);
110
+ const effective = { ...content, source: { ...content.source, remoteUrl: result.key } };
111
+ if (effective.type === 'file' && effective.name === undefined) {
112
+ effective.name = result.name;
113
+ }
114
+ return this._doSend(fromMessageContent(chatId, effective));
115
+ }
116
+ async _doSend(body) {
117
+ const result = await this.httpClient.im.message.create({
118
+ data: {
119
+ receive_id: body.receive_id,
120
+ msg_type: body.msg_type,
121
+ content: body.content,
122
+ },
123
+ params: { receive_id_type: 'chat_id' },
124
+ });
125
+ if (result.code !== 0) {
126
+ throw XabotError.platform(`Feishu API error: code=${result.code}, msg=${result.msg}`);
127
+ }
128
+ if (!result.data?.message_id) {
129
+ throw XabotError.platform('Feishu send failed: no message_id returned');
130
+ }
131
+ return messageId(result.data.message_id);
132
+ }
133
+ messages() {
134
+ return {
135
+ [Symbol.asyncIterator]: () => {
136
+ return {
137
+ next: async () => {
138
+ // If the connection was closed, stop the iterator.
139
+ if (this.#abortCtrl.signal.aborted) {
140
+ return { done: true, value: undefined };
141
+ }
142
+ // Wait for the next incoming Feishu event.
143
+ // If the buffer has events, consume them first (FIFO).
144
+ let event = this.messageBuffer.shift();
145
+ if (!event) {
146
+ event = await new Promise((resolve) => {
147
+ this.messageResolve = resolve;
148
+ });
149
+ }
150
+ // If the abort signal fired while we were waiting, stop.
151
+ if (this.#abortCtrl.signal.aborted) {
152
+ return { done: true, value: undefined };
153
+ }
154
+ const msg = toStandardMessage(event);
155
+ const content = msg.content;
156
+ if (content.type !== 'text' && content.source && !content.source.localUri) {
157
+ if (content.source.remoteUrl) {
158
+ const tmpPath = `${tmpdir()}/xabot_${randomUUID()}_${content.source.remoteUrl.replace(/\W/g, '_').slice(0, 40)}`;
159
+ try {
160
+ const resourceType = content.type === 'image' ? 'image' : 'file';
161
+ await downloadMessageResource(this.httpClient, msg.id, content.source.remoteUrl, resourceType, tmpPath);
162
+ const fileNameHint = content.type === 'file' ? content.name : undefined;
163
+ const meta = await saveTemp(tmpPath, fileNameHint);
164
+ if (!meta.mimeType) {
165
+ throw new Error(`${content.type}接收失败:无法识别文件类型`);
166
+ }
167
+ const enrichedSource = {
168
+ ...content.source,
169
+ localUri: meta.localUri,
170
+ sha256: meta.sha256,
171
+ sizeBytes: meta.sizeBytes,
172
+ mimeType: meta.mimeType,
173
+ requireOrganized: true,
174
+ };
175
+ msg.content = { ...content, source: enrichedSource };
176
+ }
177
+ catch (err) {
178
+ const reason = err instanceof Error ? err.message : String(err);
179
+ log.warn('download media failed: %s', reason);
180
+ msg.content = { type: 'text', text: `[${content.type}接收失败:${reason}]` };
181
+ msg.fallback = true;
182
+ }
183
+ }
184
+ else {
185
+ log.warn('media has no remoteUrl: type=%s', content.type);
186
+ msg.content = { type: 'text', text: `[${content.type}接收失败:缺少下载地址]` };
187
+ msg.fallback = true;
188
+ }
189
+ }
190
+ return { done: false, value: msg };
191
+ },
192
+ };
193
+ },
194
+ };
195
+ }
196
+ streamCapability() {
197
+ return StreamCapability.NonStreaming;
198
+ }
199
+ /**
200
+ * Fetch a fresh tenant_access_token from Feishu.
201
+ */
202
+ async fetchTenantToken() {
203
+ const res = await fetch('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', {
204
+ method: 'POST',
205
+ headers: { 'Content-Type': 'application/json' },
206
+ body: JSON.stringify({ app_id: this.config.appId, app_secret: this.config.appSecret }),
207
+ signal: AbortSignal.timeout(10_000),
208
+ });
209
+ if (!res.ok) {
210
+ throw XabotError.platform(`Feishu auth failed: HTTP ${res.status}`);
211
+ }
212
+ const json = (await res.json());
213
+ if (json.code !== 0 || !json.tenant_access_token) {
214
+ throw XabotError.platform(`Feishu auth failed: code=${json.code}, msg=${json.msg}`);
215
+ }
216
+ return json.tenant_access_token;
217
+ }
218
+ /**
219
+ * List subscribed event types by calling the event subscription list API.
220
+ */
221
+ async listEventSubscriptions() {
222
+ const token = await this.fetchTenantToken();
223
+ const res = await fetch('https://open.feishu.cn/open-apis/event/v1/app/event_subscription', {
224
+ headers: { Authorization: `Bearer ${token}` },
225
+ signal: AbortSignal.timeout(10_000),
226
+ });
227
+ if (!res.ok) {
228
+ throw XabotError.platform(`Feishu event subscription list failed: HTTP ${res.status}`);
229
+ }
230
+ const json = (await res.json());
231
+ if (json.code !== 0) {
232
+ throw XabotError.platform(`Feishu event subscription list failed: code=${json.code}, msg=${json.msg}`);
233
+ }
234
+ return json.data?.events ?? [];
235
+ }
236
+ async healthCheck() {
237
+ if (!this.connected) {
238
+ throw XabotError.platform('FeishuClient not connected');
239
+ }
240
+ // Verify credentials + API reachability by fetching a fresh tenant token.
241
+ await this.fetchTenantToken();
242
+ }
243
+ async setTypingIndicator(_chatId, _senderId, messageId) {
244
+ if (!messageId)
245
+ return;
246
+ const result = await this.httpClient.im.messageReaction.create({
247
+ path: { message_id: messageId },
248
+ data: { reaction_type: { emoji_type: 'Typing' } },
249
+ });
250
+ if (result?.data?.reaction_id) {
251
+ this.activeReactions.set(messageId, result.data.reaction_id);
252
+ }
253
+ }
254
+ async refreshTypingIndicator(_chatId, _senderId) {
255
+ // Feishu does not require refresh — the server maintains reactions automatically
256
+ }
257
+ async releaseTypingIndicator(_chatId, _senderId, messageId) {
258
+ if (!messageId)
259
+ return;
260
+ const reactionId = this.activeReactions.get(messageId);
261
+ if (!reactionId)
262
+ return;
263
+ try {
264
+ await this.httpClient.im.messageReaction.delete({
265
+ path: { message_id: messageId, reaction_id: reactionId },
266
+ });
267
+ }
268
+ finally {
269
+ this.activeReactions.delete(messageId);
270
+ }
271
+ }
272
+ async close() {
273
+ // Abort first so that any iterator polling abortCtrl sees the signal
274
+ // before messageResolve is cleared, preventing a race where an iterator
275
+ // sets messageResolve after the loop but before abort is called.
276
+ this.#abortCtrl.abort();
277
+ // Resolve all pending iterators so they exit cleanly instead of hanging.
278
+ while (this.messageResolve) {
279
+ const resolve = this.messageResolve;
280
+ this.messageResolve = null;
281
+ resolve({
282
+ sender: { sender_type: '' },
283
+ message: { message_id: '', chat_id: '', create_time: '', chat_type: '', message_type: '', content: '' },
284
+ });
285
+ }
286
+ for (const [messageId, reactionId] of this.activeReactions) {
287
+ await this.httpClient.im.messageReaction.delete({
288
+ path: { message_id: messageId, reaction_id: reactionId },
289
+ }).catch(() => { });
290
+ }
291
+ this.activeReactions.clear();
292
+ await this.wsClient.close({});
293
+ this.connected = false;
294
+ }
295
+ }
296
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/platforms/feishu/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { type Message, type MessageContent } from '../../core/types.js';
2
+ export interface FeishuMessageEvent {
3
+ sender: {
4
+ sender_id?: {
5
+ union_id?: string;
6
+ user_id?: string;
7
+ open_id?: string;
8
+ };
9
+ sender_type: string;
10
+ tenant_key?: string;
11
+ };
12
+ message: {
13
+ message_id: string;
14
+ root_id?: string;
15
+ parent_id?: string;
16
+ create_time: string;
17
+ update_time?: string;
18
+ chat_id: string;
19
+ thread_id?: string;
20
+ chat_type: string;
21
+ message_type: string;
22
+ content: string;
23
+ mentions?: Array<{
24
+ key: string;
25
+ id: {
26
+ union_id?: string;
27
+ user_id?: string;
28
+ open_id?: string;
29
+ };
30
+ name: string;
31
+ tenant_key?: string;
32
+ }>;
33
+ user_agent?: string;
34
+ };
35
+ }
36
+ export interface FeishuMessageBody {
37
+ receive_id: string;
38
+ msg_type: string;
39
+ content: string;
40
+ }
41
+ /** Build a Feishu message body for sending via client.im.message.create(). */
42
+ export declare function fromMessageContent(receiveId: string, content: MessageContent): FeishuMessageBody;
43
+ /**
44
+ * Convert a Feishu message receive event to a standard Message.
45
+ * The chatId is the Feishu chat_id.
46
+ * The senderId is the sender's open_id (preferred) / user_id / union_id.
47
+ */
48
+ export declare function toStandardMessage(event: FeishuMessageEvent): Message;
49
+ //# sourceMappingURL=message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../../src/platforms/feishu/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAMtG,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE;QACN,SAAS,CAAC,EAAE;YACV,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,OAAO,CAAC,EAAE,MAAM,CAAC;SAClB,CAAC;QACF,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,KAAK,CAAC;YACf,GAAG,EAAE,MAAM,CAAC;YACZ,EAAE,EAAE;gBACF,QAAQ,CAAC,EAAE,MAAM,CAAC;gBAClB,OAAO,CAAC,EAAE,MAAM,CAAC;gBACjB,OAAO,CAAC,EAAE,MAAM,CAAC;aAClB,CAAC;YACF,IAAI,EAAE,MAAM,CAAC;YACb,UAAU,CAAC,EAAE,MAAM,CAAC;SACrB,CAAC,CAAC;QACH,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAMD,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AA+BD,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,GACtB,iBAAiB,CAiBnB;AA2DD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAcpE"}
@@ -0,0 +1,131 @@
1
+ import { messageId, channelId, userId } from '../../core/types.js';
2
+ // --------------------------------------------------------------------------
3
+ // Standard Message → Feishu message body
4
+ // --------------------------------------------------------------------------
5
+ /** Convert a standard MessageContent to a Feishu message body content string. */
6
+ function contentToFeishuBody(content) {
7
+ switch (content.type) {
8
+ case 'text':
9
+ return JSON.stringify({
10
+ schema: '2.0',
11
+ body: { elements: [{ tag: 'markdown', content: content.text }] },
12
+ });
13
+ case 'image':
14
+ return JSON.stringify({ image_key: content.source.remoteUrl });
15
+ case 'audio':
16
+ // Feishu audio msg_type only accepts opus; non-opus is sent as file
17
+ if (content.source.mimeType === 'audio/opus') {
18
+ return JSON.stringify({ file_key: content.source.remoteUrl });
19
+ }
20
+ return JSON.stringify({ file_key: content.source.remoteUrl, file_name: 'audio' });
21
+ case 'video':
22
+ return JSON.stringify({ file_key: content.source.remoteUrl });
23
+ case 'file': {
24
+ const name = content.name ?? content.source.remoteUrl.split('/').pop() ?? content.source.remoteUrl;
25
+ return JSON.stringify({ file_key: content.source.remoteUrl, file_name: name });
26
+ }
27
+ }
28
+ }
29
+ /** Build a Feishu message body for sending via client.im.message.create(). */
30
+ export function fromMessageContent(receiveId, content) {
31
+ let msg_type;
32
+ switch (content.type) {
33
+ case 'text':
34
+ msg_type = 'interactive';
35
+ break;
36
+ case 'image':
37
+ msg_type = 'image';
38
+ break;
39
+ case 'audio':
40
+ // Feishu audio msg_type only accepts opus; non-opus is sent as file
41
+ msg_type = content.source.mimeType === 'audio/opus' ? 'audio' : 'file';
42
+ break;
43
+ case 'video':
44
+ msg_type = 'media';
45
+ break;
46
+ case 'file':
47
+ msg_type = 'file';
48
+ break;
49
+ }
50
+ return {
51
+ receive_id: receiveId,
52
+ msg_type,
53
+ content: contentToFeishuBody(content),
54
+ };
55
+ }
56
+ // --------------------------------------------------------------------------
57
+ // Feishu event → Standard Message
58
+ // --------------------------------------------------------------------------
59
+ function parseFeishuContent(msgType, rawContent) {
60
+ switch (msgType) {
61
+ case 'text': {
62
+ try {
63
+ const parsed = JSON.parse(rawContent);
64
+ return { type: 'text', text: parsed.text ?? '' };
65
+ }
66
+ catch {
67
+ return { type: 'text', text: rawContent };
68
+ }
69
+ }
70
+ case 'image': {
71
+ try {
72
+ const parsed = JSON.parse(rawContent);
73
+ return { type: 'image', source: { localUri: '', remoteUrl: parsed.image_key ?? '', mimeType: '', sizeBytes: 0 } };
74
+ }
75
+ catch {
76
+ return { type: 'image', source: { localUri: '', remoteUrl: '', mimeType: '', sizeBytes: 0 } };
77
+ }
78
+ }
79
+ case 'audio': {
80
+ try {
81
+ const parsed = JSON.parse(rawContent);
82
+ return { type: 'audio', source: { localUri: '', remoteUrl: parsed.file_key ?? '', mimeType: 'audio/opus', sizeBytes: 0 } };
83
+ }
84
+ catch {
85
+ return { type: 'audio', source: { localUri: '', remoteUrl: '', mimeType: 'audio/opus', sizeBytes: 0 } };
86
+ }
87
+ }
88
+ case 'media': {
89
+ try {
90
+ const parsed = JSON.parse(rawContent);
91
+ return { type: 'video', source: { localUri: '', remoteUrl: parsed.file_key ?? '', mimeType: 'video/mp4', sizeBytes: 0 } };
92
+ }
93
+ catch {
94
+ return { type: 'video', source: { localUri: '', remoteUrl: '', mimeType: 'video/mp4', sizeBytes: 0 } };
95
+ }
96
+ }
97
+ case 'file': {
98
+ try {
99
+ const parsed = JSON.parse(rawContent);
100
+ return parsed.file_name !== undefined
101
+ ? { type: 'file', source: { localUri: '', remoteUrl: parsed.file_key ?? '', mimeType: '', sizeBytes: 0 }, name: parsed.file_name }
102
+ : { type: 'file', source: { localUri: '', remoteUrl: parsed.file_key ?? '', mimeType: '', sizeBytes: 0 } };
103
+ }
104
+ catch {
105
+ return { type: 'file', source: { localUri: '', remoteUrl: '', mimeType: '', sizeBytes: 0 } };
106
+ }
107
+ }
108
+ default:
109
+ // Fallback: treat unknown types as text with the raw content
110
+ return { type: 'text', text: rawContent };
111
+ }
112
+ }
113
+ /**
114
+ * Convert a Feishu message receive event to a standard Message.
115
+ * The chatId is the Feishu chat_id.
116
+ * The senderId is the sender's open_id (preferred) / user_id / union_id.
117
+ */
118
+ export function toStandardMessage(event) {
119
+ const senderId = event.sender.sender_id?.open_id ??
120
+ event.sender.sender_id?.user_id ??
121
+ event.sender.sender_id?.union_id ??
122
+ '';
123
+ return {
124
+ id: messageId(event.message.message_id),
125
+ chatId: channelId(event.message.chat_id),
126
+ senderId: userId(senderId),
127
+ content: parseFeishuContent(event.message.message_type, event.message.content),
128
+ direction: 'incoming',
129
+ };
130
+ }
131
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../../src/platforms/feishu/message.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Client as FeishuSdkClient } from '@larksuiteoapi/node-sdk';
2
+ /** Upload an image via Feishu SDK, returning image_key. */
3
+ export declare function uploadImage(client: FeishuSdkClient, filePath: string): Promise<string>;
4
+ /** Upload a file via Feishu SDK. Returns the file_key and the actual file_name used. */
5
+ export declare function uploadFile(client: FeishuSdkClient, filePath: string, mimeType: string, displayName?: string): Promise<{
6
+ key: string;
7
+ name: string;
8
+ }>;
9
+ /** Download a resource file from a received message via im/v1/message-resource/get. */
10
+ export declare function downloadMessageResource(client: FeishuSdkClient, messageId: string, fileKey: string, type: 'image' | 'file', destPath: string): Promise<void>;
11
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../src/platforms/feishu/upload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAmBzE,2DAA2D;AAC3D,wBAAsB,WAAW,CAC/B,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAcjB;AAED,wFAAwF;AACxF,wBAAsB,UAAU,CAC9B,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAgBxC;AAED,uFAAuF;AACvF,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,OAAO,GAAG,MAAM,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAUf"}
@@ -0,0 +1,60 @@
1
+ import { createReadStream } from 'node:fs';
2
+ import { mkdir } from 'node:fs/promises';
3
+ import { basename, dirname } from 'node:path';
4
+ import { createLogger } from '../../core/logger.js';
5
+ const log = createLogger('FeishuUpload');
6
+ function mimeToFileType(mimeType) {
7
+ const lower = mimeType.toLowerCase();
8
+ if (lower.includes('opus'))
9
+ return 'opus';
10
+ if (lower.includes('mp4'))
11
+ return 'mp4';
12
+ if (lower.includes('pdf'))
13
+ return 'pdf';
14
+ if (lower.includes('word') || lower.includes('doc'))
15
+ return 'doc';
16
+ if (lower.includes('excel') || lower.includes('sheet') || lower.includes('xls'))
17
+ return 'xls';
18
+ return 'stream';
19
+ }
20
+ /** Upload an image via Feishu SDK, returning image_key. */
21
+ export async function uploadImage(client, filePath) {
22
+ const result = await client.im.image.create({
23
+ data: {
24
+ image_type: 'message',
25
+ image: createReadStream(filePath),
26
+ },
27
+ });
28
+ if (!result?.image_key) {
29
+ throw new Error('Feishu image upload failed: no image_key returned');
30
+ }
31
+ log.debug('upload image: %s → %s', filePath, result.image_key);
32
+ return result.image_key;
33
+ }
34
+ /** Upload a file via Feishu SDK. Returns the file_key and the actual file_name used. */
35
+ export async function uploadFile(client, filePath, mimeType, displayName) {
36
+ const name = displayName || basename(filePath);
37
+ const result = await client.im.file.create({
38
+ data: {
39
+ file_type: mimeToFileType(mimeType),
40
+ file_name: name,
41
+ file: createReadStream(filePath),
42
+ },
43
+ });
44
+ if (!result?.file_key) {
45
+ throw new Error('Feishu file upload failed: no file_key returned');
46
+ }
47
+ log.debug('upload file: %s → %s (name=%s)', filePath, result.file_key, name);
48
+ return { key: result.file_key, name };
49
+ }
50
+ /** Download a resource file from a received message via im/v1/message-resource/get. */
51
+ export async function downloadMessageResource(client, messageId, fileKey, type, destPath) {
52
+ const result = await client.im.messageResource.get({
53
+ params: { type },
54
+ path: { message_id: messageId, file_key: fileKey },
55
+ });
56
+ await mkdir(dirname(destPath), { recursive: true });
57
+ await result.writeFile(destPath);
58
+ log.debug('download message resource: %s/%s (%s) → %s', messageId, fileKey, type, destPath);
59
+ }
60
+ //# sourceMappingURL=upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/platforms/feishu/upload.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { PlatformClient } from '../../core/client.js';
2
+ import type { ChannelId, MessageId, UserId, Message, MessageContent } from '../../core/types.js';
3
+ import { StreamCapability } from '../../core/types.js';
4
+ export interface WechatConfig {
5
+ /** bot_token — 扫码登录后获得 */
6
+ token: string;
7
+ /** API 基座地址,默认 https://ilinkai.weixin.qq.com */
8
+ baseUrl?: string;
9
+ /** 长轮询超时,默认 35000ms */
10
+ longPollTimeoutMs?: number;
11
+ /** Token 过期时自动重新扫码的回调 */
12
+ onTokenExpired?: () => Promise<string>;
13
+ }
14
+ /**
15
+ * WeChat iLink Bot platform client using HTTP long polling.
16
+ *
17
+ * Connects to ilinkai.weixin.qq.com:
18
+ * - Long-polls POST /ilink/bot/getupdates for incoming messages
19
+ * - Sends messages via POST /ilink/bot/sendmessage
20
+ */
21
+ export declare class WechatClient implements PlatformClient {
22
+ readonly platform: "wechat";
23
+ private readonly config;
24
+ private token;
25
+ private readonly baseUrl;
26
+ private readonly pollTimeoutMs;
27
+ private readonly xWechatUin;
28
+ private getUpdatesBuf;
29
+ private readonly contextTokenStore;
30
+ private readonly messageBuffer;
31
+ private messageResolve;
32
+ private readonly typingTickets;
33
+ private connected;
34
+ private abortCtrl;
35
+ constructor(config: WechatConfig);
36
+ private post;
37
+ connect(): Promise<void>;
38
+ private pollLoop;
39
+ send(chatId: ChannelId, content: MessageContent): Promise<MessageId>;
40
+ private _sendBody;
41
+ messages(): AsyncIterable<Message>;
42
+ /** Replace token and reset poll state — used after token renewal. */
43
+ renewToken(newToken: string): void;
44
+ streamCapability(): StreamCapability;
45
+ healthCheck(): Promise<void>;
46
+ private fetchTypingTicket;
47
+ private sendTypingStatus;
48
+ setTypingIndicator(_chatId: ChannelId, senderId: UserId, _messageId?: MessageId): Promise<void>;
49
+ refreshTypingIndicator(_chatId: ChannelId, senderId: UserId): Promise<void>;
50
+ releaseTypingIndicator(_chatId: ChannelId, senderId: UserId, _messageId?: MessageId): Promise<void>;
51
+ close(): Promise<void>;
52
+ }
53
+ //# sourceMappingURL=client.d.ts.map