Spaces:
Running
Running
| import type { SlackEventMiddlewareArgs } from "@slack/bolt"; | |
| import type { SlackAppMentionEvent, SlackMessageEvent } from "../../types.js"; | |
| import type { SlackMonitorContext } from "../context.js"; | |
| import type { SlackMessageHandler } from "../message-handler.js"; | |
| import type { | |
| SlackMessageChangedEvent, | |
| SlackMessageDeletedEvent, | |
| SlackThreadBroadcastEvent, | |
| } from "../types.js"; | |
| import { danger } from "../../../globals.js"; | |
| import { enqueueSystemEvent } from "../../../infra/system-events.js"; | |
| import { resolveSlackChannelLabel } from "../channel-config.js"; | |
| export function registerSlackMessageEvents(params: { | |
| ctx: SlackMonitorContext; | |
| handleSlackMessage: SlackMessageHandler; | |
| }) { | |
| const { ctx, handleSlackMessage } = params; | |
| ctx.app.event("message", async ({ event, body }: SlackEventMiddlewareArgs<"message">) => { | |
| try { | |
| if (ctx.shouldDropMismatchedSlackEvent(body)) { | |
| return; | |
| } | |
| const message = event as SlackMessageEvent; | |
| if (message.subtype === "message_changed") { | |
| const changed = event as SlackMessageChangedEvent; | |
| const channelId = changed.channel; | |
| const channelInfo = channelId ? await ctx.resolveChannelName(channelId) : {}; | |
| const channelType = channelInfo?.type; | |
| if ( | |
| !ctx.isChannelAllowed({ | |
| channelId, | |
| channelName: channelInfo?.name, | |
| channelType, | |
| }) | |
| ) { | |
| return; | |
| } | |
| const messageId = changed.message?.ts ?? changed.previous_message?.ts; | |
| const label = resolveSlackChannelLabel({ | |
| channelId, | |
| channelName: channelInfo?.name, | |
| }); | |
| const sessionKey = ctx.resolveSlackSystemEventSessionKey({ | |
| channelId, | |
| channelType, | |
| }); | |
| enqueueSystemEvent(`Slack message edited in ${label}.`, { | |
| sessionKey, | |
| contextKey: `slack:message:changed:${channelId ?? "unknown"}:${messageId ?? changed.event_ts ?? "unknown"}`, | |
| }); | |
| return; | |
| } | |
| if (message.subtype === "message_deleted") { | |
| const deleted = event as SlackMessageDeletedEvent; | |
| const channelId = deleted.channel; | |
| const channelInfo = channelId ? await ctx.resolveChannelName(channelId) : {}; | |
| const channelType = channelInfo?.type; | |
| if ( | |
| !ctx.isChannelAllowed({ | |
| channelId, | |
| channelName: channelInfo?.name, | |
| channelType, | |
| }) | |
| ) { | |
| return; | |
| } | |
| const label = resolveSlackChannelLabel({ | |
| channelId, | |
| channelName: channelInfo?.name, | |
| }); | |
| const sessionKey = ctx.resolveSlackSystemEventSessionKey({ | |
| channelId, | |
| channelType, | |
| }); | |
| enqueueSystemEvent(`Slack message deleted in ${label}.`, { | |
| sessionKey, | |
| contextKey: `slack:message:deleted:${channelId ?? "unknown"}:${deleted.deleted_ts ?? deleted.event_ts ?? "unknown"}`, | |
| }); | |
| return; | |
| } | |
| if (message.subtype === "thread_broadcast") { | |
| const thread = event as SlackThreadBroadcastEvent; | |
| const channelId = thread.channel; | |
| const channelInfo = channelId ? await ctx.resolveChannelName(channelId) : {}; | |
| const channelType = channelInfo?.type; | |
| if ( | |
| !ctx.isChannelAllowed({ | |
| channelId, | |
| channelName: channelInfo?.name, | |
| channelType, | |
| }) | |
| ) { | |
| return; | |
| } | |
| const label = resolveSlackChannelLabel({ | |
| channelId, | |
| channelName: channelInfo?.name, | |
| }); | |
| const messageId = thread.message?.ts ?? thread.event_ts; | |
| const sessionKey = ctx.resolveSlackSystemEventSessionKey({ | |
| channelId, | |
| channelType, | |
| }); | |
| enqueueSystemEvent(`Slack thread reply broadcast in ${label}.`, { | |
| sessionKey, | |
| contextKey: `slack:thread:broadcast:${channelId ?? "unknown"}:${messageId ?? "unknown"}`, | |
| }); | |
| return; | |
| } | |
| await handleSlackMessage(message, { source: "message" }); | |
| } catch (err) { | |
| ctx.runtime.error?.(danger(`slack handler failed: ${String(err)}`)); | |
| } | |
| }); | |
| ctx.app.event("app_mention", async ({ event, body }: SlackEventMiddlewareArgs<"app_mention">) => { | |
| try { | |
| if (ctx.shouldDropMismatchedSlackEvent(body)) { | |
| return; | |
| } | |
| const mention = event as SlackAppMentionEvent; | |
| await handleSlackMessage(mention as unknown as SlackMessageEvent, { | |
| source: "app_mention", | |
| wasMentioned: true, | |
| }); | |
| } catch (err) { | |
| ctx.runtime.error?.(danger(`slack mention handler failed: ${String(err)}`)); | |
| } | |
| }); | |
| } | |