diff options
| author | Fuwn <[email protected]> | 2025-10-09 14:45:51 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-10-09 14:45:51 -0700 |
| commit | 728741feb02c58967f238b216d594bee51314d50 (patch) | |
| tree | a95a0f3d3a089807ba69242a13ac5f73fced920f | |
| parent | fix(interactions:server): Update conditions for response action (diff) | |
| download | umabotdiscord-728741feb02c58967f238b216d594bee51314d50.tar.xz umabotdiscord-728741feb02c58967f238b216d594bee51314d50.zip | |
feat(gateway:listeners): Add daily conversation starter uma persona
4 files changed, 187 insertions, 2 deletions
diff --git a/packages/gateway/src/listeners/clientReady/index.ts b/packages/gateway/src/listeners/clientReady/index.ts index 42fad20..a0b2ebd 100644 --- a/packages/gateway/src/listeners/clientReady/index.ts +++ b/packages/gateway/src/listeners/clientReady/index.ts @@ -4,6 +4,7 @@ import { handleActivity } from "./activity"; import { handleUmagramCatchup } from "./umagramCatchup"; import { initializeMessageStatistics } from "../messageStatistics"; import { initializePersonaSystem } from "../messageCreate/personaRandomMessage"; +import { initializeConversationStarterSystem } from "../messageCreate/dailyConversationStarter"; export const handleClientReady = (client: Client) => { client.once(Events.ClientReady, async (readyClient) => { @@ -11,6 +12,7 @@ export const handleClientReady = (client: Client) => { handleActivity(readyClient); initializeMessageStatistics(); initializePersonaSystem(readyClient); + initializeConversationStarterSystem(readyClient); await handleUmagramCatchup(readyClient); }); }; diff --git a/packages/gateway/src/listeners/messageCreate/dailyConversationStarter.ts b/packages/gateway/src/listeners/messageCreate/dailyConversationStarter.ts new file mode 100644 index 0000000..1d1000d --- /dev/null +++ b/packages/gateway/src/listeners/messageCreate/dailyConversationStarter.ts @@ -0,0 +1,180 @@ +import { Message, WebhookClient, Client } from "discord.js"; +import { UMA_PERSONAS } from "../../constants"; + +const ENABLED_PRIMER_MESSAGE = false; +const TARGET_CHANNEL_ID = "1410333697701314791"; +const MIN_HOURS_BETWEEN_MESSAGES = 8; +const CONVERSATION_STARTERS = [ + "Hey everyone! {username} here! What's everyone up to today? Any exciting plans?", + "Hi there! It's {username}! How's everyone feeling today? Ready for some fun conversations?", + "Hello! {username} checking in! What's the most interesting thing that happened to you recently?", + "Hey! {username} speaking! Anyone have any cool stories to share? I'm all ears!", + "Hi everyone! {username} here! What's your favorite way to spend a relaxing day?", + "Hello there! It's {username}! Anyone want to chat about something fun? I'm in the mood for good conversation!", + "Hey! {username} checking in! What's something that always makes you smile?", + "Hi! {username} here! Anyone have any interesting hobbies or projects they're working on?", + "Hello everyone! {username} speaking! What's the best thing that happened to you this week?", + "Hey there! It's {username}! Anyone want to share something they're excited about?", + "Hi! {username} checking in! What's your go-to way to cheer yourself up when you're feeling down?", + "Hello! {username} here! Anyone have any fun weekend plans or recent adventures to talk about?", + "Hey everyone! {username} speaking! What's something new you've learned or discovered recently?", + "Hi there! It's {username}! Anyone want to chat about their favorite movies, shows, or games?", + "Hello! {username} checking in! What's the most random or interesting conversation you've had lately?", +]; + +interface DailyMessageTracker { + lastMessageTime: number; + isActive: boolean; +} + +class DailyConversationStarterSystem { + private tracker: DailyMessageTracker = { + lastMessageTime: 0, + isActive: false, + }; + private webhookClient: WebhookClient | null = null; + private client: Client | null = null; + + constructor() { + // + } + + public setClient(client: Client) { + this.client = client; + + if (ENABLED_PRIMER_MESSAGE) this.sendPrimerMessage(); + } + + private async initializeWebhook() { + if (!this.client) return; + + try { + const channel = this.client.channels.cache.get(TARGET_CHANNEL_ID); + + if (channel && "createWebhook" in channel) { + const webhook = await channel.createWebhook({ + name: "Uma Conversation Starter", + avatar: UMA_PERSONAS[0].avatar, + }); + + this.webhookClient = new WebhookClient({ url: webhook.url }); + } + } catch (error) { + console.error("Failed to create conversation starter webhook:", error); + } + } + + private async sendPrimerMessage() { + try { + await this.initializeWebhook(); + + if (!this.webhookClient) { + console.error( + "Failed to create webhook for conversation starter primer message", + ); + + return; + } + + const randomPersona = + UMA_PERSONAS[Math.floor(Math.random() * UMA_PERSONAS.length)]; + const randomMessage = + CONVERSATION_STARTERS[ + Math.floor(Math.random() * CONVERSATION_STARTERS.length) + ]; + const formattedMessage = randomMessage.replace( + "{username}", + randomPersona.name, + ); + + await this.webhookClient.edit({ + name: randomPersona.name, + avatar: randomPersona.avatar, + }); + await this.webhookClient.send(formattedMessage); + + this.tracker.lastMessageTime = Date.now(); + } catch (error) { + console.error( + "Failed to send conversation starter primer message:", + error, + ); + } + } + + public async handleMessage(message: Message): Promise<void> { + if (!this.client) this.setClient(message.client); + + if (message.channelId !== TARGET_CHANNEL_ID) return; + + if (message.author.bot) return; + + if (!this.webhookClient) await this.initializeWebhook(); + + const now = Date.now(); + const timeSinceLastMessage = now - this.tracker.lastMessageTime; + const minIntervalMs = MIN_HOURS_BETWEEN_MESSAGES * 60 * 60 * 1000; + + if (timeSinceLastMessage >= minIntervalMs) { + await this.sendRandomConversationStarter(message); + } + } + + private async sendRandomConversationStarter( + triggerMessage: Message /* eslint-disable-line @typescript-eslint/no-unused-vars, no-unused-vars */, + ): Promise<void> { + try { + const randomPersona = + UMA_PERSONAS[Math.floor(Math.random() * UMA_PERSONAS.length)]; + const randomMessage = + CONVERSATION_STARTERS[ + Math.floor(Math.random() * CONVERSATION_STARTERS.length) + ]; + const formattedMessage = randomMessage.replace( + "{username}", + randomPersona.name, + ); + + if (this.webhookClient) + await this.webhookClient.edit({ + name: randomPersona.name, + avatar: randomPersona.avatar, + }); + + await this.webhookClient?.send(formattedMessage); + + this.tracker.lastMessageTime = Date.now(); + } catch (error) { + console.error("Failed to send conversation starter message:", error); + } + } + + public destroy(): void { + this.webhookClient?.destroy(); + } +} + +let conversationStarterSystem: DailyConversationStarterSystem | null = null; + +export const initializeConversationStarterSystem = (client?: Client): void => { + if (!conversationStarterSystem) { + conversationStarterSystem = new DailyConversationStarterSystem(); + + if (client) conversationStarterSystem.setClient(client); + } +}; + +export const handleDailyConversationStarter = async ( + message: Message, +): Promise<void> => { + if (conversationStarterSystem) + await conversationStarterSystem.handleMessage(message); +}; + +export const destroyConversationStarterSystem = (): void => { + if (conversationStarterSystem) { + conversationStarterSystem.destroy(); + + conversationStarterSystem = null; + } +}; diff --git a/packages/gateway/src/listeners/messageCreate/index.ts b/packages/gateway/src/listeners/messageCreate/index.ts index e0f497b..86b1d47 100644 --- a/packages/gateway/src/listeners/messageCreate/index.ts +++ b/packages/gateway/src/listeners/messageCreate/index.ts @@ -11,6 +11,7 @@ import { handleRoleplayThumbsUpReaction } from "./roleplayThumbsUpReaction"; // import { handleBotMentionAutoDelete } from "./botMentionAutoDelete"; import { recordMessageForStatistics } from "../messageStatistics"; import { handlePersonaRandomMessage } from "./personaRandomMessage"; +import { handleDailyConversationStarter } from "./dailyConversationStarter"; export const handleMessageCreate = (client: Client) => { client.on(Events.MessageCreate, async (message: Message) => { @@ -19,6 +20,7 @@ export const handleMessageCreate = (client: Client) => { await handleRandomEyesReaction(message); await handleRoleplayThumbsUpReaction(message); await handlePersonaRandomMessage(message); + await handleDailyConversationStarter(message); // handleBotMentionAutoDelete(message); if (message.guildId !== CENTRAL_GUILD_ID) return; diff --git a/packages/gateway/src/listeners/messageCreate/personaRandomMessage.ts b/packages/gateway/src/listeners/messageCreate/personaRandomMessage.ts index e27ee9e..fb3a6b9 100644 --- a/packages/gateway/src/listeners/messageCreate/personaRandomMessage.ts +++ b/packages/gateway/src/listeners/messageCreate/personaRandomMessage.ts @@ -1,6 +1,7 @@ import { Message, WebhookClient, Client } from "discord.js"; import { UMA_PERSONAS } from "../../constants"; +const ENABLED_PRIMER_MESSAGE = false; const TARGET_CHANNEL_ID = "1410333697701314791"; const MESSAGE_THRESHOLD = 250; const PERSONA_MESSAGES = [ @@ -38,7 +39,7 @@ class PersonaRandomMessageSystem { public setClient(client: Client) { this.client = client; - this.sendPrimerMessage(); + if (ENABLED_PRIMER_MESSAGE) this.sendPrimerMessage(); } private async initializeWebhook() { @@ -98,7 +99,7 @@ class PersonaRandomMessageSystem { if (!this.webhookClient) await this.initializeWebhook(); - this.tracker.messageCount++; + this.tracker.messageCount += 1; const now = Date.now(); const timeSinceLastMessage = now - this.tracker.lastRandomMessageTime; |