Package: discord-ui
discord-uiA discord.py extension for using discord ui/interaction featurespip package▪read the docs▪examplesIntroductionThis is adiscord.pyui extension made by404kusoandRedstoneZocktfor using discord's newest ui features like buttons, slash commands and context commands.DocumentationInstallationWindowspy -m pip install discord-uiLinuxpython3-mpipinstalldiscord-uiLicenseThis project is under MIT LicenseIssuesIf you find any issues, please report themhttps://github.com/discord-py-ui/discord-ui/issuesNoteIf you want to use slash commands, in the oauth2 invite link generation,
you have to check bothbotandapplication.commandsfieldsExampleExample for creating a simple slash commandimportdiscordfromdiscord.extimportcommandsfromdiscord_uiimportUI,SlashOptionclient=commands.Bot(" ")ui=UI(client)@ui.slash.command("hello_world",options=[SlashOption(bool,"cool","whether this libary is cool",required=False)],guild_ids=[785567635802816595])asyncdefcommand(ctx,cool=True):"""This is a simple slash command"""# you can use docstrings for the slash command description tooawaitctx.respond("You said this libary is "+str(cool))client.run("your_token")Example for creating a user-context commandimportdiscordfromdiscord.extimportcommandsfromdiscurd_uiimportUIclient=commands.Bot(" ")ui=UI(client)@ui.slash.user_command("avatar",guild_ids=[785567635802816595])asyncdefavatar(ctx,user:discord.Member):"""Sends the avatar of a user"""awaitctx.respond(embed=discord.Embed(description=user.display_name).set_image(url=user.avatar_url))client.run("your_token")Example for autocompletion of choicesimportdiscordfromdiscord_uiimportUI,SlashOption,AutocompleteInteractionasyncdefgenerator(ctx:AutocompleteInteraction):available_choices=["hmm","this","is","a","an","test","testing"]return[(x,x)forxinavailable_choicesifx.startswith(ctx.value_query)]@ui.slash.command("search_word",options=[SlashOption(str,"query",choice_generator=generator)])asyncdefsearch_word(ctx,query):awaitctx.send("got "+query+" for query")client.run("your_token")Example for sending a button and receiving itimportdiscordfromdiscord.extimportcommandsfromdiscord_uiimportUI,LinkButton,ButtonfromasyncioimportTimeoutErrorclient=commands.Bot(" ")ui=UI(client)@client.listen("on_message")asyncdefon_message(message:discord.Message):ifmessage.content=="!btn":msg=awaitmessage.channel.send("you",components=[[Button("press me",color="green"),LinkButton("https://discord.com",emoji="😁")],Button(custom_id="my_custom_id")])try:btn=awaitmsg.wait_for("button",client,by=message.author,timeout=20)awaitbtn.respond("you pressed `"+btn.content+"`")exceptTimeoutError:awaitmsg.delete()client.run("your_token_here")Example for sending Selectmenus and receiving themimportdiscordfromdiscord.extimportcommandsfromdiscord_uiimportUI,SelectMenu,SelectOptionfromasyncioimportTimeoutErrorclient=commands.Bot(" ")ui=UI(client)@client.listen("on_message")asyncdefon_message(message:discord.Message):ifmessage.content=="!sel":msg=awaitmessage.channel.send("you",components=[SelectMenu(options=[SelectOption("my_value",label="test",description="this is a test"),SelectOption("my_other_value",emoji="🤗",description="this is a test too")],"custom_id",max_values=2)])try:sel=awaitmsg.wait_for("select",client,by=message.author,timeout=20)awaitsel.respond("you selected `"+str([x.contentforxinsel.selected_options])+"`")exceptTimeoutError:awaitmsg.delete()client.run("your_token_here")Example for cogsfromdiscord.extimportcommandsfromdiscord_uiimportUIfromdiscord_ui.cogsimportslash_command,subslash_command,listening_componentbot=commands.Bot(" ")ui=UI(bot)classExample(commands.Cog):def__init__(self,bot):self.bot=bot@slash_command(name="example",guild_ids=[785567635802816595])asyncdefexample(self,ctx):awaitctx.respond("gotchu")@subslash_command(base_names="example",name="command"):asyncdefexample_command(self,ctx):awaitctx.respond("okayy")bot.add_cog(Example(bot))bot.run("your token")You can find more (and better) exampleshereContactYou can contact us on discordRedstonekusodiscord serverChangelogThis will be moved tohttps://discord-py-ui.github.io/discord-ui/5.1.2Fixedcommands.nukenextcord import issue (#112)5.1.0Breaking changesComponent custom ids are now optional, if no custom id is passed, a 100 characters long random string will be used and because of that the order of Component init params changedThe order of SelectMenus init params changed,custom_idcomes now afteroptionsSelectMenu("my_custom_id",[options...here])# is nowSelectMenu([options...here],"my_custom_id")Same for ButtonsButton("my_custom_id","label")# is nowButton("label","my_custom_id")ButtonStyles is now ButtonStylerenamed cog decorators, the old ones still work but they will show a deprecation warning:slash_command->slash_command,subslash_command->subslash_command,context_cog->context_command,listening_component->listening_componentRemovedSlash.edit_commandandSlash.edit_subcommand, "moved" toCommand.editSlashedCommandis nowSlashInteraction,SlashedSubCommandis nowSubSlashInteractionandSlashedContextis nowContextInteractionThe command attributes of CommandInteractions (SlashedCommand, ...) are now moved toInteraction.command.(the.commandattribute is a reference to the real command, if you change properties of the command they will be updated)The component attributes of an interaction are now moved to.componentContextCommands.paramattribute is now.targetChangedargument_typein SlashOption is nowtypeButtonStylevalue names changed: color names are now capitalized andDangeris nowDestructiveListener.target_useris nowListener.target_usersand can take users, members and ids as the valueBaseCommand.optionsandSlashOption.optionsis now of typeSlashOptionCollection, which allows you to acces options by index and namemy_command.options["option name"]# ormy_command.options[0]You can also use some methods like.get,.set(which will return itself after it set something, soSlashOption.set(key, value).set(key, value)would work) andSlashOption.options + SlashOption.optionwill add both SlashOptions togetherIf an invalid guild id was passed to a slashcommand, no exception will be raised anymore, it will just be printed into the console and ignoredlogging.error()Moved thediscord_ui.ext.pymodule into a folderon_button_pressandon_menu_selectis nowon_buttonandon_select. The old event names will still work but will be removed in the next releaseFixeddisable_action_rowActionRow.disableno interaction events being dispatched because subclasses of dpy2commands.Botinstances wouldn't get overriden which lead to not enabling needed debug eventswhen no matching component listener inListenercould be found, the events for components events wouldn't be dispatcheddelete_afterkeyword in message send override not workingmentionable type in slashoptions not being parsed to objects@discord.ext.commands.Cooldownnot working on cog slashcommandsAdded**fieldsto all functions that edit the message components (like.disable_components,.disable_component, ...). The**fieldsparameter can be used to edit other properties of the message without using.editagain and send a "useless" request@Lister.on_errorand@Listener.wrong_userdecorators for handling Exceptions in ListenersWhen no keyword was passed to@Listener.buttonor@Listener.select, the function will be called on every button/slectchannel_typeto SlashOption, list ofdiscord.ChannelType. This will restrict the shown channels for channel slash options to this list.support for nextcord. Other libsshouldwork too, but they are not tested.Mentionabletype for SlashOptionsdescription for short slashoptions. If you set the options for a slash command via callback params, you can add a description (and a type) to them with your docstring. There are 3 different styles you can use:# style 1@ui.slash.command()asyncdefmy_command(ctx,my_option,my_other_option):"""This is my command descriptionmy_option: `int`:This is the description for the my_option parametermy_other_option: `str`:This is the description for another option"""...# style 2@ui.slash.command()asyncdefmy_command(ctx,my_option:int,my_other_option:str):"""This is my command descriptionmy_option: This is the description for the my_option parametermy_other_option: This is the description for another option"""...# style 3@ui.slash.command()asyncdefmy_command(ctx,my_option,my_other_option:str):"""This is my command description`int`: This is the description for the my_option parameterThis is the description for another option"""...Note: You don't have to use`type`, you can just usetypeEmpty descriptions for slashcommands and slashoptions. The default description value is now\u200bwhich is an "empty" charModifying slashcommand options is now WWAAYYYY easier. You can just do.options[name or index].name = "new name"and the option will be updatedYou can set the autocomplete choice generator with a decorator nowui.slash.command(options=[SlashOption(str,"my_option")])asyncdefmy_command(ctx,my_option):...@my_command.options["my_option"].autocomplete_functionasyncdefmy_generator(ctx):...# or@my_command.options[0].autocomplete_functionasyncdefmy_generator(ctx):...All apllication command decorators will now return the created Command@ui.slash.command(...)asyncmy_command(ctx):...type(my_command)# SlashCommandAdded edit and delete method to slashcommand. You can use this for editing or deleting the command later# editawaitmy_command.edit(name="test")# deleteawaitmy_command.delete()idto SlashCommandcommands_syncedevent which will be dispatched when all commands where synced with the api (UI.Slash.sync_commands)BaseCommmand.updatemethod which updates the api command with the lcoal changesSlashSubCommand.base, which will be shared among all subslashcommands with the same baseRemoveddiscord.ext.commands.Botoverride for enabling the debug event, this will be enabled when creating a UI instance from the bot5.0.1FixedChoices not working5.0.0FixedRoles not being parsed correctlyChangeddefault_permissiondefault_permission can now be of typediscord.Permissionsbut the api doesn't support that yet.slash httpsome code changes to slash-http featuresAddedChoiceGeneratorContextContext class for choice generationSlashOptionchoice_generatorkeyword andautocompletekeyword.autocompleteis not needed if you pass choice_generatorFile sendingYou are now able to send hidden files4.3.8FixedIssue with SlashOptionsrequired is now false by default again4.3.7ChangedSlashOptionRequired is nowTrueby defaultFixedAttributeError: 'LinkButton' object has no attribute 'component_type'RemoveddecompressingThe lib now doesn't decompress byte data anymore, which means everything before the dpy commit848d752doesn't work with this lib.message referencein discordpy discord server4.3.6FixedSlashcommand comparingEphemeralmessage keyerror exception4.3.5Fixedsend function issues4.3.4FixedSlashOption not accepting tuple4.3.3FixedfixedTypeError: 'NoneType' object is not iterable4.3.2FixedCould not find a matching option type for parameter '<class 'NoneType'>'4.3.1Removedunused parameter4.3.0FixedMessage.wait_forby keyword doesn't work properlyRemovedHashRemoved the hash property from Buttons and SelectMenus due to the removal of it from the apiAddeddiscord_ui.extA module with useful tools and decorators to usemore informationBaseCommandBaseCommand (the superclass for all applicationcommands) has now some extra properties:- is_chat_input
> Whether this command is a slash command

