Discord bot ctx is being displayed as argument - discord

Thats a test code where im trying to work in classes. Even tho in commands it displayes ctx as required arg instead and it works only if i put it before self.
class Quiz:
def __init__(self, question, answer):
self.question = question
self.answer = answer
#bot.command(pass_context=True)
async def quiz(self, ctx):
fido = Quiz("Starter mass?", "yeah")
nope = Quiz("WHAT?", "lel")
await ctx.send(fido.question)
def check(m):
return m.content == 'heh'
msg = await bot.wait_for('message', check=check)
await ctx.send('Right {.author}!'.format(msg))
Error:
discord.ext.commands.errors.MissingRequiredArgument: ctx is a required argument that is missing.
How can I fix this?

As crazy as it sounds, remove the self argument from your method. The commands decorator will take care of this. (You can also use a command cog)
class Quiz:
def __init__(self, question, answer):
self.question = question
self.answer = answer
#bot.command(pass_context=True)
async def quiz(ctx):
fido = Quiz("Starter mass?", "yeah")
nope = Quiz("WHAT?", "lel")
await ctx.send(fido.question)
def check(m):
return m.content == 'heh'
msg = await bot.wait_for('message', check=check)
await ctx.send('Right {.author}!'.format(msg))
Also your check function doesn't work correctly. It always uses the fido question and says you are correct only after responding with 'heh'.
#bot.command(pass_context=True)
async def quiz(ctx):
fido = Quiz("Starter mass?", "yeah")
nope = Quiz("WHAT?", "lel")
question = random.choice((fido, nope))
await ctx.send(question.question)
check = lambda m: m.content.lower() == question.answer
msg = await bot.wait_for('message', check=check)
await ctx.send(f'Right **{msg.author.name}**!')

Related

Trying to make a ChatBot, but for some reason it isnt responding to messages, code and another problem is provided below

Oh and another problem it has is that it doesnt print the user_message in console as it should in line 12
client = discord.Client(command_prefix='',intents=discord.Intents.default())
#client.event
async def on_ready():
print('logged in as {0.user}'.format(client))
#client.event
async def on_message(message):
username = str(message.author).split('#')[0]
user_message = str(message.content)
channel = str(message.channel.name)
print(f'{username}: {user_message} ({channel})')
if user_message == 'Hello':
await message.channel.send('Howdy!')
Any help would be appreciated!
Your indentation is all messed up here; starting with your second client.event, your code is indented way too far; here's how the code should look:
client = discord.Client(command_prefix='',intents=discord.Intents.default())
#client.event
async def on_ready():
print('logged in as {0.user}'.format(client))
# Indentation fixed here
#client.event
async def on_message(message):
username = str(message.author).split('#')[0]
user_message = str(message.content)
channel = str(message.channel.name)
print(f'{username}: {user_message} ({channel})')
if user_message == 'Hello':
await message.channel.send('Howdy!')

How do I set a global variable which can be changed through a command in discord

Not totally sure if I'm doing it correctly but here is the code:
dcoin = ""
#client.command()
async def ddraw(ctx, dcoin1):
def check(m):
return m.author.id == ddraw
await ctx.send(dcoin1)
#client.command()
async def matches(ctx):
coin1 = "5"
if coin1 == dcoin1:
await ctx.send("Match")
else:
await ctx.send("Not a Match")
To my understanding, "dcoin1" is set to whatever is typed in the ddraw command which then changes the global variable of "dcoin1". Therefore it can check if it matches with the match command. (Used 5 as an example)
No, dcoin1 in async def ddraw(ctx, dcoin1): is an argument. It exists only in your function.
You can write this:
dcoin = ""
#client.command()
async def ddraw(ctx, dcoin1):
global dcoin
dcoin = dcoin1
await ctx.send(dcoin1)
#client.command()
async def matches(ctx):
coin1 = "5"
if coin1 == dcoin:
await ctx.send("Match")
else:
await ctx.send("Not a Match")
In this code dcoin is a global variable and users can modify it using ddraw command.

Discord.py snipe command is sniping messages from other channels

I recently made a snipe command for my discord bot but I have one problem. Snipe command snipes a message from other channels when I for example want to snipe a message in general. Here is my code:
#bot.event
async def on_message_delete(message):
if message.attachments:
bob = message.attachments[0]
bot.sniped_messages[message.guild.id] = (bob.proxy_url, message.content, message.author, message.channel.name, message.created_at)
else:
bot.sniped_messages[message.guild.id] = (message.content,message.author, message.channel.name, message.created_at)
#bot.command(aliases=['s'])
async def snipe(ctx):
try:
bob_proxy_url, contents,author, channel_name, time = bot.sniped_messages[ctx.guild.id]
except:
contents,author, channel_name, time = bot.sniped_messages[ctx.guild.id]
try:
embed = discord.Embed(description=contents , color=discord.Color.purple(), timestamp=time)
embed.set_image(url=bob_proxy_url)
embed.set_author(name=f"{author.name}#{author.discriminator}", icon_url=author.avatar_url)
embed.set_footer(text=f"Deleted in : #{channel_name}")
await ctx.channel.send(embed=embed)
except:
embed = discord.Embed(description=contents , color=discord.Color.purple(), timestamp=time)
embed.set_author(name=f"{author.name}#{author.discriminator}", icon_url=author.avatar_url)
embed.set_footer(text=f"Deleted in : #{channel_name}")
await ctx.channel.send(embed=embed)
snipe_message_author = {}
snipe_message_content = {}
#client.event
async def on_message_delete(message):
snipe_message_author[message.channel.id] = message.author
snipe_message_content[message.channel.id] = message.content
#client.command(name = 'snipe')
async def snipe(ctx):
channel = ctx.channel
try:
em = discord.Embed(description = f"`{snipe_message_content[channel.id]}`\nMessage sent by {snipe_message_author[channel.id]}!", color = 0x00c230)
em.set_author(name = f"Last deleted message in #{channel.name}")
em.set_thumbnail(url="https://cdn.discordapp.com/avatars/352793093105254402/8a2018de21ad29973696bfbf92fc31cd.png?size=4096")
em.set_footer(text = f"Snipe requested by {ctx.message.author}")
await ctx.send(embed = em)
except:
embed = discord.Embed(colour = 0x00c230)
embed.set_author(name=f"There are no deleted messages in #{ctx.channel}!")
embed.set_thumbnail(url="https://cdn.discordapp.com/avatars/352793093105254402/8a2018de21ad29973696bfbf92fc31cd.png?size=4096")
embed.set_footer(text=f"Snipe requested by {ctx.message.author}")
await ctx.channel.send(embed=embed)
Thats what I use and it works properly.
Since I added [message.channel.id] to the variables it only checks for snipes in that channel. This is how it looks like in Discord

