diff --git a/src/constants/channels.ts b/src/constants/channels.ts index a55c99d4..3f45ed3c 100644 --- a/src/constants/channels.ts +++ b/src/constants/channels.ts @@ -2,6 +2,7 @@ import { ChannelType, Client, TextChannel } from "discord.js"; import { guildId, isProd } from "../helpers/env.js"; const LOCAL_CHANNELS: Record = { + introduction: "925847644318879754", helpReact: "926931785219207301", helpThreadsReact: "950790460857794620", helpJs: "950790460857794620", @@ -20,12 +21,25 @@ const LOCAL_CHANNELS: Record = { modLog: "925847644318879754", botLog: "916081991542276096", vcLog: "1237103703740121201", + generalTech: "1166062952084942940", + jobsAdvice: "1166062952084942940", + generalReact: "1166062952084942940", + helpReactNative: "1166062952084942940", + helpStyling: "1166062952084942940", + helpBackend: "1166062952084942940", }; const PRODUCTION_CHANNELS = { + introduction: "306196179538935818", helpReact: "103696749012467712", helpThreadsReact: "902647189120118794", helpJs: "565213527673929729", + generalTech: "102860784329052160", + jobsAdvice: "287623405946011648", + generalReact: "102860784329052160", + helpReactNative: "469170673533583361", + helpStyling: "105765765117935616", + helpBackend: "145170347921113088", random: "103325358643752960", gaming: "509219336175747082", thanks: "798567961468076072", diff --git a/src/features/message-scanner.ts b/src/features/message-scanner.ts new file mode 100644 index 00000000..2693a308 --- /dev/null +++ b/src/features/message-scanner.ts @@ -0,0 +1,77 @@ +import type { ChannelHandlers } from "../types/index.d.ts"; +import { EmbedType } from "discord.js"; + +import { CHANNELS } from "../constants/channels.js"; +import { EMBED_COLOR } from "./commands.js"; + +const jobKeywords = [ + "looking for work", + "seeking opportunities", + "available for hire", + "open to work", + "freelance available", + "seeking a role", + "looking for projects", + "hire me", + "job opportunities", + "job offer", + "job opportunity", + "contact me", + "actively seeking", + "available for freelance", + "remote position", + "dm me", + "reach out", + "ready to join", + "new opportunity", + "open position", + "seeking remote", + "available now", + "remote role", + "remote opportunity", + "full-time", + "job opportunities", + "opportunities available", + "new opportunity", + "open for", + "we’re hiring", + "we are hiring", +]; + +const currencyKeywords = ["₹", "€", "$"]; +const hasCodeBlockWithDollarSign = (content: string): boolean => { + const codeBlockRegex = /```[\s\S]*?\$[\s\S]*?```/g; + return codeBlockRegex.test(content); +}; + +export const messageScanner: ChannelHandlers = { + handleMessage: async ({ msg }) => { + if (msg.author.bot) return; + + const content = msg.content.toLowerCase(); + const ignoreDollar = hasCodeBlockWithDollarSign(content); + const hasCurrencyKeyword = + !ignoreDollar && + currencyKeywords.some((keyword) => content.includes(keyword)); + + const keywordRegex = new RegExp(`\\b(${jobKeywords.join("|")})\\b`, "i"); + const containsJobKeyword = keywordRegex.test(content); + if (!containsJobKeyword && !hasCurrencyKeyword) return; + + const warningMsg = `Oops <@${msg.author.id}>! This message looks more like a job/collaboration/advice post. Mind sharing that in <#${CHANNELS.jobsLog}> or <#${CHANNELS.lookingForGroup}> or <#${CHANNELS.jobsAdvice}> instead? If this was a mistake, please try again and ask your question. Appreciate you helping us keep channels on-topic 🙌`; + const sentMsg = await msg.reply({ + embeds: [ + { + title: "Oops! Wrong Channel, Maybe?", + type: EmbedType.Rich, + description: warningMsg, + color: EMBED_COLOR, + }, + ], + }); + await msg.delete(); + setTimeout(() => { + sentMsg.delete().catch(console.error); + }, 300_000); + }, +}; diff --git a/src/index.ts b/src/index.ts index 25dcb89d..308899a1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,7 +10,7 @@ import { ActivityType, IntentsBitField, } from "discord.js"; - +import { messageScanner } from "./features/message-scanner.js"; import { logger, channelLog } from "./features/log.js"; // import codeblock from './features/codeblock'; import jobsMod, { resetJobCacheCommand } from "./features/jobs-moderation.js"; @@ -205,6 +205,19 @@ addHandler( promotionThread, ); +addHandler( + [ + CHANNELS.helpReact, + CHANNELS.helpJs, + CHANNELS.helpReactNative, + CHANNELS.helpStyling, + CHANNELS.helpBackend, + CHANNELS.generalReact, + CHANNELS.generalTech, + ], + messageScanner, +); + const threadChannels = [CHANNELS.helpJs, CHANNELS.helpThreadsReact]; addHandler(threadChannels, autothread);