Skip to main content

Unofficial discord-interactions multi page embed handler

Project description

dinteractions-Paginator

Unofficial discord-interactions multi-page embed handler

Discord PyPI - Downloads

Table of Contents

(Only works in the GitHub for some reason)

Features

  • Message per embed or persistent message
  • Index select that can be turned on/off
  • Select labels are generated based on embed's title
  • Index button that can be turned on/off
  • Ability to set the buttons to any emote, color or label
  • Custom buttons

Join our Discord server!

  • Try out example commands,
  • Ask some questions,
  • And give us feedback and suggestions!

Wanna contribute?

  • Make an issue to:
    • say what feature you want to be added
    • file a bug report
  • Make a pull request and:
    • describe what you added/removed
    • why you added/removed it
  • Make sure you use the issue/PR template!

Installation

pip install -U dinteractions-Paginator

Dependencies

Examples:

These simple examples show how to easily create interactive, multiple page embeds that anyone can interact with that automatically deactivate after 60 seconds of inactivity:

Example GIF:

Paginator with select:

Slash command:

import discord
from discord.ext import commands
from discord_slash import SlashCommand, SlashContext
from dinteractions_Paginator import Paginator

bot = commands.Bot(command_prefix="/")
slash = SlashCommand(bot, sync_commands=True)


@bot.event
async def on_ready():
    print(f"Logged in as {bot.user}!")


@slash.slash(name="embeds")
async def embeds(ctx: SlashContext):
    one = discord.Embed(title="1st Embed", description="General Kenobi!", color=discord.Color.red())
    two = discord.Embed(title="2nd Embed", description="General Kenobi!", color=discord.Color.orange())
    three = discord.Embed(title="3rd Embed", description="General Kenobi!", color=discord.Color.gold())
    four = discord.Embed(title="4th Embed", description="General Kenobi!", color=discord.Color.green())
    five = discord.Embed(title="5th Embed", description="General Kenobi!", color=discord.Color.blue())
    pages = [one, two, three, four, five]

    await Paginator(bot=bot, ctx=ctx, pages=pages, content=["1", "2", "3", "4", "5"], timeout=60).run()


bot.run("token")

Normal command:

import discord
from discord.ext import commands
from discord_slash import SlashCommand
from dinteractions_Paginator import Paginator

bot = commands.Bot(command_prefix="/")
slash = SlashCommand(bot)


@bot.event
async def on_ready():
    print(f"Logged in as {bot.user}!")


@bot.command()
async def embeds(ctx):
    one = discord.Embed(title="1st Embed", description="General Kenobi!", color=discord.Color.red())
    two = discord.Embed(title="2nd Embed", description="General Kenobi!", color=discord.Color.orange())
    three = discord.Embed(title="3rd Embed", description="General Kenobi!", color=discord.Color.gold())
    four = discord.Embed(title="4th Embed", description="General Kenobi!", color=discord.Color.green())
    five = discord.Embed(title="5th Embed", description="General Kenobi!", color=discord.Color.blue())
    pages = [one, two, three, four, five]

    await Paginator(bot=bot, ctx=ctx, pages=pages, content=["1", "2", "3", "4", "5"], timeout=60).run()


bot.run("token")

NOTE: slash = SlashCommand(bot) required to override bot

class Paginator

Arguments

Required:

  • bot - commands.Bot: The bot variable, commands.Bot is required
  • ctx
    • Union[SlashContext, commands.Context, ComponentContext, MenuContext, discord.channel.TextChannel, discord.User, discord.Member]: The context of a command.
      NOTE: if one of the latter 3 are used, there will always be a This interaction failed even though it was a success, due to no context to respond to

Optional:

  • pages - Optional[List[discord.Embed]]: the list of embeds to be paginated, defaults to None and paginates content instead
    NOTE: content must be a list for paginating without pages!
  • content - Optional[Union[str, List[str]]]: the content of the message to send, defaults to None
  • editOnMessage - Optional[discord.Message]: paginate in the specified message, defaults to False
  • files - Optional[Union[discord.File, List[discord.File]]]: files to send, defaults to None
  • hidden - Optional[bool]: if you want the paginator to be hidden, default False
  • authorOnly - Optional[bool]: if you want the paginator to work for the author only, default is False
  • onlyFor - Optional[Union[discord.User, discord.Role, List[Union[discord.User, discord.Role]]]]: components only for specified user(s) or role(s)
  • dm - Optional[bool]: if you want the paginator to be DM'ed, default False

