I'm making a Discord bot that is supposed to read from a text file and send called for line - discord.py

I'm new to this coding space, and what I'm trying to do is have the discord bot respond to slash command with it's specified line.
I have it where it works, but it responds to the command with the line below what is being called for. Here's what I have so far
#slash.slash(name="f2pquest", description="Lists all available f2p quest")
async def f2pquest(ctx, *, word: str):
await ctx.send('Checking File please stand by.')
with open("f2pquest.txt", "r") as f:
searching = re.compile(r'\b({0})\b'.format(word), flags=re.IGNORECASE).search
line = True
while line:
line = f.readline()
if not line:
break
if searching(line):
await ctx.send(f.readline())
return
await ctx.send("Quest not found")

It should just be await ctx.send(line). f.readline() will read the next line below the line that has already been read.

Related

Discord bot written in python, shows tons of error, mostly (TypeError: add() missing 1 required positional argument: 'movie_details')

so I have just started getting interested in creating discord bots for my own server and mostly for fun, so I'm a a bit of a beginner in that, and this time I'm trying to create a discord bot that logs movies I have watched with my friends and also let's me search through the list of movies, delete a movie or if i just want to list the movies, and I'm trying to use davinci-003 model from the openai API to extract the movie detail that I have added, in case i give it an incomplete movie name so it would complete it for me, or so it would add the movie year and extra details about the movie I'm trying to add, at least that was my intention.
however first of all the very first issue is my bot doesn't show any status when i run it (i.e say watching a movie in the status of the bot), and also none of the / commands work on discord, they all return "The application did not respond" on discord and I get this error in the terminal where the code is running:
when I use /add moviename
Task exception was never retrieved
future: <Task finished name='Task-19' coro=<add() done, defined at /usr/local/lib/python3.10/dist-packages/interactions/client/models/command.py:930> exception=TypeError("add() missing 1 required positional argument: 'movie_details'")>
Traceback (most recent call last):
File "/usr/local/lib/python3.10/dist-packages/interactions/client/models/command.py", line 970, in wrapper
raise e
File "/usr/local/lib/python3.10/dist-packages/interactions/client/models/command.py", line 939, in wrapper
return await coro(ctx, *args, **kwargs)
TypeError: add() missing 1 required positional argument: 'movie_details'
and same error for /delete moviename and /search moviename with their own functions though (i.e delete() or search() which is missing 1 required positional argument: 'query'), for /list however, on discord I still get "The application did not respond" even though it's just supposed to return my empty movie list.
and here is my code:
import openai
import discord
import os
import interactions
from dotenv import load_dotenv
# Load environment variables from .env file
try:
load_dotenv()
except FileNotFoundError:
print("Could not find .env file")
openai.api_key = os.getenv("API_KEY")
if openai.api_key is None:
print("API key not set. Set the API key using openai.api_key = 'YOUR_API_KEY'")
else:
print("Connected to OpenAI API key...")
# Create a bot object using the interactions library
bot = interactions.Client(
token=os.getenv("DISCORD_BOT_TOKEN"),
activity=discord.Activity(type=discord.ActivityType.watching, name="a Movie")
)
# This function is used to get the list of movies from the logger (by reading from the movie-log.txt file)
def get_movie_list():
movie_list = []
try:
with open("movie-log.txt", "r") as movie_log_file:
for line in movie_log_file:
movie_list.append(line.strip())
except FileNotFoundError:
return "movie-log.txt file not found"
else:
return "\n".join(movie_list)
# This function is used to search for movies in the logger (by searching the movie-log.txt file)
def search_movies(query):
search_results = []
try:
with open("movie-log.txt", "r") as movie_log_file:
for line in movie_log_file:
if query.lower() in line.lower():
search_results.append(line.strip())
except FileNotFoundError:
return "movie-log.txt file not found"
else:
if not search_results:
return "No results found"
return "\n".join(search_results)
# This function is used to add a movie to the logger (by appending to the movie-log.txt file)
def add_movie(movie_details):
if not movie_details:
return
# Check if the movie already exists in the logger
if movie_details in search_movies(movie_details):
return
try:
with open("movie-log.txt", "a") as movie_log_file:
movie_log_file.write(f"{movie_details}\n")
except FileNotFoundError:
return "movie-log.txt file not found"
# This function is used to delete a movie from the logger (by overwriting the movie-log.txt file)
def delete_movie(movie_details):
movie_list = get_movie_list()
if movie_details not in movie_list:
return "Movie not found"
try:
with open("movie-log.txt", "w") as movie_log_file:
for movie in movie_list:
if movie != movie_details:
movie_log_file.write(f"{movie}\n")
except FileNotFoundError:
return "movie-log.txt file not found"
# This function is used to handle errors
def handle_error(error):
try:
return f"Error of type {type(error)} occurred: {error}"
except Exception as e:
return "Unable to create error message"
# Debug intents
debug_guild = int(os.getenv("DEBUG_GUILD"))
debug_channel = int(os.getenv("DEBUG_CHANNEL"))
# Define the on_ready event handler
#bot.event
async def on_ready():
print("Bot is up and running...")
print("Bot is ready to use!")
# Define the /add command using the command decorator
#bot.command(
name="add",
description="Adds a movie to the movie log",
scope=debug_guild,
)
async def add(ctx: interactions.CommandContext, movie_details: str):
try:
response = openai.Completion.create(
engine="davinci-003",
prompt=f"/add {movie_details}",
max_tokens=1024,
temperature=0.5,
)
except Exception as e:
# Handle any errors that occurred
await ctx.send(handle_error(e))
else:
# Add the movie to the logger
result = add_movie(response.text.strip())
if result:
await ctx.send(result)
# Define the /delete command using the command decorator
#bot.command(
name="delete",
description="Deletes a movie from the movie log",
scope=debug_guild,
)
async def delete(ctx: interactions.CommandContext, movie_details: str):
try:
response = openai.Completion.create(
engine="davinci-003",
prompt=f"/delete {movie_details}",
max_tokens=1024,
temperature=0.5,
)
except Exception as e:
# Handle any errors that occurred
await ctx.send(handle_error(e))
else:
# Delete the movie from the logger
result = delete_movie(response.text.strip())
if result:
await ctx.send(result)
# Define the /search command using the command decorator
#bot.command(
name="search",
description="Searches for movies in the movie log",
scope=debug_guild,
)
async def search(ctx: interactions.CommandContext, query: str):
# Search for movies in the logger
result = search_movies(query)
if result:
await ctx.send(result)
# Define the /list command using the command decorator
#bot.command(
name="list",
description="Lists all movies in the movie log",
scope=debug_guild,
)
async def list(ctx: interactions.CommandContext):
# Get the list of movies from the logger
result = get_movie_list()
if result:
await ctx.send(result)
# Handle command errors using the on_command_error event
#bot.event
async def command_error(ctx, error):
# Send an error message if a CommandNotFound error occurred
if isinstance(error, interactions.CommandNotFound):
await ctx.send("Command not found")
# Run the bot
bot.start()
Please let me know if anything is unclear or if I don't make sense ;-; Thank you!
What I've tried:
Well, at first I was using commands from discord.ext library but then none of my / commands were even showing up on discord, and I searched the web and found out that it's outdated and that I should switch to using interactions library, I used the docs from https://discord-py-slash-command.readthedocs.io/ to switch to interactions, my / commands started showing up when tried to call on discord however I don't know if I coded them correctly.

