mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-04 17:12:10 +00:00
fix(discord): ignore empty components on media send
This commit is contained in:
@@ -64,6 +64,15 @@ export const discordMessagingActionRuntime = {
|
||||
unpinMessageDiscord,
|
||||
};
|
||||
|
||||
function hasDiscordComponentObjectKeys(value: unknown): value is Record<string, unknown> {
|
||||
return Boolean(
|
||||
value &&
|
||||
typeof value === "object" &&
|
||||
!Array.isArray(value) &&
|
||||
Object.keys(value as Record<string, unknown>).length > 0,
|
||||
);
|
||||
}
|
||||
|
||||
function parseDiscordMessageLink(link: string) {
|
||||
const normalized = link.trim();
|
||||
const match = normalized.match(
|
||||
@@ -299,10 +308,9 @@ export async function handleDiscordMessagingAction(
|
||||
const asVoice = params.asVoice === true;
|
||||
const silent = params.silent === true;
|
||||
const rawComponents = params.components;
|
||||
const componentSpec =
|
||||
rawComponents && typeof rawComponents === "object" && !Array.isArray(rawComponents)
|
||||
? discordMessagingActionRuntime.readDiscordComponentSpec(rawComponents)
|
||||
: null;
|
||||
const componentSpec = hasDiscordComponentObjectKeys(rawComponents)
|
||||
? discordMessagingActionRuntime.readDiscordComponentSpec(rawComponents)
|
||||
: null;
|
||||
const components: DiscordSendComponents | undefined =
|
||||
Array.isArray(rawComponents) || typeof rawComponents === "function"
|
||||
? (rawComponents as DiscordSendComponents)
|
||||
|
||||
@@ -46,6 +46,7 @@ const discordSendMocks = {
|
||||
removeOwnReactionsDiscord: vi.fn(async () => ({ removed: ["👍"] })),
|
||||
removeReactionDiscord: vi.fn(async () => ({})),
|
||||
searchMessagesDiscord: vi.fn(async () => ({})),
|
||||
sendDiscordComponentMessage: vi.fn(async () => ({})),
|
||||
sendMessageDiscord: vi.fn(async () => ({})),
|
||||
sendPollDiscord: vi.fn(async () => ({})),
|
||||
sendStickerDiscord: vi.fn(async () => ({})),
|
||||
@@ -71,6 +72,7 @@ const {
|
||||
removeOwnReactionsDiscord,
|
||||
removeReactionDiscord,
|
||||
searchMessagesDiscord,
|
||||
sendDiscordComponentMessage,
|
||||
sendMessageDiscord,
|
||||
sendPollDiscord,
|
||||
sendVoiceMessageDiscord,
|
||||
@@ -366,6 +368,33 @@ describe("handleDiscordMessagingAction", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("ignores empty components objects for regular media sends", async () => {
|
||||
sendMessageDiscord.mockClear();
|
||||
sendDiscordComponentMessage.mockClear();
|
||||
|
||||
await handleDiscordMessagingAction(
|
||||
"sendMessage",
|
||||
{
|
||||
to: "channel:123",
|
||||
content: "hello",
|
||||
mediaUrl: "/tmp/image.png",
|
||||
components: {},
|
||||
},
|
||||
enableAllActions,
|
||||
{ mediaLocalRoots: ["/tmp/agent-root"] },
|
||||
);
|
||||
|
||||
expect(sendDiscordComponentMessage).not.toHaveBeenCalled();
|
||||
expect(sendMessageDiscord).toHaveBeenCalledWith(
|
||||
"channel:123",
|
||||
"hello",
|
||||
expect.objectContaining({
|
||||
mediaUrl: "/tmp/image.png",
|
||||
mediaLocalRoots: ["/tmp/agent-root"],
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects voice messages that include content", async () => {
|
||||
await expect(
|
||||
handleDiscordMessagingAction(
|
||||
|
||||
Reference in New Issue
Block a user