Custom:

  • customButton - Optional[List[Union[dict, Awaitable]]]: a list of a create_button(...) and an awaitable function, default None
  • customActionRow - Optional[List[Union[dict, Awaitable]]]: a list of an action row and an awaitable function, default None

See how to use these args here!

Time:

  • timeout - Optional[int]: deactivates paginator after inactivity if enabled, defaults to None (meaning no timeout)
  • disableAfterTimeout - Optional[bool]: disable components after timeout, default True
  • deleteAfterTimeout - Optional[bool]: delete components after timeout, default False
  • timeoutEmbed - Optional[discord.Embed]: edit to embed after timeout, defaults to False

What to use:

  • useEmoji - Optional[bool]: uses the emoji, default is True
  • useButtons - Optional[bool]: uses buttons, default is True
  • useSelect - Optional[bool]: uses a select, default is True
  • useIndexButton - Optional[bool]: uses the index button, default is False and stays False if useButtons is also False
  • useLinkButton - Optional[bool]: uses the link button
  • useQuitButton - Optional[bool]: quit button to end the paginator, default False
  • useFirstLast - Optional[bool]: uses the first and last buttons, default True
  • useOverflow - Optional[bool]: uses the overflow action row if there are too many buttons, default True
  • useNotYours - Optional[bool]: sends an ephemeral (hidden) message if the paginator is not yours (see authorOnly or onlyFor), default True
  • notYoursMessage - Optional[str]: the message to send if the paginator is not yours (see authorOnly or onlyFor), default "this paginator is not for you!"

Labels:

  • firstLabel - Optional[str]: The label of the button used to go to the first page, defaults to ""
  • prevLabel - Optional[str]: The label of the button used to go to the previous page, defaults to ""
  • indexLabel - Optional[str]: The label of the index button, defaults to "Page"
  • nextLabel - Optional[str]: The label of the button used to go to the next page, defaults to ""
  • lastLabel - Optional[str]: The label of the button used to go to the last page, defaults to ""
  • linkLabel - Optional[Union[str, List[str]]]: The label for the link button
  • linkURL - Optional[Union[str, List[str]]]: The URL(s) for the link button
  • quitButtonLabel - Optional[str]: The label of the quit button, default "Quit"

