mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-03 03:03:24 -04:00
Slack: update action rows for select interactions
This commit is contained in:
@@ -165,7 +165,7 @@ describe("registerSlackInteractionEvents", () => {
|
||||
expect(app.client.chat.update).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("captures select values and skips chat.update for non-button actions", async () => {
|
||||
it("captures select values and updates action rows for non-button actions", async () => {
|
||||
enqueueSystemEventMock.mockReset();
|
||||
const { ctx, app, getHandler } = createContext();
|
||||
registerSlackInteractionEvents({ ctx: ctx as never });
|
||||
@@ -205,7 +205,19 @@ describe("registerSlackInteractionEvents", () => {
|
||||
expect(payload.actionType).toBe("static_select");
|
||||
expect(payload.selectedValues).toEqual(["canary"]);
|
||||
expect(payload.selectedLabels).toEqual(["Canary"]);
|
||||
expect(app.client.chat.update).not.toHaveBeenCalled();
|
||||
expect(app.client.chat.update).toHaveBeenCalledTimes(1);
|
||||
expect(app.client.chat.update).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
channel: "C1",
|
||||
ts: "111.222",
|
||||
blocks: [
|
||||
{
|
||||
type: "context",
|
||||
elements: [{ type: "mrkdwn", text: ":white_check_mark: *Canary* selected" }],
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("falls back to container channel and message timestamps", async () => {
|
||||
@@ -254,6 +266,62 @@ describe("registerSlackInteractionEvents", () => {
|
||||
expect(app.client.chat.update).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("summarizes multi-select confirmations in updated message rows", async () => {
|
||||
enqueueSystemEventMock.mockReset();
|
||||
const { ctx, app, getHandler } = createContext();
|
||||
registerSlackInteractionEvents({ ctx: ctx as never });
|
||||
const handler = getHandler();
|
||||
expect(handler).toBeTruthy();
|
||||
|
||||
const ack = vi.fn().mockResolvedValue(undefined);
|
||||
await handler!({
|
||||
ack,
|
||||
body: {
|
||||
user: { id: "U222" },
|
||||
channel: { id: "C2" },
|
||||
message: {
|
||||
ts: "333.444",
|
||||
text: "fallback",
|
||||
blocks: [
|
||||
{
|
||||
type: "actions",
|
||||
block_id: "multi_block",
|
||||
elements: [{ type: "multi_static_select", action_id: "openclaw:multi" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
action: {
|
||||
type: "multi_static_select",
|
||||
action_id: "openclaw:multi",
|
||||
block_id: "multi_block",
|
||||
selected_options: [
|
||||
{ text: { type: "plain_text", text: "Alpha" }, value: "alpha" },
|
||||
{ text: { type: "plain_text", text: "Beta" }, value: "beta" },
|
||||
{ text: { type: "plain_text", text: "Gamma" }, value: "gamma" },
|
||||
{ text: { type: "plain_text", text: "Delta" }, value: "delta" },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
expect(ack).toHaveBeenCalled();
|
||||
expect(app.client.chat.update).toHaveBeenCalledTimes(1);
|
||||
expect(app.client.chat.update).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
channel: "C2",
|
||||
ts: "333.444",
|
||||
blocks: [
|
||||
{
|
||||
type: "context",
|
||||
elements: [
|
||||
{ type: "mrkdwn", text: ":white_check_mark: *Alpha, Beta, Gamma +1* selected" },
|
||||
],
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("captures expanded selection and temporal payload fields", async () => {
|
||||
enqueueSystemEventMock.mockReset();
|
||||
const { ctx, getHandler } = createContext();
|
||||
|
||||
@@ -147,6 +147,36 @@ function isBulkActionsBlock(block: InteractionMessageBlock): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
function formatInteractionSelectionLabel(params: {
|
||||
actionId: string;
|
||||
summary: Omit<InteractionSummary, "actionId" | "blockId">;
|
||||
buttonText?: string;
|
||||
}): string {
|
||||
if (params.summary.actionType === "button" && params.buttonText?.trim()) {
|
||||
return params.buttonText.trim();
|
||||
}
|
||||
if (params.summary.selectedLabels?.length) {
|
||||
if (params.summary.selectedLabels.length <= 3) {
|
||||
return params.summary.selectedLabels.join(", ");
|
||||
}
|
||||
return `${params.summary.selectedLabels.slice(0, 3).join(", ")} +${
|
||||
params.summary.selectedLabels.length - 3
|
||||
}`;
|
||||
}
|
||||
if (params.summary.selectedValues?.length) {
|
||||
if (params.summary.selectedValues.length <= 3) {
|
||||
return params.summary.selectedValues.join(", ");
|
||||
}
|
||||
return `${params.summary.selectedValues.slice(0, 3).join(", ")} +${
|
||||
params.summary.selectedValues.length - 3
|
||||
}`;
|
||||
}
|
||||
if (params.summary.value?.trim()) {
|
||||
return params.summary.value.trim();
|
||||
}
|
||||
return params.actionId;
|
||||
}
|
||||
|
||||
function summarizeViewState(values: unknown): ModalInputSummary[] {
|
||||
if (!values || typeof values !== "object") {
|
||||
return [];
|
||||
@@ -274,17 +304,21 @@ export function registerSlackInteractionEvents(params: { ctx: SlackMonitorContex
|
||||
return;
|
||||
}
|
||||
|
||||
if (typedAction.type !== "button") {
|
||||
if (!blockId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const buttonText = typedAction.text?.text ?? actionId;
|
||||
const selectedLabel = formatInteractionSelectionLabel({
|
||||
actionId,
|
||||
summary: actionSummary,
|
||||
buttonText: typedAction.text?.text,
|
||||
});
|
||||
let updatedBlocks = originalBlocks.map((block) => {
|
||||
const typedBlock = block as InteractionMessageBlock;
|
||||
if (typedBlock.type === "actions" && typedBlock.block_id === blockId) {
|
||||
return {
|
||||
type: "context",
|
||||
elements: [{ type: "mrkdwn", text: `:white_check_mark: *${buttonText}* selected` }],
|
||||
elements: [{ type: "mrkdwn", text: `:white_check_mark: *${selectedLabel}* selected` }],
|
||||
};
|
||||
}
|
||||
return block;
|
||||
|
||||
Reference in New Issue
Block a user