summaryrefslogtreecommitdiff
path: root/packages/gateway/src
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-10-14 23:41:25 -0700
committerFuwn <[email protected]>2025-10-14 23:41:25 -0700
commitc45f8963a74c1baf88eb39cfef8973c9101b3512 (patch)
treee12630c340660303a871bef075ba58836310ea07 /packages/gateway/src
parentfeat(gateway:dailyConversationStarter): Decrease message cooldown (diff)
downloadumabotdiscord-c45f8963a74c1baf88eb39cfef8973c9101b3512.tar.xz
umabotdiscord-c45f8963a74c1baf88eb39cfef8973c9101b3512.zip
feat(gateway:listeners): Add memberJoin module
Diffstat (limited to 'packages/gateway/src')
-rw-r--r--packages/gateway/src/listeners/clientReady/index.ts2
-rw-r--r--packages/gateway/src/listeners/index.ts2
-rw-r--r--packages/gateway/src/listeners/memberJoin.ts189
-rw-r--r--packages/gateway/src/listeners/messageCreate/constants.ts44
4 files changed, 237 insertions, 0 deletions
diff --git a/packages/gateway/src/listeners/clientReady/index.ts b/packages/gateway/src/listeners/clientReady/index.ts
index a0b2ebd..4ab9c06 100644
--- a/packages/gateway/src/listeners/clientReady/index.ts
+++ b/packages/gateway/src/listeners/clientReady/index.ts
@@ -5,6 +5,7 @@ import { handleUmagramCatchup } from "./umagramCatchup";
import { initializeMessageStatistics } from "../messageStatistics";
import { initializePersonaSystem } from "../messageCreate/personaRandomMessage";
import { initializeConversationStarterSystem } from "../messageCreate/dailyConversationStarter";
+import { initializeWelcomeSystem } from "../memberJoin";
export const handleClientReady = (client: Client) => {
client.once(Events.ClientReady, async (readyClient) => {
@@ -13,6 +14,7 @@ export const handleClientReady = (client: Client) => {
initializeMessageStatistics();
initializePersonaSystem(readyClient);
initializeConversationStarterSystem(readyClient);
+ initializeWelcomeSystem(readyClient);
await handleUmagramCatchup(readyClient);
});
};
diff --git a/packages/gateway/src/listeners/index.ts b/packages/gateway/src/listeners/index.ts
index 2eadb41..044f10d 100644
--- a/packages/gateway/src/listeners/index.ts
+++ b/packages/gateway/src/listeners/index.ts
@@ -5,6 +5,7 @@ import { handleChannelDeletion } from "./channelDeletion";
import { handleMessageDeletion } from "./messageDeletion";
import { handleMessageEdit } from "./messageEdit";
import { handleClientReady } from "./clientReady";
+import { handleMemberJoin } from "./memberJoin";
// import { handleMediaModeration } from "./mediaModeration";
export const handleListeners = (client: Client) => {
@@ -14,5 +15,6 @@ export const handleListeners = (client: Client) => {
handleChannelDeletion(client);
handleMessageDeletion(client);
handleMessageEdit(client);
+ handleMemberJoin(client);
// handleMediaModeration(client);
};
diff --git a/packages/gateway/src/listeners/memberJoin.ts b/packages/gateway/src/listeners/memberJoin.ts
new file mode 100644
index 0000000..91104c5
--- /dev/null
+++ b/packages/gateway/src/listeners/memberJoin.ts
@@ -0,0 +1,189 @@
+import { Client, Events, GuildMember, WebhookClient } from "discord.js";
+import {
+ CENTRAL_GUILD_ID,
+ ROLEPLAY_GUILD_ID,
+ UMA_PERSONAS,
+} from "../constants";
+import { WELCOME_GREETINGS, WELCOME_ENDINGS } from "./messageCreate/constants";
+
+const CENTRAL_WELCOME_CHANNEL_ID = "1406422619087044670";
+const ROLEPLAY_WELCOME_CHANNEL_ID = "1423919139864707084";
+
+class WelcomeMessageSystem {
+ private centralWebhookClient: WebhookClient | null = null;
+ private roleplayWebhookClient: WebhookClient | null = null;
+ private client: Client | null = null;
+
+ constructor() {
+ //
+ }
+
+ public async setClient(client: Client) {
+ this.client = client;
+
+ await this.initializePersistentWebhook();
+ }
+
+ private async initializePersistentWebhook() {
+ if (!this.client) return;
+
+ // Initialize central server webhook
+ try {
+ const centralChannel = this.client.channels.cache.get(
+ CENTRAL_WELCOME_CHANNEL_ID,
+ );
+
+ if (centralChannel && "fetchWebhooks" in centralChannel) {
+ const webhooks = await centralChannel.fetchWebhooks();
+ const existingWebhook = webhooks.find(
+ (webhook) => webhook.name === "UmaBot Welcome",
+ );
+
+ if (existingWebhook) {
+ this.centralWebhookClient = new WebhookClient({
+ url: existingWebhook.url,
+ });
+ } else if ("createWebhook" in centralChannel) {
+ const webhook = await centralChannel.createWebhook({
+ name: "UmaBot Welcome",
+ avatar: "https://cdn.discordapp.com/embed/avatars/0.png",
+ });
+
+ this.centralWebhookClient = new WebhookClient({ url: webhook.url });
+ }
+ }
+ } catch (error) {
+ console.error(
+ "Failed to initialize persistent central welcome webhook:",
+ error,
+ );
+ }
+
+ try {
+ const roleplayChannel = this.client.channels.cache.get(
+ ROLEPLAY_WELCOME_CHANNEL_ID,
+ );
+
+ if (roleplayChannel && "fetchWebhooks" in roleplayChannel) {
+ const webhooks = await roleplayChannel.fetchWebhooks();
+ const existingWebhook = webhooks.find(
+ (webhook) => webhook.name === "UmaBot Welcome",
+ );
+
+ if (existingWebhook) {
+ this.roleplayWebhookClient = new WebhookClient({
+ url: existingWebhook.url,
+ });
+ } else if ("createWebhook" in roleplayChannel) {
+ const webhook = await roleplayChannel.createWebhook({
+ name: "UmaBot Welcome",
+ avatar: "https://cdn.discordapp.com/embed/avatars/0.png",
+ });
+
+ this.roleplayWebhookClient = new WebhookClient({ url: webhook.url });
+ }
+ }
+ } catch (error) {
+ console.error(
+ "Failed to initialize persistent roleplay welcome webhook:",
+ error,
+ );
+ }
+ }
+
+ private generateWelcomeMessage(userMention: string): string {
+ const greeting =
+ WELCOME_GREETINGS[Math.floor(Math.random() * WELCOME_GREETINGS.length)];
+ const ending =
+ WELCOME_ENDINGS[Math.floor(Math.random() * WELCOME_ENDINGS.length)];
+
+ return `${greeting.replace("{username}", userMention)} ${ending}`;
+ }
+
+ public async handleMemberJoin(member: GuildMember): Promise<void> {
+ if (!this.client) await this.setClient(member.client);
+
+ if (
+ member.guild.id !== CENTRAL_GUILD_ID &&
+ member.guild.id !== ROLEPLAY_GUILD_ID
+ )
+ return;
+
+ if (member.user.bot) return;
+
+ try {
+ const randomPersona =
+ UMA_PERSONAS[Math.floor(Math.random() * UMA_PERSONAS.length)];
+ const welcomeMessage = this.generateWelcomeMessage(
+ member.user.toString(),
+ );
+ let webhookClient: WebhookClient | null = null;
+ let channelId: string;
+
+ if (member.guild.id === CENTRAL_GUILD_ID) {
+ webhookClient = this.centralWebhookClient;
+ channelId = CENTRAL_WELCOME_CHANNEL_ID;
+ } else {
+ webhookClient = this.roleplayWebhookClient;
+ channelId = ROLEPLAY_WELCOME_CHANNEL_ID;
+ }
+
+ if (!webhookClient) {
+ console.error(
+ "Failed to send welcome message - webhook not initialized",
+ );
+
+ return;
+ }
+
+ const sentMessage = await webhookClient.send({
+ content: welcomeMessage,
+ username: randomPersona.name,
+ avatarURL: randomPersona.avatar,
+ });
+
+ try {
+ const channel = this.client!.channels.cache.get(channelId);
+
+ if (channel && "messages" in channel) {
+ const message = await channel.messages.fetch(sentMessage.id);
+
+ await message.react("✨");
+ }
+ } catch (error) {
+ console.error("Failed to react to welcome message:", error);
+ }
+ } catch (error) {
+ console.error("Failed to send welcome message:", error);
+ }
+ }
+
+ public destroy(): void {
+ this.centralWebhookClient?.destroy();
+ this.roleplayWebhookClient?.destroy();
+ }
+}
+
+let welcomeSystem: WelcomeMessageSystem | null = null;
+
+export const initializeWelcomeSystem = (client?: Client): void => {
+ if (!welcomeSystem) {
+ welcomeSystem = new WelcomeMessageSystem();
+
+ if (client) welcomeSystem.setClient(client);
+ }
+};
+
+export const handleMemberJoin = (client: Client) => {
+ client.on(Events.GuildMemberAdd, async (member: GuildMember) => {
+ if (welcomeSystem) await welcomeSystem.handleMemberJoin(member);
+ });
+};
+
+export const destroyWelcomeSystem = (): void => {
+ if (welcomeSystem) {
+ welcomeSystem.destroy();
+
+ welcomeSystem = null;
+ }
+};
diff --git a/packages/gateway/src/listeners/messageCreate/constants.ts b/packages/gateway/src/listeners/messageCreate/constants.ts
index 6bc66f5..9dbbc6b 100644
--- a/packages/gateway/src/listeners/messageCreate/constants.ts
+++ b/packages/gateway/src/listeners/messageCreate/constants.ts
@@ -145,3 +145,47 @@ export const PERSONA_REPLY_SECOND_PARTS = [
"I'll archive this for when I'm deciding this channel's future",
"This will be logged for my next channel management review",
];
+
+export const WELCOME_GREETINGS = [
+ "Welcome to the track, {username}!",
+ "Hey there, {username}! Welcome to our stable!",
+ "Hello, {username}! Ready to race with us?",
+ "Welcome aboard, {username}! Let's make some memories!",
+ "Hi, {username}! Welcome to the world of Uma Musume!",
+ "Hey, {username}! Welcome to our racing family!",
+ "Hello there, {username}! Welcome to the winner's circle!",
+ "Welcome, {username}! Time to show your racing spirit!",
+ "Hi, {username}! Welcome to our training grounds!",
+ "Hey, {username}! Welcome to the starting line!",
+];
+
+export const WELCOME_MIDDLES = [
+ "Hope you're ready for some racing fun!",
+ "Get ready to meet some amazing racing girls!",
+ "You're about to discover the world of Uma Musume!",
+ "Prepare for a community filled with racing spirit!",
+ "I can't wait to see what you'll bring to our community!",
+ "You're joining a place where every race tells a story!",
+ "Get ready to cheer on some incredible athletes!",
+ "You're about to learn what it means to never give up!",
+ "Hope you're excited to meet some determined racing girls!",
+ "You're entering a world of passion and perseverance!",
+ "Get ready to witness friendship and competition!",
+ "You're about to experience the magic of believing in yourself!",
+ "I can't wait to see you join our racing family!",
+ "You're joining a community with daily adventures!",
+ "Get ready to be inspired by stories of victory!",
+];
+
+export const WELCOME_ENDINGS = [
+ "Let's make some wonderful memories together! 🏆",
+ "I'm so excited to have you here! ✨",
+ "Welcome to the family! 🌟",
+ "Let's race towards our dreams together! 💫",
+ "I can't wait to see what adventures await us! 🎀",
+ "Welcome to our wonderful world! 🌸",
+ "Let's create some amazing stories together! 💕",
+ "I'm thrilled you're joining us! 🎉",
+ "Welcome to the starting line of something amazing! 🌺",
+ "Let's make every day special together! 💖",
+];