summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-10-09 14:33:14 -0700
committerFuwn <[email protected]>2025-10-09 14:33:14 -0700
commit65c67c9769e8e7efa31fdefddfd6904d3c195d98 (patch)
tree2ff1802a1372833912ad99d1b19e1a84eff5392e
parentfeat(gateway:constants): Add Uma personas (diff)
downloadumabotdiscord-65c67c9769e8e7efa31fdefddfd6904d3c195d98.tar.xz
umabotdiscord-65c67c9769e8e7efa31fdefddfd6904d3c195d98.zip
feat(gateway:listeners): Add uma persona reminder system
-rw-r--r--packages/gateway/src/listeners/clientReady/index.ts2
-rw-r--r--packages/gateway/src/listeners/messageCreate/index.ts2
-rw-r--r--packages/gateway/src/listeners/messageCreate/personaRandomMessage.ts170
3 files changed, 174 insertions, 0 deletions
diff --git a/packages/gateway/src/listeners/clientReady/index.ts b/packages/gateway/src/listeners/clientReady/index.ts
index 4e8fea7..42fad20 100644
--- a/packages/gateway/src/listeners/clientReady/index.ts
+++ b/packages/gateway/src/listeners/clientReady/index.ts
@@ -3,12 +3,14 @@ import { handleVoiceConnection } from "./voiceConnection";
import { handleActivity } from "./activity";
import { handleUmagramCatchup } from "./umagramCatchup";
import { initializeMessageStatistics } from "../messageStatistics";
+import { initializePersonaSystem } from "../messageCreate/personaRandomMessage";
export const handleClientReady = (client: Client) => {
client.once(Events.ClientReady, async (readyClient) => {
handleVoiceConnection(readyClient);
handleActivity(readyClient);
initializeMessageStatistics();
+ initializePersonaSystem(readyClient);
await handleUmagramCatchup(readyClient);
});
};
diff --git a/packages/gateway/src/listeners/messageCreate/index.ts b/packages/gateway/src/listeners/messageCreate/index.ts
index 926fda9..e0f497b 100644
--- a/packages/gateway/src/listeners/messageCreate/index.ts
+++ b/packages/gateway/src/listeners/messageCreate/index.ts
@@ -10,6 +10,7 @@ import { handleRandomEyesReaction } from "./randomEyesReaction";
import { handleRoleplayThumbsUpReaction } from "./roleplayThumbsUpReaction";
// import { handleBotMentionAutoDelete } from "./botMentionAutoDelete";
import { recordMessageForStatistics } from "../messageStatistics";
+import { handlePersonaRandomMessage } from "./personaRandomMessage";
export const handleMessageCreate = (client: Client) => {
client.on(Events.MessageCreate, async (message: Message) => {
@@ -17,6 +18,7 @@ export const handleMessageCreate = (client: Client) => {
await handleRoleplayUmagram(message);
await handleRandomEyesReaction(message);
await handleRoleplayThumbsUpReaction(message);
+ await handlePersonaRandomMessage(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
new file mode 100644
index 0000000..e27ee9e
--- /dev/null
+++ b/packages/gateway/src/listeners/messageCreate/personaRandomMessage.ts
@@ -0,0 +1,170 @@
+import { Message, WebhookClient, Client } from "discord.js";
+import { UMA_PERSONAS } from "../../constants";
+
+const TARGET_CHANNEL_ID = "1410333697701314791";
+const MESSAGE_THRESHOLD = 250;
+const PERSONA_MESSAGES = [
+ "Hi, everyone! {username} here! I want to make sure everyone knows that this channel is for NSFW content **only**! I really don't want to have to get rid of this channel for good ....",
+ "Hey there! It's {username}! Just a friendly reminder: this channel is strictly for NSFW content. Please keep it that way, or I might have to remove this channel permanently ....",
+ "Hello everyone! {username} speaking! This channel is meant for NSFW content exclusively. I'd hate to see this channel disappear because of rule violations ....",
+ "Hi all! {username} here with an important reminder! This channel is for NSFW content **only**! Let's keep it that way, or I'll have no choice but to remove this channel ....",
+ "Hey! {username} checking in! Just wanted to remind everyone that this channel is strictly for NSFW content. I really don't want to have to delete this channel ....",
+ "Hello! It's {username}! Please remember that this channel is for NSFW content only. I'd prefer not to have to permanently get rid of this channel ....",
+ "Hi everyone! {username} here! This channel is exclusively for NSFW content. Keep it clean, or I might have to remove this channel for good ....",
+ "Hey there! {username} speaking! Just a quick reminder that this channel is for NSFW content **only**! I don't want to have to delete this channel ....",
+ "Hello all! {username} here! This channel is strictly for NSFW content only. Please respect that, or I'll have no choice but to remove this channel ....",
+ "Hi! {username} checking in! Remember, this channel is for NSFW content exclusively. I really don't want to have to get rid of this channel permanently ....",
+];
+
+interface PersonaMessageTracker {
+ messageCount: number;
+ lastRandomMessageTime: number;
+ isActive: boolean;
+}
+
+class PersonaRandomMessageSystem {
+ private tracker: PersonaMessageTracker = {
+ messageCount: 0,
+ lastRandomMessageTime: 0,
+ isActive: false,
+ };
+ private webhookClient: WebhookClient | null = null;
+ private client: Client | null = null;
+
+ constructor() {
+ //
+ }
+
+ public setClient(client: Client) {
+ this.client = client;
+
+ 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 Persona",
+ avatar: UMA_PERSONAS[0].avatar,
+ });
+
+ this.webhookClient = new WebhookClient({ url: webhook.url });
+ }
+ } catch (error) {
+ console.error("Failed to create persona webhook:", error);
+ }
+ }
+
+ private async sendPrimerMessage() {
+ try {
+ await this.initializeWebhook();
+
+ if (!this.webhookClient) {
+ console.error("Failed to create webhook for primer message");
+
+ return;
+ }
+
+ const randomPersona =
+ UMA_PERSONAS[Math.floor(Math.random() * UMA_PERSONAS.length)];
+ const randomMessage =
+ PERSONA_MESSAGES[Math.floor(Math.random() * PERSONA_MESSAGES.length)];
+ const formattedMessage = randomMessage.replace(
+ "{username}",
+ randomPersona.name,
+ );
+
+ await this.webhookClient.edit({
+ name: randomPersona.name,
+ avatar: randomPersona.avatar,
+ });
+ await this.webhookClient.send(formattedMessage);
+ } catch (error) {
+ console.error("Failed to send primer persona 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();
+
+ this.tracker.messageCount++;
+
+ const now = Date.now();
+ const timeSinceLastMessage = now - this.tracker.lastRandomMessageTime;
+ const isChannelActive = timeSinceLastMessage < 5 * 60 * 1000;
+
+ if (
+ this.tracker.messageCount >= MESSAGE_THRESHOLD &&
+ isChannelActive &&
+ this.webhookClient
+ )
+ await this.sendRandomPersonaMessage(message);
+ }
+
+ private async sendRandomPersonaMessage(
+ 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 =
+ PERSONA_MESSAGES[Math.floor(Math.random() * PERSONA_MESSAGES.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.messageCount = 0;
+ this.tracker.lastRandomMessageTime = Date.now();
+ } catch (error) {
+ console.error("Failed to send persona message:", error);
+ }
+ }
+
+ public destroy(): void {
+ this.webhookClient?.destroy();
+ }
+}
+
+let personaSystem: PersonaRandomMessageSystem | null = null;
+
+export const initializePersonaSystem = (client?: Client): void => {
+ if (!personaSystem) {
+ personaSystem = new PersonaRandomMessageSystem();
+
+ if (client) personaSystem.setClient(client);
+ }
+};
+
+export const handlePersonaRandomMessage = async (
+ message: Message,
+): Promise<void> => {
+ if (personaSystem) await personaSystem.handleMessage(message);
+};
+
+export const destroyPersonaSystem = (): void => {
+ if (personaSystem) {
+ personaSystem.destroy();
+
+ personaSystem = null;
+ }
+};