moltbot-feishu 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 +21 -0
- package/README.md +99 -0
- package/clawdbot.plugin.json +33 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/src/accounts.d.ts +17 -0
- package/dist/src/accounts.d.ts.map +1 -0
- package/dist/src/accounts.js +81 -0
- package/dist/src/accounts.js.map +1 -0
- package/dist/src/channel.d.ts +8 -0
- package/dist/src/channel.d.ts.map +1 -0
- package/dist/src/channel.js +373 -0
- package/dist/src/channel.js.map +1 -0
- package/dist/src/config-schema.d.ts +157 -0
- package/dist/src/config-schema.d.ts.map +1 -0
- package/dist/src/config-schema.js +21 -0
- package/dist/src/config-schema.js.map +1 -0
- package/dist/src/dedup.d.ts +8 -0
- package/dist/src/dedup.d.ts.map +1 -0
- package/dist/src/dedup.js +25 -0
- package/dist/src/dedup.js.map +1 -0
- package/dist/src/group-filter.d.ts +15 -0
- package/dist/src/group-filter.d.ts.map +1 -0
- package/dist/src/group-filter.js +44 -0
- package/dist/src/group-filter.js.map +1 -0
- package/dist/src/media.d.ts +21 -0
- package/dist/src/media.d.ts.map +1 -0
- package/dist/src/media.js +133 -0
- package/dist/src/media.js.map +1 -0
- package/dist/src/onboarding.d.ts +51 -0
- package/dist/src/onboarding.d.ts.map +1 -0
- package/dist/src/onboarding.js +213 -0
- package/dist/src/onboarding.js.map +1 -0
- package/dist/src/probe.d.ts +10 -0
- package/dist/src/probe.d.ts.map +1 -0
- package/dist/src/probe.js +48 -0
- package/dist/src/probe.js.map +1 -0
- package/dist/src/receive.d.ts +25 -0
- package/dist/src/receive.d.ts.map +1 -0
- package/dist/src/receive.js +217 -0
- package/dist/src/receive.js.map +1 -0
- package/dist/src/runtime.d.ts +7 -0
- package/dist/src/runtime.d.ts.map +1 -0
- package/dist/src/runtime.js +14 -0
- package/dist/src/runtime.js.map +1 -0
- package/dist/src/send.d.ts +23 -0
- package/dist/src/send.d.ts.map +1 -0
- package/dist/src/send.js +158 -0
- package/dist/src/send.js.map +1 -0
- package/dist/src/status-issues.d.ts +7 -0
- package/dist/src/status-issues.d.ts.map +1 -0
- package/dist/src/status-issues.js +48 -0
- package/dist/src/status-issues.js.map +1 -0
- package/dist/src/types.d.ts +62 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +5 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +93 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feishu WebSocket message receive handler.
|
|
3
|
+
*
|
|
4
|
+
* Connects to Feishu via the SDK's WSClient, dispatches incoming
|
|
5
|
+
* messages to Clawdbot's channel reply infrastructure.
|
|
6
|
+
*/
|
|
7
|
+
import * as Lark from "@larksuiteoapi/node-sdk";
|
|
8
|
+
import { isDuplicate } from "./dedup.js";
|
|
9
|
+
import { shouldRespondInGroup } from "./group-filter.js";
|
|
10
|
+
import { sendTextMessage, updateMessage, deleteMessage } from "./send.js";
|
|
11
|
+
import { sendMediaMessage } from "./send.js";
|
|
12
|
+
import { getFeishuRuntime } from "./runtime.js";
|
|
13
|
+
/** Start the Feishu WebSocket provider. Returns a stop function. */
|
|
14
|
+
export function startFeishuProvider(options) {
|
|
15
|
+
const { account, config, log, statusSink } = options;
|
|
16
|
+
const { appId, appSecret } = account;
|
|
17
|
+
const thinkingThresholdMs = account.config.thinkingThresholdMs ?? 2500;
|
|
18
|
+
const botNames = account.config.botNames;
|
|
19
|
+
log.info(`[feishu:${account.accountId}] Starting WebSocket provider (appId=${appId})`);
|
|
20
|
+
const sdkConfig = {
|
|
21
|
+
appId,
|
|
22
|
+
appSecret,
|
|
23
|
+
domain: Lark.Domain.Feishu,
|
|
24
|
+
appType: Lark.AppType.SelfBuild,
|
|
25
|
+
};
|
|
26
|
+
const client = new Lark.Client(sdkConfig);
|
|
27
|
+
const dispatcher = new Lark.EventDispatcher({}).register({
|
|
28
|
+
"im.message.receive_v1": async (data) => {
|
|
29
|
+
try {
|
|
30
|
+
await handleIncomingMessage(data, {
|
|
31
|
+
client,
|
|
32
|
+
account,
|
|
33
|
+
config,
|
|
34
|
+
log,
|
|
35
|
+
thinkingThresholdMs,
|
|
36
|
+
botNames,
|
|
37
|
+
statusSink,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
log.error(`[feishu:${account.accountId}] Message handler error: ${err instanceof Error ? err.message : String(err)}`);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
const wsClient = new Lark.WSClient({
|
|
46
|
+
...sdkConfig,
|
|
47
|
+
loggerLevel: Lark.LoggerLevel.info,
|
|
48
|
+
});
|
|
49
|
+
wsClient.start({ eventDispatcher: dispatcher });
|
|
50
|
+
log.info(`[feishu:${account.accountId}] WebSocket client started`);
|
|
51
|
+
statusSink?.({ running: true, lastStartAt: Date.now() });
|
|
52
|
+
const stop = () => {
|
|
53
|
+
log.info(`[feishu:${account.accountId}] Stopping WebSocket provider`);
|
|
54
|
+
// Lark SDK WSClient doesn't expose a clean stop method;
|
|
55
|
+
// rely on abort signal and GC.
|
|
56
|
+
statusSink?.({ running: false, lastStopAt: Date.now() });
|
|
57
|
+
};
|
|
58
|
+
return { stop };
|
|
59
|
+
}
|
|
60
|
+
/** Handle a single incoming Feishu message event. */
|
|
61
|
+
async function handleIncomingMessage(data, ctx) {
|
|
62
|
+
const message = data.message;
|
|
63
|
+
if (!message)
|
|
64
|
+
return;
|
|
65
|
+
const chatId = message.chat_id;
|
|
66
|
+
if (!chatId)
|
|
67
|
+
return;
|
|
68
|
+
const messageId = message.message_id;
|
|
69
|
+
if (isDuplicate(messageId))
|
|
70
|
+
return;
|
|
71
|
+
// Only handle text messages for now
|
|
72
|
+
const messageType = message.message_type;
|
|
73
|
+
if (messageType !== "text" || !message.content)
|
|
74
|
+
return;
|
|
75
|
+
let text;
|
|
76
|
+
try {
|
|
77
|
+
const parsed = JSON.parse(message.content);
|
|
78
|
+
text = (parsed.text ?? "").trim();
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (!text)
|
|
84
|
+
return;
|
|
85
|
+
const chatType = message.chat_type;
|
|
86
|
+
const sender = data.sender;
|
|
87
|
+
const senderId = sender?.sender_id?.open_id ?? "";
|
|
88
|
+
// Group chat: check filter
|
|
89
|
+
if (chatType === "group") {
|
|
90
|
+
const mentions = Array.isArray(message.mentions) ? message.mentions : [];
|
|
91
|
+
text = text.replace(/@_user_\d+\s*/g, "").trim();
|
|
92
|
+
if (!text || !shouldRespondInGroup(text, mentions, ctx.botNames))
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
ctx.statusSink?.({ lastInboundAt: Date.now() });
|
|
96
|
+
const sessionKey = `feishu:${chatType === "p2p" ? senderId : chatId}`;
|
|
97
|
+
ctx.log.info(`[feishu:${ctx.account.accountId}] Received from ${senderId}: ${text.slice(0, 80)}`);
|
|
98
|
+
// Dispatch via Clawdbot runtime
|
|
99
|
+
const runtime = getFeishuRuntime();
|
|
100
|
+
const channel = runtime.channel;
|
|
101
|
+
if (!channel?.reply?.dispatchReplyWithBufferedBlockDispatcher) {
|
|
102
|
+
ctx.log.error(`[feishu:${ctx.account.accountId}] dispatchReplyWithBufferedBlockDispatcher not available`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Build inbound context
|
|
106
|
+
const inboundCtx = {
|
|
107
|
+
Body: text,
|
|
108
|
+
RawBody: text,
|
|
109
|
+
CommandBody: text,
|
|
110
|
+
From: senderId,
|
|
111
|
+
To: chatId,
|
|
112
|
+
SessionKey: sessionKey,
|
|
113
|
+
AccountId: ctx.account.accountId,
|
|
114
|
+
MessageSid: messageId,
|
|
115
|
+
ChatType: chatType === "p2p" ? "direct" : "group",
|
|
116
|
+
ConversationLabel: chatId,
|
|
117
|
+
SenderId: senderId,
|
|
118
|
+
CommandAuthorized: true,
|
|
119
|
+
Provider: "feishu",
|
|
120
|
+
Surface: "feishu",
|
|
121
|
+
OriginatingChannel: "feishu",
|
|
122
|
+
OriginatingTo: chatId,
|
|
123
|
+
DeliveryContext: {
|
|
124
|
+
channel: "feishu",
|
|
125
|
+
to: chatId,
|
|
126
|
+
accountId: ctx.account.accountId,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
// "Thinking…" placeholder logic
|
|
130
|
+
let placeholderId = "";
|
|
131
|
+
let done = false;
|
|
132
|
+
const timer = ctx.thinkingThresholdMs > 0
|
|
133
|
+
? setTimeout(async () => {
|
|
134
|
+
if (done)
|
|
135
|
+
return;
|
|
136
|
+
try {
|
|
137
|
+
const res = await ctx.client.im.message.create({
|
|
138
|
+
params: { receive_id_type: "chat_id" },
|
|
139
|
+
data: {
|
|
140
|
+
receive_id: chatId,
|
|
141
|
+
msg_type: "text",
|
|
142
|
+
content: JSON.stringify({ text: "正在思考…" }),
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
placeholderId = res?.data?.message_id ?? "";
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// Ignore placeholder failures
|
|
149
|
+
}
|
|
150
|
+
}, ctx.thinkingThresholdMs)
|
|
151
|
+
: null;
|
|
152
|
+
try {
|
|
153
|
+
await channel.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
154
|
+
ctx: inboundCtx,
|
|
155
|
+
cfg: runtime.config?.loadConfig?.() ?? ctx.config,
|
|
156
|
+
replyResolver: null,
|
|
157
|
+
dispatcherOptions: {
|
|
158
|
+
deliver: async (payload) => {
|
|
159
|
+
done = true;
|
|
160
|
+
if (timer)
|
|
161
|
+
clearTimeout(timer);
|
|
162
|
+
const p = payload;
|
|
163
|
+
const replyText = typeof p === "string" ? p : (p?.text ?? p?.body ?? "");
|
|
164
|
+
const mediaUrl = typeof p === "string" ? undefined : (p?.mediaUrl ?? p?.mediaUrls?.[0]);
|
|
165
|
+
// Skip empty / NO_REPLY
|
|
166
|
+
const trimmed = (replyText || "").trim();
|
|
167
|
+
if ((!trimmed || trimmed === "NO_REPLY" || trimmed.endsWith("NO_REPLY")) && !mediaUrl) {
|
|
168
|
+
if (placeholderId)
|
|
169
|
+
await deleteMessage(ctx.client, placeholderId);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
ctx.statusSink?.({ lastOutboundAt: Date.now() });
|
|
173
|
+
try {
|
|
174
|
+
if (mediaUrl) {
|
|
175
|
+
if (placeholderId) {
|
|
176
|
+
await deleteMessage(ctx.client, placeholderId);
|
|
177
|
+
placeholderId = "";
|
|
178
|
+
}
|
|
179
|
+
await sendMediaMessage(ctx.client, chatId, mediaUrl, replyText);
|
|
180
|
+
}
|
|
181
|
+
else if (placeholderId) {
|
|
182
|
+
// Update the "Thinking…" placeholder
|
|
183
|
+
await updateMessage(ctx.client, placeholderId, replyText);
|
|
184
|
+
placeholderId = "";
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
await sendTextMessage(ctx.client, chatId, replyText);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
ctx.log.error(`[feishu:${ctx.account.accountId}] Failed to send reply: ${err instanceof Error ? err.message : String(err)}`);
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
onError: (err) => {
|
|
195
|
+
done = true;
|
|
196
|
+
if (timer)
|
|
197
|
+
clearTimeout(timer);
|
|
198
|
+
ctx.log.error(`[feishu:${ctx.account.accountId}] Dispatcher error: ${err.message}`);
|
|
199
|
+
// Clean up placeholder
|
|
200
|
+
if (placeholderId) {
|
|
201
|
+
deleteMessage(ctx.client, placeholderId).catch(() => { });
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
done = true;
|
|
209
|
+
if (timer)
|
|
210
|
+
clearTimeout(timer);
|
|
211
|
+
ctx.log.error(`[feishu:${ctx.account.accountId}] Dispatch error: ${err instanceof Error ? err.message : String(err)}`);
|
|
212
|
+
if (placeholderId) {
|
|
213
|
+
await deleteMessage(ctx.client, placeholderId);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=receive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receive.js","sourceRoot":"","sources":["../../src/receive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global runtime reference for the Feishu plugin.
|
|
3
|
+
*/
|
|
4
|
+
import type { PluginRuntime } from "clawdbot/plugin-sdk";
|
|
5
|
+
export declare function setFeishuRuntime(next: PluginRuntime): void;
|
|
6
|
+
export declare function getFeishuRuntime(): PluginRuntime;
|
|
7
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIzD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAE1D;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAKhD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global runtime reference for the Feishu plugin.
|
|
3
|
+
*/
|
|
4
|
+
let runtime = null;
|
|
5
|
+
export function setFeishuRuntime(next) {
|
|
6
|
+
runtime = next;
|
|
7
|
+
}
|
|
8
|
+
export function getFeishuRuntime() {
|
|
9
|
+
if (!runtime) {
|
|
10
|
+
throw new Error("Feishu runtime not initialized");
|
|
11
|
+
}
|
|
12
|
+
return runtime;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,IAAI,OAAO,GAAyB,IAAI,CAAC;AAEzC,MAAM,UAAU,gBAAgB,CAAC,IAAmB;IAClD,OAAO,GAAG,IAAI,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Send messages to Feishu — text and media.
|
|
3
|
+
*/
|
|
4
|
+
import type * as Lark from "@larksuiteoapi/node-sdk";
|
|
5
|
+
import type { FeishuSendResult } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Send a text message to a Feishu chat.
|
|
8
|
+
*/
|
|
9
|
+
export declare function sendTextMessage(client: InstanceType<typeof Lark.Client>, chatId: string, text: string, replyToId?: string): Promise<FeishuSendResult>;
|
|
10
|
+
/**
|
|
11
|
+
* Send a media message (image, video, audio, or file) to a Feishu chat.
|
|
12
|
+
* Falls back to text + URL on failure.
|
|
13
|
+
*/
|
|
14
|
+
export declare function sendMediaMessage(client: InstanceType<typeof Lark.Client>, chatId: string, mediaUrl: string, text?: string, replyToId?: string): Promise<FeishuSendResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Update an existing message (e.g., replace "Thinking…" placeholder).
|
|
17
|
+
*/
|
|
18
|
+
export declare function updateMessage(client: InstanceType<typeof Lark.Client>, messageId: string, text: string): Promise<FeishuSendResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Delete a message (e.g., remove "Thinking…" placeholder).
|
|
21
|
+
*/
|
|
22
|
+
export declare function deleteMessage(client: InstanceType<typeof Lark.Client>, messageId: string): Promise<void>;
|
|
23
|
+
//# sourceMappingURL=send.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../../src/send.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,KAAK,IAAI,MAAM,yBAAyB,CAAC;AAErD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAUnD;;GAEG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,YAAY,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,EACxC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,CA6B3B;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,EACxC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,CAuF3B;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,YAAY,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,EACxC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,CAAC,CAa3B;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,YAAY,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,EACxC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
package/dist/src/send.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Send messages to Feishu — text and media.
|
|
3
|
+
*/
|
|
4
|
+
import { cleanupTemp, downloadToTempFile, getFileExtension, getMediaType, uploadFile, uploadImage, } from "./media.js";
|
|
5
|
+
/**
|
|
6
|
+
* Send a text message to a Feishu chat.
|
|
7
|
+
*/
|
|
8
|
+
export async function sendTextMessage(client, chatId, text, replyToId) {
|
|
9
|
+
if (!chatId?.trim()) {
|
|
10
|
+
return { ok: false, error: "No chat_id provided" };
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
if (replyToId) {
|
|
14
|
+
const res = await client.im.message.reply({
|
|
15
|
+
path: { message_id: replyToId },
|
|
16
|
+
data: {
|
|
17
|
+
content: JSON.stringify({ text }),
|
|
18
|
+
msg_type: "text",
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
return { ok: true, messageId: res?.data?.message_id ?? "" };
|
|
22
|
+
}
|
|
23
|
+
const res = await client.im.message.create({
|
|
24
|
+
params: { receive_id_type: "chat_id" },
|
|
25
|
+
data: {
|
|
26
|
+
receive_id: chatId.trim(),
|
|
27
|
+
msg_type: "text",
|
|
28
|
+
content: JSON.stringify({ text }),
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
return { ok: true, messageId: res?.data?.message_id ?? "" };
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Send a media message (image, video, audio, or file) to a Feishu chat.
|
|
39
|
+
* Falls back to text + URL on failure.
|
|
40
|
+
*/
|
|
41
|
+
export async function sendMediaMessage(client, chatId, mediaUrl, text, replyToId) {
|
|
42
|
+
if (!chatId?.trim()) {
|
|
43
|
+
return { ok: false, error: "No chat_id provided" };
|
|
44
|
+
}
|
|
45
|
+
if (!mediaUrl?.trim()) {
|
|
46
|
+
return { ok: false, error: "No media URL provided" };
|
|
47
|
+
}
|
|
48
|
+
let tempPath = null;
|
|
49
|
+
let isTemp = false;
|
|
50
|
+
try {
|
|
51
|
+
const downloaded = await downloadToTempFile(mediaUrl);
|
|
52
|
+
tempPath = downloaded.path;
|
|
53
|
+
isTemp = downloaded.isTemp;
|
|
54
|
+
const mediaType = getMediaType(mediaUrl);
|
|
55
|
+
const extension = getFileExtension(mediaUrl);
|
|
56
|
+
const filename = `file_${Date.now()}.${extension}`;
|
|
57
|
+
let msgType;
|
|
58
|
+
let content;
|
|
59
|
+
if (mediaType === "image") {
|
|
60
|
+
const imageKey = await uploadImage(client, tempPath);
|
|
61
|
+
msgType = "image";
|
|
62
|
+
content = JSON.stringify({ image_key: imageKey });
|
|
63
|
+
}
|
|
64
|
+
else if (mediaType === "video") {
|
|
65
|
+
const fileKey = await uploadFile(client, tempPath, filename, "mp4");
|
|
66
|
+
msgType = "media";
|
|
67
|
+
const mediaContent = { file_key: fileKey };
|
|
68
|
+
content = JSON.stringify(mediaContent);
|
|
69
|
+
}
|
|
70
|
+
else if (mediaType === "audio") {
|
|
71
|
+
const fileKey = await uploadFile(client, tempPath, filename, "opus");
|
|
72
|
+
msgType = "audio";
|
|
73
|
+
content = JSON.stringify({ file_key: fileKey });
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const fileKey = await uploadFile(client, tempPath, filename, "stream");
|
|
77
|
+
msgType = "file";
|
|
78
|
+
content = JSON.stringify({ file_key: fileKey });
|
|
79
|
+
}
|
|
80
|
+
// Send the media message
|
|
81
|
+
if (replyToId) {
|
|
82
|
+
await client.im.message.reply({
|
|
83
|
+
path: { message_id: replyToId },
|
|
84
|
+
data: { content, msg_type: msgType },
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
await client.im.message.create({
|
|
89
|
+
params: { receive_id_type: "chat_id" },
|
|
90
|
+
data: { receive_id: chatId.trim(), content, msg_type: msgType },
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Send accompanying text as separate message if provided
|
|
94
|
+
if (text?.trim()) {
|
|
95
|
+
await client.im.message.create({
|
|
96
|
+
params: { receive_id_type: "chat_id" },
|
|
97
|
+
data: {
|
|
98
|
+
receive_id: chatId.trim(),
|
|
99
|
+
content: JSON.stringify({ text }),
|
|
100
|
+
msg_type: "text",
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return { ok: true };
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
// Fallback: send as text with URL
|
|
108
|
+
try {
|
|
109
|
+
const fallbackText = text ? `${text}\n${mediaUrl}` : mediaUrl;
|
|
110
|
+
const res = await client.im.message.create({
|
|
111
|
+
params: { receive_id_type: "chat_id" },
|
|
112
|
+
data: {
|
|
113
|
+
receive_id: chatId.trim(),
|
|
114
|
+
content: JSON.stringify({ text: fallbackText }),
|
|
115
|
+
msg_type: "text",
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
return { ok: true, messageId: res?.data?.message_id ?? "" };
|
|
119
|
+
}
|
|
120
|
+
catch (fallbackErr) {
|
|
121
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
if (tempPath)
|
|
126
|
+
cleanupTemp(tempPath, isTemp);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Update an existing message (e.g., replace "Thinking…" placeholder).
|
|
131
|
+
*/
|
|
132
|
+
export async function updateMessage(client, messageId, text) {
|
|
133
|
+
try {
|
|
134
|
+
await client.im.message.update({
|
|
135
|
+
path: { message_id: messageId },
|
|
136
|
+
data: {
|
|
137
|
+
msg_type: "text",
|
|
138
|
+
content: JSON.stringify({ text }),
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
return { ok: true, messageId };
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Delete a message (e.g., remove "Thinking…" placeholder).
|
|
149
|
+
*/
|
|
150
|
+
export async function deleteMessage(client, messageId) {
|
|
151
|
+
try {
|
|
152
|
+
await client.im.message.delete({ path: { message_id: messageId } });
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// Best-effort cleanup
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=send.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/send.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diagnostic issues collector for Feishu channel.
|
|
3
|
+
*/
|
|
4
|
+
import type { ChannelAccountSnapshot, ChannelStatusIssue } from "clawdbot/plugin-sdk";
|
|
5
|
+
/** Collect configuration issues for all Feishu accounts. */
|
|
6
|
+
export declare function collectFeishuStatusIssues(accounts: ChannelAccountSnapshot[]): ChannelStatusIssue[];
|
|
7
|
+
//# sourceMappingURL=status-issues.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-issues.d.ts","sourceRoot":"","sources":["../../src/status-issues.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AA2BtF,4DAA4D;AAC5D,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,sBAAsB,EAAE,GACjC,kBAAkB,EAAE,CAiCtB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diagnostic issues collector for Feishu channel.
|
|
3
|
+
*/
|
|
4
|
+
const isRecord = (value) => Boolean(value && typeof value === "object");
|
|
5
|
+
const asString = (value) => typeof value === "string" ? value : typeof value === "number" ? String(value) : undefined;
|
|
6
|
+
function readFeishuAccountStatus(value) {
|
|
7
|
+
if (!isRecord(value))
|
|
8
|
+
return null;
|
|
9
|
+
return {
|
|
10
|
+
accountId: value.accountId,
|
|
11
|
+
enabled: value.enabled,
|
|
12
|
+
configured: value.configured,
|
|
13
|
+
dmPolicy: value.dmPolicy,
|
|
14
|
+
appId: value.appId,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** Collect configuration issues for all Feishu accounts. */
|
|
18
|
+
export function collectFeishuStatusIssues(accounts) {
|
|
19
|
+
const issues = [];
|
|
20
|
+
for (const entry of accounts) {
|
|
21
|
+
const account = readFeishuAccountStatus(entry);
|
|
22
|
+
if (!account)
|
|
23
|
+
continue;
|
|
24
|
+
const accountId = asString(account.accountId) ?? "default";
|
|
25
|
+
const enabled = account.enabled !== false;
|
|
26
|
+
const configured = account.configured === true;
|
|
27
|
+
if (enabled && !configured) {
|
|
28
|
+
issues.push({
|
|
29
|
+
channel: "feishu",
|
|
30
|
+
accountId,
|
|
31
|
+
kind: "config",
|
|
32
|
+
message: "Feishu account is enabled but not configured (missing appId or appSecret).",
|
|
33
|
+
fix: "Set channels.feishu.appId and channels.feishu.appSecret in clawdbot.json.",
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (enabled && configured && account.dmPolicy === "open") {
|
|
37
|
+
issues.push({
|
|
38
|
+
channel: "feishu",
|
|
39
|
+
accountId,
|
|
40
|
+
kind: "config",
|
|
41
|
+
message: 'Feishu dmPolicy is "open", allowing any user to message the bot without pairing.',
|
|
42
|
+
fix: 'Set channels.feishu.dmPolicy to "pairing" or "allowlist" to restrict access.',
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return issues;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=status-issues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-issues.js","sourceRoot":"","sources":["../../src/status-issues.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CACpE,OAAO,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC;AAE9C,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAsB,EAAE,CACtD,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAE5F,SAAS,uBAAuB,CAAC,KAA6B;IAC5D,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO;QACL,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC;AACJ,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,yBAAyB,CACvC,QAAkC;IAElC,MAAM,MAAM,GAAyB,EAAE,CAAC;IAExC,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC;QAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,KAAK,KAAK,CAAC;QAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,KAAK,IAAI,CAAC;QAE/C,IAAI,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC;gBACV,OAAO,EAAE,QAAQ;gBACjB,SAAS;gBACT,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,4EAA4E;gBACrF,GAAG,EAAE,2EAA2E;aACjF,CAAC,CAAC;QACL,CAAC;QAED,IAAI,OAAO,IAAI,UAAU,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;YACzD,MAAM,CAAC,IAAI,CAAC;gBACV,OAAO,EAAE,QAAQ;gBACjB,SAAS;gBACT,IAAI,EAAE,QAAQ;gBACd,OAAO,EACL,kFAAkF;gBACpF,GAAG,EAAE,8EAA8E;aACpF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feishu channel plugin — type definitions.
|
|
3
|
+
*/
|
|
4
|
+
/** Per-account configuration stored in clawdbot.json channels.feishu */
|
|
5
|
+
export type FeishuAccountConfig = {
|
|
6
|
+
/** Optional display name for this account. */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** If false, do not start this Feishu account. Default: true. */
|
|
9
|
+
enabled?: boolean;
|
|
10
|
+
/** Feishu App ID (cli_xxx). */
|
|
11
|
+
appId?: string;
|
|
12
|
+
/** Feishu App Secret. */
|
|
13
|
+
appSecret?: string;
|
|
14
|
+
/** Direct message access policy (default: pairing). */
|
|
15
|
+
dmPolicy?: "pairing" | "allowlist" | "open" | "disabled";
|
|
16
|
+
/** Allowlist for DM senders (Feishu open_id or union_id). */
|
|
17
|
+
allowFrom?: Array<string | number>;
|
|
18
|
+
/** "Thinking…" placeholder threshold in milliseconds. 0 to disable. */
|
|
19
|
+
thinkingThresholdMs?: number;
|
|
20
|
+
/** Bot name aliases used for group-chat address detection. */
|
|
21
|
+
botNames?: string[];
|
|
22
|
+
/** Max inbound media size in MB. */
|
|
23
|
+
mediaMaxMb?: number;
|
|
24
|
+
};
|
|
25
|
+
/** Top-level Feishu config section (channels.feishu). */
|
|
26
|
+
export type FeishuConfig = {
|
|
27
|
+
/** Multi-account map. */
|
|
28
|
+
accounts?: Record<string, FeishuAccountConfig>;
|
|
29
|
+
/** Default account ID when multiple accounts exist. */
|
|
30
|
+
defaultAccount?: string;
|
|
31
|
+
} & FeishuAccountConfig;
|
|
32
|
+
/** How the appId/appSecret were resolved. */
|
|
33
|
+
export type FeishuTokenSource = "config" | "plugin" | "none";
|
|
34
|
+
/** Resolved account ready for use. */
|
|
35
|
+
export type ResolvedFeishuAccount = {
|
|
36
|
+
accountId: string;
|
|
37
|
+
name?: string;
|
|
38
|
+
enabled: boolean;
|
|
39
|
+
appId: string;
|
|
40
|
+
appSecret: string;
|
|
41
|
+
tokenSource: FeishuTokenSource;
|
|
42
|
+
config: FeishuAccountConfig;
|
|
43
|
+
};
|
|
44
|
+
/** Result of sending a message via Feishu API. */
|
|
45
|
+
export type FeishuSendResult = {
|
|
46
|
+
ok: boolean;
|
|
47
|
+
messageId?: string;
|
|
48
|
+
error?: string;
|
|
49
|
+
};
|
|
50
|
+
/** Feishu probe result. */
|
|
51
|
+
export type FeishuProbeResult = {
|
|
52
|
+
ok: boolean;
|
|
53
|
+
bot?: {
|
|
54
|
+
name?: string;
|
|
55
|
+
openId?: string;
|
|
56
|
+
};
|
|
57
|
+
error?: string;
|
|
58
|
+
elapsedMs: number;
|
|
59
|
+
};
|
|
60
|
+
/** Media type classification. */
|
|
61
|
+
export type FeishuMediaType = "image" | "video" | "audio" | "file";
|
|
62
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wEAAwE;AACxE,MAAM,MAAM,mBAAmB,GAAG;IAChC,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,CAAC;IACzD,6DAA6D;IAC7D,SAAS,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACnC,uEAAuE;IACvE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,yDAAyD;AACzD,MAAM,MAAM,YAAY,GAAG;IACzB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAC/C,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,mBAAmB,CAAC;AAExB,6CAA6C;AAC7C,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE7D,sCAAsC;AACtC,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,MAAM,EAAE,mBAAmB,CAAC;CAC7B,CAAC;AAEF,kDAAkD;AAClD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,2BAA2B;AAC3B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,GAAG,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,iCAAiC;AACjC,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|