rename bot directory to src, add chatwidget

This commit is contained in:
2025-07-09 16:50:16 +02:00
parent 8fd889856b
commit 3e025a586a
59 changed files with 417 additions and 1 deletions

72
src/events/message.ts Normal file
View File

@@ -0,0 +1,72 @@
import { EventSubChannelChatMessageEvent } from "@twurple/eventsub-base"
import { chatterId, streamerId, eventSub, commandPrefix, singleUserMode, streamerUsers } from "..";
import { User } from "../user";
import commands, { sendMessage } from "../commands";
import { redis } from "bun";
import { isAdmin } from "../lib/admins";
import cheers from "../cheers";
import logger from "../lib/logger";
import { addMessageToChatWidget } from "../chatwidget/message";
logger.info(`Loaded the following commands: ${commands.keys().toArray().join(', ')}`);
eventSub.onChannelChatMessage(streamerId, streamerId, parseChatMessage);
async function parseChatMessage(msg: EventSubChannelChatMessageEvent) {
addMessageToChatWidget(msg);
if (!singleUserMode && msg.chatterId === chatterId) return;
// return if double user mode is on and the chatter says something, we don't need them
const user = await User.initUsername(msg.chatterName);
// Get user from cache or place user in cache
// Given the fact that this is the user that chats, this user object always exists and cannot be null
//
// One of the flaws with the user object is solved by creating the object with the name.
// This way, if a user changes their name, the original name stays in the cache for at least 1 hour (extendable by using that name as target for item)
// and both are usable to target the same user (id is the same)
// The only problem would be if a user changed their name and someone else took their name right after
if (!streamerUsers.includes(msg.chatterId)) user?.makeVulnerable(); // Make the user vulnerable to explosions if not streamerbot or chatterbot
if (!msg.isCheer && !msg.isRedemption) await handleChatMessage(msg, user!)
else if (msg.isCheer && !msg.isRedemption) await handleCheer(msg, msg.bits, user!);
};
async function handleChatMessage(msg: EventSubChannelChatMessageEvent, user: User) {
// Parse commands:
if (msg.messageText.startsWith(commandPrefix)) {
const commandSelection = msg.messageText.slice(commandPrefix.length).split(' ')[0]!;
const selected = commands.get(commandSelection.toLowerCase());
if (!selected) return;
if (await redis.sismember('disabledcommands', selected.name)) return;
switch (selected.usertype) {
case "admin":
if (!await isAdmin(user.id)) return;
break;
case "streamer":
if (!streamerUsers.includes(msg.chatterId)) return;
break;
};
try { await selected.execute(msg, user); }
catch (err) {
logger.err(err as string);
await sendMessage('ERROR: Something went wrong', msg.messageId);
await user.clearLock();
};
};
};
export async function handleCheer(msg: EventSubChannelChatMessageEvent, bits: number, user: User) {
const selection = cheers.get(bits);
if (!selection) return;
if (await redis.sismember('disabledcheers', selection.name)) { await sendMessage(`The ${selection.name} cheer is disabled`); return; };
try {
selection.execute(msg, user);
} catch (err) {
logger.err(err as string);
};
};