Betting, Required arguement missing? - discord.py

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.

Related

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

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.

My discord bot's command code on Python won't execute for some reason

This is a code of mine that make my bot get access to Reddit post by using user's argument:
#bot.command()
async def reddit(ctx, *, args):
global block, embed
keywords = ""
sub = ['memes', 'showerthoughts', 'jokes', 'antijokes']
if args:
for i in range(0, len(sub)):
if sub[i] in args:
keywords = sub[i]
break
else:
await ctx.send("The sub-reddit is invalid, dear dummy.")
return
block = await ctx.send(f"Fetching {keywords}...")
for count in range(1, 5):
await asyncio.sleep(0.05)
await block.edit(content=f"Fetching {keywords}...`{str(count)}/5`")
count += 1
subreddit = reddit.subreddit(keywords)
all_subs = []
top = subreddit.top(limit=50)
for submission in top:
all_subs.append(submission)
random_sub = random.choice(all_subs)
name = random_sub.title
url = random_sub.url
text = random_sub.selftext
embed = discord.Embed(title=name, color=discord.Color.green(), description=text)
embed.set_image(url = url)
embed.set_footer(text=f"Asked by {ctx.message.author.display_name}")
await block.edit(embed=embed)
The problem is it seem to cause error:
Ignoring exception in on_command_error
Traceback (most recent call last):
File "C:\Users\admin\PycharmProjects\pythonProject\venv\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "C:/Users/admin/PycharmProjects/pythonProject/main.py", line 23, in on_command_error
timeleft = round(error.retry_after, 2);
AttributeError: 'CommandInvokeError' object has no attribute 'retry_after'
This is the code it refered to:
#bot.event
async def on_command_error(ctx, error):
timeleft = round(error.retry_after, 2);
if isinstance(error, commands.CommandOnCooldown):
await ctx.send(f'Wah, spicy. Stop spamming. Try it again after `{timeleft}` seconds')
The code works just fine, however, only when I try to execute the reddit command, it begin to throw the above errors. I have no idea why this happenned.
Turn out it's because of the duplicate name of existed reddit variable. Beginner mistake, as expected from a total beginner like me. The problem is solved.

fetch_message(id) with user token

make await fetch_message(id) work with user token
client.run((token), bot=False)
I'm trying to get a bot that uses a user's token to respond to a message by id i try use await fetch_message(id) but i got:
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\edgar\AppData\Local\Programs\Python\Python37\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "C:\Users\edgar\Desktop\bot\bot.py", line 20, in on_message
msg = await channel.fetch_message(826185450141253682)
File "C:\Users\edgar\AppData\Local\Programs\Python\Python37\lib\site-packages\discord\abc.py", line 1002, in fetch_message
data = await self._state.http.get_message(channel.id, id)
File "C:\Users\edgar\AppData\Local\Programs\Python\Python37\lib\site-packages\discord\http.py", line 241, in request
raise Forbidden(r, data)
discord.errors.Forbidden: 403 Forbidden (error code: 20002): Only bots can use this endpoint
NOTE This workaround only works if your selfbot was running at the point the message where send.
you can use the cached_mesages attribute from the discord Client.
messages = client.cached_messages
# and then use the utils.get function to seek for the id in this list
message = discord.utils.get(messages, id=id_to_seek)
# utils.get() returns None if message not found
# else it returnes a normal Message object you can work with.
I never tried this on a selfbot, but this prevents you from making the API call and should work just as expected.

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)

how to make bot assign roles when given command

i am trying to make the bot give the 'mall' role and remove the 'study hall' role. However, it keeps returning the error
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\frost\AppData\Local\Programs\Python\Python38-32\lib\site-packages\discord\client.py", line 333, in _run_event
await coro(*args, **kwargs)
File "D:\GalaxyConflux Master\gcclient.py", line 89, in on_message
role.id = 798193741403127818
AttributeError: 'str' object has no attribute 'id'
the code that is running is this
#client.event
async def on_message(message):
if message.content.startswith(gccmd.cmd_prfx + 'mall'):
role = 'Mall'
role.id = 798193741403127818
await message.author.add_roles(role.id)
i have tried many different approaches but each result in a similar error.
I had it just go off of the role = 'Mall' part but that did not work either.
How can I convert the role id into an actual id?
Thanks so much!
~Glimmer
here's an example peice that shows you how to add a role and remove one.
#client.command()
async def mall(ctx):
# if prefix is '-' you'd type: -mall
await user.remove_roles(#ROLE_ID)
await user.add_roles(#ROLE_ID)
await ctx.send("Mall role added!")
#client.command()
async def home(ctx):
# if prefix is '-' you'd type: -home
await user.remove_roles(#ROLE_ID)
await user.add_roles(#ROLE_ID)
await ctx.send("Home role added!")
If you want to remove multiple roles, you'd have to just add all of the roles there you want to remove, then add the one's you want.
For example, if you are heading to the mall from your house, it removes every role including the house role and adds the mall one.

Resources