0
votes

I'm trying to make Discord bot command, where Bot creates Emoji and if user reacts on this Emoji - bot doing some required stuff, but getting this error on check part:

discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: check() takes 1 positional argument but 2 were given

The Bot sends the message and attaches Emoji to it, but however, the check part throws an error and I don’t know how to solve it.

Here's my code:

An error is issued in the penultimate line of code

@commands.command()
async def test(self, ctx):
    author = ctx.author
    message = await ctx.send('test')

    emote = 'βœ”'

    for e in emote:
        await message.add_reaction(e)

    def check(author):
        def react_check(reaction, emoji):
            return message.author == author and reaction.message.id==msg.id and reaction.emoji==emoji
        return check

    await self.client.wait_for('reaction_add', check=check(author, emote), timeout=60)
    await ctx.send('some stuff after check')
3
check only accepts author argument as input but you are passing in author and emote - sshashank124
You are passing two arguments to your check() function. - marxmacher
Even with just await self.client.wait_for('reaction_add', check=check, timeout=60) this error is occure, but i pass only 1 argument in this case? - Clonexy700
in this case you don't pass any argument to check on right side =check. Do you get exactly the same error or little different ? - furas
I tried 2 versions of check. First version in code and i getting error here. If i not passing any arguments, i'm getting absolutely same error. The second version of check is using await self.client.wait_for('reaction_add', check=lambda reaction, user: reaction.emoji == 'βœ”', timeout=60) but if i use this, Discord Bot not waiting for user reaction and sending message after check immediately - Clonexy700

3 Answers

1
votes

You can actually find a very nice example in the discord.py documentation.

@client.event
async def on_message(message):
    if message.content.startswith('$thumb'):
        channel = message.channel
        await channel.send('Send me that πŸ‘ reaction, mate')

        def check(reaction, user):
            return user == message.author and str(reaction.emoji) == 'πŸ‘'

        try:
            reaction, user = await client.wait_for('reaction_add', timeout=60.0, check=check)
        except asyncio.TimeoutError:
            await channel.send('πŸ‘Ž')
        else:
            await channel.send('πŸ‘')

As you can see your problem is the following: You are passing your function check already having executed with arguments into the wait_for function. That is the incorrect way to do it, especially because your variables reaction and user have never been defined.

What you actually need to do is the following:

def check(author):
    def react_check(reaction, emoji):
        return message.author == author and reaction.message.id==msg.id and reaction.emoji==emoji
    return check

author, emote = await self.client.wait_for('reaction_add', check=check, timeout=60)

This passes the function, not the returned value from the function into wait_for.

1
votes

Main error is in function check and for fixing the error it will be slightly changed, but will work correctly.

def check(reaction, user):
    return (reaction.message.id == message.id) and (user.id == ctx.author.id) and (str(reaction) in emote)

And just some improvements in code, so full code is here below:

@commands.command()
async def test(self, ctx):
    author = ctx.author
    message = await ctx.send('test')

    emote = 'βœ”'

    for e in emote:
        await message.add_reaction(e)

    def check(reaction, user):
        return (reaction.message.id == message.id) and (user.id == ctx.author.id) and (str(reaction) in emote)

    try:
        reaction, user = await self.client.wait_for('reaction_add', check=check, timeout=60)
    except asyncio.TimeoutError:
        await ctx.send("Timed out")
                return
    if str(reaction) == 'βœ”':
        await ctx.send('some stuff')
1
votes

The purpose of check here is that it is a function that when called returns a function that can be used as a check for this wait_for. The correct way to use it is:

def check(author):
    def react_check(reaction, emoji):
        return message.author == author and reaction.message.id==msg.id and reaction.emoji==emoji
    return check

await self.client.wait_for('reaction_add', check=check(author), timeout=60)