Emojis:

  • firstEmoji - Optional[Union[discord.emoji.Emoji, discord.partial_emoji.PartialEmoji, dict, str]: emoji of the button used to go to the first page, defaults to "⏮️"
  • prevEmoji - Optional[Union[discord.emoji.Emoji, discord.partial_emoji.PartialEmoji, dict, str]: emoji of the button used to go to the previous page, defaults to "◀"
  • nextEmoji - Optional[Union[discord.emoji.Emoji, discord.partial_emoji.PartialEmoji, dict, str]: emoji of the button used to go to the next page, defaults to "▶"
  • lastEmoji - Optional[Union[discord.emoji.Emoji, discord.partial_emoji.PartialEmoji, dict, str]: emoji of the button used to go to the last page, defaults to "⏭️"
  • quitButtonEmoji - Optional[Union[discord.emoji.Emoji, discord.partial_emoji.PartialEmoji, dict, str]: emoji of the quit button, defaults to None

Styles (the colo[u]r of the buttons):

  • firstStyle - Optional[Union[ButtonStyle, int]]: the style of button (ButtonStyle or int) for the first button, defaults to 1 (ButtonStyle.blue)
  • prevStyle - Optional[Union[ButtonStyle, int]]: the style of button (ButtonStyle or int) for the previous button, defaults to 1 (ButtonStyle.blue)
  • indexStyle - Optional[Union[ButtonStyle, int]]: the style of button (ButtonStyle or int) for the index button, defaults to 3 (ButtonStyle.green)
  • nextStyle - Optional[Union[ButtonStyle, int]]: the style of button (ButtonStyle or int) for the next button, defaults to 1 (ButtonStyle.blue)
  • lastStyle - Optional[Union[ButtonStyle, int]]: the style of button (ButtonStyle or int) for the last button, defaults to 1 (ButtonStyle.blue)
  • quitButtonStyle - Optional[Union[ButtonStyle, int]]: the style of button (ButtonStyle or int) for the quit button, defaults to 4 (ButtonStyle.red)

Returns

class TimedOut

More info on customButton and customActionRow:

You can define your own custom button, with its own code!

Example code:
@slash.slash(name="custom-action-row")
async def _custom_action_row(ctx: SlashContext):
    # Embeds:
    pages = [
        discord.Embed(title="1"),
        discord.Embed(title="2"),
        discord.Embed(title="3"),
        discord.Embed(title="4"),
        discord.Embed(title="5"),
    ]

    # Custom button:
    custom_button = create_button(style=3, label="A Green Button")

    # Function:
    async def custom_function(self, button_ctx):  # Required arguments
        await button_ctx.send("test", hidden=True)
        await self.ctx.send("lol")

    # Paginator:
    await Paginator(
        bot,
        ctx,
        pages,
        timeout=60,
        customButton=[
            custom_button,
            custom_function,
        ],  # Note that custom_function is not called
    ).run()

The code above runs a normal paginator, with 1 extra action row at the bottom!

You can define your own custom action row, with its own code!

Example code:
@slash.slash(name="custom-action-row")
async def _custom_action_row(ctx: SlashContext):
    # Embeds:
    pages = [
        discord.Embed(title="1"),
        discord.Embed(title="2"),
        discord.Embed(title="3"),
        discord.Embed(title="4"),
        discord.Embed(title="5"),
    ]

    # Action row:
    buttons = [
        create_button(style=3, label="A Green Button"),
    ]
    custom_action_row = create_actionrow(*buttons)

    # Function:
    async def custom_function(self, button_ctx):  # Required arguments
        await button_ctx.send("test", hidden=True)
        await self.ctx.send("lol")

    # Paginator:
    await Paginator(
        bot,
        ctx,
        pages,
        timeout=60,
        customActionRow=[
            custom_action_row,
            custom_function,
        ],  # Note that custom_function is not called
    ).run()

The code above runs a normal paginator, with 1 extra action row at the bottom!

FYI: You can also use customButton and customActionRow together! Also, you can do self.stop = True in the custom function to stop the paginator.

You can use the paginator method self.goToPage(page) to go to the specific page number in the message. The parameter page is the page number, starting from 1.

Example GIF:

You can access all the attributes of class Paginator with self, such as the original command's context (self.ctx), the bot variable (self.bot), and other things that you passed into it!


class TimedOut

Attributes

  • ctx - Union[commands.Context, SlashContext]: The original context
  • buttonContext - ComponentContext: The context for the paginator's components
  • timeTaken - int: How long in seconds that user(s) used the paginator before the timeout
  • lastContent - str: The last content that the paginator stopped at after timeout
  • lastEmbed - discord.Embed: The last embed that the paginator stopped at after timeout
  • successfulUsers - List[discord.User]: Users that successfully used the paginator, the first user is the invoker
  • failedUsers - List[discord.User]: Users that failed to use the paginator

Credits

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dinteractions_Paginator-2.0.0a4.tar.gz (26.5 kB view details)

Uploaded Source

Built Distribution

dinteractions_Paginator-2.0.0a4-py3-none-any.whl (23.3 kB view details)

Uploaded Python 3

File details

Details for the file dinteractions_Paginator-2.0.0a4.tar.gz.

File metadata

  • Download URL: dinteractions_Paginator-2.0.0a4.tar.gz
  • Upload date:
  • Size: 26.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.9

File hashes

Hashes for dinteractions_Paginator-2.0.0a4.tar.gz
Algorithm Hash digest
SHA256 bb4799e10d45b98e084eb37ab1f615f15f126fcce7643a15d7685ae9fe2d9acf
MD5 53891887c239c1485d0aa8fc7ee88dce
BLAKE2b-256 4143acf379419070a7b443c179af5ca5645a2380b31e8c2b16bf68f82358485f

See more details on using hashes here.

File details

Details for the file dinteractions_Paginator-2.0.0a4-py3-none-any.whl.

File metadata

  • Download URL: dinteractions_Paginator-2.0.0a4-py3-none-any.whl
  • Upload date:
  • Size: 23.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.9

File hashes

Hashes for dinteractions_Paginator-2.0.0a4-py3-none-any.whl
Algorithm Hash digest
SHA256 0f8ee51ade5415a03757c5a403b4087ec5e3da694e81afbc42e97453ebca992f
MD5 91e14b5825b39a08bfded39934eaa0dc
BLAKE2b-256 dfb8aa7d068a6ed4ddd5933d8193f30f5c37c1915d470b6705fef61251a07007

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page