diff --git a/extensions/slack/src/monitor/message-handler/prepare.test.ts b/extensions/slack/src/monitor/message-handler/prepare.test.ts index 0ea12b699bab..48c7296a089a 100644 --- a/extensions/slack/src/monitor/message-handler/prepare.test.ts +++ b/extensions/slack/src/monitor/message-handler/prepare.test.ts @@ -188,6 +188,14 @@ describe("slack prepareSlackMessage inbound contract", () => { expect(prepared.ctxPayload.BodyForAgent).toContain(body); }); + it("keeps a whole code point when the inbound preview boundary crosses an emoji", async () => { + const prefix = "a".repeat(159); + const prepared = await prepareWithDefaultCtx(createSlackMessage({ text: `${prefix}😀tail` })); + + assertPrepared(prepared); + expect(prepared.preview).toBe(prefix); + }); + it("logs inbound metadata without logging message content", async () => { const body = "confidential acquisition target: northstar; do not include this text in logs"; shouldLogVerboseMock.mockReturnValue(true); diff --git a/extensions/slack/src/monitor/message-handler/prepare.ts b/extensions/slack/src/monitor/message-handler/prepare.ts index 08cf005b39f4..b3c17c6bf5ca 100644 --- a/extensions/slack/src/monitor/message-handler/prepare.ts +++ b/extensions/slack/src/monitor/message-handler/prepare.ts @@ -35,6 +35,7 @@ import { normalizeOptionalString, } from "openclaw/plugin-sdk/string-coerce-runtime"; import { enqueueSystemEvent } from "openclaw/plugin-sdk/system-event-runtime"; +import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime"; import { resolveSlackReplyToMode } from "../../account-reply-mode.js"; import type { ResolvedSlackAccount } from "../../accounts.js"; import { reactSlackMessage } from "../../actions.js"; @@ -1210,7 +1211,7 @@ export async function prepareSlackMessage(params: { const roomLabel = channelName ? `#${channelName}` : `#${message.channel}`; const senderName = await resolveSenderName(); - const preview = rawBody.replace(/\s+/g, " ").slice(0, 160); + const preview = truncateUtf16Safe(rawBody.replace(/\s+/g, " "), 160); const inboundLabel = isDirectMessage ? `Slack DM from ${senderName}` : `Slack message in ${roomLabel} from ${senderName}`;