Clear User Channel History Command (#88)

* Add: Clear user channel message history command

* Update: Checks if messages are empty and has clearer replies

* Fix: Issue where duplication happens on channel-toggle true in threads

* Update: version increment

* Fix: Missing test case for commands.test.ts

* Readability fix

---------

Co-authored-by: Jonathan Smoley <67881240+JT2M0L3Y@users.noreply.github.com>
This commit is contained in:
Kevin Dang
2024-07-25 14:26:50 -07:00
committed by GitHub
parent e60c2f88b8
commit 352d88ee9d
8 changed files with 99 additions and 9 deletions

View File

@@ -8,7 +8,7 @@ services:
build: ./ # find docker file in designated path build: ./ # find docker file in designated path
container_name: discord container_name: discord
restart: always # rebuild container always restart: always # rebuild container always
image: discord/bot:0.5.5 image: discord/bot:0.5.6
environment: environment:
CLIENT_TOKEN: ${CLIENT_TOKEN} CLIENT_TOKEN: ${CLIENT_TOKEN}
GUILD_ID: ${GUILD_ID} GUILD_ID: ${GUILD_ID}

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "discord-ollama", "name": "discord-ollama",
"version": "0.5.5", "version": "0.5.6",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "discord-ollama", "name": "discord-ollama",
"version": "0.5.5", "version": "0.5.6",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"discord.js": "^14.15.3", "discord.js": "^14.15.3",

View File

@@ -1,6 +1,6 @@
{ {
"name": "discord-ollama", "name": "discord-ollama",
"version": "0.5.5", "version": "0.5.6",
"description": "Ollama Integration into discord", "description": "Ollama Integration into discord",
"main": "build/index.js", "main": "build/index.js",
"exports": "./build/index.js", "exports": "./build/index.js",

View File

@@ -0,0 +1,34 @@
import { ChannelType, Client, CommandInteraction, TextChannel } from 'discord.js'
import { SlashCommand } from '../utils/commands.js'
import { clearChannelInfo } from '../utils/index.js'
export const ClearUserChannelHistory: SlashCommand = {
name: 'clear-user-channel-history',
description: 'clears history for user running this command in current channel',
// Clear channel history for intended user
run: async (client: Client, interaction: CommandInteraction) => {
// fetch current channel
const channel = await client.channels.fetch(interaction.channelId)
// if not an existing channel or a GuildText, fail command
if (!channel || channel.type !== ChannelType.GuildText) return
// clear channel info for user
const successfulWipe = await clearChannelInfo(interaction.channelId,
interaction.channel as TextChannel,
interaction.user.username)
// check result of clearing history
if (successfulWipe)
interaction.reply({
content: `Channel history in **${channel.name}** cleared for **${interaction.user.username}**.`,
ephemeral: true
})
else
interaction.reply({
content: `Channel history could not be found for **${interaction.user.username}** in **${channel.name}**.\n\nPlease chat with **${client.user?.username}** to start a chat history.`,
ephemeral: true
})
}
}

View File

@@ -7,6 +7,7 @@ import { Shutoff } from './shutoff.js'
import { Capacity } from './capacity.js' import { Capacity } from './capacity.js'
import { PrivateThreadCreate } from './threadPrivateCreate.js' import { PrivateThreadCreate } from './threadPrivateCreate.js'
import { ChannelToggle } from './channelToggle.js' import { ChannelToggle } from './channelToggle.js'
import { ClearUserChannelHistory } from './cleanUserChannelHistory.js'
export default [ export default [
ThreadCreate, ThreadCreate,
@@ -16,5 +17,6 @@ export default [
Disable, Disable,
Shutoff, Shutoff,
Capacity, Capacity,
ChannelToggle ChannelToggle,
ClearUserChannelHistory
] as SlashCommand[] ] as SlashCommand[]

View File

@@ -19,7 +19,7 @@ export const ThreadCreate: SlashCommand = {
}) })
// Send a message in the thread // Send a message in the thread
thread.send(`Hello ${interaction.user} and others! \n\nIt's nice to meet you. Please talk to me by typing **@${client.user?.username}** with your prompt.`) thread.send(`Hello ${interaction.user} and others! \n\nIt's nice to meet you. Please talk to me by typing **@${client.user?.username}** with your prompt.\n\nIf I do not respond, ensure \`channel-toggle\` is set to \`false\``)
// handle storing this chat channel // handle storing this chat channel
// store: thread.id, thread.name // store: thread.id, thread.name

View File

@@ -58,6 +58,61 @@ export async function getThread(filename: string, callback: (config: Thread | un
} }
} }
/**
* Method to check if a thread history file exists
*
* @param channel parent thread of the requested thread (can be GuildText)
* @returns true if channel does not exist, false otherwise
*/
async function checkChannelInfoExists(channel: TextChannel, user: string) {
// thread exist handler
const isThread: boolean = await new Promise((resolve) => {
getThread(`${channel.id}-${user}.json`, (channelInfo) => {
if (channelInfo?.messages)
resolve(true)
else
resolve(false)
})
})
return isThread
}
/**
* Method to clear channel history for requesting user
*
* @param filename guild id string
* @param channel the TextChannel in the Guild
* @param user username of user
* @returns nothing
*/
export async function clearChannelInfo(filename: string, channel: TextChannel, user: string): Promise<boolean> {
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 = `data/${filename}-${user}.json`
const cleanedHistory: boolean = await new Promise((resolve) => {
fs.readFile(fullFileName, 'utf8', (error, data) => {
if (error)
console.log(`[Error: openChannelInfo] Incorrect file format`)
else {
const object = JSON.parse(data)
if (object['messages'].length === 0) // already empty, let user know
resolve(false)
else {
object['messages'] = [] // cleared history
fs.writeFileSync(fullFileName, JSON.stringify(object, null, 2))
resolve(true)
}
}
})
})
console.log(cleanedHistory)
return cleanedHistory
}
/** /**
* Method to open the channel history * Method to open the channel history
* *
@@ -67,7 +122,6 @@ export async function getThread(filename: string, callback: (config: Thread | un
* @param messages their messages * @param messages their messages
*/ */
export async function openChannelInfo(filename: string, channel: TextChannel, user: string, messages: UserMessage[] = []): Promise<void> { export async function openChannelInfo(filename: string, channel: TextChannel, user: string, messages: UserMessage[] = []): Promise<void> {
// thread exist handler
const isThread: boolean = await new Promise((resolve) => { const isThread: boolean = await new Promise((resolve) => {
getThread(`${channel.id}.json`, (threadInfo) => { getThread(`${channel.id}.json`, (threadInfo) => {
if (threadInfo?.messages) if (threadInfo?.messages)
@@ -77,7 +131,7 @@ export async function openChannelInfo(filename: string, channel: TextChannel, us
}) })
}) })
// This is an existing thread, don't create another json // this is a thread channel, do not duplicate files
if (isThread) return if (isThread) return
const fullFileName = `data/${filename}-${user}.json` const fullFileName = `data/${filename}-${user}.json`

View File

@@ -22,6 +22,6 @@ describe('#commands', () => {
// test specific commands in the object // test specific commands in the object
it('references specific commands', () => { it('references specific commands', () => {
const commandsString = commands.map(e => e.name).join(', ') const commandsString = commands.map(e => e.name).join(', ')
expect(commandsString).toBe('thread, private-thread, message-style, message-stream, toggle-chat, shutoff, modify-capacity, channel-toggle') expect(commandsString).toBe('thread, private-thread, message-style, message-stream, toggle-chat, shutoff, modify-capacity, channel-toggle, clear-user-channel-history')
}) })
}) })