mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-11 04:04:32 +00:00
Slack: enrich block action context payloads
This commit is contained in:
@@ -11,7 +11,11 @@ type RegisteredHandler = (args: {
|
|||||||
ack: () => Promise<void>;
|
ack: () => Promise<void>;
|
||||||
body: {
|
body: {
|
||||||
user: { id: string };
|
user: { id: string };
|
||||||
|
team?: { id?: string };
|
||||||
|
trigger_id?: string;
|
||||||
|
response_url?: string;
|
||||||
channel?: { id?: string };
|
channel?: { id?: string };
|
||||||
|
container?: { channel_id?: string; message_ts?: string; thread_ts?: string };
|
||||||
message?: { ts?: string; text?: string; blocks?: unknown[] };
|
message?: { ts?: string; text?: string; blocks?: unknown[] };
|
||||||
};
|
};
|
||||||
action: Record<string, unknown>;
|
action: Record<string, unknown>;
|
||||||
@@ -100,7 +104,11 @@ describe("registerSlackInteractionEvents", () => {
|
|||||||
respond,
|
respond,
|
||||||
body: {
|
body: {
|
||||||
user: { id: "U123" },
|
user: { id: "U123" },
|
||||||
|
team: { id: "T9" },
|
||||||
|
trigger_id: "123.trigger",
|
||||||
|
response_url: "https://hooks.slack.test/response",
|
||||||
channel: { id: "C1" },
|
channel: { id: "C1" },
|
||||||
|
container: { channel_id: "C1", message_ts: "100.200", thread_ts: "100.100" },
|
||||||
message: {
|
message: {
|
||||||
ts: "100.200",
|
ts: "100.200",
|
||||||
text: "fallback",
|
text: "fallback",
|
||||||
@@ -131,16 +139,24 @@ describe("registerSlackInteractionEvents", () => {
|
|||||||
actionType: string;
|
actionType: string;
|
||||||
value: string;
|
value: string;
|
||||||
userId: string;
|
userId: string;
|
||||||
|
teamId?: string;
|
||||||
|
triggerId?: string;
|
||||||
|
responseUrl?: string;
|
||||||
channelId: string;
|
channelId: string;
|
||||||
messageTs: string;
|
messageTs: string;
|
||||||
|
threadTs?: string;
|
||||||
};
|
};
|
||||||
expect(payload).toMatchObject({
|
expect(payload).toMatchObject({
|
||||||
actionId: "openclaw:verify",
|
actionId: "openclaw:verify",
|
||||||
actionType: "button",
|
actionType: "button",
|
||||||
value: "approved",
|
value: "approved",
|
||||||
userId: "U123",
|
userId: "U123",
|
||||||
|
teamId: "T9",
|
||||||
|
triggerId: "123.trigger",
|
||||||
|
responseUrl: "https://hooks.slack.test/response",
|
||||||
channelId: "C1",
|
channelId: "C1",
|
||||||
messageTs: "100.200",
|
messageTs: "100.200",
|
||||||
|
threadTs: "100.100",
|
||||||
});
|
});
|
||||||
expect(resolveSessionKey).toHaveBeenCalledWith({
|
expect(resolveSessionKey).toHaveBeenCalledWith({
|
||||||
channelId: "C1",
|
channelId: "C1",
|
||||||
@@ -192,6 +208,52 @@ describe("registerSlackInteractionEvents", () => {
|
|||||||
expect(app.client.chat.update).not.toHaveBeenCalled();
|
expect(app.client.chat.update).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("falls back to container channel and message timestamps", async () => {
|
||||||
|
enqueueSystemEventMock.mockReset();
|
||||||
|
const { ctx, app, getHandler, resolveSessionKey } = createContext();
|
||||||
|
registerSlackInteractionEvents({ ctx: ctx as never });
|
||||||
|
const handler = getHandler();
|
||||||
|
expect(handler).toBeTruthy();
|
||||||
|
|
||||||
|
const ack = vi.fn().mockResolvedValue(undefined);
|
||||||
|
await handler!({
|
||||||
|
ack,
|
||||||
|
body: {
|
||||||
|
user: { id: "U111" },
|
||||||
|
team: { id: "T111" },
|
||||||
|
container: { channel_id: "C222", message_ts: "222.333", thread_ts: "222.111" },
|
||||||
|
},
|
||||||
|
action: {
|
||||||
|
type: "button",
|
||||||
|
action_id: "openclaw:container",
|
||||||
|
block_id: "container_block",
|
||||||
|
value: "ok",
|
||||||
|
text: { type: "plain_text", text: "Container" },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(ack).toHaveBeenCalled();
|
||||||
|
expect(resolveSessionKey).toHaveBeenCalledWith({
|
||||||
|
channelId: "C222",
|
||||||
|
channelType: undefined,
|
||||||
|
});
|
||||||
|
expect(enqueueSystemEventMock).toHaveBeenCalledTimes(1);
|
||||||
|
const [eventText] = enqueueSystemEventMock.mock.calls[0] as [string];
|
||||||
|
const payload = JSON.parse(eventText.replace("Slack interaction: ", "")) as {
|
||||||
|
channelId?: string;
|
||||||
|
messageTs?: string;
|
||||||
|
threadTs?: string;
|
||||||
|
teamId?: string;
|
||||||
|
};
|
||||||
|
expect(payload).toMatchObject({
|
||||||
|
channelId: "C222",
|
||||||
|
messageTs: "222.333",
|
||||||
|
threadTs: "222.111",
|
||||||
|
teamId: "T111",
|
||||||
|
});
|
||||||
|
expect(app.client.chat.update).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it("captures expanded selection and temporal payload fields", async () => {
|
it("captures expanded selection and temporal payload fields", async () => {
|
||||||
enqueueSystemEventMock.mockReset();
|
enqueueSystemEventMock.mockReset();
|
||||||
const { ctx, getHandler } = createContext();
|
const { ctx, getHandler } = createContext();
|
||||||
|
|||||||
@@ -31,8 +31,12 @@ type InteractionSummary = {
|
|||||||
selectedDateTime?: number;
|
selectedDateTime?: number;
|
||||||
inputValue?: string;
|
inputValue?: string;
|
||||||
userId?: string;
|
userId?: string;
|
||||||
|
teamId?: string;
|
||||||
|
triggerId?: string;
|
||||||
|
responseUrl?: string;
|
||||||
channelId?: string;
|
channelId?: string;
|
||||||
messageTs?: string;
|
messageTs?: string;
|
||||||
|
threadTs?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ModalInputSummary = {
|
type ModalInputSummary = {
|
||||||
@@ -205,7 +209,11 @@ export function registerSlackInteractionEvents(params: { ctx: SlackMonitorContex
|
|||||||
const { ack, body, action, respond } = args;
|
const { ack, body, action, respond } = args;
|
||||||
const typedBody = body as unknown as {
|
const typedBody = body as unknown as {
|
||||||
user?: { id?: string };
|
user?: { id?: string };
|
||||||
|
team?: { id?: string };
|
||||||
|
trigger_id?: string;
|
||||||
|
response_url?: string;
|
||||||
channel?: { id?: string };
|
channel?: { id?: string };
|
||||||
|
container?: { channel_id?: string; message_ts?: string; thread_ts?: string };
|
||||||
message?: { ts?: string; text?: string; blocks?: unknown[] };
|
message?: { ts?: string; text?: string; blocks?: unknown[] };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -222,8 +230,9 @@ export function registerSlackInteractionEvents(params: { ctx: SlackMonitorContex
|
|||||||
const actionId = typedAction.action_id ?? "unknown";
|
const actionId = typedAction.action_id ?? "unknown";
|
||||||
const blockId = typedAction.block_id;
|
const blockId = typedAction.block_id;
|
||||||
const userId = typedBody.user?.id ?? "unknown";
|
const userId = typedBody.user?.id ?? "unknown";
|
||||||
const channelId = typedBody.channel?.id;
|
const channelId = typedBody.channel?.id ?? typedBody.container?.channel_id;
|
||||||
const messageTs = typedBody.message?.ts;
|
const messageTs = typedBody.message?.ts ?? typedBody.container?.message_ts;
|
||||||
|
const threadTs = typedBody.container?.thread_ts;
|
||||||
const actionSummary = summarizeAction(typedAction);
|
const actionSummary = summarizeAction(typedAction);
|
||||||
const eventPayload: InteractionSummary = {
|
const eventPayload: InteractionSummary = {
|
||||||
interactionType: "block_action",
|
interactionType: "block_action",
|
||||||
@@ -231,8 +240,12 @@ export function registerSlackInteractionEvents(params: { ctx: SlackMonitorContex
|
|||||||
blockId,
|
blockId,
|
||||||
...actionSummary,
|
...actionSummary,
|
||||||
userId,
|
userId,
|
||||||
|
teamId: typedBody.team?.id,
|
||||||
|
triggerId: typedBody.trigger_id,
|
||||||
|
responseUrl: typedBody.response_url,
|
||||||
channelId,
|
channelId,
|
||||||
messageTs,
|
messageTs,
|
||||||
|
threadTs,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Log the interaction for debugging
|
// Log the interaction for debugging
|
||||||
|
|||||||
Reference in New Issue
Block a user