Skip to content

A library for creating stateless dynamic discord menus. Supports complex paginated or tabbed navigation with discord reactions.

License

Notifications You must be signed in to change notification settings

TsubakiBotPad/discord-menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

68 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

python_version

Installation

Install latest via pip:

pip install discord-menu

What is discord-menu?

discord-menu is a flexible python framework for creating interactive menus out of Discord Embeds. Users can click specified emojis and the embed responds according to preset instructions.

Its primary features are:

  1. Declaritive UI Syntax - React/SwiftUI like definition of Views.
  2. Stateless compute - Menus do not require maintaining a session and no data needs to be stored on the bot's server.
  3. Event driven - No polling needed and interactions respond immediately to input.
  4. Scalable state - Message state is managed directly in the Embed, leveraging Discord's storage scalability.
  5. Flexibility - Arbitrary code can be executed on emoji clicks, allowing for complex features like pagination, child menus, or user authorizaton!

How to use

Example code demonstrated with Red-DiscordBot. Raw discord.py should also work with slight modification of imports.

Supported convenience menus

  1. SimpleTextMenu - Use this if you just want to display some text.
  2. SimpleTabbedTextMenu - This is useful if you a few different panes of text content that a user would select between.
  3. ClosableMenu - Write a custom view (more than just text) with a close button.
  4. TabbedMenu - Write custom views, and tab between them using dedicated emojis. Closable by default.
  5. ScrollableMenu - Write custom views, and scroll between them using left and right arrows. Closable by default.

SimpleTextMenu

import discord
from redbot.core import commands

from discordmenu.menu.listener.menu_listener import MenuListener
from discordmenu.menu.listener.menu_map import MenuMap, MenuMapEntry
from discordmenu.menu.simple_text_menu import SimpleTextMenu, SimpleTextViewState

menu_map = MenuMap()
menu_map[SimpleTextMenu.MENU_TYPE] = MenuMapEntry(SimpleTextMenu, EmbedTransitions)

class TestCog(commands.Cog):
    def __init__(self, bot):
        self.listener = MenuListener(bot, menu_map)

    @commands.Cog.listener('on_raw_reaction_add')
    @commands.Cog.listener('on_raw_reaction_remove')
    async def on_raw_reaction_update(self, payload: discord.RawReactionActionEvent):
        await self.listener.on_raw_reaction_update(payload)

    async def simplemenu(self, ctx):
        await SimpleTextMenu.menu().create(ctx, SimpleTextViewState("Hello World!"))

simpletext

Code

SimpleTabbedTextMenu

import discord
from redbot.core import commands

from discordmenu.menu.listener.menu_listener import MenuListener
from discordmenu.menu.listener.menu_map import MenuMap, MenuMapEntry
from discordmenu.menu.simple_tabbed_text_menu import SimpleTabbedTextMenu, SimpleTabbedTextMenuTransitions,
    SimpleTabbedTextViewState

menu_map = MenuMap()
menu_map[SimpleTabbedTextMenu.MENU_TYPE] = MenuMapEntry(SimpleTabbedTextMenu, SimpleTabbedTextMenuTransitions)


class TestCog(commands.Cog):
    def __init__(self, bot):
        self.listener = MenuListener(bot, menu_map)

    @commands.Cog.listener('on_raw_reaction_add')
    @commands.Cog.listener('on_raw_reaction_remove')
    async def on_raw_reaction_update(self, payload: discord.RawReactionActionEvent):
        await self.listener.on_raw_reaction_update(payload)

    async def simpletabbedtextmenu(self, ctx):
        vs = SimpleTabbedTextViewState("Initial message.", ["Message 1", "Message 2", "Message 3"])
        await SimpleTabbedTextMenu.menu().create(ctx, vs)

simpletabbedtext

Code

Sample code for other menus

For example code for ClosableMenu, TabbedMenu, or ScrollableMenu, refer to the test file.

Advanced usage

If you're looking for ideas on what you can do with this framework, or for info on how to create complex menus, refer to documentation on advanced usage.

This menu system is originally built for looking up data from the popular puzzle gacha game Puzzle & Dragons - feel free to join the discord server for a demo on the complex system that powers data accessbility within the community.

Running tests + sample code

Prerequisite: Create a Discord bot

If you don't have one already, follow the instructions to create a bot in Red's official documentation:

Creating a bot account

Keep the bot token that you get from Discord at the end of the instructions handy - you will need it to set up the bot later.

Installation

  1. Create a python 3 venv in the test folder. virtualenv -p python3 <envname>
  2. Activate the venv.
  3. pip install -r requirements.txt

The above steps install Red-Discord bot framework. You can now follow more detailed instructions to startup the bot. Or run these in command line and follow the prompts:

  • redbot-setup
  • redbot <bot_name>

Interact with the bot

The rest of the guide takes place from inside Discord. Replace ^ with your prefix to talk to your bot.

  1. Once the bot is launched, set it to the test directory as a cog path.
^addpath /Users/me/src/discord-menu/test
  1. Load testcog
^reload testcog
  1. Run a test command. Test code for simplemenu.
^t

simpletext

Contributing

If you encounter a bug or would like to make a feature request, please file a Github issue or submit a pull request.

Also, if you don't understand something in the documentation, you are experiencing problems, or you just need a gentle nudge in the right direction, please don't hesitate to join the discord server.