import { TextChannel, ThreadChannel } from 'discord.js' import { Channel, UserMessage } from '../index.js' import fs from 'fs/promises' import path from 'path' /** * Method to check if a thread history file exists * * @param channel parent thread of the requested thread (can be GuildText) * @returns true if channel exists, false otherwise */ async function checkChannelInfoExists(channel: TextChannel, user: string) { const doesExists: boolean = await new Promise((resolve) => { getChannelInfo(`${channel.id}-${user}.json`, (channelInfo) => { if (channelInfo?.messages) { resolve(true) } else { resolve(false) } }) }) return doesExists } /** * Method to clear channel history for requesting user * * @param filename guild id string * @param channel the TextChannel in the Guild * @param user username or ID of user * @returns true if history was cleared, false if already empty or not found */ export async function clearChannelInfo(filename: string, channel: TextChannel, user: string): Promise { const channelInfoExists: boolean = await checkChannelInfoExists(channel, user) // If thread does not exist, file can't be found if (!channelInfoExists) return false // Attempt to clear user channel history const fullFileName = path.join('/app/data', `${filename}-${user}.json`) try { const data = await fs.readFile(fullFileName, 'utf8') const object = JSON.parse(data) if (object['messages'].length === 0) { console.log(`[Util: clearChannelInfo] History already empty for ${fullFileName}`) return false } object['messages'] = [] await fs.writeFile(fullFileName, JSON.stringify(object, null, 2), { flag: 'w', mode: 0o600 }) console.log(`[Util: clearChannelInfo] Cleared history for ${fullFileName}`) return true } catch (error) { console.log(`[Util: clearChannelInfo] Failed to clear ${fullFileName}: ${error}`) return false } } /** * Method to open the channel history * * @param filename name of the json file for the channel by user (without path) * @param channel the text channel info * @param user the user's ID or clientId for bots * @param messages their messages */ export async function openChannelInfo(filename: string, channel: TextChannel | ThreadChannel, user: string, messages: UserMessage[] = []): Promise { const fullFileName = path.join('/app/data', `${filename}-${user}.json`) console.log(`[Util: openChannelInfo] Attempting to create/open ${fullFileName}`) try { if (await fs.access(fullFileName).then(() => true).catch(() => false)) { const data = await fs.readFile(fullFileName, 'utf8') const object = JSON.parse(data) if (messages.length > 0) { object['messages'] = messages } await fs.writeFile(fullFileName, JSON.stringify(object, null, 2), { flag: 'w', mode: 0o600 }) console.log(`[Util: openChannelInfo] Updated ${fullFileName}`) } else { const object: Channel = { id: channel?.id || filename, name: channel?.name || 'unknown', user, messages: messages } const directory = path.dirname(fullFileName) await fs.mkdir(directory, { recursive: true }) await fs.writeFile(fullFileName, JSON.stringify(object, null, 2), { flag: 'w', mode: 0o600 }) console.log(`[Util: openChannelInfo] Created '${fullFileName}' in working directory`) } } catch (error) { console.log(`[Util: openChannelInfo] Failed to write ${fullFileName}: ${error}`) throw error } } /** * Method to get the channel information/history * * @param filename name of the json file for the channel by user (without path) * @param callback function to handle resolving message history */ export async function getChannelInfo(filename: string, callback: (config: Channel | undefined) => void): Promise { const fullFileName = path.join('/app/data', filename) console.log(`[Util: getChannelInfo] Reading ${fullFileName}`) try { const data = await fs.readFile(fullFileName, 'utf8') const config = JSON.parse(data) if (!config || !Array.isArray(config.messages)) { console.log(`[Util: getChannelInfo] Invalid or empty config in ${fullFileName}: ${JSON.stringify(config)}`) callback(undefined) } else { console.log(`[Util: getChannelInfo] Successfully read ${fullFileName}`) callback(config) } } catch (error) { console.log(`[Util: getChannelInfo] Failed to read ${fullFileName}: ${error}`) callback(undefined) } }