@takibeiy/moltbot_cn 2026.1.27 → 2026.2.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/build-info.json +5 -0
- package/dist/canvas-host/a2ui/.bundle.hash +1 -0
- package/dist/canvas-host/a2ui/a2ui.bundle.js +17770 -0
- package/dist/canvas-host/a2ui/index.html +307 -0
- package/dist/control-ui/assets/index-BAFzd9IE.css +1 -0
- package/dist/control-ui/assets/index-CxUFDXFX.js +3162 -0
- package/dist/control-ui/assets/index-CxUFDXFX.js.map +1 -0
- package/dist/control-ui/favicon.ico +0 -0
- package/dist/control-ui/index.html +15 -0
- package/dist/hooks/bundled/boot-md/HOOK.md +19 -0
- package/dist/hooks/bundled/command-logger/HOOK.md +122 -0
- package/dist/hooks/bundled/session-memory/HOOK.md +86 -0
- package/dist/hooks/bundled/soul-evil/HOOK.md +71 -0
- package/extensions/diagnostics-otel/node_modules/.bin/acorn +3 -7
- package/extensions/googlechat/node_modules/.bin/clawdbot +3 -7
- package/extensions/googlechat/node_modules/.bin/moltbot +3 -7
- package/extensions/line/node_modules/.bin/clawdbot +3 -7
- package/extensions/line/node_modules/.bin/moltbot +3 -7
- package/extensions/matrix/node_modules/.bin/clawdbot +3 -7
- package/extensions/matrix/node_modules/.bin/markdown-it +3 -7
- package/extensions/matrix/node_modules/.bin/moltbot +3 -7
- package/extensions/memory-core/node_modules/.bin/clawdbot +3 -7
- package/extensions/memory-core/node_modules/.bin/moltbot +3 -7
- package/extensions/memory-lancedb/node_modules/.bin/arrow2csv +3 -7
- package/extensions/memory-lancedb/node_modules/.bin/openai +3 -7
- package/extensions/msteams/node_modules/.bin/clawdbot +3 -7
- package/extensions/msteams/node_modules/.bin/moltbot +3 -7
- package/extensions/nostr/node_modules/.bin/clawdbot +3 -7
- package/extensions/nostr/node_modules/.bin/moltbot +3 -7
- package/extensions/qq/node_modules/.bin/vitest +3 -7
- package/extensions/qq/src/channel.ts +30 -2
- package/extensions/qq/src/onebot/api.test.ts +44 -0
- package/extensions/qq/src/onebot/api.ts +13 -0
- package/extensions/qq/src/send.test.ts +53 -8
- package/extensions/qq/src/send.ts +29 -1
- package/extensions/twitch/node_modules/.bin/clawdbot +3 -7
- package/extensions/twitch/node_modules/.bin/moltbot +3 -7
- package/extensions/zalo/node_modules/.bin/clawdbot +3 -7
- package/extensions/zalo/node_modules/.bin/moltbot +3 -7
- package/extensions/zalouser/node_modules/.bin/clawdbot +3 -7
- package/extensions/zalouser/node_modules/.bin/moltbot +3 -7
- package/git-hooks/pre-commit +0 -0
- package/package.json +2 -2
- package/skills/nano-banana-pro/scripts/generate_image.py +0 -0
- package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +0 -0
- package/skills/tmux/scripts/find-sessions.sh +0 -0
- package/skills/tmux/scripts/wait-for-text.sh +0 -0
- package/extensions/diagnostics-otel/node_modules/.bin/acorn.CMD +0 -12
- package/extensions/diagnostics-otel/node_modules/.bin/acorn.ps1 +0 -41
- package/extensions/googlechat/node_modules/.bin/clawdbot.CMD +0 -12
- package/extensions/googlechat/node_modules/.bin/clawdbot.ps1 +0 -41
- package/extensions/googlechat/node_modules/.bin/moltbot.CMD +0 -12
- package/extensions/googlechat/node_modules/.bin/moltbot.ps1 +0 -41
- package/extensions/line/node_modules/.bin/clawdbot.CMD +0 -12
- package/extensions/line/node_modules/.bin/clawdbot.ps1 +0 -41
- package/extensions/line/node_modules/.bin/moltbot.CMD +0 -12
- package/extensions/line/node_modules/.bin/moltbot.ps1 +0 -41
- package/extensions/matrix/node_modules/.bin/clawdbot.CMD +0 -12
- package/extensions/matrix/node_modules/.bin/clawdbot.ps1 +0 -41
- package/extensions/matrix/node_modules/.bin/markdown-it.CMD +0 -12
- package/extensions/matrix/node_modules/.bin/markdown-it.ps1 +0 -41
- package/extensions/matrix/node_modules/.bin/moltbot.CMD +0 -12
- package/extensions/matrix/node_modules/.bin/moltbot.ps1 +0 -41
- package/extensions/memory-core/node_modules/.bin/clawdbot.CMD +0 -12
- package/extensions/memory-core/node_modules/.bin/clawdbot.ps1 +0 -41
- package/extensions/memory-core/node_modules/.bin/moltbot.CMD +0 -12
- package/extensions/memory-core/node_modules/.bin/moltbot.ps1 +0 -41
- package/extensions/memory-lancedb/node_modules/.bin/arrow2csv.CMD +0 -12
- package/extensions/memory-lancedb/node_modules/.bin/arrow2csv.ps1 +0 -41
- package/extensions/memory-lancedb/node_modules/.bin/openai.CMD +0 -12
- package/extensions/memory-lancedb/node_modules/.bin/openai.ps1 +0 -41
- package/extensions/msteams/node_modules/.bin/clawdbot.CMD +0 -12
- package/extensions/msteams/node_modules/.bin/clawdbot.ps1 +0 -41
- package/extensions/msteams/node_modules/.bin/moltbot.CMD +0 -12
- package/extensions/msteams/node_modules/.bin/moltbot.ps1 +0 -41
- package/extensions/nostr/node_modules/.bin/clawdbot.CMD +0 -12
- package/extensions/nostr/node_modules/.bin/clawdbot.ps1 +0 -41
- package/extensions/nostr/node_modules/.bin/moltbot.CMD +0 -12
- package/extensions/nostr/node_modules/.bin/moltbot.ps1 +0 -41
- package/extensions/nostr/node_modules/.bin/tsc +0 -21
- package/extensions/nostr/node_modules/.bin/tsc.CMD +0 -12
- package/extensions/nostr/node_modules/.bin/tsc.ps1 +0 -41
- package/extensions/nostr/node_modules/.bin/tsserver +0 -21
- package/extensions/nostr/node_modules/.bin/tsserver.CMD +0 -12
- package/extensions/nostr/node_modules/.bin/tsserver.ps1 +0 -41
- package/extensions/qq/node_modules/.bin/vite +0 -21
- package/extensions/qq/node_modules/.bin/vite.CMD +0 -12
- package/extensions/qq/node_modules/.bin/vite.ps1 +0 -41
- package/extensions/qq/node_modules/.bin/vitest.CMD +0 -12
- package/extensions/qq/node_modules/.bin/vitest.ps1 +0 -41
- package/extensions/twitch/node_modules/.bin/clawdbot.CMD +0 -12
- package/extensions/twitch/node_modules/.bin/clawdbot.ps1 +0 -41
- package/extensions/twitch/node_modules/.bin/moltbot.CMD +0 -12
- package/extensions/twitch/node_modules/.bin/moltbot.ps1 +0 -41
- package/extensions/zalo/node_modules/.bin/clawdbot.CMD +0 -12
- package/extensions/zalo/node_modules/.bin/clawdbot.ps1 +0 -41
- package/extensions/zalo/node_modules/.bin/moltbot.CMD +0 -12
- package/extensions/zalo/node_modules/.bin/moltbot.ps1 +0 -41
- package/extensions/zalouser/node_modules/.bin/clawdbot.CMD +0 -12
- package/extensions/zalouser/node_modules/.bin/clawdbot.ps1 +0 -41
- package/extensions/zalouser/node_modules/.bin/moltbot.CMD +0 -12
- package/extensions/zalouser/node_modules/.bin/moltbot.ps1 +0 -41
|
@@ -2,17 +2,13 @@
|
|
|
2
2
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
3
|
|
|
4
4
|
case `uname` in
|
|
5
|
-
*CYGWIN
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
5
|
+
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
|
10
6
|
esac
|
|
11
7
|
|
|
12
8
|
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/
|
|
9
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules"
|
|
14
10
|
else
|
|
15
|
-
export NODE_PATH="/
|
|
11
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
12
|
fi
|
|
17
13
|
if [ -x "$basedir/node" ]; then
|
|
18
14
|
exec "$basedir/node" "$basedir/../moltbot/moltbot.mjs" "$@"
|
|
@@ -2,17 +2,13 @@
|
|
|
2
2
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
3
|
|
|
4
4
|
case `uname` in
|
|
5
|
-
*CYGWIN
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
5
|
+
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
|
10
6
|
esac
|
|
11
7
|
|
|
12
8
|
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/
|
|
9
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules"
|
|
14
10
|
else
|
|
15
|
-
export NODE_PATH="/
|
|
11
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
12
|
fi
|
|
17
13
|
if [ -x "$basedir/node" ]; then
|
|
18
14
|
exec "$basedir/node" "$basedir/../moltbot/moltbot.mjs" "$@"
|
|
@@ -2,17 +2,13 @@
|
|
|
2
2
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
3
|
|
|
4
4
|
case `uname` in
|
|
5
|
-
*CYGWIN
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
5
|
+
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
|
10
6
|
esac
|
|
11
7
|
|
|
12
8
|
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/
|
|
9
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules"
|
|
14
10
|
else
|
|
15
|
-
export NODE_PATH="/
|
|
11
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
12
|
fi
|
|
17
13
|
if [ -x "$basedir/node" ]; then
|
|
18
14
|
exec "$basedir/node" "$basedir/../moltbot/moltbot.mjs" "$@"
|
|
@@ -2,17 +2,13 @@
|
|
|
2
2
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
3
|
|
|
4
4
|
case `uname` in
|
|
5
|
-
*CYGWIN
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
5
|
+
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
|
10
6
|
esac
|
|
11
7
|
|
|
12
8
|
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/
|
|
9
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules"
|
|
14
10
|
else
|
|
15
|
-
export NODE_PATH="/
|
|
11
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
12
|
fi
|
|
17
13
|
if [ -x "$basedir/node" ]; then
|
|
18
14
|
exec "$basedir/node" "$basedir/../moltbot/moltbot.mjs" "$@"
|
|
@@ -2,17 +2,13 @@
|
|
|
2
2
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
3
|
|
|
4
4
|
case `uname` in
|
|
5
|
-
*CYGWIN
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
5
|
+
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
|
10
6
|
esac
|
|
11
7
|
|
|
12
8
|
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/
|
|
9
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/vitest@2.1.9_@types+node@25.1.0/node_modules/vitest/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/vitest@2.1.9_@types+node@25.1.0/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules"
|
|
14
10
|
else
|
|
15
|
-
export NODE_PATH="/
|
|
11
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/vitest@2.1.9_@types+node@25.1.0/node_modules/vitest/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/vitest@2.1.9_@types+node@25.1.0/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
12
|
fi
|
|
17
13
|
if [ -x "$basedir/node" ]; then
|
|
18
14
|
exec "$basedir/node" "$basedir/../vitest/vitest.mjs" "$@"
|
|
@@ -8,6 +8,7 @@ import type { ChannelPlugin, MoltbotConfig } from "clawdbot/plugin-sdk";
|
|
|
8
8
|
import {
|
|
9
9
|
applyAccountNameToChannelSection,
|
|
10
10
|
buildChannelConfigSchema,
|
|
11
|
+
createTypingCallbacks,
|
|
11
12
|
DEFAULT_ACCOUNT_ID,
|
|
12
13
|
migrateBaseNameToDefaultAccount,
|
|
13
14
|
normalizeAccountId,
|
|
@@ -23,7 +24,7 @@ import { QQConfigSchema, QQ_DEFAULT_WS_URL } from "./config-schema.js";
|
|
|
23
24
|
import { QQConnectionManager, createConnectionManager } from "./connection.js";
|
|
24
25
|
import { parseQQTarget, normalizeQQMessagingTarget, looksLikeQQTargetId } from "./normalize.js";
|
|
25
26
|
import { qqOnboardingAdapter } from "./onboarding.js";
|
|
26
|
-
import { sendQQTextMessage, sendQQMediaMessage } from "./send.js";
|
|
27
|
+
import { sendQQTextMessage, sendQQMediaMessage, setQQTypingStatus } from "./send.js";
|
|
27
28
|
import { isBotMentioned, removeBotMention } from "./monitor.js";
|
|
28
29
|
import { getQQRuntime } from "./runtime.js";
|
|
29
30
|
import type {
|
|
@@ -308,6 +309,31 @@ export const qqPlugin: ChannelPlugin<ResolvedQQAccount> = {
|
|
|
308
309
|
currentCfg,
|
|
309
310
|
route.agentId,
|
|
310
311
|
);
|
|
312
|
+
|
|
313
|
+
// Create typing callbacks (only for private chats)
|
|
314
|
+
const typingCallbacks = isPrivate
|
|
315
|
+
? createTypingCallbacks({
|
|
316
|
+
start: async () => {
|
|
317
|
+
const api = manager.getApi();
|
|
318
|
+
if (api) await setQQTypingStatus(api, message.senderId, true);
|
|
319
|
+
},
|
|
320
|
+
stop: async () => {
|
|
321
|
+
const api = manager.getApi();
|
|
322
|
+
if (api) await setQQTypingStatus(api, message.senderId, false);
|
|
323
|
+
},
|
|
324
|
+
onStartError: (err) => {
|
|
325
|
+
ctx.log?.debug?.(
|
|
326
|
+
`[${accountId}] typing start failed: ${String(err)}`,
|
|
327
|
+
);
|
|
328
|
+
},
|
|
329
|
+
onStopError: (err) => {
|
|
330
|
+
ctx.log?.debug?.(
|
|
331
|
+
`[${accountId}] typing stop failed: ${String(err)}`,
|
|
332
|
+
);
|
|
333
|
+
},
|
|
334
|
+
})
|
|
335
|
+
: undefined;
|
|
336
|
+
|
|
311
337
|
const { dispatcher, replyOptions, markDispatchIdle } =
|
|
312
338
|
core.channel.reply.createReplyDispatcherWithTyping({
|
|
313
339
|
humanDelay,
|
|
@@ -345,6 +371,8 @@ export const qqPlugin: ChannelPlugin<ResolvedQQAccount> = {
|
|
|
345
371
|
`[${accountId}] ${info.kind} reply failed: ${String(err)}`,
|
|
346
372
|
);
|
|
347
373
|
},
|
|
374
|
+
onReplyStart: typingCallbacks?.onReplyStart,
|
|
375
|
+
onIdle: typingCallbacks?.onIdle,
|
|
348
376
|
});
|
|
349
377
|
|
|
350
378
|
// Dispatch to auto-reply pipeline
|
|
@@ -460,7 +488,7 @@ export const qqPlugin: ChannelPlugin<ResolvedQQAccount> = {
|
|
|
460
488
|
// Outbound Adapter - Sending Messages
|
|
461
489
|
// ==========================================================================
|
|
462
490
|
outbound: {
|
|
463
|
-
deliveryMode: "
|
|
491
|
+
deliveryMode: "gateway",
|
|
464
492
|
textChunkLimit: 4000,
|
|
465
493
|
|
|
466
494
|
sendText: async ({ to, text, accountId, replyToId }) => {
|
|
@@ -366,4 +366,48 @@ describe("OneBotApi", () => {
|
|
|
366
366
|
expect(result).toBe(false);
|
|
367
367
|
});
|
|
368
368
|
});
|
|
369
|
+
|
|
370
|
+
describe("setInputStatus", () => {
|
|
371
|
+
it("sets typing status (text input)", async () => {
|
|
372
|
+
const client = createMockClient();
|
|
373
|
+
const api = new OneBotApi(client);
|
|
374
|
+
|
|
375
|
+
vi.mocked(client.callApi).mockResolvedValue(undefined);
|
|
376
|
+
|
|
377
|
+
await api.setInputStatus(12345, 1);
|
|
378
|
+
|
|
379
|
+
expect(client.callApi).toHaveBeenCalledWith("set_input_status", {
|
|
380
|
+
user_id: 12345,
|
|
381
|
+
event_type: 1,
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it("sets normal status", async () => {
|
|
386
|
+
const client = createMockClient();
|
|
387
|
+
const api = new OneBotApi(client);
|
|
388
|
+
|
|
389
|
+
vi.mocked(client.callApi).mockResolvedValue(undefined);
|
|
390
|
+
|
|
391
|
+
await api.setInputStatus(12345, 2);
|
|
392
|
+
|
|
393
|
+
expect(client.callApi).toHaveBeenCalledWith("set_input_status", {
|
|
394
|
+
user_id: 12345,
|
|
395
|
+
event_type: 2,
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
it("defaults to text input (1)", async () => {
|
|
400
|
+
const client = createMockClient();
|
|
401
|
+
const api = new OneBotApi(client);
|
|
402
|
+
|
|
403
|
+
vi.mocked(client.callApi).mockResolvedValue(undefined);
|
|
404
|
+
|
|
405
|
+
await api.setInputStatus(12345);
|
|
406
|
+
|
|
407
|
+
expect(client.callApi).toHaveBeenCalledWith("set_input_status", {
|
|
408
|
+
user_id: 12345,
|
|
409
|
+
event_type: 1,
|
|
410
|
+
});
|
|
411
|
+
});
|
|
412
|
+
});
|
|
369
413
|
});
|
|
@@ -355,6 +355,19 @@ export class OneBotApi {
|
|
|
355
355
|
return false;
|
|
356
356
|
}
|
|
357
357
|
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Set input status (typing indicator).
|
|
361
|
+
* Only works for private chats.
|
|
362
|
+
* @param userId Target user ID
|
|
363
|
+
* @param eventType 0=voice, 1=text typing, 2=normal
|
|
364
|
+
*/
|
|
365
|
+
async setInputStatus(userId: number, eventType: 0 | 1 | 2 = 1): Promise<void> {
|
|
366
|
+
await this.client.callApi("set_input_status", {
|
|
367
|
+
user_id: userId,
|
|
368
|
+
event_type: eventType,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
358
371
|
}
|
|
359
372
|
|
|
360
373
|
// ============================================================================
|
|
@@ -12,13 +12,25 @@ import {
|
|
|
12
12
|
sendQQMediaMessage,
|
|
13
13
|
sendQQRawMessage,
|
|
14
14
|
sendQQTextMessage,
|
|
15
|
+
setQQTypingStatus,
|
|
15
16
|
} from "./send.js";
|
|
16
17
|
|
|
18
|
+
// Mock loadWebMedia from plugin-sdk
|
|
19
|
+
vi.mock("clawdbot/plugin-sdk", () => ({
|
|
20
|
+
loadWebMedia: vi.fn().mockResolvedValue({
|
|
21
|
+
buffer: Buffer.from("fake-image-data"),
|
|
22
|
+
contentType: "image/jpeg",
|
|
23
|
+
kind: "image",
|
|
24
|
+
fileName: "image.jpg",
|
|
25
|
+
}),
|
|
26
|
+
}));
|
|
27
|
+
|
|
17
28
|
// Mock API factory
|
|
18
29
|
function createMockApi(overrides: Partial<OneBotApi> = {}): OneBotApi {
|
|
19
30
|
return {
|
|
20
31
|
sendPrivateMsg: vi.fn().mockResolvedValue({ message_id: 100 }),
|
|
21
32
|
sendGroupMsg: vi.fn().mockResolvedValue({ message_id: 200 }),
|
|
33
|
+
setInputStatus: vi.fn().mockResolvedValue(undefined),
|
|
22
34
|
...overrides,
|
|
23
35
|
} as unknown as OneBotApi;
|
|
24
36
|
}
|
|
@@ -107,6 +119,8 @@ describe("sendQQTextMessage", () => {
|
|
|
107
119
|
});
|
|
108
120
|
|
|
109
121
|
describe("sendQQMediaMessage", () => {
|
|
122
|
+
const expectedBase64 = `base64://${Buffer.from("fake-image-data").toString("base64")}`;
|
|
123
|
+
|
|
110
124
|
it("sends image to private chat", async () => {
|
|
111
125
|
const api = createMockApi();
|
|
112
126
|
|
|
@@ -118,7 +132,7 @@ describe("sendQQMediaMessage", () => {
|
|
|
118
132
|
|
|
119
133
|
expect(result.ok).toBe(true);
|
|
120
134
|
expect(api.sendPrivateMsg).toHaveBeenCalledWith(12345, [
|
|
121
|
-
{ type: "image", data: { file:
|
|
135
|
+
{ type: "image", data: { file: expectedBase64 } },
|
|
122
136
|
]);
|
|
123
137
|
});
|
|
124
138
|
|
|
@@ -133,7 +147,7 @@ describe("sendQQMediaMessage", () => {
|
|
|
133
147
|
});
|
|
134
148
|
|
|
135
149
|
expect(api.sendPrivateMsg).toHaveBeenCalledWith(12345, [
|
|
136
|
-
{ type: "image", data: { file:
|
|
150
|
+
{ type: "image", data: { file: expectedBase64 } },
|
|
137
151
|
{ type: "text", data: { text: "Look at this!" } },
|
|
138
152
|
]);
|
|
139
153
|
});
|
|
@@ -148,7 +162,7 @@ describe("sendQQMediaMessage", () => {
|
|
|
148
162
|
});
|
|
149
163
|
|
|
150
164
|
expect(api.sendPrivateMsg).toHaveBeenCalledWith(12345, [
|
|
151
|
-
{ type: "record", data: { file:
|
|
165
|
+
{ type: "record", data: { file: expectedBase64 } },
|
|
152
166
|
]);
|
|
153
167
|
});
|
|
154
168
|
|
|
@@ -162,7 +176,7 @@ describe("sendQQMediaMessage", () => {
|
|
|
162
176
|
});
|
|
163
177
|
|
|
164
178
|
expect(api.sendGroupMsg).toHaveBeenCalledWith(67890, [
|
|
165
|
-
{ type: "video", data: { file:
|
|
179
|
+
{ type: "video", data: { file: expectedBase64 } },
|
|
166
180
|
]);
|
|
167
181
|
});
|
|
168
182
|
|
|
@@ -176,7 +190,7 @@ describe("sendQQMediaMessage", () => {
|
|
|
176
190
|
});
|
|
177
191
|
|
|
178
192
|
expect(api.sendPrivateMsg).toHaveBeenCalledWith(12345, [
|
|
179
|
-
{ type: "text", data: { text:
|
|
193
|
+
{ type: "text", data: { text: `[文件] ${expectedBase64}` } },
|
|
180
194
|
]);
|
|
181
195
|
});
|
|
182
196
|
|
|
@@ -192,7 +206,7 @@ describe("sendQQMediaMessage", () => {
|
|
|
192
206
|
|
|
193
207
|
expect(api.sendPrivateMsg).toHaveBeenCalledWith(12345, [
|
|
194
208
|
{ type: "reply", data: { id: "888" } },
|
|
195
|
-
{ type: "image", data: { file:
|
|
209
|
+
{ type: "image", data: { file: expectedBase64 } },
|
|
196
210
|
]);
|
|
197
211
|
});
|
|
198
212
|
|
|
@@ -289,6 +303,8 @@ describe("convenience functions", () => {
|
|
|
289
303
|
});
|
|
290
304
|
|
|
291
305
|
describe("sendPrivateImage", () => {
|
|
306
|
+
const expectedBase64 = `base64://${Buffer.from("fake-image-data").toString("base64")}`;
|
|
307
|
+
|
|
292
308
|
it("sends image to user", async () => {
|
|
293
309
|
const api = createMockApi();
|
|
294
310
|
|
|
@@ -301,13 +317,15 @@ describe("convenience functions", () => {
|
|
|
301
317
|
|
|
302
318
|
expect(result.ok).toBe(true);
|
|
303
319
|
expect(api.sendPrivateMsg).toHaveBeenCalledWith(12345, [
|
|
304
|
-
{ type: "image", data: { file:
|
|
320
|
+
{ type: "image", data: { file: expectedBase64 } },
|
|
305
321
|
{ type: "text", data: { text: "Check this out!" } },
|
|
306
322
|
]);
|
|
307
323
|
});
|
|
308
324
|
});
|
|
309
325
|
|
|
310
326
|
describe("sendGroupImage", () => {
|
|
327
|
+
const expectedBase64 = `base64://${Buffer.from("fake-image-data").toString("base64")}`;
|
|
328
|
+
|
|
311
329
|
it("sends image to group", async () => {
|
|
312
330
|
const api = createMockApi();
|
|
313
331
|
|
|
@@ -315,8 +333,35 @@ describe("convenience functions", () => {
|
|
|
315
333
|
|
|
316
334
|
expect(result.ok).toBe(true);
|
|
317
335
|
expect(api.sendGroupMsg).toHaveBeenCalledWith(67890, [
|
|
318
|
-
{ type: "image", data: { file:
|
|
336
|
+
{ type: "image", data: { file: expectedBase64 } },
|
|
319
337
|
]);
|
|
320
338
|
});
|
|
321
339
|
});
|
|
322
340
|
});
|
|
341
|
+
|
|
342
|
+
describe("setQQTypingStatus", () => {
|
|
343
|
+
it("sets typing status to true", async () => {
|
|
344
|
+
const api = createMockApi();
|
|
345
|
+
|
|
346
|
+
await setQQTypingStatus(api, 12345, true);
|
|
347
|
+
|
|
348
|
+
expect(api.setInputStatus).toHaveBeenCalledWith(12345, 1);
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
it("sets typing status to false (normal)", async () => {
|
|
352
|
+
const api = createMockApi();
|
|
353
|
+
|
|
354
|
+
await setQQTypingStatus(api, 12345, false);
|
|
355
|
+
|
|
356
|
+
expect(api.setInputStatus).toHaveBeenCalledWith(12345, 2);
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
it("silently ignores errors", async () => {
|
|
360
|
+
const api = createMockApi({
|
|
361
|
+
setInputStatus: vi.fn().mockRejectedValue(new Error("API not supported")),
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
// Should not throw
|
|
365
|
+
await expect(setQQTypingStatus(api, 12345, true)).resolves.toBeUndefined();
|
|
366
|
+
});
|
|
367
|
+
});
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Handles sending text and media messages via OneBot API.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { loadWebMedia } from "clawdbot/plugin-sdk";
|
|
7
8
|
import type { OneBotApi } from "./onebot/api.js";
|
|
8
9
|
import type { OneBotMessageSegment, OneBotSendMsgResponse } from "./onebot/types.js";
|
|
9
10
|
import { formatQQTarget, parseQQTarget, type ParsedQQTarget } from "./normalize.js";
|
|
@@ -149,6 +150,7 @@ export async function sendQQTextMessage(
|
|
|
149
150
|
|
|
150
151
|
/**
|
|
151
152
|
* Send a media message to a QQ target.
|
|
153
|
+
* Downloads the media and converts to base64 for NapCatQQ compatibility.
|
|
152
154
|
*/
|
|
153
155
|
export async function sendQQMediaMessage(
|
|
154
156
|
api: OneBotApi,
|
|
@@ -163,9 +165,13 @@ export async function sendQQMediaMessage(
|
|
|
163
165
|
}
|
|
164
166
|
|
|
165
167
|
try {
|
|
168
|
+
// Load media and convert to base64 for NapCatQQ compatibility
|
|
169
|
+
const media = await loadWebMedia(options.file);
|
|
170
|
+
const base64File = `base64://${media.buffer.toString("base64")}`;
|
|
171
|
+
|
|
166
172
|
const segments = buildMediaSegments(
|
|
167
173
|
options.mediaType,
|
|
168
|
-
|
|
174
|
+
base64File,
|
|
169
175
|
options.caption,
|
|
170
176
|
options.replyToMessageId,
|
|
171
177
|
);
|
|
@@ -285,3 +291,25 @@ export async function sendGroupImage(
|
|
|
285
291
|
caption,
|
|
286
292
|
});
|
|
287
293
|
}
|
|
294
|
+
|
|
295
|
+
// ============================================================================
|
|
296
|
+
// Typing Status
|
|
297
|
+
// ============================================================================
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Set typing status for a private chat.
|
|
301
|
+
* Only works for private chats (OneBot v11 limitation).
|
|
302
|
+
* Silently ignores errors since not all implementations support this API.
|
|
303
|
+
*/
|
|
304
|
+
export async function setQQTypingStatus(
|
|
305
|
+
api: OneBotApi,
|
|
306
|
+
userId: number,
|
|
307
|
+
typing: boolean,
|
|
308
|
+
): Promise<void> {
|
|
309
|
+
try {
|
|
310
|
+
// 0=voice, 1=text typing, 2=normal
|
|
311
|
+
await api.setInputStatus(userId, typing ? 1 : 2);
|
|
312
|
+
} catch {
|
|
313
|
+
// Silently ignore - not all OneBot implementations support this
|
|
314
|
+
}
|
|
315
|
+
}
|
|
@@ -2,17 +2,13 @@
|
|
|
2
2
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
3
|
|
|
4
4
|
case `uname` in
|
|
5
|
-
*CYGWIN
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
5
|
+
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
|
10
6
|
esac
|
|
11
7
|
|
|
12
8
|
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/
|
|
9
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules"
|
|
14
10
|
else
|
|
15
|
-
export NODE_PATH="/
|
|
11
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
12
|
fi
|
|
17
13
|
if [ -x "$basedir/node" ]; then
|
|
18
14
|
exec "$basedir/node" "$basedir/../moltbot/moltbot.mjs" "$@"
|
|
@@ -2,17 +2,13 @@
|
|
|
2
2
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
3
|
|
|
4
4
|
case `uname` in
|
|
5
|
-
*CYGWIN
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
5
|
+
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
|
10
6
|
esac
|
|
11
7
|
|
|
12
8
|
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/
|
|
9
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules"
|
|
14
10
|
else
|
|
15
|
-
export NODE_PATH="/
|
|
11
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
12
|
fi
|
|
17
13
|
if [ -x "$basedir/node" ]; then
|
|
18
14
|
exec "$basedir/node" "$basedir/../moltbot/moltbot.mjs" "$@"
|
|
@@ -2,17 +2,13 @@
|
|
|
2
2
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
3
|
|
|
4
4
|
case `uname` in
|
|
5
|
-
*CYGWIN
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
5
|
+
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
|
10
6
|
esac
|
|
11
7
|
|
|
12
8
|
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/
|
|
9
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules"
|
|
14
10
|
else
|
|
15
|
-
export NODE_PATH="/
|
|
11
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
12
|
fi
|
|
17
13
|
if [ -x "$basedir/node" ]; then
|
|
18
14
|
exec "$basedir/node" "$basedir/../moltbot/moltbot.mjs" "$@"
|
|
@@ -2,17 +2,13 @@
|
|
|
2
2
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
3
|
|
|
4
4
|
case `uname` in
|
|
5
|
-
*CYGWIN
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
5
|
+
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
|
10
6
|
esac
|
|
11
7
|
|
|
12
8
|
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/
|
|
9
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules"
|
|
14
10
|
else
|
|
15
|
-
export NODE_PATH="/
|
|
11
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
12
|
fi
|
|
17
13
|
if [ -x "$basedir/node" ]; then
|
|
18
14
|
exec "$basedir/node" "$basedir/../moltbot/moltbot.mjs" "$@"
|
|
@@ -2,17 +2,13 @@
|
|
|
2
2
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
3
|
|
|
4
4
|
case `uname` in
|
|
5
|
-
*CYGWIN
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
5
|
+
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
|
10
6
|
esac
|
|
11
7
|
|
|
12
8
|
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/
|
|
9
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules"
|
|
14
10
|
else
|
|
15
|
-
export NODE_PATH="/
|
|
11
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
12
|
fi
|
|
17
13
|
if [ -x "$basedir/node" ]; then
|
|
18
14
|
exec "$basedir/node" "$basedir/../moltbot/moltbot.mjs" "$@"
|
|
@@ -2,17 +2,13 @@
|
|
|
2
2
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
3
|
|
|
4
4
|
case `uname` in
|
|
5
|
-
*CYGWIN
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
5
|
+
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
|
10
6
|
esac
|
|
11
7
|
|
|
12
8
|
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/
|
|
9
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules"
|
|
14
10
|
else
|
|
15
|
-
export NODE_PATH="/
|
|
11
|
+
export NODE_PATH="/Users/taki/Documents/Node/moltbot/node_modules:/Users/taki/Documents/Node/node_modules:/Users/taki/Documents/node_modules:/Users/taki/node_modules:/Users/node_modules:/node_modules:/Users/taki/Documents/Node/moltbot/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
12
|
fi
|
|
17
13
|
if [ -x "$basedir/node" ]; then
|
|
18
14
|
exec "$basedir/node" "$basedir/../moltbot/moltbot.mjs" "$@"
|
package/git-hooks/pre-commit
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@takibeiy/moltbot_cn",
|
|
3
|
-
"version": "2026.1
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2026.2.1",
|
|
4
|
+
"description": "WhatsApp gateway CLI (Baileys web) with Pi RPC agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"exports": {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|