discord.py How to make a emoji guess game?

Hi i am making a Discord bot and i wanted to add a fun command that asks a emoji about a film and it wants you to answer properly. How am i suppossed to do that? Btw here is my code;
#client.command()
async def emoji(ctx):
filmemojis = [':woman_frowning: :sparkler: :woman_with_veil: :high_heel:',
':ocean: :fish: :mag:',
':nerd: :man_mage: :sparkler: :school:',
':tiger2: :person_wearing_turban: :man_rowing_boat:',
':ring: :crown: :volcano:',
':earth_americas: :rocket: :monkey_face:',
':rocket: :alien: :sunglasses: :sunglasses:',
':mouse2: :pizza: :turtle: :turtle: :turtle: :turtle:',
':mushroom: :grinning: :weary: :smirk: :triumph: :open_mouth: :innocent: :pensive:',
':ship: :couple_with_heart_woman_man:',
':blue_car: :watch: :arrow_right_hook: :hourglass_flowing_sand:']
await ctx.send(f'{random.choice(filmemojis)}\nWhat film is this?')
You are looking for Bot.wait_for
#client.command()
async def emoji(ctx):
filmemojis = [
':woman_frowning: :sparkler: :woman_with_veil: :high_heel:',
':ocean: :fish: :mag:',
':nerd: :man_mage: :sparkler: :school:',
':tiger2: :person_wearing_turban: :man_rowing_boat:',
':ring: :crown: :volcano:',
':earth_americas: :rocket: :monkey_face:',
':rocket: :alien: :sunglasses: :sunglasses:',
':mouse2: :pizza: :turtle: :turtle: :turtle: :turtle:',
':mushroom: :grinning: :weary: :smirk: :triumph: :open_mouth: :innocent: :pensive:',
':ship: :couple_with_heart_woman_man:',
':blue_car: :watch: :arrow_right_hook: :hourglass_flowing_sand:'
]
await ctx.send(f'{random.choice(filmemojis)}\nWhat film is this?')
def check(m):
"""Checks if the user that replied is the same as the one that invoked the command"""
return m.author == ctx.author
message = await client.wait_for('message', check=check) # You can also add a timeout
Adding a timeout
try:
message = await client.wait_for('message', check-check, timeout=60.0) # Change the timeout accordingly
except asyncio.TimeoutError: # You need to import asyncio for this
await ctx.send('whatever')

'RawReactionActionEvent' object has no attribute 'member'

Im having this issue and i still cant find a solution this is the code
#commands.Cog.listener()
async def on_raw_reaction_add(self, payload):
if payload.message_id == commands.reaction_message.id and commands.reaction_role != None:
await payload.member.add_roles(commands.reaction_role)
#commands.Cog.listener()
async def on_raw_reaction_remove(self, payload):
if payload.message_id == commands.reaction_message.id and commands.reaction_role != None:
guild = self.client.get_guild(payload.guild_id)
member = guild.get_member(payload.user_id)
await member.remove_roles(commands.reaction_role)
#commands.command()
async def set_reaction_message(self, ctx, message_id=None, role_id=None):
for channel in ctx.guild.channels:
try:
commands.reaction_message = await channel.fetch_message(int(message_id))
break
except:
pass
problem: File "c:\Users\MY-NAME\Desktop\Overige en school\Discord Bot\cogs\reaction.py", line 17, in on_raw_reaction_add
await payload.member.add_roles(commands.reaction_role)
AttributeError: 'RawReactionActionEvent' object has no attribute 'member'
can someone please help me this is been bothering me now for 2days and i can't even find a solution
I know according to the documentation discord.RawReactionActionEvent payload has the object member. But why don't you make it easier for yourself and get the member in the same way as in your on_raw_reaction_remove event? The following should work.
#commands.Cog.listener()
async def on_raw_reaction_add(self, payload):
if payload.message_id == commands.reaction_message.id and commands.reaction_role != None:
guild = self.client.get_guild(payload.guild_id)
member = guild.get_member(payload.user_id)
await member.add_roles(commands.reaction_role)
#commands.Cog.listener()
async def on_raw_reaction_remove(self, payload):
if payload.message_id == commands.reaction_message.id and commands.reaction_role != None:
guild = self.client.get_guild(payload.guild_id)
member = guild.get_member(payload.user_id)
await member.remove_roles(commands.reaction_role)
#commands.command()
async def set_reaction_message(self, ctx, message_id=None, role_id=None):
for channel in ctx.guild.channels:
try:
commands.reaction_message = await channel.fetch_message(int(message_id))
break
except:
pass

Resources