diff --git a/.eslintrc.json b/.eslintrc.json index 36fcae4..695c6b2 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -16,6 +16,13 @@ "import/prefer-default-export": "off", "import/no-default-export": "error", "@typescript-eslint/prefer-readonly-parameter-types": "off", + "class-methods-use-this": "off", + "@typescript-eslint/class-methods-use-this": [ + "error", + { + "ignoreOverrideMethods": true + } + ], "import/order": [ "error", { diff --git a/src/AprilBot.ts b/src/AprilBot.ts index 87a5cb6..c3f0046 100644 --- a/src/AprilBot.ts +++ b/src/AprilBot.ts @@ -1,13 +1,43 @@ import { GenericAprilBot } from './GenericAprilBot'; +import { getLogger } from './logger'; +import type { + SocketModeEventPayload, + ReactionAddedEvent, + ReactionRemovedEvent, + MessageEvent, +} from './types'; + +const logger = getLogger(); class AprilBot extends GenericAprilBot { constructor(userToken: string, appToken: string) { super(userToken, appToken); + logger.debug('AprilBot is constructed'); } - public async start() { - await super.start(); - } + protected override handleMessage = ({ + ack, + event, + }: SocketModeEventPayload) => { + ack(); + logger.debug(event, 'handleMessage'); + }; + + protected override handleReactionAdded = ({ + ack, + event, + }: SocketModeEventPayload) => { + ack(); + logger.debug(event, 'handleReactionAdded'); + }; + + protected override handleReactionRemoved = ({ + ack, + event, + }: SocketModeEventPayload) => { + ack(); + logger.debug(event, 'handleReactionRemoved'); + }; } export { AprilBot }; diff --git a/src/GenericAprilBot.ts b/src/GenericAprilBot.ts index d671b86..fc1fc4e 100644 --- a/src/GenericAprilBot.ts +++ b/src/GenericAprilBot.ts @@ -1,5 +1,11 @@ import { SocketModeClient } from '@slack/socket-mode'; import { WebClient } from '@slack/web-api'; +import type { + SocketModeEventPayload, + ReactionAddedEvent, + ReactionRemovedEvent, + MessageEvent, +} from './types'; abstract class GenericAprilBot { private readonly userToken: string; @@ -19,9 +25,24 @@ abstract class GenericAprilBot { this.webClient = new WebClient(this.userToken); } - public async start() { + public async start(): Promise { + this.socketModeClient.on('message', this.handleMessage); + this.socketModeClient.on('reaction_added', this.handleReactionAdded); + this.socketModeClient.on('reaction_removed', this.handleReactionRemoved); await this.socketModeClient.start(); } + + protected abstract handleMessage: ( + args: SocketModeEventPayload, + ) => void; + + protected abstract handleReactionAdded: ( + args: SocketModeEventPayload, + ) => void; + + protected abstract handleReactionRemoved: ( + args: SocketModeEventPayload, + ) => void; } export { GenericAprilBot }; diff --git a/src/logger.ts b/src/logger.ts index ab71b4a..7cc9a7b 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -2,6 +2,7 @@ import pino from 'pino'; const getLogger = () => pino({ + level: process.env.LOG_LEVEL ?? 'info', transport: { target: 'pino-pretty', options: { diff --git a/src/types/MessageEvent.ts b/src/types/MessageEvent.ts new file mode 100644 index 0000000..de3d2e4 --- /dev/null +++ b/src/types/MessageEvent.ts @@ -0,0 +1,31 @@ +interface MessageEvent { + user: string; + type: string; + ts: string; + client_msg_id: string; + text: string; + team: string; + thread_ts?: string; + blocks: MessageBlock[]; + channel: string; + event_ts: string; + channel_type: string; +} + +interface MessageBlock { + type: string; + block_id: string; + elements: BlockElement[]; +} + +interface BlockElement { + type: string[]; + elements: BlockElementElement[]; +} + +interface BlockElementElement { + type: string; + text: string; +} + +export { MessageEvent }; diff --git a/src/types/ReactionAddedEvent.ts b/src/types/ReactionAddedEvent.ts new file mode 100644 index 0000000..7b99741 --- /dev/null +++ b/src/types/ReactionAddedEvent.ts @@ -0,0 +1,14 @@ +interface ReactionAddedEvent { + type: string; + user: string; + reaction: string; + item: { + type: string; + channel: string; + ts: string; + }; + item_user: string; + event_ts: string; +} + +export { ReactionAddedEvent }; diff --git a/src/types/ReactionRemovedEvent.ts b/src/types/ReactionRemovedEvent.ts new file mode 100644 index 0000000..9087ed1 --- /dev/null +++ b/src/types/ReactionRemovedEvent.ts @@ -0,0 +1,14 @@ +interface ReactionRemovedEvent { + type: string; + user: string; + reaction: string; + item: { + type: string; + channel: string; + ts: string; + }; + item_user: string; + event_ts: string; +} + +export { ReactionRemovedEvent }; diff --git a/src/types/SocketModeEventPayload.ts b/src/types/SocketModeEventPayload.ts new file mode 100644 index 0000000..59a0eb8 --- /dev/null +++ b/src/types/SocketModeEventPayload.ts @@ -0,0 +1,6 @@ +interface SocketModeEventPayload { + event: T; + ack: () => void; +} + +export { SocketModeEventPayload }; diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..18a092e --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,4 @@ +export * from './MessageEvent'; +export * from './ReactionAddedEvent'; +export * from './ReactionRemovedEvent'; +export * from './SocketModeEventPayload';