From 7e42408adeb5d23876f70c63b7a079bb73a3dce0 Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 16 Feb 2026 13:08:29 -0500 Subject: [PATCH] Slack: dedupe normalized interaction selections --- src/slack/monitor/events/interactions.test.ts | 7 +++--- src/slack/monitor/events/interactions.ts | 25 ++++++++++++++++--- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/slack/monitor/events/interactions.test.ts b/src/slack/monitor/events/interactions.test.ts index 264e3fdef..5ce371744 100644 --- a/src/slack/monitor/events/interactions.test.ts +++ b/src/slack/monitor/events/interactions.test.ts @@ -211,12 +211,13 @@ describe("registerSlackInteractionEvents", () => { type: "multi_conversations_select", action_id: "openclaw:route", selected_user: "U777", - selected_users: ["U888"], + selected_users: ["U777", "U888"], selected_channel: "C777", - selected_channels: ["C888"], + selected_channels: ["C777", "C888"], selected_conversation: "G777", - selected_conversations: ["G888"], + selected_conversations: ["G777", "G888"], selected_options: [ + { text: { type: "plain_text", text: "Alpha" }, value: "alpha" }, { text: { type: "plain_text", text: "Alpha" }, value: "alpha" }, { text: { type: "plain_text", text: "Beta" }, value: "beta" }, ], diff --git a/src/slack/monitor/events/interactions.ts b/src/slack/monitor/events/interactions.ts index 5a3d09d0a..91fd554d8 100644 --- a/src/slack/monitor/events/interactions.ts +++ b/src/slack/monitor/events/interactions.ts @@ -70,6 +70,23 @@ function readOptionLabels(options: unknown): string[] | undefined { return labels.length > 0 ? labels : undefined; } +function uniqueNonEmptyStrings(values: string[]): string[] { + const unique: string[] = []; + const seen = new Set(); + for (const entry of values) { + if (typeof entry !== "string") { + continue; + } + const trimmed = entry.trim(); + if (!trimmed || seen.has(trimmed)) { + continue; + } + seen.add(trimmed); + unique.push(trimmed); + } + return unique; +} + function summarizeAction( action: Record, ): Omit { @@ -89,7 +106,7 @@ function summarizeAction( value?: string; }; const actionType = typed.type; - const selectedValues = [ + const selectedValues = uniqueNonEmptyStrings([ ...(typed.selected_option?.value ? [typed.selected_option.value] : []), ...(readOptionValues(typed.selected_options) ?? []), ...(typed.selected_user ? [typed.selected_user] : []), @@ -98,11 +115,11 @@ function summarizeAction( ...(Array.isArray(typed.selected_channels) ? typed.selected_channels : []), ...(typed.selected_conversation ? [typed.selected_conversation] : []), ...(Array.isArray(typed.selected_conversations) ? typed.selected_conversations : []), - ].filter((entry) => typeof entry === "string" && entry.trim().length > 0); - const selectedLabels = [ + ]); + const selectedLabels = uniqueNonEmptyStrings([ ...(typed.selected_option?.text?.text ? [typed.selected_option.text.text] : []), ...(readOptionLabels(typed.selected_options) ?? []), - ].filter((entry) => typeof entry === "string" && entry.trim().length > 0); + ]); return { actionType,