Discord bot repeating the command but not an event in discord.py

I want to ask something.I got stuck on something.I wanted to add some new features to my bot such as swear words so that making cleaner server.I finished my code and tried to give command which is !dc greetings(!dc is my command_prefix btw).My bot sent 'Hi everyone' message for 7 times.That 7 times is same number as the number of swear words in "Badwords.txt".By looking these,that repeating issue is related to this file handling codes(or not idk).Interesting thins is when I write swear word into server's chatbox,bot send only one "Please do not use this word ever" message.So How can i prevent bot not to repeat for many times?Thank you
import discord
from discord.ext import commands
intents = discord.Intents(messages=True, guilds=True, reactions=True, members=True,presences=True)
client = commands.Bot(command_prefix="!dc ", intents=intents)
#Below command gets repeated 7 times everytime.That number is same as the number of swear words in "Badwords.txt"
#client.command(aliases=["sayHi"])
async def greetings(ctx):
await ctx.send('Hi everyone')
#My purpose in the below codes is countering profanity
with open("Badwords.txt", "r", encoding="utf-8") as f:
word = f.read()
badwords = word.split(",")
#In the below event,bot sends message only 1 time for 1 message
#client.event
async def on_message(message):
msg = message.content
for x in badwords:
if x in msg:
await message.delete()
await message.channel.send("Please do not use this word ever")
else:
await client.process_commands(message)
client.run(Token)
I would take the await client.process_commands(message) out of the else statement. I have also moved the with open inside the on message event so everything a message is sent, it will open the file to check if the message contained a bad word.
import discord
from discord.ext import commands
intents = discord.Intents(messages=True, guilds=True, reactions=True, members=True,presences=True)
client = commands.Bot(command_prefix="!dc ", intents=intents)
#client.command(aliases=["sayHi"])
async def greetings(ctx):
await ctx.send('Hi everyone')
#client.event
async def on_message(message):
msg = message.content
with open("Badwords.txt", "r", encoding="utf-8") as f:
word = f.read()
badwords = word.split(",")
for x in badwords:
if x in msg:
await message.delete()
await message.channel.send("Please do not use this word ever")
else:
return
await client.process_commands(message)
client.run(Token)
await client.process_commands(message) was taken out of the else statement because, with your current code, the bot would only process the commands if the message did NOT contain a bad word. But we need it to process the commands every time a message is sent.

