Im making a Discord bot using the PyCord library that is effectivly a word of the day/phrase of the day bot for a language server. One of the requests is that it has the ability to add and remove words in discord which the bot will send. I wrote the code for the commands which where working perfectly upuntil 2 days ago where it no longer functions at all despite no changes to the code. thats beside the point anyway, any help on how to get this code to work would be greatly appreciated :).
Code:
#The commands!
@self.slash_command(name="add_word")
async def greet(ctx, add_word: Option(str, "What word do you wish to add", required = True, default = '')):
with open("words.txt", "a") as n:
n.write("\n" + add_word)
await ctx.respond(f"Added the word: **{add_word}** to the list")
@self.slash_command(name="remove_word")
async def greet(ctx, remove_word: Option(str, "What word do you wish to remove?", required = True, default = '')):
with open("words.txt", 'w') as file:
new_text_1 = str.replace(remove_word, '')
file.write(new_text_1)
await ctx.respond(f"Removed the word: **{remove_word}** from the list")
@self.slash_command(name="add_phrase")
async def greet(ctx, phrase_entry: Option(str, "What phrase do you wish to add", required = True, default = '')):
with open("phrases.txt", "a") as n:
n.write("\n" + phrase_entry)
await ctx.respond(f"Added the word: **{phrase_entry}** to the list")
@self.slash_command(name="remove_phrase")
async def greet(ctx, remove_phrase: Option(str, "What phrase do you wish to remove?", required = True, default = '')):
with open("phrases.txt", 'w') as file:
new_text_1 = str.replace(remove_phrase, '')
file.write(new_text_1)
await ctx.respond(f"Removed the phrase: **{remove_phrase}** from the list")
@self.slash_command(name="add_hard_word")
async def greet(ctx, add_hard_word: Option(str, "What difficult word do you wish to add", required = True, default = '')):
with open("hard_words.txt", "a") as n:
n.write("\n" + add_hard_word)
await ctx.respond(f"Added the hard word: **{add_hard_word}** to the list")
@self.slash_command(name="remove_hard_word")
async def greet(ctx, remove_hard_word: Option(str, "What difficult word do you wish to remove?", required = True, default = '')):
with open("hard_words.txt", 'w') as file:
new_text_1 = str.replace(remove_hard_word, '')
file.write(new_text_1)
await ctx.respond(f"Removed the hard word: **{remove_hard_word}** from the list")
@self.slash_command(name="add_hard_phrase")
async def greet(ctx, hard_phrase_entry: Option(str, "What difficult phrase do you wish to add", required = True, default = '')):
with open("hard_phrases.txt", "a") as n:
n.write("\n" + hard_phrase_entry)
await ctx.respond(f"Added the hard word: **{hard_phrase_entry}** to the list")
@self.slash_command(name="remove_hard_phrase")
async def greet(ctx, remove_hard_phrase: Option(str, "What difficult phrase do you wish to remove?", required = True, default = '')):
with open("hard_phrases.txt", 'w') as file:
new_text_1 = str.replace(remove_hard_phrase, '')
file.write(new_text_1)
await ctx.respond(f"Removed the hard phrase: **{remove_hard_phrase}** from the li
I'm not entirely sure how it was working before. I think your issues are within the remove
commands for removing words and phrases.
Let's take your remove_word
command.
@self.slash_command(name="remove_word")
async def greet(ctx, remove_word: Option(str, "What word do you wish to remove?", required = True, default = '')):
with open("words.txt", 'w') as file:
new_text_1 = str.replace(remove_word, '')
file.write(new_text_1)
await ctx.respond(f"Removed the word: **{remove_word}** from the list")
In this, we open the text file to remove the word from. And then we, call the str.replace
function on str
? Huh? The replace
should be called on the string you want to replace things in - this is why it's throwing that weird error message. So, to do so, we need to actually read the lines/words in words.txt
and then remove those occurences from the file.
That might end up looking something like this:
@client.slash_command()
async def remove_word(ctx, word: str):
word_to_remove = word.lower()
with open("words.txt", "r+") as f:
file_words = f.readlines()
f.seek(0)
for file_word in file_words:
if file_word.strip("\n") != word_to_remove:
f.write(file_word )
f.truncate()
await ctx.respond(f"Removed the word: **{word}** from the list")
I have simplified it a little - remove the self
and Option
; but you can add those back in later.
So, what we're doing:
r+
mode - this allows us to read and write the file without removing if it if already existsf.readlines()
to read every line into a list as file_words
f.seek(0)
to go back to the beginning of the file (as f.readlines()
will "read" the whole file and put as at the end)f.truncate()
to remove the stuff that was in the file beforeNote that I didn't use replace at all - I wanted to remove the line completely rather than making it an empty line. You can of course, do some more complicated checks for word equality if you want to as well.
Hopefully this is enough to apply it in your context and update your other remove
methods as well.
Separately, I would rename all of the function names as well to something that matches what it does - so that they're not all called greet
. It's better practice and will make things easier as you go. That way, you don't need to specify the name
of the command either, as it can just be the function name.