Skip to content

Commit

Permalink
split slack module
Browse files Browse the repository at this point in the history
  • Loading branch information
Sonam Serchan authored and sonam-serchan committed Aug 1, 2023
1 parent 526af7a commit 4788b13
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 120 deletions.
36 changes: 36 additions & 0 deletions src/emojis/emojiHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import emojis from "../helpers/files/emojis.json";

export function getEmojisToReactWith(text: string): Array<string> {
const lowerCaseText = text.toLowerCase();

const keywords = Object.values(emojis).flat();

// search for each keyword in the text
const emojisToReactWith = findMatchingEmojiKeywords(
keywords,
lowerCaseText,
emojis
);

return Array.from(new Set(emojisToReactWith));
}

function findMatchingEmojiKeywords(
keywords: string[],
lowerCaseText: string,
emojis: Record<string, string[]>
): Array<string> {
const matchingEmojiKeywords: Array<string> = [];

for (const keyword of keywords) {
//this is too deep too
if (lowerCaseText.includes(keyword)) {
matchingEmojiKeywords.push(
Object.keys(emojis).find((key) =>
emojis[key].includes(keyword)
)!
);
}
}
return matchingEmojiKeywords;
}
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { HttpFunction } from "@google-cloud/functions-framework";
import { Log, Logging } from "@google-cloud/logging";
import { SUCCESS_MESSAGE } from "./helpers/constants";
import { writeLog } from "./helpers/logs";
import { handleSlackMessageEvent, postMessageToSlack } from "./helpers/slack";
import { handleSlackMessageEvent } from "./slack/slackEventHandler";
import { SlackWebClient } from "./helpers/types";
import { createHttpTask } from "./helpers/task";
import { readSecret } from "./helpers/secrets";
import { askOpenAI } from "./helpers/openai";
import { postMessageToSlack } from "./slack/slackInteraction";
const { WebClient } = require("@slack/web-api");

// Creates a client
Expand Down
16 changes: 16 additions & 0 deletions src/slack/slackEventHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { SlackEvent } from "../helpers/interfaces";
import { SlackWebClient } from "../helpers/types";
import { strategies } from "./slackEventStrategies";

export async function handleSlackMessageEvent(
slackWebClient: SlackWebClient,
slackEvent: SlackEvent
): Promise<void> {
const strategyName: string = slackEvent.subtype ?? slackEvent.type;
let strategy = strategies[strategyName];
if (strategy) {
await strategy.handle(slackWebClient, slackEvent);
return;
}
console.log(`No strategy found for event type ${slackEvent.type}`);
}
50 changes: 50 additions & 0 deletions src/slack/slackEventStrategies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {
SlackChannelJoinEvent,
SlackEvent,
SlackMessageChangedEvent,
SlackMessageEvent,
} from "../helpers/interfaces";
import { SlackWebClient } from "../helpers/types";
import { handleSlackJoinEvent, reactToSlackPost } from "./slackInteraction";

interface SlackEventStrategy {
handle(slackWebClient: SlackWebClient, slackEvent: SlackEvent): void;
}

class ChannelJoinStrategy implements SlackEventStrategy {
async handle(
slackWebClient: SlackWebClient,
slackEvent: SlackChannelJoinEvent
) {
const userId = slackEvent.user;
const slackChannel = slackEvent.channel;
await handleSlackJoinEvent(slackWebClient, slackChannel, userId);
}
}

class MessageStrategy implements SlackEventStrategy {
async handle(
slackWebClient: SlackWebClient,
slackEvent: SlackMessageEvent
): Promise<void> {
const { text, channel, ts } = slackEvent;
await reactToSlackPost(slackWebClient, text, channel, ts);
}
}

export class MessageChangedStrategy implements SlackEventStrategy {
async handle(
slackWebClient: SlackWebClient,
slackEvent: SlackMessageChangedEvent
): Promise<void> {
const { channel } = slackEvent;
const { text, ts } = slackEvent.message;
await reactToSlackPost(slackWebClient, text, channel, ts);
}
}

export const strategies: Record<string, SlackEventStrategy> = {
channel_join: new ChannelJoinStrategy(),
message: new MessageStrategy(),
message_changed: new MessageChangedStrategy(),
};
142 changes: 23 additions & 119 deletions src/helpers/slack.ts → src/slack/slackInteraction.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,30 @@
import SLACK_MESSAGE_BLOCKS from "./files/welcomeMessageBlocks.json";
import { SlackWebClient } from "./types";
import {
SlackEvent,
SlackChannelJoinEvent,
SlackMessageEvent,
SlackMessageChangedEvent,
} from "./interfaces";
import emojis from "./files/emojis.json";
import { ChatPostMessageArguments, ErrorCode } from "@slack/web-api";
import { SlackWebClient } from "../helpers/types";
import { getEmojisToReactWith } from "../emojis/emojiHandler";
import SLACK_MESSAGE_BLOCKS from "../helpers/files/welcomeMessageBlocks.json";

