如何在不中断向 Discord.py 中的用户发送确认消息的情况下处理交互?

问题描述 投票:0回答:1
  • 我的问题: 机器人每 30 分钟循环一次任务以检查日历,当有课程时,机器人发送一个嵌入了 2 个按钮“加入或不加入”课程的“确认”。

  • 新问题:循环公会成员并向用户发送消息(使用嵌入式按钮)时,bot必须等待第一次用户点击。如果第一个用户不回复消息,机器人将无法继续发送消息.

这是我确认的嵌入代码:

class confirm_join_class(discord.ui.View):

    join: bool = None
    def __init__(self, *, timeout=180):
        super().__init__(timeout=timeout)

    @discord.ui.button(label='join', style=discord.ButtonStyle.green)
    async def join_class(self, interaction: discord.Interaction,  button: discord.ui.Button,):        
        self.join = True
        await interaction.response.send_message("join")
        self.stop()
    
    @discord.ui.button(label='not join', style=discord.ButtonStyle.green)
    async def off_class(self, interaction: discord.Interaction,  button: discord.ui.Button,):        
        self.join = False
        await interaction.response.send_message("lazy")
        self.stop()

这是我的任务循环代码:

@tasks.loop(seconds=60)
async def checking_time(bot: discord.Client):
    nearest_event:event = get_today_event(1)[0]

    for guild in bot.guilds:
        print("Discord channel guild name: " + guild.name)
        async for member in guild.fetch_members(limit=150):
            print(member.roles)
            for r in member.roles:       
                if(nearest_event.student_role == r.name):
                    print(f"found user {member.name}")

                    user = await bot.fetch_user(member.id)

                    embeded_message = embeded_tools.calendar_event_to_embed(nearest_event)
                    confirm_button = embeded_tools.confirm_join_class()


                    await user.send(embed=embeded_message, view=confirm_button)
                    await confirm_button.wait()


                    if(confirm_button.join is True):
                        print("LOG: join")
                        
                    else:
                        print("LOG: not join")

如果我删除

await confirm_button.wait()
,答案将是错误的。

python button discord discord.py interaction
1个回答
0
投票

您的问题的一个解决方案是使用 asyncio 的收集功能同时执行向所有用户发送消息,然后等待他们的响应。

这是一个示例,说明如何使用此方法修改任务循环:

@tasks.loop(seconds=60)
async def checking_time(bot: discord.Client):
    nearest_event:event = get_today_event(1)[0]

    for guild in bot.guilds:
        print("Discord channel guild name: " + guild.name)
        members = []

        async for member in guild.fetch_members(limit=150):
            print(member.roles)
            for r in member.roles:       
                if(nearest_event.student_role == r.name):
                    print(f"found user {member.name}")

                    user = await bot.fetch_user(member.id)
                    members.append(user)

        embeded_message = embeded_tools.calendar_event_to_embed(nearest_event)
        confirm_button = embeded_tools.confirm_join_class()

        tasks = []
        for user in members:
            tasks.append(asyncio.ensure_future(user.send(embed=embeded_message, view=confirm_button)))

        await asyncio.gather(*tasks)

        for user in members:
            if confirm_button in user._state.interaction_task._tasks:
                await confirm_button.wait()
                if(confirm_button.join is True):
                    print("LOG: join")
                else:
                    print("LOG: not join")

在这个修改后的代码中,机器人不是一次向每个用户发送一条消息并等待他们的响应,而是使用 asyncio 的收集功能同时向所有用户发送消息,正如我已经解释过的那样。一旦发送了所有消息,代码就会使用 confirm_button.wait() 分别等待每个用户的响应,并相应地记录他们的响应。

我希望这个解决方案可以帮助您解决问题! 干杯!

© www.soinside.com 2019 - 2024. All rights reserved.