Skip to content

Commit cef6cca

Browse files
committed
fix(zalouser): keep outbound message text truncation UTF-16 safe
Replace two raw .slice(0, 2000) calls with truncateUtf16Safe in Zalo media-message and plain-text send paths to prevent dangling surrogate pairs when the 2000-code-unit boundary splits an emoji or CJK supplementary character in outbound user-visible messages.
1 parent bd7da9d commit cef6cca

1 file changed

Lines changed: 15 additions & 6 deletions

File tree

extensions/zalouser/src/zalo-js.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
normalizeOptionalLowercaseString,
2727
normalizeOptionalString,
2828
} from "openclaw/plugin-sdk/string-coerce-runtime";
29-
import { sleep } from "openclaw/plugin-sdk/text-utility-runtime";
29+
import { sleep, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
3030
import { normalizeZaloReactionIcon } from "./reaction.js";
3131
import { createZalouserSendReceipt } from "./send-receipt.js";
3232
import type {
@@ -1238,7 +1238,7 @@ export async function sendZaloTextMessage(
12381238
contentType: media.contentType,
12391239
kind: media.kind,
12401240
});
1241-
const payloadText = (text || options.caption || "").slice(0, 2000);
1241+
const payloadText = truncateUtf16Safe(text || options.caption || "", 2000);
12421242
const textStyles = clampTextStyles(payloadText, options.textStyles);
12431243

12441244
if (media.kind === "audio") {
@@ -1313,7 +1313,7 @@ export async function sendZaloTextMessage(
13131313
};
13141314
}
13151315

1316-
const payloadText = text.slice(0, 2000);
1316+
const payloadText = truncateUtf16Safe(text, 2000);
13171317
const textStyles = clampTextStyles(payloadText, options.textStyles);
13181318
const response = await api.sendMessage(
13191319
textStyles ? { msg: payloadText, styles: textStyles } : payloadText,
@@ -1334,7 +1334,10 @@ export async function sendZaloTextMessage(
13341334
return {
13351335
ok: false,
13361336
error: toErrorMessage(error),
1337-
receipt: createZalouserSendReceipt({ threadId: trimmedThreadId, kind: "unknown" }),
1337+
receipt: createZalouserSendReceipt({
1338+
threadId: trimmedThreadId,
1339+
kind: "unknown",
1340+
}),
13381341
};
13391342
}
13401343
},
@@ -1466,7 +1469,10 @@ export async function sendZaloLink(
14661469
return {
14671470
ok: false,
14681471
error: "No URL provided",
1469-
receipt: createZalouserSendReceipt({ threadId: trimmedThreadId, kind: "card" }),
1472+
receipt: createZalouserSendReceipt({
1473+
threadId: trimmedThreadId,
1474+
kind: "card",
1475+
}),
14701476
};
14711477
}
14721478

@@ -1497,7 +1503,10 @@ export async function sendZaloLink(
14971503
return {
14981504
ok: false,
14991505
error: toErrorMessage(error),
1500-
receipt: createZalouserSendReceipt({ threadId: trimmedThreadId, kind: "card" }),
1506+
receipt: createZalouserSendReceipt({
1507+
threadId: trimmedThreadId,
1508+
kind: "card",
1509+
}),
15011510
};
15021511
}
15031512
}

0 commit comments

Comments
 (0)