Discord py write something in document

#bot.command()
async def ppadd(ctx, nums):
with open("paypal.txt", "r") as f:
for line in f:
lines = f.readlines()
paypal = lines
f.close()
operation = f"{line} + {nums}"
await ctx.send(f'{operation} = {eval(operation)}')
w = open("paypal.txt", 'w')
for line in lines:
if paypal not in line:
w.write(eval(operation))
w.close()
Hey, i wanna add a overview of my balance to my bot, the !balance command works, but i wanna have the command !ppadd to add a number of money i earned this day. Everything works as i want, but in the .txt document it doesnt replace the old amount with the new one, it just clears the document. Anybody knwo, hwo to help me?

Discord.py onmessage role allocation issue

I've been trying to work this out but can't work out what i'm doing wrong, the method worked fine to delete and display the message but when I tried to get it to allocate a role at the same time I broke it
#bot.event
async def on_message(msg):
for badword in file:
if badword in msg.content.lower():
role = discord.utils.get(msg.guild.roles, name="Muted")
await msg.author.add_roles(role)
await msg.delete()
await msg.channel.send(f'{msg.author.mention}! That was a bad word! You have been muted!')
await bot.process_commands(msg)
I presume i'm missing something simple?
This is the error i'm getting:
Ignoring exception in on_message
Traceback (most recent call last):
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "main.py", line 283, in on_message
await msg.author.add_roles(role)
File "/opt/virtualenvs/python3/lib/python3.8/site-packages/discord/member.py", line 676, in add_roles
await req(guild_id, user_id, role.id, reason=reason)
AttributeError: 'NoneType' object has no attribute 'id'
Also the above is making my other bot.commands repeat indefinitely. So now when I use the random quote command it never stops til I shut off the bot:
#wisdom function
#bot.command(help="Wisdom function",
brief="Get a random wise quote")
async def wisdom(ctx):
responses = open('quotes.txt').read().splitlines()
random.seed(a=None)
response = random.choice(responses)
await ctx.send(f'Hey {ctx.message.author.mention} here is your wisdom:')
await ctx.send(response)
await req(guild_id, user_id, role.id, reason=reason)
^^^^^^^
AttributeError: 'NoneType' object has no attribute 'id'
The problem here is discord.utils.get cannot find a role called Muted, so it returns a NoneType. When you are trying to assign the role, you are essentially doing msg.author.add_roles(None). Maybe try making sure that the role exists, or referencing it by ID instead of Name.
Edit: You should also (in your quote function) send the quote in the same message as the first. (By using \n as a line-break)
Edit 2: You should use a with block to readlines from your file, because with what you have now, the file never closes. Also, read() returns a string, you cannot do readlines() off of the string. Instead do readlines() off of the file object.
Edit 3: You are processing commands for every badword in file (why it runs forever)
Refer to #Frederick Reynolds post about your errors in reading the textfile. I can point out a few things as well, however. For your on_message function, you never check if the message is from your own bot itself, which triggers the repetition of the function. To avoid this, add if msg.author == bot.user: return at the beginning of this function. Secondly, role = discord.utils.get(msg.guild.roles, name="Muted") is not able to find the Muted role for some reason, which is why it sets the value of role to None. This is why, when you call await msg.author.add_roles(role), you're basically doing await msg.author.add_roles(None). Lastly, your indentation is wrong, as you are awaiting bot.process_comands(msg) for every badword in file. Here's the fixed code for the function
#bot.event
async def on_message(msg):
if msg.author == bot.user:
return
for badword in file:
if badword in msg.content.lower():
role = discord.utils.get(msg.guild.roles, name="Muted")
await msg.author.add_roles(role)
await msg.delete()
await msg.channel.send(f'{msg.author.mention}! That was a bad word! You have been muted!')
await bot.process_commands(msg)

