@meet-im/meet 3.3.1 → 3.4.1
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/dist/src/bot.js +3 -0
- package/dist/src/generated/plugin-build-meta.d.ts +1 -1
- package/dist/src/generated/plugin-build-meta.js +1 -1
- package/dist/src/probe.d.ts +0 -2
- package/dist/src/probe.js +1 -13
- package/dist/src/reply-dispatcher.d.ts +2 -0
- package/dist/src/reply-dispatcher.js +33 -19
- package/dist/src/send.d.ts +5 -1
- package/dist/src/send.js +10 -24
- package/package.json +1 -1
package/dist/src/bot.js
CHANGED
|
@@ -108,6 +108,7 @@ export async function handleMeetMessage(params) {
|
|
|
108
108
|
to: `user:${ctx.senderId}`,
|
|
109
109
|
text: replyText,
|
|
110
110
|
accountId,
|
|
111
|
+
runtime,
|
|
111
112
|
});
|
|
112
113
|
}
|
|
113
114
|
catch (err) {
|
|
@@ -388,6 +389,8 @@ export async function handleMeetMessage(params) {
|
|
|
388
389
|
agentId: route.agentId,
|
|
389
390
|
runtime: runtime,
|
|
390
391
|
chatId: ctx.chatId,
|
|
392
|
+
senderId: ctx.senderId,
|
|
393
|
+
mentionedBot: ctx.mentionedBot,
|
|
391
394
|
replyToMessageId: ctx.messageId,
|
|
392
395
|
accountId,
|
|
393
396
|
bot,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const MEET_PLUGIN_VERSION = "3.
|
|
1
|
+
export declare const MEET_PLUGIN_VERSION = "3.4.1";
|
|
2
2
|
export declare const MEET_OPENCLAW_VERSION = "2026.5.18";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const MEET_PLUGIN_VERSION = "3.
|
|
1
|
+
export const MEET_PLUGIN_VERSION = "3.4.1";
|
|
2
2
|
export const MEET_OPENCLAW_VERSION = "2026.5.18";
|
package/dist/src/probe.d.ts
CHANGED
package/dist/src/probe.js
CHANGED
|
@@ -1,16 +1,4 @@
|
|
|
1
1
|
import { getMeetClient } from "./client.js";
|
|
2
|
-
let _logger = null;
|
|
3
|
-
export function setProbeLogger(logger) {
|
|
4
|
-
_logger = logger;
|
|
5
|
-
}
|
|
6
|
-
function log(message) {
|
|
7
|
-
if (_logger) {
|
|
8
|
-
_logger.log(message);
|
|
9
|
-
}
|
|
10
|
-
else {
|
|
11
|
-
console.log(message);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
2
|
const probeCache = new Map();
|
|
15
3
|
const PROBE_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
16
4
|
export async function probeMeet(account) {
|
|
@@ -36,7 +24,7 @@ export async function probeMeet(account) {
|
|
|
36
24
|
botId: account.apiToken?.split(":")[0],
|
|
37
25
|
};
|
|
38
26
|
if (updates && updates.msgs.length > 0) {
|
|
39
|
-
log(`[${account.accountId}] probe: received ${updates.msgs.length} update(s)`);
|
|
27
|
+
console.log(`[${account.accountId}] probe: received ${updates.msgs.length} update(s)`);
|
|
40
28
|
}
|
|
41
29
|
probeCache.set(cacheKey, { result, timestamp: Date.now() });
|
|
42
30
|
return result;
|
|
@@ -75,7 +75,7 @@ export function protectMentionsInChunks(chunks) {
|
|
|
75
75
|
return result;
|
|
76
76
|
}
|
|
77
77
|
export async function createMeetReplyDispatcher(opts) {
|
|
78
|
-
const { cfg, agentId, chatId, replyToMessageId, accountId, mediaLocalRoots, sessionInfo, apiToken, apiEndpoint, typingMode } = opts;
|
|
78
|
+
const { cfg, agentId, chatId, senderId, mentionedBot, replyToMessageId, accountId, mediaLocalRoots, sessionInfo, apiToken, apiEndpoint, typingMode } = opts;
|
|
79
79
|
const core = getMeetRuntime();
|
|
80
80
|
const textChunkLimit = core.channel.text.resolveTextChunkLimit(cfg, "meet", accountId, {
|
|
81
81
|
fallbackLimit: 4000,
|
|
@@ -89,42 +89,46 @@ export async function createMeetReplyDispatcher(opts) {
|
|
|
89
89
|
ctx: { ChatType: chatType },
|
|
90
90
|
})
|
|
91
91
|
: undefined;
|
|
92
|
+
const shouldAutoMentionSender = chatType === "channel" && mentionedBot === true && !!senderId;
|
|
93
|
+
const senderMentionText = shouldAutoMentionSender ? `<@${senderId}>` : undefined;
|
|
92
94
|
// 创建 typing callbacks(如果配置了 typing 且有必要参数)
|
|
93
95
|
const hasTypingParams = typingMode && typingMode !== "none" && sessionInfo && apiToken;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const next = typingRequestChain.then(async () => {
|
|
97
|
-
opts.runtime.log?.(`[${accountId}][${chatId}]: typing ${label} sending...`);
|
|
98
|
-
return await run();
|
|
99
|
-
});
|
|
100
|
-
typingRequestChain = next.then(() => undefined).catch(() => { });
|
|
101
|
-
return next;
|
|
102
|
-
};
|
|
96
|
+
// stop 请求需要等待最后一个 start 完成,避免乱序
|
|
97
|
+
let lastStartPromise = Promise.resolve();
|
|
103
98
|
const typingCallbacks = hasTypingParams
|
|
104
99
|
? createTypingCallbacks({
|
|
105
100
|
start: async () => {
|
|
106
|
-
|
|
101
|
+
// 直接发送,不串行化。typing start 是幂等的,重复发送无害
|
|
102
|
+
opts.runtime.log?.(`[${accountId}][${chatId}]: typing start sending...`);
|
|
103
|
+
const startPromise = sendTypingMeet({
|
|
107
104
|
accountId,
|
|
108
105
|
chatId,
|
|
109
106
|
chatType: chatType ?? "channel",
|
|
110
107
|
sessionInfo,
|
|
111
108
|
token: apiToken,
|
|
112
109
|
apiEndpoint,
|
|
113
|
-
}))
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
110
|
+
}).then((result) => {
|
|
111
|
+
if (!result.ok && result.reason === "error") {
|
|
112
|
+
throw result.error;
|
|
113
|
+
}
|
|
114
|
+
opts.runtime.log?.(`[${accountId}][${chatId}]: typing start sent ok=${result.ok}`);
|
|
115
|
+
});
|
|
116
|
+
// 记录当前 start 请求,供 stop 等待
|
|
117
|
+
lastStartPromise = startPromise;
|
|
118
|
+
await startPromise;
|
|
118
119
|
},
|
|
119
120
|
stop: async () => {
|
|
120
|
-
|
|
121
|
+
// 等待最后一个 start 完成,避免 stop 在 start 之前到达
|
|
122
|
+
await lastStartPromise;
|
|
123
|
+
opts.runtime.log?.(`[${accountId}][${chatId}]: typing stop sending...`);
|
|
124
|
+
await stopTypingMeet({
|
|
121
125
|
accountId,
|
|
122
126
|
chatId,
|
|
123
127
|
chatType: chatType ?? "channel",
|
|
124
128
|
sessionInfo,
|
|
125
129
|
token: apiToken,
|
|
126
130
|
apiEndpoint,
|
|
127
|
-
})
|
|
131
|
+
});
|
|
128
132
|
},
|
|
129
133
|
onStartError: (err) => {
|
|
130
134
|
opts.runtime.error?.(`[${accountId}][${chatId}]: typing start failed: ${String(err)}`);
|
|
@@ -181,6 +185,7 @@ export async function createMeetReplyDispatcher(opts) {
|
|
|
181
185
|
mediaUrl: mediaUrls[0],
|
|
182
186
|
mediaLocalRoots,
|
|
183
187
|
accountId,
|
|
188
|
+
runtime: opts.runtime,
|
|
184
189
|
});
|
|
185
190
|
// 后续媒体不带文本
|
|
186
191
|
for (let i = 1; i < mediaUrls.length; i++) {
|
|
@@ -191,6 +196,7 @@ export async function createMeetReplyDispatcher(opts) {
|
|
|
191
196
|
mediaUrl: mediaUrls[i],
|
|
192
197
|
mediaLocalRoots,
|
|
193
198
|
accountId,
|
|
199
|
+
runtime: opts.runtime,
|
|
194
200
|
});
|
|
195
201
|
}
|
|
196
202
|
return;
|
|
@@ -198,13 +204,20 @@ export async function createMeetReplyDispatcher(opts) {
|
|
|
198
204
|
// 只有文本,分片发送
|
|
199
205
|
const rawChunks = core.channel.text.chunkTextWithMode(text, textChunkLimit, chunkMode);
|
|
200
206
|
const protectedChunks = protectMentionsInChunks(rawChunks);
|
|
201
|
-
for (const
|
|
207
|
+
for (const [index, rawChunk] of protectedChunks.entries()) {
|
|
208
|
+
const chunk = index === 0 && senderMentionText
|
|
209
|
+
? rawChunk.includes(senderMentionText)
|
|
210
|
+
? rawChunk
|
|
211
|
+
: `${senderMentionText} ${rawChunk}`
|
|
212
|
+
: rawChunk;
|
|
202
213
|
await sendMessageMeet({
|
|
203
214
|
cfg,
|
|
204
215
|
to: chatId,
|
|
205
216
|
text: chunk,
|
|
206
217
|
accountId,
|
|
207
218
|
replyToMessageId,
|
|
219
|
+
atIds: index === 0 && shouldAutoMentionSender && senderId ? [Number(senderId)] : undefined,
|
|
220
|
+
runtime: opts.runtime,
|
|
208
221
|
});
|
|
209
222
|
}
|
|
210
223
|
},
|
|
@@ -250,6 +263,7 @@ export async function createMeetReplyDispatcher(opts) {
|
|
|
250
263
|
to: chatId,
|
|
251
264
|
text: userMessage,
|
|
252
265
|
accountId,
|
|
266
|
+
runtime: opts.runtime,
|
|
253
267
|
});
|
|
254
268
|
}
|
|
255
269
|
catch {
|
package/dist/src/send.d.ts
CHANGED
|
@@ -10,11 +10,11 @@ export declare function inferContentTypeFromFileName(fileName: string): string |
|
|
|
10
10
|
* 如果原始 contentType 缺失或为通用二进制流,则根据文件名推断
|
|
11
11
|
*/
|
|
12
12
|
export declare function resolveContentType(fileName: string, originalContentType?: string): string;
|
|
13
|
-
export declare function setSendMessageLogger(logger: RuntimeEnv): void;
|
|
14
13
|
export declare function extractAtIds(text: string): {
|
|
15
14
|
text: string;
|
|
16
15
|
atIds: number[];
|
|
17
16
|
};
|
|
17
|
+
export declare function mergeAtIds(explicitAtIds?: number[], extractedAtIds?: number[]): number[];
|
|
18
18
|
export type SendMessageMeetOpts = {
|
|
19
19
|
cfg: ClawdbotConfig;
|
|
20
20
|
to: string;
|
|
@@ -22,6 +22,8 @@ export type SendMessageMeetOpts = {
|
|
|
22
22
|
accountId?: string;
|
|
23
23
|
replyToMessageId?: string;
|
|
24
24
|
atIds?: number[];
|
|
25
|
+
/** Optional runtime for consistent logging. If not provided, falls back to console. */
|
|
26
|
+
runtime?: RuntimeEnv;
|
|
25
27
|
};
|
|
26
28
|
export declare function sendMessageMeet(opts: SendMessageMeetOpts): Promise<{
|
|
27
29
|
messageId: string;
|
|
@@ -41,6 +43,8 @@ export type SendMediaMeetOpts = {
|
|
|
41
43
|
total: number;
|
|
42
44
|
speedPerSecond: string;
|
|
43
45
|
}) => void;
|
|
46
|
+
/** Optional runtime for consistent logging. If not provided, falls back to console. */
|
|
47
|
+
runtime?: RuntimeEnv;
|
|
44
48
|
};
|
|
45
49
|
export declare function sendMediaMeet(opts: SendMediaMeetOpts): Promise<{
|
|
46
50
|
messageId: string;
|
package/dist/src/send.js
CHANGED
|
@@ -108,25 +108,6 @@ export function resolveContentType(fileName, originalContentType) {
|
|
|
108
108
|
const inferred = inferContentTypeFromFileName(fileName);
|
|
109
109
|
return inferred || originalContentType || "application/octet-stream";
|
|
110
110
|
}
|
|
111
|
-
let _logger = null;
|
|
112
|
-
export function setSendMessageLogger(logger) {
|
|
113
|
-
_logger = logger;
|
|
114
|
-
}
|
|
115
|
-
function log(message) {
|
|
116
|
-
if (_logger) {
|
|
117
|
-
_logger.log(message);
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
console.log(message);
|
|
121
|
-
}
|
|
122
|
-
function logError(message) {
|
|
123
|
-
if (_logger) {
|
|
124
|
-
_logger.error(message);
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
console.error(message);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
111
|
export function extractAtIds(text) {
|
|
131
112
|
const atIds = [];
|
|
132
113
|
text.replace(MENTION_PATTERN, (_, id1, id2) => {
|
|
@@ -138,8 +119,13 @@ export function extractAtIds(text) {
|
|
|
138
119
|
});
|
|
139
120
|
return { text: text.trim(), atIds };
|
|
140
121
|
}
|
|
122
|
+
export function mergeAtIds(explicitAtIds, extractedAtIds) {
|
|
123
|
+
return [...new Set([...(explicitAtIds ?? []), ...(extractedAtIds ?? [])])];
|
|
124
|
+
}
|
|
141
125
|
export async function sendMessageMeet(opts) {
|
|
142
|
-
const { cfg, to, text, accountId, atIds: explicitAtIds } = opts;
|
|
126
|
+
const { cfg, to, text, accountId, atIds: explicitAtIds, runtime } = opts;
|
|
127
|
+
const log = runtime?.log ?? console.log;
|
|
128
|
+
const logError = runtime?.error ?? console.error;
|
|
143
129
|
const account = resolveMeetAccount({ cfg, accountId });
|
|
144
130
|
if (!account.configured) {
|
|
145
131
|
throw new Error(`Meet account not configured: ${accountId ?? "default"}`);
|
|
@@ -181,9 +167,7 @@ export async function sendMessageMeet(opts) {
|
|
|
181
167
|
// 先重写 @handle 为 <@userId>,再提取 atIds
|
|
182
168
|
const textWithMentions = rewriteMeetKnownMentions(text, account.accountId);
|
|
183
169
|
const { text: cleanText, atIds: extractedAtIds } = extractAtIds(textWithMentions);
|
|
184
|
-
const finalAtIds = explicitAtIds
|
|
185
|
-
? [...explicitAtIds, ...extractedAtIds]
|
|
186
|
-
: extractedAtIds;
|
|
170
|
+
const finalAtIds = mergeAtIds(explicitAtIds, extractedAtIds);
|
|
187
171
|
log(`send message to=${to} atIds=${finalAtIds.join(",") || "none"}`);
|
|
188
172
|
const sessionInfo = parseTargetToSessionInfo(to, Number(botUserId));
|
|
189
173
|
try {
|
|
@@ -202,7 +186,9 @@ export async function sendMessageMeet(opts) {
|
|
|
202
186
|
}
|
|
203
187
|
}
|
|
204
188
|
export async function sendMediaMeet(opts) {
|
|
205
|
-
const { cfg, to, text, mediaUrl, mediaLocalRoots, accountId, onProgress } = opts;
|
|
189
|
+
const { cfg, to, text, mediaUrl, mediaLocalRoots, accountId, onProgress, runtime: logRuntime } = opts;
|
|
190
|
+
const log = logRuntime?.log ?? console.log;
|
|
191
|
+
const logError = logRuntime?.error ?? console.error;
|
|
206
192
|
const account = resolveMeetAccount({ cfg, accountId });
|
|
207
193
|
if (!account.configured) {
|
|
208
194
|
throw new Error(`Meet account not configured: ${accountId ?? "default"}`);
|