export function getEmojisToReactWith(text: string): Array<string> {
const lowerCaseText = text.toLowerCase();

const keywords = Object.values(emojis).flat();

// search for each keyword in the text
const emojisToReactWith = findMatchingEmojiKeywords(
keywords,
lowerCaseText,
emojis
);

return Array.from(new Set(emojisToReactWith));
}

function findMatchingEmojiKeywords(
keywords: string[],
lowerCaseText: string,
emojis: Record<string, string[]>
): Array<string> {
const matchingEmojiKeywords: Array<string> = [];

for (const keyword of keywords) {
//this is too deep too
if (lowerCaseText.includes(keyword)) {
matchingEmojiKeywords.push(
Object.keys(emojis).find((key) =>
emojis[key].includes(keyword)
)!
export async function addReactionToSlackPost(
emoji: string,
timestamp: string,
slackChannel: string,
slackWebClient: SlackWebClient
) {
try {
console.log(
`Adding emoji ${emoji} to slack post with timestamp ${timestamp} in channel ${slackChannel}.`
);
await slackWebClient.reactions.add({
channel: slackChannel,
timestamp: timestamp,
name: emoji,
});
} catch (error: any) {
if (error.code === ErrorCode.PlatformError) {
console.log(
`Error while adding reaction to slack post: '${error.message}' and error code: '${error.code}'`
);
}
}
return matchingEmojiKeywords;
}

export async function getCurrentEmojisOnSlackPost(
Expand Down Expand Up @@ -114,30 +97,6 @@ export async function reactToSlackPost(
}
}

export async function addReactionToSlackPost(
emoji: string,
timestamp: string,
slackChannel: string,
slackWebClient: SlackWebClient
) {
try {
console.log(
`Adding emoji ${emoji} to slack post with timestamp ${timestamp} in channel ${slackChannel}.`
);
await slackWebClient.reactions.add({
channel: slackChannel,
timestamp: timestamp,
name: emoji,
});
} catch (error: any) {
if (error.code === ErrorCode.PlatformError) {
console.log(
`Error while adding reaction to slack post: '${error.message}' and error code: '${error.code}'`
);
}
}
}

export async function postMessageToSlack(
slackWebClient: SlackWebClient,
text: string,
Expand All @@ -156,7 +115,7 @@ export async function postMessageToSlack(
return await slackWebClient.chat.postMessage(chatPostMessageArguments);
}

async function handleSlackJoinEvent(
export async function handleSlackJoinEvent(
slackWebClient: SlackWebClient,
slackChannel: string,
userId: string
Expand All @@ -171,58 +130,3 @@ async function handleSlackJoinEvent(

await postMessageToSlack(slackWebClient, welcomeMessageText, slackChannel);
}

interface SlackEventStrategy {
handle(slackWebClient: SlackWebClient, slackEvent: SlackEvent): void;
}

export class ChannelJoinStrategy implements SlackEventStrategy {
async handle(
slackWebClient: SlackWebClient,
slackEvent: SlackChannelJoinEvent
) {
const userId = slackEvent.user;
const slackChannel = slackEvent.channel;
await handleSlackJoinEvent(slackWebClient, slackChannel, userId);
}
}

export class MessageStrategy implements SlackEventStrategy {
async handle(
slackWebClient: SlackWebClient,
slackEvent: SlackMessageEvent
): Promise<void> {
const { text, channel, ts } = slackEvent;
await reactToSlackPost(slackWebClient, text, channel, ts);
}
}

export class MessageChangedStrategy implements SlackEventStrategy {
async handle(
slackWebClient: SlackWebClient,
slackEvent: SlackMessageChangedEvent
): Promise<void> {
const { channel } = slackEvent;
const { text, ts } = slackEvent.message;
await reactToSlackPost(slackWebClient, text, channel, ts);
}
}

export const strategies: Record<string, SlackEventStrategy> = {
channel_join: new ChannelJoinStrategy(),
message: new MessageStrategy(),
message_changed: new MessageChangedStrategy(),
};

export async function handleSlackMessageEvent(
slackWebClient: SlackWebClient,
slackEvent: SlackEvent
): Promise<void> {
const strategyName: string = slackEvent.subtype ?? slackEvent.type;
let strategy = strategies[strategyName];
if (strategy) {
await strategy.handle(slackWebClient, slackEvent);
return;
}
console.log(`No strategy found for event type ${slackEvent.type}`);
}

0 comments on commit 4788b13

Please sign in to comment.