- is_message_context
> Whether this command is a message context command

- is_user_context
> Whether this command is a user context commandSlashedCommandAdded properties:- is_alias
> Whether the invoked command is an alias or not

- aliases
> All the available aliases for the commandListenersListeners are something that you can use for a better processing of received components.
You could see them as a cog to the message componentsmore informationChangedSelectInteractionSelectInteraction.selected_valuesare not the raw values that were selected,SelectMenu.selected_optionsare the options of typeSlashOptionthat were selectedMISSING => NoneAll instance values that wereMISSINGby default are nowNone4.2.15Fixed#974.2.14Fixedsmall SelectOption issuescontext commandsChangedallow context commands to have names with spaces4.2.13FixedTypeError: 'EMPTY' is not a callable objectin context commands4.2.12Fixedcontext commands4.2.11Fixedcog context commands returned wrong type4.2.10Fixedcog context commands typo withguild_permissionkeyword4.2.8Addededit_subcomandFixedprint statementsFixed#94 (again 💀)received subcommandsThe base_names and the name will be now set to the right value4.2.7Addedon_componentThere is now an event with the namecomponentthat will be dispatched whenever a component was received
If you useMessage.wait_for, there is now a new event choice with the namecomponent(message.wait_for("component", client))Fixed#94DM issue with deleting messagesChangededitEdit now takes "content" as not positional (.edit("the content")works now)component lenghtYou are now able to set component values with the right max lenght4.2.6Fixedemebdsthere was an issue with sending embeds4.2.5Fixedlistening_componentsThere was an issue with listening components that they needed two parameters but only one was passed
Another issue wasTypeError: __init__() missing 1 required positional argument: 'custom_id'?emebdsthere was an issue with sending embeds4.2.2Changedsync_commandsthedelete_unusedkeyword is now optional, if you don't pass a parameter,slash.delete_unusedwill be used (from the__init__function)4.2.1Fixedcannot import name 'InteractionResponseType' from 'discord.enums'4.2.0Addedcog_remove syncwhen you remove a cog the slash commands will now get deleted if you setdelete_unusedto True and setsync_on_cogto Truealternativ slash optionsyou don't have to specify options in one of the slash decorators anymore. Instead, you can set them in your callback function
Example@ui.slash.command()asyncdefgreet(ctx,user):# This will add an required option with the name "user" of type "user""""Greets a userYou can use multiline docstrings, because only the first line will be used for the description"""...@ui.slash.command()asyncdeftag(ctx,target:discord.User=None):# This will add an optional option with the name "target" of type "user"# Note: you could also use target: "user" = None or anything else you would use in SlashOption for the type...Fixedsync_commandsif you would sync the commands after the first sync, it threw an error4.1.4Fixedslashcommands in forbidden guildswhen trying to get slash commands in a guild with noappication.commandspermission, it won't throw an exepction anymore4.1.2FixedSubcommands editingsubcommand checks were wrong and this would result in errors likeIn options.0.options.2: Option name 'name' is already used in these options4.1.1FixedInteraction.author.voiceFor some reason the voice property of the creator or the interaction would be setGlobal slashcommandsThey wouldn't be registered to the api4.1.0Addedpy 3.6 < supportYou should be able to use this package with python 3.6 or newerFixedprintForgot to remove print statements💀4.0.4Fixedslashcommandwhen a user was passed in an option, its guild was always Nonecontext commandsif no name passed, the context command wouldn't take the callback name as the name of the command4.0.3FixedMessage.wait_for4.0.2FixedIssue with receiving context commands4.0.1Fixeddiscord.ext import error4.0.0AddedYou now have much more control over your slash commands!PermissionsYou can update your permissions with theSlash.update_permissionsfunctionCreating commandsYou can now create slash commands without the decorator in a much more eaisier way! Check out theSlash.add_commandfunctionEdit commandsYou can edit commands in code with theSlash.edit_commandfunctionListening componentsYou can add and remove listening components now with theComponents.add_listening_component,Components.remove_listening_componentandComponents.remove_listening_componentsfunctionsCogsYou can now use cog decorators likeslash_command,subslash_commandandlistening_componentFixedSlashCommandSlash commands wouldn't be updated if onlydefault_permissionwas changedChangedwait_forMessage.wait_for now takesbyandcheckas parameters andevent_nameandclientswitched place (wait_for(client, "event_name")is nowwait_for("event_name", client))listening componentsYou can specify listening_components now more presicely, you can add messages, users, and a check to filterInteraction.memberInteraction.memberis nowInteraction.authorlistening comonentsListening component callback functions now only take one parameter, the used componenton_button_pressandon_menu_selectThese events now take a sole parameter, the used component. If you want to acces to message, usepassed_component.messageRemovedResponseMessageRemoved ResponseMessage3.3.5FixedSelectMenuSelectMenu issue when creating it from data3.3.4ChangededitMessage.editnow takes aembedparameterFixedprintForgot to remove someprintstatements3.3.3Addedclass representationclasses have now a__repr__functionUI(override_dpy)You can now choose whether you want to override some of dpy objects and functions (default is True) (seethe override modulefor more information)
This also appeals to theComponentsclass (Components(override_dpy))
note: if you don't want to create aUIobject, you can instead override dpy with theoverride_dpymethodfromdiscord_uiimportoverride_dpyoverride_dpy()Fixeddpy2discord.py v2 now auto-decompresses socket data and passes a string instead of the uncompressed data.override dpy messagewhen overriding dpy message object, the components would mix3.3.2AddedEphemeralResponseMessageYou can now edit a ephemeral message which was created from an interaction (ex. when a button in a hidden message was pressed)3.3.1AddedinteractionInteraction.channelandInteraction.guild3.3.0Fixedinteraction usage in dms3.2.9Addedratelimit fixThe lib will now retry after the ratelimit reset and doesn't throw an HTTPException anymoreFixedsync_commandsGotKeyErrorexception while syncing commands3.2.8Fixedhidden respondingWhen a hidden response was about to be send without defering the interaction it would thrown an error3.2.7AddedwarningsWhen a guild_permission with an invalid guild id is passed, it will throw an exception when syncing the commandsWhen the value of a guild_permission is not of typeSlashPermissionit will throw an exceptioncontext-commandsYou can now have context commands with the same name as a normal slash commandslashcommand descriptionYou can use docstrings"""docstring"""for setting the description of a slash commmand by setting the dosctring for the callback functionChangedauto_deferauto_defer is now disabled by defaultslash syncYou can now disable auto_sync for slash commmands and sync them by yourself withSlash.sync_commands(delete_unused)Interacion.deferInteraction._deferredis notInteraction.deferredandInteraction.defer()doesn't throw an exception anymore, it will just log the error withlogging.error()FixedtryThere was a try/catch in theInteraction.respondfunction that would allow the code to continue when an exception occured while responding with ninja_modecontext commandsThere was an issue adding context-commandsCommand checkingNow, the libary only edits commands when changes were made3.2.6Addedauto ninja_modeIf you use.respond(), the function will try to use ninja_mode automaticallyChangedprojectMoved git-project tohttps://github.com/discord-py-ui/discord-uiFixedninja_mode responseresponding with ninja_mode would end up in an exceptionfile sendingfixed another file sending issue with slash commands3.2.5Fixed#89 (thanks for reporting)3.2.4Fixed version issues with the package3.2.2Fixed#85:AttributeError: module 'discord' has no attribute '_Components__version'3.2.0FixedI'm really sorry for all the issues this libary got, if you still find issues, please report them inhttps://github.com/discord-py-ui/discord-ui/issuesSelectOpionThere was an issue with emojis not being set in SelectOptionsLinkButtonThere was an issue with setting the url not being setSlashCommandsThere was an issue with creating commands that don't already existChangedSelectInteraction.valuesis not.selected_valuesAddedInteractionButtons and SelectMenus have a.messageproperty for the message where their interaction was creted
ResponseMessages have a.interactionproperty for the received interactionEventsWe added ainteraction_receivedevent for all interactions that are received3.1.0Addeddiscordpy 2 supportWe added support for discord.py v2, so you can stay loyal to our libary and use it together with discord.py v2!ExceptionsAdded own Exceptions for errorsParseMethodYou can change the way the extension parses interaction data. You can choose betweendifferent MethodsAuto-deferThe libary will autodefer all interactions public. If you want to change that, take a look atthe documentation for this featureslashcommand edit checkSlash commands will only be edited if there were some changes, so you won't get ainvalid interactionerror in discord after starting the bot
If only permissions were changed, just the permissions will be edited and not the whole command like beforeFixedslash commandsI finally fixed the damn slashcommand system, it should work nowParsingThe resolving, fetching and pulling from the cache methods should all work3.0.1Fixedsmall project issues3.0.0Addedcontext commandsContext commands are now availableChangedProject nameThe project's name was changed fromdiscord-message-componentstodiscord-uiExtensionis nowUI2.1.0AddedWebhook supportYou are now able to use webhooks together with message components, to send a webhook message with the components, use theComponents.send_webhookfunction.
The standart webhook function is also overriden with the new component functionFloat typeYou can now usefloatas the argument type for a slash command optionAuto empty namesButtons, LinkButtons and SelectOptions labels are now by default\u200b, which is an "empty" charChangedCode documentation to more be more informativeFixedFixed small code issues (they were already fixed in previous versions, but I just wanna list this here)Docs are now working2.0.2FixedSelectOptionSelect option threw an exception if it was smaller than 1 or higher than 1002.0.0AddedSlashcomamnd supportSlashclass for slash commandsSlash.command,Slash.subcommandandSlash.subcommand_groupsare available for creating slash commandsSlashedCommandandSlashedSubCommandare there for used slash commandsMessagedisable_action_row(row_numbers:int|range, disable:bool)disables (enables) component row(s) in the messagedisable_components(disable:bool)disables (enables) all componentssoverridesMessageable.sendreturns Message instead of discord.Message and takes components parameteroverride_clientfunction addedinteraction.send, creates followup messages which can be hiddenComponent.listening_componentA listening component with a callback function that will always be executed whenever a component with the specified custom_id
was usedChangedMessageAll Message objects don't use the client object anymoreMessage.wait_for now needs the client as the first parameterFixedInteractionAll interaction responses work nowA lot of issues I fogor💀1.2.2FixedDocs fixed1.2.1FixedSmall code fixes1.2.0AddedComplete message component suppportSelect menusdocumentation1.1.2FixedSmall code fixes1.1.1AddedMessage.edit()You can now edit messages with button support1.1.0ChangedMajor changes to request code, now using the client's requestResponseMessage.acknowledge()->ResponseMessage.defer()Changed the name of the function + changedResponseMessage.acknowledged->ResponseMessage.deferredResponseMessage.defer()=>await ResponseMessage.defer()defer(acknowledge) is now async and needs to be awaitedAddedhidden responsesYou can now send responses only visible to the userFixedResponseMessage.respond()Now doesn't show a failed interaction1.0.5FixedResponseMessage.respond()responding now doesn't fail after sending the message, it will now defer the interaction by it self if not already deferred and then send the message1.0.4AddedResponseMessage.acknowledgedWhether the message was acknowledged with theResponseMessage.acknowledged()functionChangedResponseMessage.respond()=>await ResponseMessage.respond()respond() function is now async and needs to be awaitedResponseMessage.respond() -> None=>ResponseMessage.respond() -> Message or Nonerespond() now returns the sent message or None if ninja_mode is true1.0.3AddedButton.hashButtons have now a custom hash property, generated by the discord api