Skip to content

Commit dd6588f

Browse files
committed
feat: added roast ai agent and wrapped prisma update/create to prisma. to avoid race condition
1 parent c572dfe commit dd6588f

3 files changed

Lines changed: 130 additions & 61 deletions

File tree

src/commands/roast.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 log from "../components/utils/log";
3+
import agentHandler from "../components/ai/agentHandler";
4+
import { greetings } from "../components/utils/data";
5+
6+
export const info = {
7+
command: "roast",
8+
description: "Interact with the Roast AI agent.",
9+
usage: "roast <query>",
10+
example: "roast Who are you?",
11+
role: "user",
12+
cooldown: 5000,
13+
};
14+
15+
export default async function (msg: Message): Promise<void> {
16+
const query = msg.body.replace(/^roast\b\s*/i, "").trim();
17+
if (query.length === 0 && !msg.hasQuotedMsg) {
18+
await msg.reply(greetings[Math.floor(Math.random() * greetings.length)]);
19+
return;
20+
}
21+
22+
const mentioned = msg.mentionedIds.length > 0;
23+
24+
const prompt = `You are Roast, your job is to roast anyone,
25+
regarding of there status, no hard feelings your only doing your job.
26+
You can use nasty emojis or actions, Only give one response at a time!
27+
the Date today is %_TODAY_%. Response briefly and concisely,
28+
${mentioned && "You can mentioned user using @ (ps thats there handle/name/username whatever you'd like to call it)and"}
29+
Now roast: ${query}`;
30+
31+
let text = await agentHandler(prompt);
32+
33+
if (!text) {
34+
log.error("roast", "No response generated.");
35+
await msg.reply("Sorry, I couldn't generate a response. Please try again.");
36+
return;
37+
}
38+
39+
const mentions: string[] = [];
40+
41+
if (mentioned) {
42+
const mentionedContacts = await msg.getMentions();
43+
44+
for (let i = 0; i < mentionedContacts.length; i++) {
45+
const c = mentionedContacts[i];
46+
mentions.push(c.id._serialized);
47+
text = text.replaceAll(
48+
msg.mentionedIds[i].split("@")[0],
49+
c.id._serialized.split("@")[0],
50+
);
51+
}
52+
}
53+
54+
await msg.reply(text, undefined, { mentions });
55+
}

