我的问题: 机器人每 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()
,答案将是错误的。
您的问题的一个解决方案是使用 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() 分别等待每个用户的响应,并相应地记录他们的响应。
我希望这个解决方案可以帮助您解决问题! 干杯!