Skip to content

Commit 3d51ffd

Browse files
committed
feat: multiple bug fixes and improvements i cant even hold count of.
1 parent d54be82 commit 3d51ffd

16 files changed

Lines changed: 218 additions & 171 deletions

File tree

src/commands/help.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Message } from "../../types/message"
22
import log from "../components/utils/log";
3-
import { commands } from "../index";
3+
import { commands } from "../components/utils/cmd/loader";
44

55
export const info = {
66
command: "help",
@@ -16,7 +16,7 @@ type CommandType = {
1616
role: string;
1717
};
1818

19-
const PAGE_SIZE = 10;
19+
const PAGE_SIZE = 20;
2020

2121
function paginate(items: string[], page: number, pageSize: number): string[] {
2222
const start = (page - 1) * pageSize;

src/commands/reload.ts

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import axios from "../components/axios";
33
import log from "../components/utils/log";
44
import fs from "fs";
55
import path from "path";
6-
import { commands, commandDirs } from "../index";
6+
import { commands, commandDirs } from "../components/utils/cmd/loader";
77
import Loader from "../components/utils/cmd/loader";
88

99
export const info = {
@@ -20,7 +20,7 @@ export default async function (msg: Message) {
2020

2121
if (query.length !== 0) {
2222
if (!commands[query.toLocaleLowerCase()]) {
23-
await msg.reply(`Command "${query}" not found.`);
23+
await msg.reply(`Command \`${query}\` not found.`);
2424
return;
2525
}
2626

@@ -34,20 +34,12 @@ export default async function (msg: Message) {
3434
}
3535
}
3636

37-
if (!found)
38-
await msg.reply(
39-
`
40-
\`Failed to load\`
41-
${query}
42-
`,
43-
);
44-
if (found)
45-
await msg.reply(
46-
`
47-
\`Successfully reloaded\`
48-
${query}
49-
`,
50-
);
37+
if (!found) {
38+
await msg.reply(`\`Failed to load\`\n${query}`);
39+
} else {
40+
await msg.reply(`\`Successfully reloaded\`\n${query}`);
41+
}
42+
5143
return;
5244
}
5345

src/commands/stats.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import os from "os";
44
import si from "systeminformation";
55
import { getUserCount, getBlockUserCount } from "../components/services/user";
66
import { client } from "../components/client";
7-
import { commands } from "../index";
7+
import { commands } from "../components/utils/cmd/loader";
88

99
export const info = {
1010
command: "stats",

src/commands/unload.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { Message } from "../../types/message";
2+
import { commands, commandDirs } from "../components/utils/cmd/loader";
3+
import Loader from "../components/utils/cmd/loader";
4+
import path from "path";
5+
6+
export const info = {
7+
command: "unload",
8+
description: "Unload a specific command.",
9+
usage: "unload [command]",
10+
example: "unload ai",
11+
role: "admin",
12+
cooldown: 5000,
13+
};
14+
15+
export default async function (msg: Message) {
16+
const query = msg.body.replace(/^unload\b\s*/i, "").trim().toLowerCase();
17+
18+
if (!query) {
19+
await msg.reply("Please specify a command to unload.");
20+
return;
21+
}
22+
23+
if (!commands[query]) {
24+
await msg.reply(`Command "${query}" not found.`);
25+
return;
26+
}
27+
28+
if (query === "unload") {
29+
await msg.reply(
30+
`"${query}" can't be un-unloaded, 'cause the command that unloads can't be unloaded when it unloads unloading!`
31+
);
32+
return;
33+
}
34+
35+
const possibleExtensions = [".ts", ".js"];
36+
let found = false;
37+
38+
for (const ext of possibleExtensions) {
39+
for (const dir of commandDirs) {
40+
const filePath = path.resolve(dir, `${query}${ext}`);
41+
try {
42+
delete require.cache[require.resolve(filePath)];
43+
delete commands[query];
44+
found = true;
45+
} catch {
46+
}
47+
}
48+
}
49+
50+
if (!found) {
51+
await msg.reply(`\`Failed to unload\`\n${query}`);
52+
} else {
53+
await msg.reply(`\`Successfully unloaded\`\n${query}`);
54+
}
55+
}

src/components/client.ts

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
Reaction,
88
} from "whatsapp-web.js";
99
import qrcode from "qrcode-terminal";
10-
import cliProgress from "cli-progress";
10+
import LoadingBar from "./utils/loadingBar";
1111
import messageEvent from "./events/message";
1212
import messageEdit from "./events/edit";
1313
import groupLeave from "./events/groups/leave";
@@ -16,15 +16,7 @@ import reaction from "./events/reaction";
1616
import ready from "./events/ready";
1717
import revoke from "./events/revoke";
1818

19-
const loadingBar = new cliProgress.SingleBar(
20-
{
21-
format: "Loading | {bar} | {value}%",
22-
barCompleteChar: "█",
23-
barIncompleteChar: "-",
24-
hideCursor: true,
25-
},
26-
cliProgress.Presets.shades_classic
27-
);
19+
const loadingBar = LoadingBar("Loading Client | {bar} | {value}%");
2820
const client = new Client({
2921
puppeteer: {
3022
executablePath:
@@ -40,11 +32,13 @@ client.on("loading_screen", (percent: number, message: string) => {
4032
isLoadingBarStarted = true;
4133
}
4234

35+
if (percent >= 99) loadingBar.stop();
36+
4337
loadingBar.update(percent, { message });
4438
});
4539

4640
client.on("authenticated", () =>
47-
log.info("Auth", "Client authenticated successfully.")
41+
log.info("Auth", "Client authenticated successfully."),
4842
);
4943

5044
client.on("qr", (qr: string) => {
@@ -53,34 +47,34 @@ client.on("qr", (qr: string) => {
5347
qrcode.generate(qr, { small: true });
5448
});
5549

56-
client.on("ready", async () => {
57-
loadingBar.stop();
58-
ready();
59-
});
50+
client.on("ready", async () => ready());
6051

6152
client.on("message_reaction", async (react: Reaction) =>
62-
reaction(client, react)
53+
reaction(client, react),
6354
);
6455

6556
// client.on("message", (msg) => messageEvent(msg));
6657
client.on("message_create", async (msg: Message) => messageEvent(msg));
6758

6859
client.on(
6960
"message_edit",
70-
async (msg: Message, newBody: string, prevBody: string) =>
71-
messageEdit(msg, newBody, prevBody)
61+
async (msg: Message, newBody: string, prevBody: string) => {
62+
msg.body = newBody;
63+
await Promise.all([messageEdit(msg, newBody, prevBody), messageEvent(msg)]);
64+
},
7265
);
7366

7467
client.on(
7568
"message_revoke_everyone",
76-
async (msg: Message, revoked_msg?: Message) => revoke(msg, revoked_msg)
69+
async (msg: Message, revoked_msg?: Message) => revoke(msg, revoked_msg),
7770
);
7871

7972
client.on("group_join", async (notif: GroupNotification) => groupJoin(notif));
8073
client.on("group_leave", async (notif: GroupNotification) => groupLeave(notif));
81-
client.on("auth_failure", (msg: string) =>
82-
log.error("Auth", "Authentication failed. Please try again.")
83-
);
74+
client.on("auth_failure", (msg: string) => {
75+
loadingBar.stop();
76+
log.error("Auth", "Authentication failed. Please try again.");
77+
});
8478

8579
client.initialize();
8680

src/components/events/edit.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@ export default async function (
1111
_newBody: string,
1212
prevBody: string,
1313
) {
14-
if (msg.fromMe || msg.timestamp < Date.now() / 1000 - 10) return;
15-
1614
// const isGroup = !!msg.author;
1715
// const user = await getUserbyLid(msg.from) || "Your";
18-
if (prevBody) await addMessage(msg, prevBody, "edit");
16+
await addMessage(msg, prevBody, "edit");
1917
// await msg.reply(
2018
// `${isGroup ? user : "Your"} message was edited from "${prevBody}".`
2119
// );

src/components/events/groups/join.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { GroupNotification } from "whatsapp-web.js";
22
import log from "../../utils/log";
33
import sleep from "../../utils/sleep";
4+
import { client } from "../../client";
5+
6+
const PROJECT_CANIS_ALIAS = process.env.PROJECT_CANIS_ALIAS || "Canis";
47

58
export default async function (notif: GroupNotification) {
69
try {
@@ -10,9 +13,19 @@ export default async function (notif: GroupNotification) {
1013

1114
for (const contact of recipients) {
1215
const name = contact.pushname || contact.name || contact.id.user;
16+
const isSelf = contact.id._serialized === client.info.wid._serialized;
17+
18+
await sleep(2000);
19+
1320
log.info("Group Join", `${name} joined the group ${group.name}`);
14-
await sleep(2000); // prevent flooding
15-
await notif.reply(`👋 Welcome *${name}* 🎉`);
21+
if (isSelf) {
22+
await notif.reply(
23+
`🙋‍♂️ Hello everyone! I'm ${PROJECT_CANIS_ALIAS} your WhatsApp Bot,
24+
for more information please send \`help\` or \`legal\.`,
25+
);
26+
} else {
27+
await notif.reply(`👋 Welcome *${name}* 🎉`);
28+
}
1629
}
1730
} catch (err) {
1831
log.error("Group Join", "Failed to process group join event:", err);

src/components/events/message.ts

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import {
55
MessageSendOptions,
66
} from "whatsapp-web.js";
77
import log from "../utils/log";
8-
import { commands } from "../../index";
8+
import { commands } from "../utils/cmd/loader";
99
import rateLimiter from "../utils/rateLimiter";
1010
import sleep from "../utils/sleep";
1111
import { findOrCreateUser, isBlocked } from "../services/user";
1212
import { client } from "../client";
1313
import Font from "../utils/font";
1414
import quiz from "./quiz";
15+
import { errors } from "../utils/data";
1516

1617
const commandPrefix = process.env.COMMAND_PREFIX || "!";
1718
const commandPrefixLess = process.env.COMMAND_PREFIX_LESS === "true";
@@ -177,24 +178,30 @@ export default async function (msg: Message) {
177178

178179
if (statusMessages[status]) {
179180
const logFn = status === 500 ? log.error : log.warn;
180-
logFn(key, statusMessages[status], { status, headers });
181+
log.error(key, error);
181182
const text = `
182-
\`${statusMessages[status]}\`
183+
\`${errors[Math.floor(Math.random() * errors.length)]}\`\`
183184
184-
Error fetching data for "${key}" command the
185-
provider returned a ${status} status code.
185+
We encountered an error while processing ${key}.
186+
Provider returned an error ${statusMessages[status]}.
187+
We notify the developers of the issue.
188+
Please try again later.
186189
`;
187190
await msg.reply(text);
188191
return;
189192
}
190193
}
191-
log.error(
192-
key,
193-
"Unexpected error occurred while processing the request:",
194-
error,
195-
);
196-
await msg.reply(
197-
`An unexpected error occurred while processing your request for "${key}". Please try again later.`,
198-
);
194+
log.error(key, error);
195+
const text = `
196+
\`${errors[Math.floor(Math.random() * errors.length)]}\`
197+
198+
We encountered an error while processing ${key}.
199+
We notify the developers of the issue.
200+
Please try again later.
201+
If the problem persists, please create an issue on GitHub.
202+
203+
https://github.com/project-canis/project-canis/issues/
204+
`;
205+
await msg.reply(text);
199206
}
200207
}

src/components/utils/cmd/loader.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
11
import log from "../log";
22
import { promises as fs } from "fs";
33
import path from "path";
4-
import { commands, commandDirs } from "../../../index";
54
import { exec } from "child_process";
6-
import cliProgress from "cli-progress";
5+
import LoadingBar from "../loadingBar";
76
import util from "util";
7+
import { Message } from "../../../../types/message";
88
const execPromise = util.promisify(exec);
9+
const basePath = path.join(__dirname, "..", "..", "..", "commands");
10+
11+
export const commandDirs = [basePath, path.join(basePath, "private")];
12+
export const commands: Record<
13+
string,
14+
{
15+
command: string;
16+
description: string;
17+
usage: string;
18+
example: string;
19+
role: string;
20+
cooldown: number;
21+
exec: (msg: Message) => void;
22+
}
23+
> = {};
924

1025
async function ensureDependencies(
1126
dependencies: { name: string; version: string }[],
@@ -75,7 +90,9 @@ export async function mapCommands() {
7590
for (const dir of commandDirs) {
7691
const files = await fs.readdir(dir);
7792

78-
const tuples: [string, string][] = files.map((f) => [f, dir] as [string, string]);
93+
const tuples: [string, string][] = files.map(
94+
(f) => [f, dir] as [string, string],
95+
);
7996
allFiles = [...allFiles, ...tuples];
8097
}
8198

@@ -85,16 +102,9 @@ export async function mapCommands() {
85102
return;
86103
}
87104

88-
const bar = new cliProgress.SingleBar(
89-
{
90-
format: "Loading Commands | {bar} | {value}/{total} {command}",
91-
barCompleteChar: "█",
92-
barIncompleteChar: "-",
93-
hideCursor: true,
94-
},
95-
cliProgress.Presets.shades_classic,
105+
const bar = LoadingBar(
106+
"Loading Commands | {bar} | {value}/{total} {command}",
96107
);
97-
98108
bar.start(total, 0, { command: "" });
99109

100110
for (const [file, dir] of allFiles) {

src/components/utils/cmd/watcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { watch } from "fs/promises";
22
import loader from "./loader";
33
import log from "../log";
44
import path from "path";
5-
import { commandDirs } from "../../../index";
5+
import { commandDirs } from "./loader";
66

77
export default async function () {
88
for (const dir of commandDirs) {

0 commit comments

Comments
 (0)