问题
What I'm trying to do: Learning to make a proper help menu for my discord.py bot by having the ctx.message.author
react to the message with the reactions given. The bot checks if they've been reacted to, then edits the message. If the ctx.message.author
un-reacts, it goes back to the first menu (menuu).
Problem(s): I'm not sure how to loop through this until the timeout
runs out. I'm also not sure how to check if the user un-reacts to the message.
Error(s): No errors.
@client.command()
async def menuu(ctx):
#what reaction goes where menuu
menuu = discord.Embed(title="menuu", color=0x8d78d9)
menuu.add_field(name="Topics: ", value="React with <:oneone:772681764321099827>", inline=False)
menuu.add_field(name="Games: ", value="React with <:twotwo:772681764271423528>", inline=False)
menuu.add_field(name="Misc: ", value="React with <:threethree:772681763939024897>", inline=False)
menuu.set_footer(text=f"Ensure you drink some water today, you're doing so well {ctx.message.author}")
#topics menuu
topics = discord.Embed(title="Topics", color=0x8d78d9)
topics.add_field(name="`bl!topic`: ", value="Friend makers and ice breakers", inline=False)
topics.add_field(name="`bl!debate`: ", value="menuu not complete sorry haha")
topics.set_footer(text="Never forget to believe in yourself, because I do!")
#game menuu
games = discord.Embed(title="Games", color=0x8d78d9)
games.add_field(name="`nothing here`: ", value="Technically there is but still", inline=False)
games.set_footer(text="Eat some food, take a nap, good luck on the journey ahead")
#misc menuu
misc = discord.Embed(title="Misc", color=0x8d78d9)
misc.add_field(name="`miscmimscimc`: ", value="aeaeaeaeaeaeeae", inline=False)
misc.set_footer(text="You look lovely today, you're rocking this look")
msg = await ctx.send(embed=menuu)#send message
#add reactions things
await msg.add_reaction("<:oneone:772681764321099827>")
await msg.add_reaction("<:twotwo:772681764271423528>")
await msg.add_reaction("<:threethree:772681763939024897>")
await msg.add_reaction("<:stop:773054889685024768>")
try:
def check(reaction, user):
return user == ctx.message.author and str(reaction.emoji) in ["<:oneone:772681764321099827>","<:twotwo:772681764271423528>","<:threethree:772681763939024897>"]
reaction, user = await client.wait_for("reaction_add", timeout=60, check=check)
if str(reaction.emoji) == "<:oneone:772681764321099827>":
await msg.edit(embed=topics)
await msg.remove_reaction("<:oneone:772681764321099827>", ctx.message.author)
if str(reaction.emoji) == "<:twotwo:772681764271423528>":
await msg.edit(embed=games)
await msg.remove_reaction("<:twotwo:772681764271423528>", ctx.message.author)
if str(reaction.emoji) == "<:threethree:772681763939024897>":
await msg.edit(embed=misc)
await msg.remove_reaction("<:threethree:772681763939024897>", ctx.message.author)
if str(reaction.emoji) == "<:stop:773054889685024768>":
await msg.edit(embed=menuu)
await msg.remove_reaction("<:stop:773054889685024768>", ctx.message.author)
except asyncio.TimeoutError:
await ctx.send("Time has run out, message no work now")
```
回答1:
I've created an easy enough to use 'book-manager'. If you put all of your menuus into a list called pages you can use this function:
async def createbook(bot, ctx, title, pages, **kwargs):
header = kwargs.get("header", "") # String
results = kwargs.get("results", 0) # Int
pagenum = 1
def get_results():
results_min = (pagenum - 1) * 8 + 1
if pagenum == len(pages): results_max = results
else: results_max = pagenum * 8
return f"Showing {results_min} - {results_max} results out of {results}"
pagemax = len(pages)
if results:
header = get_results()
if len(pages) == 0: pagemax = 1
embed = discord.Embed(title=title, description=f"{header}\n\n{pages[pagenum - 1]}", colour=0xF42F42)
embed.set_footer(text=f"Page {pagenum}/{pagemax}", icon_url=fboturl)
msg = await ctx.send(embed=embed)
await msg.add_reaction("⬅️")
await msg.add_reaction("➡")
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) in ["⬅️", "➡"]
while True:
try:
reaction, user = await bot.wait_for("reaction_add", timeout = 60, check=check)
await msg.remove_reaction(reaction, user)
if str(reaction.emoji) == "⬅️":
pagenum -= 1
if pagenum < 1: pagenum = len(pages)
elif str(reaction.emoji) == "➡":
pagenum += 1
if pagenum > len(pages): pagenum = 1
header = get_results() if results else header
if str(reaction.emoji) == "⬅️" or str(reaction.emoji) == "➡":
embed = discord.Embed(title=title, description=f"{header}\n\n{pages[pagenum - 1]}", colour=0xF42F42)
embed.set_footer(text=f"Page {pagenum}/{len(pages)}", icon_url=fboturl)
await msg.edit(embed=embed)
except:
header = get_results() if results else header
embed = discord.Embed(title="FBot Server Status", description=f"{header}\n\n{pages[pagenum - 1]}", colour=0xF42F42)
embed.set_footer(text=f"Request timed out", icon_url=fboturl)
await msg.edit(embed=embed)
break
(I avoid using numbers purely because books with more than 10 pages are annoying to manage)
回答2:
So after a really long time of trial and error, I have figured out my own method based off of Judev1's create-book thing. I incorporated the way the page number changes, as well as the wait_for
and time out things.
@client.command(aliases=["help"])
async def menuu(ctx):
#first just giving all the embeds a purpose and a place to exist
user = ctx.author
menuu = discord.Embed(title="Help Menuu", color=0x8d78d9)
menuu.add_field(name="How to navigate : ", value="```Use the arrow reactions below to navigate this menuu```", inline=False)
menuu.add_field(name="How to invite bot : ", value="```Use bl!invite to invite this bot and join our support server!```", inline=True)
menuu.set_footer(text=f"Ensure you drink some water today, you're doing so well {ctx.message.author}")
#topics menuu
topics = discord.Embed(title="Topics", color=0x8d78d9)
topics.add_field(name="bl!topic : ", value="```Friend makers and ice breakers```", inline=False)
topics.add_field(name="bl!debate : ", value="```Sends a debate topic (Trigger Warning: Some topics may trigger certain individuals. Please tread with caution when using this command)```", inline=False)
topics.add_field(name="bl!wyr : ", value="```Would you rather questions```", inline = False)
topics.add_field(name="bl!place : ", value="```So many places in the world, so little time```", inline = True)
topics.set_footer(text="Never forget to believe in yourself, because I do!")
#game menuu
games = discord.Embed(title="Games", color=0x8d78d9)
games.add_field(name=f"bl!powpow `@blitz` : ", value="```Who will win? You, or that person you mentioned?```", inline=False)
games.add_field(name=f"bl!battle `@blitz` : ", value="```Basically powpow but less work```", inline=True)
games.set_footer(text="Eat some food, take a nap, good luck on the journey ahead")
#pics menuu
pics = discord.Embed(title="Picture Things:tm:", color=0x8d78d9)
pics.add_field(name="bl!avatar `@blitz` : ", value="```Get the profile picture of the mentioned person```", inline=False)
pics.add_field(name="bl!hug `@blitz` : ", value="```Hugs, many hug gifs :)```", inline= True)
pics.add_field(name="bl!slap `@blitz` : ", value="```Slap whoever you want without the pain```", inline=False)
pics.set_footer(text="You look lovely today, you're rocking this look")
##send message##
msg = await ctx.send(embed=menuu)
pages = 1 #page it's currently on
left = "<a:totheleft:767541559440572427>" #left arrow reaction
right = "<a:totheright:767541574287884309>" #right arrow reaction
await msg.add_reaction(left) #add reaction to send menuu
await msg.add_reaction(right) #and again
def check(reaction, user): #checking if user is author and the reaction is either left or right (as defined earlier)
return user == ctx.author and str(reaction.emoji) in [left, right]
while True:
try:
reaction, user = await client.wait_for("reaction_add", timeout = 120, check=check)
await msg.remove_reaction(reaction, user)
if str(reaction.emoji) == left:
pages = pages - 1
if pages < 1:
pages = 4 #if pages is less than 1, go straight to 4
if str(reaction.emoji) == right:
pages = pages + 1
if pages > 4:
pages = 1 #if pages is more than 4, go back to 1
#if this is the page number, edit so it's this embed instead
if pages == 1:
await msg.edit(embed=menuu)
elif pages == 2:
await msg.edit(embed=topics)
elif pages == 3:
await msg.edit(embed=games)
elif pages == 4:
await msg.edit(embed=pics)
except: #timeout error handling
embed = discord.Embed(title="Run command again to use", description="Have a good day {ctx.author.display_name}! `bl!menuu`")
await msg.edit(embed=embed)
break
来源:https://stackoverflow.com/questions/64675404/how-to-loop-with-a-reaction-embed-menu