Search code examples
pythondiscorddiscord.py

Bot won't respond to Emoji Reaction


I'm planning to make a bot that got Name and Birthday from User input, and before storing the user's answer to database (in my case, Google Spreadsheet via gspread), Ask the user that input is correct.

So I decided to show an react emojis bottom the Checking embed, and If user reacts with ⭕, It will append the User's input to Google Spreadsheet. in the other hand, if user reacts with ❌ one, It discard the user input and Showing Error Message.

The bot works.... only the Checking Embed. how nice. and yes, bot deployed with no error, and If I use slash command and input the Data, the Bot prints Checking Embed and React Emojis well. (Look at the Picture for result.)

But It didn't react when I responded emoji. both of all not work.

here's my code about that command.

@slash.slash(
    name="테스트쓰기",
    description="샘플 데이터를 구글 시트에 작성합니다.",
    guild_ids=[865433__________],
    options=[
        create_option(
            name="이름",
            description="스프레드시트에 표시될 이름",
            option_type=3,
            required=True
        ),
        create_option(
            name="생일",
            description="MM-DD 형식으로 입력",
            option_type=3,
            required=True
        )
    ],
    connector={
    '이름': 'uname',
    '생일': 'btday'
    }
)
async def ap_sheet(ctx:SlashContext, uname:str, btday:str):
    checker = await ctx.send(embed=check_emb(ctx, uname=uname, btday=btday))
    
    await checker.add_reaction("⭕")
    await checker.add_reaction("❌")

    async def check(reaction, user):
        return user == ctx.user and reaction.message.id == checker.id and str(reaction.emoji) in ['⭕','❌']
        
        while True : 
            try:
                reaction, user = await bot.wait_for("reaction_add", check=check, wait_for=20.0) #Wait 20sec for user input
                
                if str(reaction.emoji) == '⭕': #User Accepts and wants to append data to sheet
                    await checker.delete()
                    await ctx.send(discord.Embed(title="완료", description="입력한 정보를 내보냈습니다.", color=discord.Color.blue()), delete_after=5)
                    gc1.append_row([uname, ctx.author.id, btday])
                    
                elif str(reaction.emoji) == '❌': #User Cancels command
                    await checker.delete()
                    await ctx.send(discord.Embed(title="취소됨!", description="사용자의 조작에 의해 취소되었어요.", color=discord.Color.red()), delete_after=5)
    
                pass
            
            except asyncio.TimeoutError: #Time is Over
                await ctx.send("시간 초과되었습니다.")

Solution

  • This is the proper way to call a check, it doesnt look like yours is ever called

    answers = ["⭕","❌"]
        for reaction in answers:
            await ctx.message.add_reaction(emoji=reaction)
    
     def check(reaction, user):
            if str(reaction.emoji) in answers and user.id == ctx.author.id:
                return user == ctx.author and str(reaction.emoji) == str(reaction.emoji)
    
    try:
        reaction, user = await bot.wait_for('reaction_add', timeout=20.0, check=check)
        if(str(reaction)=="❌"):
            #Deny code here, I would recommend deleting the prompt
        if(str(reaction)=="⭕"):
            #Confirm code here
    except:
        #Code will go here if there is a timeout. I would recommend deleting the prompt