Betting, Required arguement missing?

Im starting a new bot, which I hope can eventually start to allow users to bet. Im having trouble finalising this command as it allows the bot to run but when use the ?Coinflip command it says:
Ignoring exception in command coinflip:
Traceback (most recent call last):
File
"C:\Users\sambe\AppData\Local\Programs\Python\Python36\lib\site-packages\discord\ext\commands\bot.py",
line 859, in invoke
await ctx.command.invoke(ctx) File "C:\Users\sambe\AppData\Local\Programs\Python\Python36\lib\site-packages\discord\ext\commands\core.py",
line 718, in invoke
await self.prepare(ctx) File "C:\Users\sambe\AppData\Local\Programs\Python\Python36\lib\site-packages\discord\ext\commands\core.py",
line 682, in prepare
await self._parse_arguments(ctx) File "C:\Users\sambe\AppData\Local\Programs\Python\Python36\lib\site-packages\discord\ext\commands\core.py",
line 596, in _parse_arguments
transformed = await self.transform(ctx, param) File "C:\Users\sambe\AppData\Local\Programs\Python\Python36\lib\site-packages\discord\ext\commands\core.py",
line 442, in transform
raise MissingRequiredArgument(param) discord.ext.commands.errors.MissingRequiredArgument: guess is a
required argument that is missing.
This is the command I am using:
#bot.command(pass_context=True)
async def coinflip(ctx, guess: str, amount: float):
guesses = ('heads', 'tails')
guess = guess.lower()
if guess not in guesses:
await bot.say("Invalid guess.")
return
author = ctx.message.author
balance = get_dollars(author)
if balance < amount:
await bot.say("You don't have that much money. Your balance is ${balance:.2f}")
return
result = random.sample(guesses)
if result == guess:
await bot.say("You won!")
add_dollars(author, amount)
else:
await bot.say("You lost!")
remove_dollars(author, amount)
Id like it to give a coinflip command which gives off random numbers.
Although it just ignores the command.
This error means that you aren't passing enough arguments while using this command. You are propably sending ?coinflip instead of ?coinflip heads 12.

Resources