Kali
Kali

Reputation: 65

Making embeds of more than one page using discord.py

I'm currently trying to make a bot using discord.py. One of the functions I want it to have is to show the users with X role. I've managed to create said function, and make the bot send the results with a nice embed. However, now I want to improve it and make it more similar to Nadeko's inrole function (i.e. only one embed and the user can react to it to change the page).

@client.command(name = "inrole", brief = "Users with a certain role",
            description= "I'll give you a list with all the users with a certain role.", pass_context=True)
async def inrole(ctx, *args):
    server = ctx.message.guild
    role_name = (' '.join(args))
    role_id = server.roles[0]
    for role in server.roles:
        if role_name.lower() == role.name.lower():
            role_id = role
            break
    else:
        await ctx.send(f"Oh noes! That role doesn't exist!")
        return
    n = 0
    members = []

    for member in server.members:
        if role_id in member.roles:
            n += 1
            name = str(n) + ". " + member.name + " #" + member.discriminator + "\n"
            members.append(name)
    composite_members = [members[x:x + 20] for x in range(0, len(members), 20)]

    for elements in composite_members:
        string = ""
        for element in elements:
            string = string + element
        embedVar = discord.Embed(title=f"List of users with {role} - {n}", colour=discord.Colour.blue())
        embedVar.add_field(name = "Members", value = string)
        await ctx.send(embed=embedVar)

I've read the documentation, but I'm still quite lost in how to make it like Nadeko's. Right now, if there are 200 users with that role, then it will print 10 embeds, which can be rather annoying. Thanks in advance!

EDIT: I've improved the code a bit, but now I have a different problem.

def predicate(message, l, r):
    def check(reaction, user):

        if reaction.message.id != message.id or user == client.user:
            return False
        if l and reaction.emoji == "⏪":
            return True
        if r and reaction.emoji == "⏩":
            return True
        return False

    return check

#inrole function. To see all members with that role
@client.command(name = "inrole", brief = "Users with a certain role",
                description= "I'll give you a list with all the users with a certain role.", pass_context=True)
async def inrole(ctx, *role):
    server = ctx.message.guild
    role_name = (' '.join(role))
    role_id = server.roles[0]
    for role in server.roles:
        if role_name.lower() == role.name.lower():
            role_id = role
            break
    else:
        await ctx.send(f"Oh noes! That role doesn't exist!")
        return
    n = 0
    members = []
    for member in server.members:
        if role_id in member.roles:
            n += 1
            name = str(n) + ". " + member.name + " #" + member.discriminator + "\n"
            members.append(name)
    composite_members = [members[x:x + 20] for x in range(0, len(members), 20)]
    pages = []
    for elements in composite_members:
        string = ""
        for element in elements:
            string = string + element
        embedVar = discord.Embed(title=f"List of users with {role} - {n}", colour=discord.Colour.blue())
        embedVar.add_field(name = "Members", value = string)
        pages.append(embedVar)

    page = 0
    left = "⏪"
    right = "⏩"
    while True:
        msg = await ctx.send(embed = pages[(page)])
        l = page != 0
        r = page != len(pages) - 1
        if l:
            await msg.add_reaction(left)

        if r:
            await msg.add_reaction(right)
        # bot.wait_for_reaction
        react = await client.wait_for('reaction_add', check=predicate(msg, l, r))
        
        if react[0] == left:
            page -= 1
        elif react[0] == right:
            page += 1

        await msg.delete()

In the last if/elif statement, it doesn't work. There isn't an error, but although react[0] is the same emoji as right or left (respectively), page never changes, and thus the embed doesn't change either. I changed the elif for an else, and it that case it does work, but it can only go forward.

Upvotes: 0

Views: 2680

Answers (2)

Kali
Kali

Reputation: 65

Figured it out. Issue was that react[0] wasn't the same type as left and right. Here's the solution for that issue, if anyone is interested:

    if str(react[0]) == left:
        page -= 1
    elif str(react[0]) == right:
        page += 1

The rest of the code is exactly the same as the one I posted in the edit.

Upvotes: 1

Manoj A
Manoj A

Reputation: 432

message_ = None
@client.command()
async def edit(ctx):
    global message_
    message_ = await ctx.send('EMBED PAGE[1]')
   
@client.event
async def on_reaction_add(reaction, user):
    global message_
    msg_ID = 487165969903517696
    if int(reaction.message.id) != ChID:
        return;
    elif user.reaction.emoji == "🏃":
        message_.edit(content='EMBED PAGE [2]')
    

this is just an idea! I'm not sure this code works but there is an option to edit our embed message! so use that to make your embed message better [documentation for edit]

Upvotes: 0

Related Questions