@xwang152/claw-lark 0.1.11 → 0.1.13
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 +39 -126
- package/README_zh.md +29 -100
- package/dist/index.d.ts +21 -0
- package/{index.ts → dist/index.js} +9 -24
- package/dist/index.js.map +1 -0
- package/dist/src/channel.d.ts +12 -0
- package/dist/src/channel.js +362 -0
- package/dist/src/channel.js.map +1 -0
- package/dist/src/client.d.ts +31 -0
- package/dist/src/client.js +84 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/monitor.d.ts +36 -0
- package/dist/src/monitor.js +212 -0
- package/dist/src/monitor.js.map +1 -0
- package/dist/src/runtime.d.ts +23 -0
- package/dist/src/runtime.js +33 -0
- package/dist/src/runtime.js.map +1 -0
- package/dist/src/types.d.ts +136 -0
- package/dist/src/types.js +8 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/webhook.d.ts +22 -0
- package/dist/src/webhook.js +131 -0
- package/dist/src/webhook.js.map +1 -0
- package/package.json +9 -1
- package/.eslintrc.json +0 -18
- package/.github/workflows/npm-publish.yml +0 -39
- package/.prettierrc +0 -7
- package/eslint.config.js +0 -34
- package/src/__tests__/sample.test.ts +0 -7
- package/src/openclaw-plugin-sdk.d.ts +0 -28
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lark Channel Plugin
|
|
3
|
+
*
|
|
4
|
+
* Implements the ChannelPlugin interface for Lark/Feishu integration.
|
|
5
|
+
* Provides account configuration, message sending, and gateway management.
|
|
6
|
+
*/
|
|
7
|
+
import { createLarkClient } from "./client.js";
|
|
8
|
+
import { getLarkRuntime } from "./runtime.js";
|
|
9
|
+
import { monitorLarkProvider } from "./monitor.js";
|
|
10
|
+
// Default values for account configuration
|
|
11
|
+
const DEFAULTS = {
|
|
12
|
+
domain: "feishu",
|
|
13
|
+
connectionMode: "websocket",
|
|
14
|
+
webhookPort: 3000,
|
|
15
|
+
dmPolicy: "pairing",
|
|
16
|
+
groupPolicy: "open",
|
|
17
|
+
requireMention: true,
|
|
18
|
+
mediaMaxMb: 30,
|
|
19
|
+
renderMode: "auto",
|
|
20
|
+
historyLimit: 10,
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Extract Feishu channel config from OpenClaw config
|
|
24
|
+
*/
|
|
25
|
+
function getChannelConfig(cfg) {
|
|
26
|
+
return cfg.channels?.feishu ?? {};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get account config from channel config, with empty object fallback
|
|
30
|
+
*/
|
|
31
|
+
function getAccountConfig(channelConfig, accountId) {
|
|
32
|
+
return channelConfig.accounts?.[accountId] ?? {};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Check if default account has env var credentials configured
|
|
36
|
+
*/
|
|
37
|
+
function hasEnvCredentials() {
|
|
38
|
+
return Boolean(process.env.LARK_APP_ID && process.env.LARK_APP_SECRET);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Resolve account configuration with defaults and env fallbacks.
|
|
42
|
+
* For "default" account, environment variables take precedence.
|
|
43
|
+
*/
|
|
44
|
+
function resolveAccount(cfg, accountId) {
|
|
45
|
+
const channelConfig = getChannelConfig(cfg);
|
|
46
|
+
const accountConfig = getAccountConfig(channelConfig, accountId);
|
|
47
|
+
// Resolve credentials - env vars as fallback for default account
|
|
48
|
+
const isDefault = accountId === "default";
|
|
49
|
+
const appId = accountConfig.appId ?? (isDefault ? process.env.LARK_APP_ID : undefined);
|
|
50
|
+
const appSecret = accountConfig.appSecret ?? (isDefault ? process.env.LARK_APP_SECRET : undefined);
|
|
51
|
+
const encryptKey = accountConfig.encryptKey ?? (isDefault ? process.env.LARK_ENCRYPT_KEY : undefined);
|
|
52
|
+
const verificationToken = accountConfig.verificationToken ?? (isDefault ? process.env.LARK_VERIFICATION_TOKEN : undefined);
|
|
53
|
+
const configured = Boolean(appId?.trim() && appSecret?.trim());
|
|
54
|
+
return {
|
|
55
|
+
accountId,
|
|
56
|
+
enabled: accountConfig.enabled ?? true,
|
|
57
|
+
configured,
|
|
58
|
+
appId: appId ?? "",
|
|
59
|
+
appSecret: appSecret ?? "",
|
|
60
|
+
encryptKey,
|
|
61
|
+
verificationToken,
|
|
62
|
+
domain: accountConfig.domain ?? DEFAULTS.domain,
|
|
63
|
+
connectionMode: accountConfig.connectionMode ?? DEFAULTS.connectionMode,
|
|
64
|
+
webhookPort: accountConfig.webhookPort ?? DEFAULTS.webhookPort,
|
|
65
|
+
dmPolicy: accountConfig.dmPolicy ?? DEFAULTS.dmPolicy,
|
|
66
|
+
dmAllowlist: accountConfig.dmAllowlist ?? [],
|
|
67
|
+
groupPolicy: accountConfig.groupPolicy ?? DEFAULTS.groupPolicy,
|
|
68
|
+
requireMention: accountConfig.requireMention ?? DEFAULTS.requireMention,
|
|
69
|
+
groupAllowlist: accountConfig.groupAllowlist ?? [],
|
|
70
|
+
mediaMaxMb: accountConfig.mediaMaxMb ?? DEFAULTS.mediaMaxMb,
|
|
71
|
+
renderMode: accountConfig.renderMode ?? DEFAULTS.renderMode,
|
|
72
|
+
historyLimit: accountConfig.historyLimit ?? DEFAULTS.historyLimit,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Determine receive_id_type from recipient ID format.
|
|
77
|
+
* IDs starting with "oc_" are chat IDs, otherwise open IDs.
|
|
78
|
+
*/
|
|
79
|
+
function inferReceiveIdType(recipientId) {
|
|
80
|
+
return recipientId.startsWith("oc_") ? "chat_id" : "open_id";
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Send a message via Lark API, supporting text and interactive cards.
|
|
84
|
+
*/
|
|
85
|
+
async function sendTextMessage(account, recipientId, text, threadId) {
|
|
86
|
+
try {
|
|
87
|
+
const client = createLarkClient(account);
|
|
88
|
+
const renderMode = account.renderMode;
|
|
89
|
+
// Determine if we should use a card
|
|
90
|
+
const useCard = renderMode === "card" ||
|
|
91
|
+
(renderMode === "auto" && (text.includes("```") || text.includes("| --- |") || text.includes("\n- ")));
|
|
92
|
+
let msgType;
|
|
93
|
+
let content;
|
|
94
|
+
if (useCard) {
|
|
95
|
+
msgType = "interactive";
|
|
96
|
+
// Simple Markdown card
|
|
97
|
+
content = JSON.stringify({
|
|
98
|
+
header: {
|
|
99
|
+
title: {
|
|
100
|
+
tag: "plain_text",
|
|
101
|
+
content: "OpenClaw",
|
|
102
|
+
},
|
|
103
|
+
template: "blue",
|
|
104
|
+
},
|
|
105
|
+
elements: [
|
|
106
|
+
{
|
|
107
|
+
tag: "div",
|
|
108
|
+
text: {
|
|
109
|
+
tag: "lark_md",
|
|
110
|
+
content: text,
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
msgType = "text";
|
|
118
|
+
// Transform <at id="xxx">@Name</at> to Lark's plain text mention format: <at user_id="xxx">@Name</at>
|
|
119
|
+
const transformedText = text.replace(/<at id="([^"]+)">(@[^<]+)<\/at>/g, '<at user_id="$1">$2</at>');
|
|
120
|
+
content = JSON.stringify({ text: transformedText });
|
|
121
|
+
}
|
|
122
|
+
const response = await client.im.message.create({
|
|
123
|
+
params: {
|
|
124
|
+
receive_id_type: inferReceiveIdType(recipientId),
|
|
125
|
+
},
|
|
126
|
+
data: {
|
|
127
|
+
receive_id: recipientId,
|
|
128
|
+
msg_type: msgType,
|
|
129
|
+
content,
|
|
130
|
+
...(threadId && { root_id: threadId }),
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
if (response.code === 0 && response.data) {
|
|
134
|
+
return { ok: true, messageId: response.data.message_id };
|
|
135
|
+
}
|
|
136
|
+
return { ok: false, error: response.msg ?? "Unknown error" };
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
return {
|
|
140
|
+
ok: false,
|
|
141
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* List available chat groups
|
|
147
|
+
*/
|
|
148
|
+
async function listGroups(account) {
|
|
149
|
+
try {
|
|
150
|
+
const client = createLarkClient(account);
|
|
151
|
+
const response = await client.im.chat.list({
|
|
152
|
+
params: { page_size: 100 },
|
|
153
|
+
});
|
|
154
|
+
if (response.code === 0 && response.data?.items) {
|
|
155
|
+
return response.data.items.map((chat) => ({
|
|
156
|
+
id: chat.chat_id ?? "",
|
|
157
|
+
name: chat.name ?? "Unknown",
|
|
158
|
+
}));
|
|
159
|
+
}
|
|
160
|
+
return [];
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Lark/Feishu channel plugin implementation
|
|
168
|
+
*/
|
|
169
|
+
export const larkPlugin = {
|
|
170
|
+
id: "feishu",
|
|
171
|
+
meta: {
|
|
172
|
+
label: "Feishu",
|
|
173
|
+
selectionLabel: "Feishu / Lark",
|
|
174
|
+
docsPath: "/channels/feishu",
|
|
175
|
+
blurb: "Chat with your OpenClaw bot on Feishu or Lark",
|
|
176
|
+
order: 75,
|
|
177
|
+
},
|
|
178
|
+
capabilities: {
|
|
179
|
+
chatTypes: ["direct", "group"],
|
|
180
|
+
reactions: false,
|
|
181
|
+
threads: true,
|
|
182
|
+
media: true,
|
|
183
|
+
nativeCommands: false,
|
|
184
|
+
streamingBlocked: false,
|
|
185
|
+
},
|
|
186
|
+
config: {
|
|
187
|
+
listAccountIds(cfg) {
|
|
188
|
+
const channelConfig = getChannelConfig(cfg);
|
|
189
|
+
const accountIds = Object.keys(channelConfig.accounts ?? {});
|
|
190
|
+
// Include default account if env vars are configured
|
|
191
|
+
if (!accountIds.includes("default") && hasEnvCredentials()) {
|
|
192
|
+
accountIds.push("default");
|
|
193
|
+
}
|
|
194
|
+
return accountIds;
|
|
195
|
+
},
|
|
196
|
+
resolveAccount(cfg, accountId) {
|
|
197
|
+
return resolveAccount(cfg, accountId ?? "default");
|
|
198
|
+
},
|
|
199
|
+
isConfigured(account) {
|
|
200
|
+
return account.configured;
|
|
201
|
+
},
|
|
202
|
+
setAccountEnabled(cfg, accountId, enabled) {
|
|
203
|
+
const channelConfig = getChannelConfig(cfg);
|
|
204
|
+
return {
|
|
205
|
+
...cfg,
|
|
206
|
+
channels: {
|
|
207
|
+
...cfg.channels,
|
|
208
|
+
lark: {
|
|
209
|
+
...channelConfig,
|
|
210
|
+
accounts: {
|
|
211
|
+
...channelConfig.accounts,
|
|
212
|
+
[accountId]: {
|
|
213
|
+
...channelConfig.accounts?.[accountId],
|
|
214
|
+
enabled,
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
outbound: {
|
|
223
|
+
deliveryMode: "direct",
|
|
224
|
+
textChunkLimit: 4000,
|
|
225
|
+
chunkerMode: "markdown",
|
|
226
|
+
async sendText(args) {
|
|
227
|
+
const { account, recipientId, text, threadId } = args;
|
|
228
|
+
return sendTextMessage(account, recipientId, text, threadId);
|
|
229
|
+
},
|
|
230
|
+
async sendMedia(args) {
|
|
231
|
+
const { account, recipientId, mediaId, mediaType, fileName, threadId } = args;
|
|
232
|
+
try {
|
|
233
|
+
const client = createLarkClient(account);
|
|
234
|
+
const response = await client.im.message.create({
|
|
235
|
+
params: {
|
|
236
|
+
receive_id_type: inferReceiveIdType(recipientId),
|
|
237
|
+
},
|
|
238
|
+
data: {
|
|
239
|
+
receive_id: recipientId,
|
|
240
|
+
msg_type: mediaType === "image" ? "image" : "file",
|
|
241
|
+
content: JSON.stringify(mediaType === "image" ? { image_key: mediaId } : { file_key: mediaId, file_name: fileName }),
|
|
242
|
+
...(threadId && { root_id: threadId }),
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
if (response.code === 0 && response.data) {
|
|
246
|
+
return { ok: true, messageId: response.data.message_id };
|
|
247
|
+
}
|
|
248
|
+
return { ok: false, error: response.msg ?? "Unknown error" };
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
return {
|
|
252
|
+
ok: false,
|
|
253
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
async downloadMedia(args) {
|
|
258
|
+
const { account, mediaId, messageId } = args;
|
|
259
|
+
try {
|
|
260
|
+
const client = createLarkClient(account);
|
|
261
|
+
// For Lark, we usually need the message ID to get the file
|
|
262
|
+
if (!messageId)
|
|
263
|
+
return null;
|
|
264
|
+
const response = await client.im.messageResource.get({
|
|
265
|
+
path: {
|
|
266
|
+
message_id: messageId,
|
|
267
|
+
file_key: mediaId,
|
|
268
|
+
},
|
|
269
|
+
params: {
|
|
270
|
+
type: args.mediaType,
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
if (response instanceof Buffer) {
|
|
274
|
+
return response;
|
|
275
|
+
}
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
gateway: {
|
|
284
|
+
async startAccount(args) {
|
|
285
|
+
const { account, abortSignal } = args;
|
|
286
|
+
const api = getLarkRuntime();
|
|
287
|
+
if (!account.configured) {
|
|
288
|
+
api.logger.warn(`[feishu] Account ${account.accountId} not configured`);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (!account.enabled) {
|
|
292
|
+
api.logger.debug(`[feishu] Account ${account.accountId} disabled`);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
api.logger.info(`[feishu] Starting provider: account=${account.accountId}, mode=${account.connectionMode}, domain=${account.domain}`);
|
|
296
|
+
await monitorLarkProvider({ account, abortSignal });
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
directory: {
|
|
300
|
+
async listPeers(account) {
|
|
301
|
+
try {
|
|
302
|
+
const client = createLarkClient(account);
|
|
303
|
+
const response = await client.contact.user.list({
|
|
304
|
+
params: { page_size: 50 },
|
|
305
|
+
});
|
|
306
|
+
if (response.code === 0 && response.data?.items) {
|
|
307
|
+
return response.data.items.map((user) => ({
|
|
308
|
+
id: user.open_id,
|
|
309
|
+
name: user.name,
|
|
310
|
+
}));
|
|
311
|
+
}
|
|
312
|
+
return [];
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
return [];
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
async listGroups(account) {
|
|
319
|
+
return listGroups(account);
|
|
320
|
+
},
|
|
321
|
+
async resolveSelf() {
|
|
322
|
+
return null;
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
dmPolicy: {
|
|
326
|
+
mode(cfg) {
|
|
327
|
+
const channelConfig = getChannelConfig(cfg);
|
|
328
|
+
return channelConfig.accounts?.default?.dmPolicy ?? DEFAULTS.dmPolicy;
|
|
329
|
+
},
|
|
330
|
+
allowlist(cfg) {
|
|
331
|
+
const channelConfig = getChannelConfig(cfg);
|
|
332
|
+
return channelConfig.accounts?.default?.dmAllowlist ?? [];
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
groupPolicy: {
|
|
336
|
+
mode(cfg) {
|
|
337
|
+
const channelConfig = getChannelConfig(cfg);
|
|
338
|
+
return channelConfig.accounts?.default?.groupPolicy ?? DEFAULTS.groupPolicy;
|
|
339
|
+
},
|
|
340
|
+
mentionGated(cfg) {
|
|
341
|
+
const channelConfig = getChannelConfig(cfg);
|
|
342
|
+
return channelConfig.accounts?.default?.requireMention ?? DEFAULTS.requireMention;
|
|
343
|
+
},
|
|
344
|
+
allowlist(cfg) {
|
|
345
|
+
const channelConfig = getChannelConfig(cfg);
|
|
346
|
+
return channelConfig.accounts?.default?.groupAllowlist ?? [];
|
|
347
|
+
},
|
|
348
|
+
},
|
|
349
|
+
setup: {
|
|
350
|
+
validate(account) {
|
|
351
|
+
const errors = [];
|
|
352
|
+
if (!account.appId?.trim()) {
|
|
353
|
+
errors.push("App ID is required. Set via channels.lark.accounts.<id>.appId or LARK_APP_ID env var.");
|
|
354
|
+
}
|
|
355
|
+
if (!account.appSecret?.trim()) {
|
|
356
|
+
errors.push("App Secret is required. Set via channels.lark.accounts.<id>.appSecret or LARK_APP_SECRET env var.");
|
|
357
|
+
}
|
|
358
|
+
return errors;
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
};
|
|
362
|
+
//# sourceMappingURL=channel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/channel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lark SDK Client Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates and caches Lark API clients. Supports both REST API
|
|
5
|
+
* and WebSocket clients for different use cases.
|
|
6
|
+
*/
|
|
7
|
+
import * as Lark from "@larksuiteoapi/node-sdk";
|
|
8
|
+
import type { ResolvedLarkAccount } from "./types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Create or retrieve a cached Lark REST API client.
|
|
11
|
+
*
|
|
12
|
+
* Clients are cached by appId + appSecret + domain to allow
|
|
13
|
+
* efficient reuse across multiple calls with the same account.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createLarkClient(account: ResolvedLarkAccount): Lark.Client;
|
|
16
|
+
/**
|
|
17
|
+
* Create a Lark WebSocket client for long-lived connections.
|
|
18
|
+
*
|
|
19
|
+
* WebSocket clients are NOT cached because they manage their own
|
|
20
|
+
* connection lifecycle and should be created fresh for each session.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createLarkWSClient(account: ResolvedLarkAccount): Lark.WSClient;
|
|
23
|
+
/**
|
|
24
|
+
* Create an event dispatcher for handling Lark webhook/websocket events.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createEventDispatcher(encryptKey?: string, verificationToken?: string): Lark.EventDispatcher;
|
|
27
|
+
/**
|
|
28
|
+
* Clear all cached clients.
|
|
29
|
+
* Useful for testing or when credentials change.
|
|
30
|
+
*/
|
|
31
|
+
export declare function clearClientCache(): void;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lark SDK Client Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates and caches Lark API clients. Supports both REST API
|
|
5
|
+
* and WebSocket clients for different use cases.
|
|
6
|
+
*/
|
|
7
|
+
import * as Lark from "@larksuiteoapi/node-sdk";
|
|
8
|
+
// REST client cache - keyed by appId:appSecret:domain
|
|
9
|
+
const clientCache = new Map();
|
|
10
|
+
/**
|
|
11
|
+
* Convert domain string to Lark SDK enum
|
|
12
|
+
*/
|
|
13
|
+
function toLarkDomain(domain) {
|
|
14
|
+
return domain === "feishu" ? Lark.Domain.Feishu : Lark.Domain.Lark;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Generate cache key for an account
|
|
18
|
+
*/
|
|
19
|
+
function cacheKey(account) {
|
|
20
|
+
return `${account.appId}:${account.appSecret}:${account.domain}`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Validate account has required credentials
|
|
24
|
+
*/
|
|
25
|
+
function validateCredentials(account) {
|
|
26
|
+
if (!account.appId || !account.appSecret) {
|
|
27
|
+
throw new Error("Lark appId and appSecret are required");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create or retrieve a cached Lark REST API client.
|
|
32
|
+
*
|
|
33
|
+
* Clients are cached by appId + appSecret + domain to allow
|
|
34
|
+
* efficient reuse across multiple calls with the same account.
|
|
35
|
+
*/
|
|
36
|
+
export function createLarkClient(account) {
|
|
37
|
+
validateCredentials(account);
|
|
38
|
+
const key = cacheKey(account);
|
|
39
|
+
const cached = clientCache.get(key);
|
|
40
|
+
if (cached) {
|
|
41
|
+
return cached;
|
|
42
|
+
}
|
|
43
|
+
const client = new Lark.Client({
|
|
44
|
+
appId: account.appId,
|
|
45
|
+
appSecret: account.appSecret,
|
|
46
|
+
appType: Lark.AppType.SelfBuild,
|
|
47
|
+
domain: toLarkDomain(account.domain),
|
|
48
|
+
});
|
|
49
|
+
clientCache.set(key, client);
|
|
50
|
+
return client;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Create a Lark WebSocket client for long-lived connections.
|
|
54
|
+
*
|
|
55
|
+
* WebSocket clients are NOT cached because they manage their own
|
|
56
|
+
* connection lifecycle and should be created fresh for each session.
|
|
57
|
+
*/
|
|
58
|
+
export function createLarkWSClient(account) {
|
|
59
|
+
validateCredentials(account);
|
|
60
|
+
return new Lark.WSClient({
|
|
61
|
+
appId: account.appId,
|
|
62
|
+
appSecret: account.appSecret,
|
|
63
|
+
domain: toLarkDomain(account.domain),
|
|
64
|
+
loggerLevel: Lark.LoggerLevel.info,
|
|
65
|
+
autoReconnect: true,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create an event dispatcher for handling Lark webhook/websocket events.
|
|
70
|
+
*/
|
|
71
|
+
export function createEventDispatcher(encryptKey, verificationToken) {
|
|
72
|
+
return new Lark.EventDispatcher({
|
|
73
|
+
encryptKey,
|
|
74
|
+
verificationToken,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Clear all cached clients.
|
|
79
|
+
* Useful for testing or when credentials change.
|
|
80
|
+
*/
|
|
81
|
+
export function clearClientCache() {
|
|
82
|
+
clientCache.clear();
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,IAAI,MAAM,yBAAyB,CAAC;AAOhD,sDAAsD;AACtD,MAAM,WAAW,GAAG,IAAI,GAAG,EAA+B,CAAC;AAE3D;;GAEG;AACH,SAAS,YAAY,CAAC,MAAkB;IACtC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,OAA4B;IAC5C,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,OAA4B;IACvD,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAA4B;IAC3D,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAE7B,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC;QAC7B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;QAC/B,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC;KACrC,CAAC,CAAC;IAEH,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAA4B;IAC7D,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAE7B,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC;QACvB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC;QACpC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;QAClC,aAAa,EAAE,IAAI;KACpB,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,UAAmB,EACnB,iBAA0B;IAE1B,OAAO,IAAI,IAAI,CAAC,eAAe,CAAC;QAC9B,UAAU;QACV,iBAAiB;KAClB,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,WAAW,CAAC,KAAK,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lark Message Monitor
|
|
3
|
+
*
|
|
4
|
+
* Listens for incoming messages via WebSocket or webhook
|
|
5
|
+
* and routes them to the OpenClaw message handler.
|
|
6
|
+
*/
|
|
7
|
+
import type { ResolvedLarkAccount, LarkMessageEvent, ParsedMessage } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Extract plain text from Lark message content.
|
|
10
|
+
* Handles different message types (text, post/rich-text).
|
|
11
|
+
*/
|
|
12
|
+
export declare function extractText(content: string, messageType: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Parse Lark message event into normalized format.
|
|
15
|
+
* Returns null for empty or invalid messages.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseMessage(event: LarkMessageEvent): ParsedMessage | null;
|
|
18
|
+
/**
|
|
19
|
+
* Route incoming message to OpenClaw handler.
|
|
20
|
+
*/
|
|
21
|
+
export declare function routeMessage(event: LarkMessageEvent, account: ResolvedLarkAccount): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Start monitoring for Lark messages.
|
|
24
|
+
*
|
|
25
|
+
* Supports both WebSocket and webhook modes:
|
|
26
|
+
* - WebSocket: Long connection (enterprise accounts)
|
|
27
|
+
* - Webhook: HTTP callback (individual accounts, requires ngrok)
|
|
28
|
+
*/
|
|
29
|
+
export declare function monitorLarkProvider(options: {
|
|
30
|
+
account: ResolvedLarkAccount;
|
|
31
|
+
abortSignal?: AbortSignal;
|
|
32
|
+
}): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Stop the active monitor connection.
|
|
35
|
+
*/
|
|
36
|
+
export declare function stopMonitor(): void;
|