src/components/services/group.ts

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,32 @@ import * as Sentry from "@sentry/node";
66
export async function findOrCreateGroup(chat: WAWebJS.Chat): Promise<void> {
77
try {
88
if (!chat.isGroup) return;
9+
910
const groupChat = chat as GroupChat;
1011

11-
const group = await prisma.group
12-
.update({
12+
await prisma.$transaction(async (tx) => {
13+
const existingGroup = await tx.group.findUnique({
1314
where: { gid: groupChat.id.user },
15+
});
16+
17+
if (existingGroup) {
18+
await tx.group.update({
19+
where: { gid: groupChat.id.user },
20+
data: {
21+
name: groupChat.name,
22+
description: groupChat.description,
23+
},
24+
});
25+
return;
26+
}
27+
28+
await tx.group.create({
1429
data: {
30+
gid: groupChat.id.user,
1531
name: groupChat.name,
1632
description: groupChat.description,
1733
},
18-
})
19-
.catch(() => null);
20-
21-
if (group) return;
22-
23-
await prisma.group.create({
24-
data: {
25-
gid: groupChat.id.user,
26-
name: groupChat.name,
27-
description: groupChat.description,
28-
},
34+
});
2935
});
3036
} catch (error) {
3137
Sentry.captureException(error);

src/components/services/user.ts

Lines changed: 56 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -47,59 +47,63 @@ export async function addUserQuizPoints(
4747
}
4848

4949
export async function findOrCreateUser(msg: Message): Promise<boolean> {
50-
try {
51-
const lid = (msg.author ?? msg.from).split("@")[0];
50+
const lid = (msg.author ?? msg.from).split("@")[0];
5251

53-
const min = 0.1;
54-
const max = 0.9;
55-
const rand = Math.random() * (max - min) + min;
56-
const points = parseFloat(rand.toFixed(1));
52+
const min = 0.1;
53+
const max = 0.9;
54+
const rand = Math.random() * (max - min) + min;
55+
const points = parseFloat(rand.toFixed(1));
5756

58-
const user = await prisma.user
59-
.update({
60-
where: { lid },
61-
data: {
62-
commandCount: { increment: 1 },
63-
points: {
64-
increment: points,
57+
try {
58+
const result = await prisma.$transaction(async (tx) => {
59+
const user = await tx.user.findUnique({ where: { lid } });
60+
61+
if (user) {
62+
await tx.user.update({
63+
where: { lid },
64+
data: {
65+
commandCount: { increment: 1 },
66+
points: { increment: points },
6567
},
66-
},
67-
})
68-
.catch(() => null);
68+
});
69+
70+
return false;
71+
}
6972

70-
if (user) return false;
73+
const contact = await msg.getContact();
74+
const name = contact?.pushname || contact?.name || "null";
75+
const number = contact?.number || "0";
76+
const countryCode = contact
77+
? await contact.getCountryCode().catch(() => "null")
78+
: "null";
79+
const about = contact ? await contact.getAbout().catch(() => null) : null;
7180

72-
const contact = await msg.getContact();
81+
await Promise.allSettled([
82+
msg.react("✅"),
83+
tx.user.create({
84+
data: {
85+
lid,
86+
name,
87+
number,
88+
countryCode,
89+
type: contact?.isBusiness ? "business" : "private",
90+
mode: msg.author ? "group" : "private",
91+
about: about ? filterContent(about) : null,
92+
commandCount: 1,
93+
points,
94+
},
95+
}),
96+
]);
7397

74-
const name = contact?.pushname || contact?.name || "null";
75-
const number = contact?.number || "0";
76-
const countryCode = contact
77-
? await contact.getCountryCode().catch(() => "null")
78-
: "null";
79-
const about = contact ? await contact.getAbout().catch(() => null) : null;
98+
return true;
99+
});
80100

81-
await Promise.allSettled([
82-
msg.react("✅"),
83-
prisma.user.create({
84-
data: {
85-
lid,
86-
name,
87-
number,
88-
countryCode,
89-
type: contact?.isBusiness ? "business" : "private",
90-
mode: msg.author ? "group" : "private",
91-
about: about ? filterContent(about) : null,
92-
commandCount: 1,
93-
points,
94-
},
95-
}),
96-
]);
97-
return true;
101+
return result;
98102
} catch (error) {
99103
Sentry.captureException(error);
100104
log.error("Database", `Failed to find or create user.`, error);
105+
return false;
101106
}
102-
return false;
103107
}
104108

105109
export async function getUserbyLid(lid: string) {
@@ -286,9 +290,11 @@ export async function deductUserPoints(
286290
points: number,
287291
): Promise<void> {
288292
try {
289-
prisma.user.update({
290-
where: { lid },
291-
data: { points: { decrement: points } },
293+
await prisma.$transaction(async (tx) => {
294+
await tx.user.update({
295+
where: { lid },
296+
data: { points: { decrement: points } },
297+
});
292298
});
293299
} catch (error) {
294300
Sentry.captureException(error);
@@ -301,9 +307,11 @@ export async function addUserPoints(
301307
points: number,
302308
): Promise<void> {
303309
try {
304-
prisma.user.update({
305-
where: { lid },
306-
data: { points: { increment: points } },
310+
await prisma.$transaction(async (tx) => {
311+
await tx.user.update({
312+
where: { lid },
313+
data: { points: { increment: points } },
314+
});
307315
});
308316
} catch (error) {
309317
Sentry.captureException(error);

0 commit comments

Comments
 (0)