1
votes

I'm still learning the discord.py library so I apologize for any rookie mistakes.

The code below is part of a function which performs 3 actions:

  1. Connect to an sqlite3 database
  2. Ask what kitname to create and insert the new kitname into the sqlite3 database
  3. Ask if the user would like to add cards to their kitname.
 #To create a new kit
@client.command(name="createkit")
async def createkit(message):
    author = message.author
    await author.send("What name would you like to give the new kit?")
    msg = await client.wait_for('message')
    kitName = msg.content #name of kit user wants to make
    userID = msg.author.id #User ID of the author of the reply message
    userName = msg.author.name #Username of the author who wrote the reply message
    db = sqlite3.connect('kits.sqlite')
    cursor = db.cursor()
    cursor.execute('''
    CREATE TABLE IF NOT EXISTS kits(
    DeckID INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
    User TEXT NOT NULL,
    UserID INTEGER NOT NULL,
    Deckname TEXT NOT NULL
    )
    ''')
    print("Connected to Kits")
    cursor.execute(f"SELECT * FROM kits WHERE UserID = {userID}")
    sql = ("INSERT INTO kits(User, UserID, Deckname) VALUES(?,?,?)")
    val = (userName, userID, kitName)
    cursor.execute(sql, val)
    db.commit()
    await author.send(f"{kitName} has been created!")
    addCards = await author.send(f"Would you like to add cards to {kitName}?")
    await addCards.add_reaction('????')
    await addCards.add_reaction('????')
    reaction, user = await client.wait_for('reaction_add')
    if user == client.user:
        return
    elif str(reaction.emoji) == '????':
        print(user)
        await user.send('Great!') #<-- error
        print("Replied with thumbs up!")
    elif str(reaction.emoji) == '????':
        await user.send('Too bad...') #<-- error
        print("Replied with thumbs down!")
    cursor.close()
    db.close()```

Parts 1 and 2 work without any issues. Part 3 which asks users to react with a thumbs up or thumbs down emoji throws the error below:

discord.ext.commands.errors.CommandInvokeError: 
Command raised an exception: AttributeError: 
'ClientUser' object has no attribute 'send'

The weird thing with this is I will restart the bot and go through the command use. I will react with the thumbs up emoji, and it will reply with "Great!" without producing any errors. I will run through it a second time and reply with a either a thumbs down or thumbs up, and the above error occurs. It seems to work for the first time, but then the second time it errors out. Even if I restart the bot shortly after, it will fail. If I wait a while before restarting then try again, the bot will work once, then fail every time after that with the same problem. I am not sure what the issue is. I have looked over some other threads that seem to address the problem to no avail.

Any help in advance is greatly appreciated!

1
Try printing out the user object after wait_for and see what type it is. Maybe it is not always the same type, as the error said, ClientUser objects don't have a send methodHymns For Disco
@HymnsForDisco It looks like it is printing the bot as user, which would explain why it can't send, I think... I added if user == client.user: return before the elif str(reaction.emoji)... lines and I still get the same problem. It worked once, then failed for attempts after. Maybe a check? I'm entirely foreign to those.Zarvix
Please include the entire function.Patrick Haugh
@PatrickHaugh Edited to show that entire function. Thanks in advance for the help.Zarvix

1 Answers

2
votes

The reason for your error is that the bot is trying to DM itself.

Discord.py's wait_for function accepts a check kwarg that allows you to filter for a specific event. If you do not include this check then the library will wait till the next event of that type (in this case a reaction_add) from anywhere. In your specific case it happends to be the bot adding the reaction:

await addCards.add_reaction('👍')
await addCards.add_reaction('👎')

A Simple fix for this is to write a check function that will only return True if someone else adds that reaction:

def check(reaction,user):
    return not user.bot and reaction.message.id == addCards.id and str(reaction.emoji) in ['👍','👎']

reaction, user = await client.wait_for('reaction_add',check=check)