Skip to content

Commit 32bee49

Browse files
committed
feat: introducing react queue, so the bot react one message at the time, this is seperated from download queue
1 parent 5def3a4 commit 32bee49

7 files changed

Lines changed: 80 additions & 57 deletions

File tree

src/components/client.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import revoke from "./events/revoke";
2020
import callEvent from "./events/call";
2121
import DownloadMedia from "./utils/message/download";
2222
import CheckSpamLink from "./utils/phishtank/checkSpam";
23-
import queue from "./queue";
23+
import queue from "./queue/download";
2424
import groupAdminChanged from "./events/groups/groupAdminChanged";
2525

2626
let instance: Client | null = null;
@@ -91,7 +91,6 @@ function registerEvents(client: Client): void {
9191

9292
client.on("message_create", (msg: Message) => {
9393
CheckSpamLink(msg);
94-
queue.add(() => DownloadMedia(msg));
9594
messageEvent(msg, "create");
9695
});
9796
client.on("media_uploaded", (msg: Message) =>

src/components/events/message.ts

Lines changed: 6 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
1-
import {
2-
Client,
3-
Message,
4-
MessageContent,
5-
MessageSendOptions,
6-
} from "whatsapp-web.js";
1+
import { Message, MessageContent, MessageSendOptions } from "whatsapp-web.js";
72
import log from "../utils/log";
83
import { commands } from "../utils/cmd/loader";
94
import { penalizeUser, rateLimiter } from "../utils/rateLimiter";
10-
import sleep from "../utils/sleep";
115
import {
126
addBlockUser,
137
deductUserPoints,
@@ -21,14 +15,12 @@ import quiz from "../utils/quiz";
2115
import riddle from "../utils/riddle";
2216
import { getSetting } from "../services/settings";
2317
import { errors, mentionResponses } from "../utils/data";
24-
import { funD, happyEE, sadEE, loveEE } from "../../data/reaction";
25-
import { containsAny } from "../utils/string";
18+
import autoReaction from "../utils/message/react";
2619
import { InstantDownloader } from "../utils/instantdl/downloader";
2720
import { checkInappropriate } from "../utils/contentChecker";
28-
import prisma from "../prisma";
2921
import redis from "../redis";
30-
import queue from "../queue";
31-
import regex from "../emoji";
22+
import downloadQueue from "../queue/download";
23+
import reactQueue from "../queue/react";
3224
import ai from "../../commands/ai";
3325
import * as Sentry from "@sentry/node";
3426

@@ -127,7 +119,7 @@ export default async function (msg: Message, type: string): Promise<void> {
127119
await Promise.allSettled([
128120
quiz(msg),
129121
riddle(msg),
130-
queue.add(() => InstantDownloader(msg)),
122+
downloadQueue.add(() => InstantDownloader(msg)),
131123
(async () => {
132124
// override the msg!
133125
const react = { ...msg };
@@ -142,40 +134,7 @@ export default async function (msg: Message, type: string): Promise<void> {
142134
)
143135
return;
144136

145-
react.react = async (reaction: string): Promise<void> => {
146-
// add delay for more
147-
// humanly like interaction
148-
const min = 2000;
149-
const max = 6000;
150-
const randomMs = Math.floor(Math.random() * (max - min + 1)) + min;
151-
152-
await sleep(randomMs);
153-
const isEmoji = /.*[A-Za-z0-9].*/.test(reaction);
154-
log.info("AutoReact", lid, reaction);
155-
156-
if (Math.random() < 0.1 && !isEmoji)
157-
if (Math.random() < 0.2)
158-
(await client()).sendMessage(react.id.remote, reaction);
159-
else await msg.reply(reaction);
160-
else await msg.react(reaction);
161-
};
162-
163-
const emojis = [
164-
...new Set([...react.body.matchAll(regex)].map((m) => m[0])),
165-
];
166-
if (emojis.length > 0) {
167-
await react.react(
168-
emojis[Math.floor(Math.random() * emojis.length)],
169-
);
170-
} else if (containsAny(react.body, funD)) {
171-
await react.react("🤣");
172-
} else if (containsAny(react.body, happyEE)) {
173-
await msg.reply(funD[Math.floor(Math.random() * funD.length)]);
174-
} else if (containsAny(react.body, sadEE)) {
175-
await react.react("😭");
176-
} else if (containsAny(react.body, loveEE)) {
177-
await react.react("❤️");
178-
}
137+
reactQueue.add(() => autoReaction(msg));
179138
})(),
180139
(async () => {
181140
const botId = (await client()).info.wid._serialized;

src/components/events/reaction.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { rateLimiter } from "../utils/rateLimiter";
66
import { getBlockUser } from "../services/user";
77
import * as Sentry from "@sentry/node";
88
import redis from "../redis";
9+
import reactQueue from "../queue/react";
910

1011
export default async function (client: Client, react: Reaction): Promise<void> {
1112
if (react.msgId.fromMe || react.id.fromMe) return;
@@ -39,9 +40,15 @@ export default async function (client: Client, react: Reaction): Promise<void> {
3940
try {
4041
const message = await client.getMessageById(react.msgId._serialized);
4142
if (!message) return;
42-
await sleep(2000);
43+
44+
const min = 2000;
45+
const max = 6000;
46+
const randomMs = Math.floor(Math.random() * (max - min + 1)) + min;
47+
48+
await sleep(randomMs);
49+
4350
await Promise.allSettled([
44-
message.react(react.reaction),
51+
reactQueue.add(() => message.react(react.reaction)),
4552
redis.set(key, "1", {
4653
expiration: {
4754
type: "EX",

src/components/process.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import * as Sentry from "@sentry/node";
22
import log from "./utils/log";
33
import { client } from "./client";
44
import redis from "./redis";
5-
import queue from "./queue";
5+
import downloadQueue from "./queue/download";
6+
import reactQueue from "./queue/react";
67
import prisma from "./prisma";
78

89
async function gracefulShutdown(signal: string): Promise<void> {
@@ -14,12 +15,11 @@ async function gracefulShutdown(signal: string): Promise<void> {
1415
await popupBrowser.close();
1516
log.info("Browser", "Puppeteer browser closed successfully.");
1617
}
18+
// all work must be empty, before it send a SAVE Command to redis
19+
// avoiding conflicts when exiting the redis and db
20+
await Promise.allSettled([downloadQueue.onIdle(), reactQueue.onIdle()]);
1721
redis.sendCommand(["SAVE"]);
18-
await Promise.allSettled([
19-
redis.quit(),
20-
queue.onIdle(),
21-
prisma.$disconnect(),
22-
]);
22+
await Promise.allSettled([redis.quit(), prisma.$disconnect()]);
2323
} catch (err) {
2424
Sentry.captureException(err);
2525
log.error("Browser", `Error closing browser: ${(err as Error).message}`);

src/components/queue/react.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import PQueue from "p-queue";
2+
3+
declare global {
4+
var _sharedQueue: PQueue;
5+
}
6+
7+
if (!global._sharedQueue) {
8+
global._sharedQueue = new PQueue({
9+
// a user can only react 1 message at a time
10+
// else its a bot
11+
concurrency: 1,
12+
});
13+
}
14+
15+
const queue = global._sharedQueue;
16+
17+
export default queue;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { sleep } from "groq-sdk/core";
2+
import { Message } from "../../../types/message";
3+
import log from "../log";
4+
import client from "../../client";
5+
import regex from "../../emoji";
6+
import { containsAny } from "../string";
7+
import { funD, happyEE, loveEE, sadEE } from "../../../data/reaction";
8+
9+
async function react(react: Message, reaction: string): Promise<void> {
10+
const min = 2000;
11+
const max = 6000;
12+
const randomMs = Math.floor(Math.random() * (max - min + 1)) + min;
13+
const lid: string = react.author
14+
? react.author.split("@")[0]
15+
: react.from.split("@")[0];
16+
17+
await sleep(randomMs);
18+
const isEmoji = /.*[A-Za-z0-9].*/.test(reaction);
19+
log.info("AutoReact", lid, reaction);
20+
21+
if (Math.random() < 0.1 && !isEmoji)
22+
if (Math.random() < 0.2)
23+
(await client()).sendMessage(react.id.remote, reaction);
24+
else await react.reply(reaction);
25+
else await react.react(reaction);
26+
}
27+
28+
export default async function (msg: Message): Promise<void> {
29+
const emojis = [...new Set([...msg.body.matchAll(regex)].map((m) => m[0]))];
30+
if (emojis.length > 0) {
31+
await react(msg, emojis[Math.floor(Math.random() * emojis.length)]);
32+
} else if (containsAny(msg.body, funD)) {
33+
await react(msg, "🤣");
34+
} else if (containsAny(msg.body, happyEE)) {
35+
await react(msg, funD[Math.floor(Math.random() * funD.length)]);
36+
} else if (containsAny(msg.body, sadEE)) {
37+
await react(msg, "😭");
38+
} else if (containsAny(msg.body, loveEE)) {
39+
await react(msg, "❤️");
40+
}
41+
}

0 commit comments

Comments
 (0)