Skip to content

Commit de86ea4

Browse files
committed
feat: job scanner
1 parent a7bda5b commit de86ea4

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

src/features/job-scanner.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import type { ChannelHandlers } from "../types/index.js";
2+
import { EmbedType } from "discord.js";
3+
4+
import { CHANNELS } from "../constants/channels.js";
5+
import { EMBED_COLOR } from "./commands.js";
6+
7+
const jobKeywords = [
8+
"looking for work",
9+
"seeking opportunities",
10+
"available for hire",
11+
"open to work",
12+
"freelance available",
13+
"seeking a role",
14+
"looking for projects",
15+
"hire me",
16+
"job opportunities",
17+
"job offer",
18+
"job opportunity",
19+
"contact me",
20+
"actively seeking",
21+
"available for freelance",
22+
"remote position",
23+
"dm me",
24+
"reach out",
25+
"ready to join",
26+
"new opportunity",
27+
"open position",
28+
"seeking remote",
29+
"available now",
30+
"remote role",
31+
"remote opportunity",
32+
"full-time",
33+
"job opportunities",
34+
"opportunities available",
35+
"new opportunity",
36+
"open for",
37+
"we’re hiring",
38+
"we are hiring",
39+
];
40+
41+
const currencyKeywords = ["₹", "€", "$"];
42+
const hasCodeBlockWithDollarSign = (content: string): boolean => {
43+
const codeBlockRegex = /```[\s\S]*?\$[\s\S]*?```/g;
44+
return codeBlockRegex.test(content);
45+
};
46+
47+
export const jobScanner: ChannelHandlers = {
48+
handleMessage: async ({ msg }) => {
49+
if (msg.author.bot) return;
50+
51+
const content = msg.content.toLowerCase();
52+
const ignoreDollar = hasCodeBlockWithDollarSign(content);
53+
const hasCurrencyKeyword =
54+
!ignoreDollar &&
55+
currencyKeywords.some((keyword) => content.includes(keyword));
56+
57+
const keywordRegex = new RegExp(`\\b(${jobKeywords.join("|")})\\b`, "i");
58+
const containsJobKeyword = keywordRegex.test(content);
59+
if (!containsJobKeyword && !hasCurrencyKeyword) return;
60+
61+
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.`;
62+
const sentMsg = await msg.reply({
63+
embeds: [
64+
{
65+
title: "Oops! Wrong Channel, Maybe?",
66+
type: EmbedType.Rich,
67+
description: warningMsg,
68+
color: EMBED_COLOR,
69+
},
70+
],
71+
});
72+
await msg.delete().catch(console.error);
73+
setTimeout(() => {
74+
sentMsg.delete().catch(console.error);
75+
}, 300_000);
76+
},
77+
};

src/index.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
import { recommendBookCommand } from "./features/book-list.js";
4242
import { mdnSearch } from "./features/mdn.js";
4343
import "./server.js";
44+
import { jobScanner } from "./features/job-scanner.js";
4445

4546
export const bot = new Client({
4647
intents: [
@@ -205,7 +206,18 @@ addHandler(
205206
],
206207
promotionThread,
207208
);
208-
209+
addHandler(
210+
[
211+
CHANNELS.helpReact,
212+
CHANNELS.helpJs,
213+
CHANNELS.helpReactNative,
214+
CHANNELS.helpStyling,
215+
CHANNELS.helpBackend,
216+
CHANNELS.generalReact,
217+
CHANNELS.generalTech,
218+
],
219+
jobScanner,
220+
);
209221
const threadChannels = [CHANNELS.helpJs, CHANNELS.helpThreadsReact];
210222
addHandler(threadChannels, autothread);
211223

0 commit comments

Comments
 (0)