Package: better-interactions
better-interactionsBetter interactions for discord-py-interactionsJoin theDiscord serverto ask questions, get help, or to discuss the project!Installation:pip install -U better-interactionsWhat is this library?This isbetter-interactions, a library fordiscord-py-interactionswhich modifies component callbacks, and adds useful helper functions.What does this have?Listed below are all the features this library currently has:Subcommands that you can create easilyComponent callbacks are modified so you can enable checking if thecustom_idof the component starts with the one provided in the decoratorActionRowfunction which enables usage ofActionRow(...)Component functions forButtonandSelectMenuthat has checks so you never have to incorrectly useButton(...)orSelectMenu(...)spread_to_rowsfunction which allows components to be spread to multipleActionRowsSubcommandsSubcommands are technically options for commands, meaning to make subcommands, you may need long chains of options and if/elif/else conditionals.This library provides a way to make subcommands, similar to subcommands indiscord-py-interactions<=3.0.2.How to use:Here's some examples of subcommand usage:frominteractions.ext.better_interactionsimportbase...# sets up bot.base, optionalbot.load("interactions.ext.better_interactions")...# create a base command:the_base=bot.base("the_base",scope=874781880489222154)# Or without loading:the_base=base(bot,"the_base",scope=874781880489222154)# create a subcommand with an optional group and required name:@the_base.subcommand(group="the_group",name="the_name",description="A simple subcommand",)asyncdefthe_group(ctx:interactions.CommandContext,):awaitctx.send("1")# another subcommand in the same group:@the_base.subcommand(group="the_group",name="the_name2",description="A simple subcommand",)asyncdefthe_group2(ctx:interactions.CommandContext,):awaitctx.send("2")# another subcommand in the same group with some options:@the_base.subcommand(group="the_group",name="the_name3",description="A simple subcommand",options=[interactions.Option(type=interactions.OptionType.STRING,name="the_string",description="A string",required=True,),],)asyncdefthe_group3(ctx:interactions.CommandContext,the_string,):awaitctx.send(f"3{the_string}")# a subcommand in a different group:@the_base.subcommand(group="the_group2",name="the_name4",description="A simple subcommand4",)asyncdefthe_group24(ctx:interactions.CommandContext,):awaitctx.send("4")# a subcommand with no group:@the_base.subcommand(name="the_name5",description="A simple subcommand5",)asyncdefthe_name5(ctx:interactions.CommandContext,):awaitctx.send("5")# finishes the command:the_base.finish()This approach that I took is similar to the one indiscord-py-interactions<=3.0.2, and the least complicated way to do it.How to use inside of extensions:main.py:importinteractionsbot=interactions.Bot(...)bot.load("interactions.ext.better_interactions")# optional...# load cog before bot.start()bot.load("cog")bot.start()cog.py:frominteractions.ext.better_interactionsimport(extension_base,BetterExtension,)classCog(BetterExtension):def__init__(self,bot):self.bot=botthe_base=extension_base("the_base",scope=874781880489222154)@the_base.subcommand(name="name1",description="subcommand")asyncdefb(self,ctx):awaitctx.send("You used /the_base name1")@the_base.subcommand(group="group1",name="name2",description="group subcommand")asyncdefc(self,ctx):awaitctx.send("You used /the_base group1 name2")the_base.finish()defsetup(bot):returnCog(bot)New component callbackThe new component callbacks are modified so you can enable checking if thecustom_idof the component starts with the one provided in the decorator.How to use:In your bot, you must use this line:bot=interactions.Client(...)bot.load("interactions.ext.better_interactions")Then, you can use the decorator!If you want to useinteractions-wait-forwith this extension, you must add its respective keyword arguments into the setup function as well.Below is an example of a component callback.@bot.component("test",startswith=True)asyncdefstartswith_custom_id(ctx):awaitctx.send(ctx.data.custom_id)Thestartswith=Truekeyword argument is optional, and if it is not provided, it will default toFalseand will be used like the normal component callbacks.If you want to check if thecustom_idof the component starts with the one provided in the decorator, you can use thestartswith=Truekeyword argument.By settingstartswith=True, the component callback now fires when thecustom_idof the component starts with the one provided in the decorator.For example, if you have a component with acustom_idof"test", and you setstartswith=True, the component callback will fire when thecustom_idof the component starts with"test".Let's say a button withcustom_idof"test1"is clicked. Since it starts with"test", the component callback will fire.However, if something like"tes"is clicked, the component callback will not fire.To sum it up, the component callback will fire when thecustom_idof the component starts with the one provided in the decorator.Why should I use this?This is useful if you want to check if thecustom_idof the component starts with the one provided in the decorator. Indiscord-py-interactions, the component callbacks are only fired when they are the exact samecustom_idas the one provided in the decorator. This is not that useful, since you waste a lot of data you could have stored in the component custom IDs. The callbacks provided frominteractions-better-componentsfix the aforementioned issue.ActionRow functionTheActionRowfunction enables usage ofActionRow(...)instead ofActionRow(components=[...]).How to use:Below is an example ofActionRowusage:@bot.command(name="test",description="Test command",)asyncdeftest(ctx):awaitctx.send("test",components=[ActionRow(select1),ActionRow(button1,button2,button3),])Why should I use this?This is only for aesthetics, making the code look cleaner. UsingActionRow(...)is the same as usingActionRow(components=[...]), however, it is more readable.Button and SelectMenuTheButtonandSelectMenufunctions are made so you never have to incorrectly useButton(...)orSelectMenu(...).How to use:Below is an example ofButtonusage:frominteractions.ext.better_interactionsimportButton@bot.command(name="test",description="Test command",)asyncdeftest(ctx):awaitctx.send("test",components=[Button(style=1,custom_id="test1",label="Test 1",),])You can importButtonandSelectMenufrombetter_interactionsand use them like you would useButton(...)andSelectMenu(...)fromdiscord-py-interactions.spread_to_rows functionThespread_to_rowsfunction allows components to be spread to multipleActionRows with an optionalmax_in_rowargument.How to use:You use the function like this:spread_to_rows(*components, max_in_row=3).max_in_row=5by default.Separate components byNoneto explicitly start a new row.Below is an example ofspread_to_rowsusage that spreads components to 2ActionRows with 5 components each:@bot.command(name="test",description="Test command",)asyncdeftest(ctx):awaitctx.send("test",components=spread_to_rows(button1,button2,button3,button4,button5,button6,button7,button8,button9,button10,))CreditsCatalyst4 for helping me solve countless issuesThe devs ofdiscord-py-interactions