From ea41a076a72c080d617c8d77a06b2896eb7ba5fa Mon Sep 17 00:00:00 2001 From: BoppleOpple Date: Wed, 2 Apr 2025 22:52:09 -0400 Subject: [PATCH 1/4] toggling should work now --- src/interactions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interactions.ts b/src/interactions.ts index c21f24c..9a5addc 100644 --- a/src/interactions.ts +++ b/src/interactions.ts @@ -570,8 +570,8 @@ export async function toggleDMs(interaction: ChatInputCommandInteraction Date: Wed, 2 Apr 2025 22:54:19 -0400 Subject: [PATCH 2/4] simplified a goofy line of code --- src/interactions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interactions.ts b/src/interactions.ts index 9a5addc..184a9d1 100644 --- a/src/interactions.ts +++ b/src/interactions.ts @@ -584,7 +584,7 @@ export async function toggleDMs(interaction: ChatInputCommandInteraction Date: Thu, 3 Apr 2025 22:38:40 -0400 Subject: [PATCH 3/4] firebase calls moved to helpers, fixed issue where having dms disabled disables all commands --- res/test-server-configs.json | 2 +- src/__mocks__/botSettings.ts | 8 ++++++++ src/{serverSetting.ts => botSettings.ts} | 19 +++++++++++++++++++ src/discordApp.ts | 22 ++-------------------- src/interactions.test.ts | 2 ++ src/interactions.ts | 12 ++++++++++++ 6 files changed, 44 insertions(+), 21 deletions(-) create mode 100644 src/__mocks__/botSettings.ts rename src/{serverSetting.ts => botSettings.ts} (66%) diff --git a/res/test-server-configs.json b/res/test-server-configs.json index 7e94d67..5ef31bd 100644 --- a/res/test-server-configs.json +++ b/res/test-server-configs.json @@ -1,7 +1,7 @@ { "123456789": { "isEnabled": false, - "lastToggled": "2025-04-02T05:09:09.785Z", + "lastToggled": "2025-04-04T02:30:51.034Z", "toggledBy": "987654321" } } \ No newline at end of file diff --git a/src/__mocks__/botSettings.ts b/src/__mocks__/botSettings.ts new file mode 100644 index 0000000..a46eba5 --- /dev/null +++ b/src/__mocks__/botSettings.ts @@ -0,0 +1,8 @@ +const botSettings = jest.requireActual("../botSettings"); +const mockBotSettings = jest.createMockFromModule("../botSettings"); + +mockBotSettings.getUserSetting = jest.fn().mockResolvedValue("enabled"); +mockBotSettings.getServerSetting = jest.fn().mockResolvedValue("active"); +mockBotSettings.toggleServerSetting = jest.fn().mockResolvedValue("inactive"); + +module.exports = mockBotSettings; \ No newline at end of file diff --git a/src/serverSetting.ts b/src/botSettings.ts similarity index 66% rename from src/serverSetting.ts rename to src/botSettings.ts index 3aaeebe..990d5bb 100644 --- a/src/serverSetting.ts +++ b/src/botSettings.ts @@ -20,6 +20,25 @@ export async function getServerSetting(guildId: string): Promise { } } +// Get the current setting for the server (whether the bot is enabled or disabled) +export async function getUserSetting(userId: string): Promise { + const dbRef = ref(database, `users/${userId}/dmsStatus`); + + try { + const snapshot = await get(dbRef); + if (snapshot.exists()) { + return snapshot.val(); + } else { + // Default to "enabled" if no setting is found + await set(dbRef, "enabled"); + return "enabled"; + } + } catch (error) { + console.error("Error getting user setting:", error); + throw error; + } +} + // Toggle the bot's enabled/disabled setting for the server export async function toggleServerSetting(guildId: string): Promise { const currentSetting = await getServerSetting(guildId); diff --git a/src/discordApp.ts b/src/discordApp.ts index 61e33d6..903c422 100644 --- a/src/discordApp.ts +++ b/src/discordApp.ts @@ -6,9 +6,8 @@ import { Message, } from "discord.js"; import { clarify, embed, ping, tone, requestAnonymousClarification, mood, toggleBot, inDepthClarification, postemptiveToneAdd, getTones, action, toggleDMs } from "./interactions" -import { get, ref } from "firebase/database"; -import database from "./firebase"; import { cleanupMoods } from "./helpers"; +import { getServerSetting, getUserSetting } from "./botSettings"; export async function launchBot(): Promise { @@ -53,25 +52,8 @@ export async function launchBot(): Promise { const guildId = interaction.guildId!; // Get the guildId for server-wide bot status try { - // Check the user's DM status - const userDMRef = ref(database, `users/${userId}/dmsStatus`); - const userDMSnapshot = await get(userDMRef); - const userDMStatus = userDMSnapshot.exists() ? userDMSnapshot.val() : "enabled"; // Default to 'enabled' if not set - - // If DMs are disabled for the user, ignore the interaction and reply with a message - if (userDMStatus === "disabled") { - if (interaction.isCommand() && interaction.commandName !== "toggledms"){ - return interaction.reply({ - content: "Sorry, DMs are currently disabled for this user.", - flags: 64, // Make it ephemeral - }); - } - } - // Check the bot status for the server - const botStatusRef = ref(database, `servers/${guildId}/botStatus`); - const botSnapshot = await get(botStatusRef); - const botStatus = botSnapshot.exists() ? botSnapshot.val() : "active"; // Default to 'active' if not set + const botStatus = await getServerSetting(guildId); // Default to 'active' if not set // If the bot is inactive, ignore the interaction and reply with a message if (botStatus === "inactive") { diff --git a/src/interactions.test.ts b/src/interactions.test.ts index 99a120e..7061c20 100644 --- a/src/interactions.test.ts +++ b/src/interactions.test.ts @@ -12,10 +12,12 @@ import { MockDiscord } from "./testing/mocks/mockDiscord"; import * as gptRequests from "./gptRequests"; import * as firebase from "firebase/database"; import * as helpers from "./helpers"; +import * as botSettings from "./botSettings"; jest.mock("./gptRequests") jest.mock("discord.js"); jest.mock("firebase/database"); jest.mock("./helpers"); +jest.mock("./botSettings"); describe("Testing application commands", ()=>{ beforeAll(()=>{ diff --git a/src/interactions.ts b/src/interactions.ts index 184a9d1..1adb301 100644 --- a/src/interactions.ts +++ b/src/interactions.ts @@ -22,6 +22,7 @@ import { addRoleToDatabase, MINIMUM_MOOD_LIFESPAN, removeRoleIfUnused } from "./ //getTones and Clarify rely on toneJSON. Implementing it in firebase would be better //import tonesData from "./tones.json" assert { type: "json"}; import { readFile } from 'fs/promises'; +import { getUserSetting } from "./botSettings"; //console.log(tonesData.tones); @@ -473,6 +474,17 @@ export async function mood(interaction: ChatInputCommandInteraction): export async function requestAnonymousClarification(interaction: MessageContextMenuCommandInteraction): Promise{ await interaction.deferReply({ephemeral: true}); + // Check the user's DM status + const userDMStatus = await getUserSetting(interaction.user.id); + + // If DMs are disabled for the user, ignore the interaction and reply with a message + if (userDMStatus === "disabled") { + interaction.editReply({ + content: "Sorry, DMs are currently disabled for this user." + }); + return; + } + try { const targetMessage = interaction.targetMessage; From 8ccc96dd010b8c7c5560f3912611b6318318b889 Mon Sep 17 00:00:00 2001 From: BoppleOpple Date: Thu, 3 Apr 2025 22:39:06 -0400 Subject: [PATCH 4/4] removed unused files --- res/server-configs.json | 7 --- res/test-server-configs.json | 7 --- src/serverConfigManager.test.ts | 70 ----------------------- src/serverConfigManager.ts | 99 --------------------------------- 4 files changed, 183 deletions(-) delete mode 100644 res/server-configs.json delete mode 100644 res/test-server-configs.json delete mode 100644 src/serverConfigManager.test.ts delete mode 100644 src/serverConfigManager.ts diff --git a/res/server-configs.json b/res/server-configs.json deleted file mode 100644 index 2ca65c8..0000000 --- a/res/server-configs.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "1294893558024638475": { - "isEnabled": true, - "lastToggled": "2024-12-11T17:16:01.394Z", - "toggledBy": "186318354422824960" - } -} \ No newline at end of file diff --git a/res/test-server-configs.json b/res/test-server-configs.json deleted file mode 100644 index 5ef31bd..0000000 --- a/res/test-server-configs.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "123456789": { - "isEnabled": false, - "lastToggled": "2025-04-04T02:30:51.034Z", - "toggledBy": "987654321" - } -} \ No newline at end of file diff --git a/src/serverConfigManager.test.ts b/src/serverConfigManager.test.ts deleted file mode 100644 index ec3238b..0000000 --- a/src/serverConfigManager.test.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { describe, it, beforeEach, expect } from '@jest/globals'; -import fs from 'fs'; -import path from 'path'; -import { ServerConfigManager } from './serverConfigManager'; - -describe('ServerConfigManager', () => { - const TEST_CONFIG_PATH = './res/test-server-configs.json'; - let serverConfigManager: ServerConfigManager; - - beforeEach(() => { - // Clean up test file before each test - if (fs.existsSync(TEST_CONFIG_PATH)) { - fs.unlinkSync(TEST_CONFIG_PATH); - } - - // Stop console.log output from flooding tests - jest.spyOn(console, "log").mockImplementation(() => {}); - - serverConfigManager = new ServerConfigManager(TEST_CONFIG_PATH); - }); - - it('should successfully toggle server status from enabled to disabled', () => { - const guildId = '123456789'; - const userId = '987654321'; - - // Verify initial state is enabled - expect(serverConfigManager.isServerEnabled(guildId)).toBe(true); - - // Toggle to disabled - const config = serverConfigManager.toggleServerStatus(guildId, userId); - - // Verify the toggle - expect(config.isEnabled).toBe(false); - expect(config.toggledBy).toBe(userId); - expect(config.lastToggled).not.toBeNull(); - - // Verify the state persisted - expect(serverConfigManager.isServerEnabled(guildId)).toBe(false); - }); - - it('should toggle server status multiple times successfully', () => { - const guildId = '123456789'; - const userId = '987654321'; - - // First toggle (true -> false) - let config = serverConfigManager.toggleServerStatus(guildId, userId); - expect(config.isEnabled).toBe(false); - - // Second toggle (false -> true) - config = serverConfigManager.toggleServerStatus(guildId, userId); - expect(config.isEnabled).toBe(true); - - // Third toggle (true -> false) - config = serverConfigManager.toggleServerStatus(guildId, userId); - expect(config.isEnabled).toBe(false); - }); - - it('should persist server status between instance recreations', () => { - const guildId = '123456789'; - const userId = '987654321'; - - // Toggle with first instance - serverConfigManager.toggleServerStatus(guildId, userId); - expect(serverConfigManager.isServerEnabled(guildId)).toBe(false); - - // Create new instance and verify state persisted - const newServerConfigManager = new ServerConfigManager(TEST_CONFIG_PATH); - expect(newServerConfigManager.isServerEnabled(guildId)).toBe(false); - }); -}); \ No newline at end of file diff --git a/src/serverConfigManager.ts b/src/serverConfigManager.ts deleted file mode 100644 index 691be11..0000000 --- a/src/serverConfigManager.ts +++ /dev/null @@ -1,99 +0,0 @@ - -import fs from 'fs'; -import path from 'path'; - -interface ServerConfig { - isEnabled: boolean; - lastToggled: string | null; - toggledBy: string | null; -} - -class ServerConfigManager { - private configPath: string; - private serverStates: Map; - - constructor(configPath: string = './res/server-configs.json') { - this.configPath = path.resolve(configPath); - this.serverStates = new Map(); - - // Load initial states from file if it exists - try { - if (fs.existsSync(this.configPath)) { - const savedConfigs = JSON.parse(fs.readFileSync(this.configPath, 'utf8')); - for (const [guildId, config] of Object.entries(savedConfigs)) { - this.serverStates.set(guildId, config as ServerConfig); - } - console.log('[ServerConfigManager] Loaded existing configurations'); - } - } catch (error) { - console.error('[ServerConfigManager] Error loading initial config:', error); - } - } - - private saveToFile(): void { - try { - const configObject = Object.fromEntries(this.serverStates); - fs.writeFileSync(this.configPath, JSON.stringify(configObject, null, 2)); - console.log('[ServerConfigManager] Saved configurations to file'); - } catch (error) { - console.error('[ServerConfigManager] Error saving to file:', error); - } - } - - public toggleServerStatus(guildId: string, userId: string): ServerConfig { - console.log(`[ServerConfigManager] Attempting to toggle server ${guildId}`); - - // Get current state or create default - let currentConfig = this.serverStates.get(guildId) || { - isEnabled: true, - lastToggled: null, - toggledBy: null - }; - - // Log before state - console.log('[ServerConfigManager] Before toggle:', currentConfig); - - // Create new config object with toggled state - const newConfig: ServerConfig = { - isEnabled: !currentConfig.isEnabled, - lastToggled: new Date().toISOString(), - toggledBy: userId - }; - - // Update in-memory state - this.serverStates.set(guildId, newConfig); - - // Log after state - console.log('[ServerConfigManager] After toggle:', newConfig); - - // Save to file as backup - this.saveToFile(); - - return newConfig; - } - - public isServerEnabled(guildId: string): boolean { - // If no state is stored, default to enabled - const state = this.serverStates.get(guildId); - if (!state) { - return true; - } - return state.isEnabled; - } - - public getServerConfig(guildId: string): ServerConfig { - const config = this.serverStates.get(guildId); - if (!config) { - const defaultConfig: ServerConfig = { - isEnabled: true, - lastToggled: null, - toggledBy: null - }; - this.serverStates.set(guildId, defaultConfig); - return defaultConfig; - } - return config; - } -} -export { ServerConfigManager }; -export default new ServerConfigManager(); \ No newline at end of file