interactions.py Documentation

repository·stable·Indexed 19 days ago

https://github.com/interactions-py/interactions.py

A feature-rich, highly extensible Discord bot framework for Python providing 100% coverage of the Discord API. Version 5.16.0 offers a modern interface with automated command synchronization, support for slash commands, and a comprehensive set of Discord models for entities like Users, Guilds, and Channels. The library includes built-in extensions for prefixed commands, debug tools, hot reloading via Jurigged, Sentry integration, and paginators.

Tokens
36.5K
Snippets
123
Records
143
Agent score
75%

What's inside interactions.py

  1. Explore Discord Models in interactions.py

    stable

    The interactions.py framework provides a comprehensive set of models that map to Discord's data structures. These models allow you to interact with Discord objects like Users, Guilds, Channels, Messages, and Embeds in a type-safe and structured manner.

    Key categories of models include:

    • Core Entities: User, Guild, Channel, Message, Role, Emoji.
    • Interaction Components: Components, Modals, Poll, Reaction.
    • Metadata & Utilities: Snowflake, Timestamp, Enums, Color, Asset.
    • Specialized Objects: Thread, Voice state, Scheduled event, Stage instance, Webhooks.
  2. Manage Component Layout with ActionRows

    stable

    Discord requires components to be contained within ActionRow objects. A message can have up to 5 action rows, and each row can contain up to 5 buttons or a single select menu.

    To control the layout specifically, you have three options:

    1. Automatic: Pass components directly; the library wraps them in ActionRows for you.
    2. Manual: Define ActionRow() objects explicitly and pass a list of them to components.
    3. spread_to_rows(): Use this function to automatically organize a list of components into the appropriate number of ActionRows.

    Note: The components are organized in a 5x5 grid.

    from interactions import ActionRow, Button, ButtonStyle, spread_to_rows
    
    # Manual layout using ActionRow
    components: list[ActionRow] = [
        ActionRow(
            Button(style=ButtonStyle.GREEN, label="Click Me"),
            Button(style=ButtonStyle.GREEN, label="Click Me Too")
        )
    ]
    await channel.send("Look, Buttons!", components=components)
    
    # Automatic layout using spread_to_rows
    components: list[ActionRow] = spread_to_rows(
        Button(style=ButtonStyle.GREEN, label="Click Me"),
        Button(style=ButtonStyle.GREEN, label="Click Me Too")
    )
    await channel.send("Look, Buttons!", components=components)
  3. Mapping discord.py classes to interactions.py

    stable

    When porting your code, note the following mapping of core classes and models:

    discord.pyinteractions.py
    Bot / Clientinteractions.Client
    CogExtension

    Important Note on Members: In interactions.py, Member is not a subclass of User. If your logic relies on isinstance(obj, User), you must explicitly check for both types: isinstance(obj, (User, Member)).

  4. How Context Menus work in interactions.py

    stable

    Context menus are a type of interaction that appear when a user right-clicks an object (like a message or a user) and selects Apps.

    Under the hood, they function similarly to slash commands. They rely on ctx.target to access the specific object the user interacted with. You can also define scopes and permissions for context menus just as you would for standard interactions.

    # Concept: ctx.target identifies the object interacted with
    @message_context_menu(name="example")
    async def example(ctx: ContextMenuContext):
        target = ctx.target
        # ...
  5. Importing interactions.py

    stable

    The library supports two primary import patterns. While the documentation often uses the from interactions import X style, you can also use import interactions and access objects via the interactions namespace.

    Note on Namespaces: When using import interactions, certain categories of objects are located in sub-namespaces. For example, events are accessed via interactions.events.X rather than directly under the root namespace.

    # Recommended pattern for cleaner code
    from interactions import Client, SlashCommand
    
    # Alternative pattern
    import interactions
    # Accessing events via sub-namespace
    # interactions.events.on_ready()
  6. What are Tasks and how do they work?

    stable

    Tasks are background processes used to asynchronously run code based on a specified trigger. Internally, they create an asyncio.Task that runs a loop to check if the task's trigger conditions are met. You can define tasks using decorators for simplicity or register them manually for more control.

    from interactions import Task, IntervalTrigger
    
    @Task.create(IntervalTrigger(minutes=10))
    async def print_every_ten():
        print("It's been 10 minutes!")
  7. Organize code using Extensions

    stable

    Extensions allow you to split your commands and listeners into separate files to better organize your project. This prevents your main file from becoming too large and provides the benefit of being able to reload specific parts of your bot without shutting it down.

    To use extensions, you must:

    1. Create a class that inherits from Extension.
    2. Define your commands and listeners within that class.
    3. Use bot.load_extension("module_name") in your main file to load the extension (using the module name without the .py extension).

    Note: When defining commands inside an Extension class, you must include self as the first argument in your command functions (e.g., async def my_command(self, ctx):).

    # File: `test_components.py`
    from interactions import ActionRow, Button, ButtonStyle, Extension, slash_command
    
    class ButtonExampleSkin(Extension):
        @slash_command()
        async def multiple_buttons(self, ctx):
            await ctx.send(
                "2 buttons in a row",
                components=[
                    Button(style=ButtonStyle.BLURPLE, label="A blurple button"),
                    Button(style=ButtonStyle.RED, label="A red button"),
                ],
            )
  8. How to define Subcommands and Groups

    stable

    Subcommands allow you to group related commands under a single base command. This results in a structure like /base group command in Discord.

    Note: Using subcommands or groups makes the base command itself unusable as a standalone command.

    There are three ways to define them:

    1. Decorator Pattern: Define the base command, then use @base_function.subcommand(...) for additional commands.
    2. Repeat Definition: Define each subcommand as its own @slash_command with group_name and sub_cmd_name parameters. This is useful for splitting commands across multiple files.
    3. Class Definition: Use the SlashCommand and .group() objects explicitly.
    # Method 1: Decorator Pattern
    @slash_command(
        name="base",
        description="My command base",
        group_name="group",
        group_description="My command group",
        sub_cmd_name="command",
        sub_cmd_description="My command",
    )
    async def my_command_function(ctx: SlashContext):
        await ctx.send("Hello World")
    
    @my_command_function.subcommand(
        group_name="group",
        group_description="My command group",
        sub_cmd_name="second_command",
        sub_cmd_description="My second command",
    )
    async def my_second_command_function(ctx: SlashContext):
        await ctx.send("Hello World")
    
    # Method 2: Repeat Definition (Good for multiple files)
    @slash_command(
        name="base",
        description="My command base",
        group_name="group",
        group_description="My command group",
        sub_cmd_name="second_command",
        sub_cmd_description="My second command",
    ) 
    async def my_second_command_function(ctx: SlashContext):
        await ctx.send("Hello World")
    
    # Method 3: Class Definition
    from interactions import SlashCommand
    
    base = SlashCommand(name="base", description="My command base")
    group = base.group(name="group", description="My command group")
    
    @group.subcommand(sub_cmd_name="second_command", sub_cmd_description="My second command")
    async def my_second_command_function(ctx: SlashContext):
        await ctx.send("Hello World")