V3 Final merge (#1966)
* Update azure-pipelines.yml * Update deploy.yml * Remove version tag from proj * Update deploy.yml * Removed versions from project files * Removed style of the nuget badge and added logo (#201) The style was not properly added to it and the plastic version does not look good with the discord badge. I thought it would look better with a logo * Fix Type not being set in SocketApplicationCommand * Remove useless GuildId property * meta: update XML * Add Autocomplete to SlashCommandOptionBuilder * Added autocomplete in SlashCommandOptionBuilder. (#206) Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com> * Fix duplicate autocomplete * Fix #208 * Fix sub commands being interpreted as a parameter for autocomplete * Fix exposed optional * Support the discord:// protocol in buttons (#207) * Update UrlValidation.cs * Update ComponentBuilder.cs * Add docs and better error messages. * Fix wonky intentation * Add competing activity status type (#205) * Update GuildPermissionsTests.cs * Update GuildPermissions.cs * Add competing status type * Add Icons to IRole (#204) * Added icon field to IRole * Added GetGuildRoleIconUrl() * Added Clean Content Function (#174) * Added Clean Content Function * Fixed Spelling problems and bad var handling * Add StripMarkDown Method * Clean Content Expanded (#212) * Implement CleanContent In IMessage & RestMessage * Update Spelling and Documentation * Add SanatizeMessage to MessageHelper and Refactor Rest and Socket Message * Add event for autocomplete interaction (#214) * Spelling corrections (#215) * Remove null collections * Followup with file async warnings (#216) * Changed from NotNullOrWhitespace to NotNullOrEmpty * Added NotNullOrEmpty on filename * Added system to interpret from the path * Added a check for if it contains a period * It has been done, how ever it will break stuff * Changed to use ??= how ever still added error check * Added space under check * Changed from with a period to valid file extension * Added checks for SendFileAsync * Removed filename != null && * Add channel types in application command options. (#217) * add channel types in application command options * Indent Docs * Stage instance audit logs as well as thread audit log type * Update azure-pipelines.yml * Update azure-pipelines.yml * Fix system messages not including mentioned users. Added ContextMenuCommand message type * Remove file extension check (#218) * Fix NRE in modify guild channel * Fix 429's not being accounted for in ratelimit updates * meta: add net5 framework Co-Authored-By: MrCakeSlayer <13650699+MrCakeSlayer@users.noreply.github.com> * Proper doc logos (#221) * Update GuildPermissionsTests.cs * Update GuildPermissions.cs * Add competing activity status type * logo changes * logo text as path * add missing logo * Update package logo and favicon * Update docfx references * Remove Console.WriteLine * Rename Available to IsAvailable in stickers * Rename Default and Required to IsDefault and IsRequired in IApplicationCommandOption. Rename DefaultPermission to IsDefaultPermission in IApplicationCommand * Fix different rest channels not deserializing properly * Refactor summaries and boolean property names * General cleanup (#223) * General cleanup * Add Async suffix to SendAutocompleteResult * Fix more formatting * Fix unused RequestOptions in GetActiveThreadsAsync * Add message to ArgumentNullException * Ephemeral attachments * Add missing jsonproperty attribute * Add IMessage.Interaction * Update attachment checks for embed urls * meta: bump version * Remove old package configs and update image * Update package logos * Fix logo reference for azure * Deprecate old package definitions in favor for target file * Deprecate old package definitions in favor for target file Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update package ids * Fix url validation * meta: bump version * Fix assignment of UserMentions (#233) * Fix CleanContent (#231) * Fix SocketSlashCommandData access modifier. (#237) Fixes #229 * Update README with better header (#232) * Update README with better header Adds HTML elements that implement the main logo & improve the redirection tag positions. * Resolving border issue in light-mode * Update sponsor section * Implement checks for interaction respond times and multiple interaction responses. closes #236, #235 * Add response check to socket auto complete * meta: bump versions * Fix #239 * meta: bump version * meta: update logo * meta: bump versions * Revert received at time, confirmed by discord staff to be accurate * Update docs * Update CHANGELOG.md * meta: docs building * Update docs.yml * Update docs.yml * Fix docfx version * Update docs.yml * Update docs.bat * Rename docs repo for clone * update docfx version * Update docs.bat * Update docfx version * Remove docs from pipeline * FAQ revamped, metadata updated (#241) * FAQ revamped, metadata updated * Update FAQ.md * Update README.md * Docs index improvement * Fix InvalidOperationException in modify channel * feature: guild avatars, closes #238 * feature: modify role icons * meta: changelog * meta: bump version * Update README.md * Fix non value type options not being included in autocomplete * Add new activity flags (#254) * Add new activity flags * Add missing commas * Added support for GUILD_JOIN_REQUEST_DELETE event (#253) Fixes #247 * Adding BotHTTPInteraction user flag (#252) * animated guild banner support (#255) * Docs work (WIP) (#242) * Main page work * Metadata logo dir * More main page edits * Naming change * Dnet guide entries pruned * Add student hub guild directory channel (#256) * animated guild banner support * Add guild directory channel * Fix followup with file overwrite having incorrect parameter locations * Update GUILD_JOIN_REQUEST_DELETE event * Update head.tmpl.partial * Removed BannerId and AccentColor (#260) * Removed BannerId property, GetBannerURL method, and AccentColor property from IUser and socket entities. * Fixed errors in IUser.cs * Added back summary for GetAvatarUrl method in IUser.cs * Support Guild Boost Progress Bars (#262) * Support Guild Boost Progress Bars * Update SocketChannel.cs * Fix non-optional and unnecessary values. * Spelling * Reordering and consistency. * Remove log for reconnect * Add missing flags to SystemChannelMessageDeny (#267) * Rename new activity flags * Guild feature revamp and smart gateway intent checks * Get thread user implementation * Amend creating slash command guide (#269) * Adding BotHTTPInteraction user flag * Added comments explaining the Global command create stipulations. * Fix numeric type check for options * Add state checking to ConnectionManager.StartAsync (#272) * initial interface changes * Multi file upload + attachment editing * meta: bump versions * Update CHANGELOG.md * Update CHANGELOG.md * Support Min and Max values on ApplicationCommandOptions (#273) * Support Min and Max values on ApplicationCommandOptions * Support decimal min/max values * Docs imrpovments + use ToNullable * Logomark, doc settings edit (#258) * Logomark, doc settings edit * Replace standard logo * Bumping docfx plugins to latest release * Bump version metadata * Logo svg fix * Change default sticker behavior and add AlwaysResolveSticker to the config * Implement rest based interactions. Added ED25519 checks. Updated summaries. * Update package logo * Automatically fix ordering of optional command options (#276) * auto fix optional command option order * clean up indentation * Fix maximum number of Select Menu Options (#282) As of https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-menu-structure the maximum number of options is 25, not less than 25. Hopefully the change catches all necessary locations * Add voice region to modify voice channels * Update summaries on rest interactions * Interaction Specific Interfaces (#283) * added interaction specific interfaces * fix build error * implement change requests * Update application * Add Guild Scheduled Events (#279) * guild events initial * sharded events * Add new gateway intents and fix bugs * More work on new changes to guild events * Update guild scheduled events * Added events to extended guild and add event start event * Update preconditions * Implement breaking changes guild guild events. Add guild event permissions * Update tests and change privacy level requirements * Update summaries and add docs for guild events * meta: bump version * Increment meta version (#285) * Increment meta version * Update docfx.json * Fix #289 and add configureawaits to rest based interactions * meta: bump version * Add GUILD_SCHEDULED_EVENT_USER_ADD and GUILD_SCHEDULED_EVENT_USER_REMOVE (#287) * Remove newline * Fix autocomplete result value * meta: bump versions * Add `GuildScheduledEventUserAdd` and `GuildScheduledEventUserRemove` to sharded client * Make RestUserCommand public (#292) * Fix Components not showing on FUWF (#288) (#293) Adds Components to Payload JSON Generation * Implement smarter rest resolvable interaction data. Fixes #294 * Add UseInteractionSnowflakeDate to config #286 * Implement Better Discord Errors (#291) * Initial error parsing * Implement better errors * Add missing error codes * Add voice disconnect opcodes * Remove unused class, add summaries to discordjsonerror, and remove public constructor of slash command properties * Add error code summary * Update error message summary * Update src/Discord.Net.Core/DiscordJsonError.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.WebSocket/API/Voice/VoiceCloseCode.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Fix autocomplete result value Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Change the minimum length of slash commands to 1 (#284) * Change the minimum length of slash commands to 1. This is the correct value according to the docs and it has been changed after user feedback. * Fix the limit in 3 other places Co-authored-by: quin lynch <lynchquin@gmail.com> * Add new thread creation properties * Add role emoji. Fixes #295 * Fix mocked text channel * Fix precondition checks. Closes #281 * Initial fix (#297) * meta: bump version * Update property names and summaries * Add Audit Log Data classes for Threads (#301) * Add ThreadDeleteAuditLogData * Add ThreadCreateAuditLogData * Fix ThreadCreateAuditLogData using old instead of new value * Create ThreadInfo Class * Fix Thread not being a property * Add ThreadUpdateAuditLogData * Cleanup usings * Add RateLimit to ThreadAuditLogData classese Co-authored-by: Playwo <eliaswolf2001@t-online.de> * Fix #300 * Interaction Command Service (#52) * init * attribute rename * added docs * Revert "added docs" This reverts commit 30aa0c4ef7e190a726ec2cb3a183da5e2f9b07d9. * added basic docs * Switched to nested modules for method grouping, changed command traversal method * interface now declares the helper methods * added new method with predicate parameter * added config option for deleting the "thinking" state of unhandled commands * Slash Module Base now exposes helper methods for interacting with the underlying Interaction * Revert "interface now declares the helper methods" This reverts commit 541b0be93530e880c482962d41cd6e0cefa4e771. * IDiscordInteraction now declares the helper methods * new cancelable wait interaction method * added support for user created command types * added option type 'number', added write method to typereaders * added enum and timespan typereaders * revert * added interface method declarations * inline docs * revert interface changes * current user id assignment in sharded client * added wildcards to interactions, tweaks * tweaks on interaction wild card pattern * Pre-app menu * fixed CurrentUserId and added application command events * made event listener persistent * Sharded Client Application Command Events and CurrentUserId Issue (#105) * added interface method declarations * inline docs * current user id assignment in sharded client * fixed CurrentUserId and added application command events * made event listener persistent * removed option type converter, task offloaded to typereaders * added "deleteOGResponse" method to module base * Upstream fetch for Discord-Net-Labs/release/3.x * solved merge conflicts * removed merge artifacts * added new Context Command attributes * added Conxtext Command info classes and changed the naming scheme for the existing classes * added IgnoreGroupNames prop to command attributes * added ContextCommand builder * moved command builders to internal * added ContextCommand methods to the command service * command service now uses InteractionHelper to register commands * bug fixes and refactorings * docs update * added inline docs to public members * added inline docs * added method name property to command infos * added inline docs * changed the execution callback to a declared delegate * createInstance delegate is now created only once per module * declared the ExecuteCallback delegate * introduced a way to modify the command permissions * changed method names * added optional compiled lambda module builder * added the missing sync execution option * moved run mode selection to the base class * info class refactorings * switched to compiled lambda based method invoke * command refactorings * added docs * removed untended class * bug fixes * minor refactorings * reflection changes * bug fix for interaction parameters * commands and modules now groups the preconditons on building * added default permission to context commands * added DontAutoRegister attribute * renamed TypeReader to TypeConverter * added docs to TypeConverterResult, made ISlashModuleBase public * namespace and project change * added inline docs file * renamed ExecuteComponentCommand method * added scoped service support to the dependency injection model * fixed premature disposal of scoped services * extended the scope to cover the precondition checking methods * removed slash command related preconditions from core lib * added sample application * precondition checks are now executed according to the command RunMode * reverting the conflicting changes * reverted SocketInteraction * reverting more conflicts * added indentations to inline docs * implemented change requests * updated the sample app * moved builders to public * added indentations to typeconverter docs * renamed old componentCommandExecuted event * bug fix for generic typeconverters * Revert "bug fix for generic typeconverters" This reverts commit fcc61957deb5dfc17c41367f1c7c72d27024b0ee. * bug fix for context commands * code cleanup * removed public module build method * modev OnModuleBuilding execution inside the module build method * added try-catch blocks encapsulating arg generation * fixed parameter preconditions not raising commandExecuted event * removed OnModuleBuilding execution from ModuleClassBuilder * removed setters from Precondition ErrorMessages * added methods to interaction service for creating user defined modules * added IParameterInfo parameter to TypeConverter.Write * changed the target frameworks * DefaultValueConverter bug fix * GenerateArgs refactorings * WaitForMessageComponent now relies message id * added ChannelTypes support * added ChannelTypes support * fix build error for new lib version * added ToString method to CommandInfo * added ToString method to CommandInfo * Fix index out of bounds error for new non-null slash command option collection * enum converter rework * added user extendable types to command context and module base * added regex anchors to ensure pattern matches the whole string * incomplete guides * add missing ignoreGroupNames assignment for ComponentInteraction * typeconverters now seperate pascal casing parameter names * fix missing IServiceScopefactory ? * Revert "typeconverters now seperate pascal casing parameter names" This reverts commit 141300f3d2c244fc6795999d910462939d16a2e1. * moved the option name pascal casing seperator to RestUtils * fix component command arg generation * removed , from default command delimiters * updated the regex to match every non whitespace value * added Autocomplete interaction support and updated the regex to match every non whitespace value * replaced the posix class with range exps in pascal casing seperator * added inline docs to autocompleter related classes * added regex metacharacter escape to wildcard patterns * added null check to Regex EscapeExcluding * added .net5.0 support and updated the project package * added .net5.0 support and updated the project package * add dependency injection to autocompleters * add net6.0 * bump versions * bug fix: pascal casing parameters are not assigned * rework autocomplete commands to accept command and parameter names seperatly * rename *InteractionCommandContext to *InteractionContext * add max-min value support to number type slash command options * add hide attribute to deafult enum converter * add inline docs * guides update: min/max value and autocomplete interactions * remove net6.0 support * add inline doc to Config.EnableAutocompleters * add autocompleters guide * added attribute usage to min/max value * implement rest based interactions * add handling logic for rest based interactions * update default TypeConverters to accommodate rest based interactions * added interaction specific interfaces * fix build error * implement change requests * bump metapackage version * replace concrete interface types with interfaces in command execution logic * fix min/max value attribute target * add rest specific interaction module for creating interaction responses for rest based interactions within the module * update rest callback to accept an interaction context parameter * clean up RestResponseCallback implementation artifacts * fix command registration bug when using the sharded socket client * update docs * fix build errors * fix slash command depth check * implement requested changes * fix build error * the grand finale * the grand finale Co-authored-by: quin lynch <lynchquin@gmail.com> * Remove XML doc * Add Interactions service to azure build * Add DocFX refs to interaction framework docs * meta: bump docfx version * meta: bump versions * Remove versioning metadata in csproj * Fix user command mismatch in docs * Fix parameter in message commands * Fix SocketVoiceChannel options are created as generic mentionables in Interaction service (#308) * added interaction specific interfaces * fix build error * implement change requests * add autocomplete respond method to IAutocompleteInteraction * fix sharded client current user * fix generic typeconverter picking priority * Revert "fix sharded client current user" This reverts commit a9c15ffd6ab02651e83e72c275889502b60cfddc. * Revert "add autocomplete respond method to IAutocompleteInteraction" This reverts commit f2fc50f1f19a0b41144b6dc93080d2f3a01282fc. * meta: bump version * Improve the `GuildFeatures` converter (#311) * Fix Message/User commands are not being executed when their name have spaces on it (#310) * added interaction specific interfaces * fix build error * implement change requests * add autocomplete respond method to IAutocompleteInteraction * fix sharded client current user * fix generic typeconverter picking priority * Revert "fix sharded client current user" This reverts commit a9c15ffd6ab02651e83e72c275889502b60cfddc. * Revert "add autocomplete respond method to IAutocompleteInteraction" This reverts commit f2fc50f1f19a0b41144b6dc93080d2f3a01282fc. * fix command parsing for names with spaces * meta: bump version * fix minor spelling mistake * add missing $ on docs Co-Authored-By: Liege72 <65319395+Liege72@users.noreply.github.com> * Squashed commit of the following: commit ff0bbbd4d3c4141a6e7eedbe2da0a2cbf5a8a208 Merge: 41b4686b19a66bf8Author: quin lynch <lynchquin@gmail.com> Date: Sat Nov 27 08:39:35 2021 -0400 Merge branch 'dev' of https://github.com/discord-net/Discord.Net into dev commit19a66bf878Author: Daniel Baynton <49287178+230Daniel@users.noreply.github.com> Date: Fri Nov 26 15:41:55 2021 +0000 feature: Add method to clear guild user cache (#1767) * Add method to clear a SocketGuild's user cache * Add optional predicate * Compress overload to be consistant * Fix global user not clearing (may cause other issues) * Remove debug code and add param documentation * Standardise doc string * Remove old hack-fix * Rename new method for consistency * Add missing line to reset downloaderPromise * Undo accidental whitespace changes * Rider better actually keep the tab this time Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com> commitb9274d115dAuthor: Monica S <FiniteReality@users.noreply.github.com> Date: Fri Nov 26 15:41:08 2021 +0000 Add characters commonly use in links to Sanitize (#1152) Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com> commit51e06e9ce1Author: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Fri Nov 26 11:30:19 2021 -0400 feature: warn on invalid gateway intents (#1948) commit82276e351aAuthor: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Fri Nov 26 11:29:53 2021 -0400 feature: default application games (#1949) * Initial implementation * Add missing summary commit4f1fe2b084Merge:9d6dc6273cd9f399Author: quin lynch <lynchquin@gmail.com> Date: Fri Nov 26 11:23:32 2021 -0400 Merge branch 'siscodeorg-commands/validate-get-best-match' into dev commit3cd9f39918Merge:9d6dc627adf3a9c4Author: quin lynch <lynchquin@gmail.com> Date: Fri Nov 26 11:23:05 2021 -0400 Merge branch 'commands/validate-get-best-match' of https://github.com/siscodeorg/Discord.Net into siscodeorg-commands/validate-get-best-match commitadf3a9c459Author: roridev <t3ctotalmenterandom1@outlook.com> Date: Fri Nov 26 09:26:53 2021 -0300 Fix incorrect casing on `HandleCommandPipeline` commita92ec56d88Author: roridev <t3ctotalmenterandom1@outlook.com> Date: Thu Nov 25 16:42:18 2021 -0300 Add requested changes Changes: - Use IResult instead of Optional CommandMatch - Rework branching workflow commitd1b31c8f52Author: roridev <t3ctotalmenterandom1@outlook.com> Date: Thu Nov 25 15:31:48 2021 -0300 Add `MatchResult` commit9d6dc6279dAuthor: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Thu Nov 25 11:25:19 2021 -0400 Update socket presence and add new presence event (#1945) commit10afd96e6eAuthor: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Thu Nov 25 11:24:44 2021 -0400 feature: Handle bidirectional usernames (#1943) * Initial implementation * Update summary commit143ca6db43Author: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Thu Nov 25 11:23:33 2021 -0400 fix NRE when adding parameters thru builders (#1946) commitd5f5ae132cAuthor: Cenk Ergen <57065323+Cenngo@users.noreply.github.com> Date: Thu Nov 25 18:22:50 2021 +0300 fix sharded client current user (#1947) commitb5c150dc16Author: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Wed Nov 24 12:53:39 2021 -0400 Add Voice binaries (#1944) * Add binaries and read me * Update sending voice docs * Undo markdown formatting commitbc440abd44Author: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Wed Nov 24 12:52:55 2021 -0400 Implement multi-file upload to webhooks (#1942) commitf7a07aec02Author: Paulo <pnmanjos@hotmail.com> Date: Wed Nov 24 09:57:06 2021 -0300 Add default nullable enum typereader (#1518) commit6abdfcbf87Author: Slate <kristian.f@hotmail.co.uk> Date: Wed Nov 24 12:55:07 2021 +0000 Added negative TimeSpan handling (#1666) - Added unit tests for the TimeSpanTypeReader - Fixes https://github.com/discord-net/Discord.Net/issues/1657 commite0dbe7c695Author: Paulo <pnmanjos@hotmail.com> Date: Wed Nov 24 09:43:57 2021 -0300 Add MaxBitrate to the interface (#1861) Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com> commit3cb662ff7aAuthor: d4n <dan3436@hotmail.com> Date: Tue Nov 23 10:49:31 2021 -0500 Add null check to AllowedMentions.ToModel() (#1865) commit900c1f4385Author: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Tue Nov 23 11:46:18 2021 -0400 Fix emoto try parse (#1941) commit933ea42eaaAuthor: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Tue Nov 23 09:58:05 2021 -0400 Merge Labs 3.X into dev (#1923) * meta: bump version * Null or empty fix (#176) * Add components and stickers to ReplyAsync extension * Fixed null or empty * Changed Label to Description * -||- Co-authored-by: quin lynch <lynchquin@gmail.com> * More regions (#177) * Preconditions * ChannelHelper * RestDMChannel * RestGroupChannel * RestBan * RestGroupUser * EntityExtensions * DiscordSocketClient * DiscordSocketClient * Discord.net.core.xml fix (#178) * Changed Label to Description * Added Discord- .MessageComponent .ISticker[] ,Discord.MessageComponent,Discord.ISticker[] to ReplyAsync * Remove references to labs * Update Discord.Net.sln * Added SendMessagesInThreads and StartEmbeddedActivities. (#175) * Added SendMessagesInThreads and StartEmbeddedActivities. Adjusted owner perms. Change UsePublicThreads -> CreatePublicThreads Change UsePrivateThreads -> CreatePrivateThreads * removed extra /// * Added UsePublicThreads and UsePrivateThreads back with Obsolete Attribute * removed 'false' from Obsolete Attribute * Squashed commit of the following: commit dca41a348e36a9b4e7006ef3a76377eb32aad276 Author: quin lynch <lynchquin@gmail.com> Date: Thu Sep 23 07:02:19 2021 -0300 Autocomplete commands * meta: xml. closes #171 * Revert user agent and $device to dnet * meta: bump version * meta: bump vers * Fix sticker args * Grammer fix (#179) * Made IVoiceChannel mentionable * Embeds array for send message async (#181) * meta: bump version * meta: bump vers * Fix sticker args * Grammer fix (#179) * Added embeds for SendMessageAsync * [JsonProperty("embed")] forgot to remove this public Optional<Embed> Embed { get; set; } * It has been done as requested. * Changed the old way of handeling single embeds * Moved embeds param and added options param * xmls Co-authored-by: quin lynch <lynchquin@gmail.com> * Fix thread permissions (#183) * Update GuildPermissionsTests.cs * Update GuildPermissions.cs * Use compound assignment (#186) * Used compound assignment * -||- * -||- * Remove unnecessary suppression (#188) * Inlined variable declarations (#185) * Fixed some warnings (#184) * Fixed some warnings * Another fixed warning * Changed the SSendFileAsync to SendFileAsync * Removed para AlwaysAcknowledgeInteractions * Moved it back to the previous version * Added periods to the end like quin requested!! :(( Co-authored-by: MrCakeSlayer <13650699+MrCakeSlayer@users.noreply.github.com> * Object initialization can be simplified fixed (#189) * Conditional-expression-simplification (#193) * Capitlazation fixes (#192) * Removed-this. (#191) * Use 'switch' expression (#187) * Use 'switch' expression * Reverted it to the old switch case * Fixed-compiler-error (#194) * Submitting updates to include new permissions. (#195) * Submitting updates to include new permissions. * Make old permissions obsolete and update tests Co-authored-by: quin lynch <lynchquin@gmail.com> * Update azure-pipelines.yml * Update azure-pipelines.yml * Update azure-pipelines.yml * Add support for long in autocomplete option * Add support for sending files with multiple embeds (#196) * Add support for sending files with multiple embeds * Simplify prepending single embed to embed array * Consistency for embeds endpoints (#197) * Changed the way of handling prepending of embeds. For consistency. * reformatted the summary * Revert pipeline * Fix duplicate merge conflicts * Changed minimum slash command name length to 1 per Discord API docs (#198) * Channel endpoints requirements correction (#199) * Added some requirements to channels for topic * Changed check from NotNullOrEmpty to NotNullOrEmpty * Added some requirements to channels for name Preconditions.LessThan * Formatting of file * Added restriction for description not being null (#200) * Update azure-pipelines.yml * Update deploy.yml * Remove version tag from proj * Update deploy.yml * Removed versions from project files * Removed style of the nuget badge and added logo (#201) The style was not properly added to it and the plastic version does not look good with the discord badge. I thought it would look better with a logo * Fix Type not being set in SocketApplicationCommand * Remove useless GuildId property * meta: update XML * Add Autocomplete to SlashCommandOptionBuilder * Added autocomplete in SlashCommandOptionBuilder. (#206) Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com> * Fix duplicate autocomplete * Fix #208 * Fix sub commands being interpreted as a parameter for autocomplete * Fix exposed optional * Support the discord:// protocol in buttons (#207) * Update UrlValidation.cs * Update ComponentBuilder.cs * Add docs and better error messages. * Fix wonky intentation * Add competing activity status type (#205) * Update GuildPermissionsTests.cs * Update GuildPermissions.cs * Add competing status type * Add Icons to IRole (#204) * Added icon field to IRole * Added GetGuildRoleIconUrl() * Added Clean Content Function (#174) * Added Clean Content Function * Fixed Spelling problems and bad var handling * Add StripMarkDown Method * Clean Content Expanded (#212) * Implement CleanContent In IMessage & RestMessage * Update Spelling and Documentation * Add SanatizeMessage to MessageHelper and Refactor Rest and Socket Message * Add event for autocomplete interaction (#214) * Spelling corrections (#215) * Remove null collections * Followup with file async warnings (#216) * Changed from NotNullOrWhitespace to NotNullOrEmpty * Added NotNullOrEmpty on filename * Added system to interpret from the path * Added a check for if it contains a period * It has been done, how ever it will break stuff * Changed to use ??= how ever still added error check * Added space under check * Changed from with a period to valid file extension * Added checks for SendFileAsync * Removed filename != null && * Add channel types in application command options. (#217) * add channel types in application command options * Indent Docs * Stage instance audit logs as well as thread audit log type * Update azure-pipelines.yml * Update azure-pipelines.yml * Fix system messages not including mentioned users. Added ContextMenuCommand message type * Remove file extension check (#218) * Fix NRE in modify guild channel * Fix 429's not being accounted for in ratelimit updates * meta: add net5 framework Co-Authored-By: MrCakeSlayer <13650699+MrCakeSlayer@users.noreply.github.com> * Proper doc logos (#221) * Update GuildPermissionsTests.cs * Update GuildPermissions.cs * Add competing activity status type * logo changes * logo text as path * add missing logo * Update package logo and favicon * Update docfx references * Remove XML files and use original pipeline format * Remove console writeline * Remove Console.WriteLine * Remove useless log * Rename Available sticker field to IsAvailable * Rename Available to IsAvailable in stickers * Add summary indent for role members * Add summary indent to SocketInvite * Rename DefaultPermission to IsDefaultPermission * Rename Default to IsDefault and Required to IsRequired in IApplicationCommandOption * Rename Default and Required to IsDefault and IsRequired in IApplicationCommandOption. Rename DefaultPermission to IsDefaultPermission in IApplicationCommand * Remove extra white spaces * Renamed Joined, Archived, and Locked to HasJoined, IsArchived, and IsLocked * Rename Live and DiscoverableDisabled to IsDiscoverableDisabled and IsLive in IStageChannel * Remove newline * Add indent to summaries * Remove unnecessary json serializer field * Fix ToEntity for roletags incorrectly using IsPremiumSubscriber * Update RestChannel for new channel types * Fix different rest channels not deserializing properly * fully qualify internal for UrlValidation and add indent to summary * Add missing periods to InteractionResponseType * Fix summary in IApplicationCommandOptionChoice * Update IApplicationCommandOption summaries * Update IApplicationCommandInteractionDataOption summaries * Update IApplicationCommandInteractionData summaries * Update IApplicationCommand summaries * Update ApplicationCommandType summaries * rename DefaultPermission to IsDefaultPermission in ApplicationCommandProperties * update ApplicationCommandOptionChoiceProperties summaries * Rename Default, Required, and Autocomplete to IsDefault, IsRequired, and IsAutocomplete in ApplicationCommandOptionProperties * Update SlashCommandProperties summaries * update SlashCommandBuilder boolean field names, summaries, and choice parameters * Update SelectMenuOption summaries, Rename Default to IsDefault in SelectMenuOption * update SelectMenuComponent summaries. Rename Disabled to IsDisabled in SelectMenuComponent * update ComponentBuilder summaries and boolean fields. * Update ButtonComponent summaries and boolean fields * update ActionRowComponent summaries * Update UserCommandBuilder * Update MessageCommandBuilder summaries and boolean properties * Update IGuild summary * Update IGuild summaries * Update StagePrivacyLevel summary * update IThreadChannel summaries * Update IStageChannel summaries * Refactor summaries and boolean property names * General cleanup (#223) * General cleanup * Add Async suffix to SendAutocompleteResult * Fix more formatting * Fix unused RequestOptions in GetActiveThreadsAsync * Add message to ArgumentNullException * Ephemeral attachments * Add missing jsonproperty attribute * Add IMessage.Interaction * Update attachment checks for embed urls * meta: bump version * Remove old package configs and update image * Update package logos * Fix logo reference for azure * Deprecate old package definitions in favor for target file * Deprecate old package definitions in favor for target file Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update package ids * Fix url validation * meta: bump version * Fix assignment of UserMentions (#233) * Fix CleanContent (#231) * Fix SocketSlashCommandData access modifier. (#237) Fixes #229 * Update README with better header (#232) * Update README with better header Adds HTML elements that implement the main logo & improve the redirection tag positions. * Resolving border issue in light-mode * Update sponsor section * Implement checks for interaction respond times and multiple interaction responses. closes #236, #235 * Add response check to socket auto complete * meta: bump versions * Fix #239 * meta: bump version * meta: update logo * meta: bump versions * Revert received at time, confirmed by discord staff to be accurate * Merge branch 'release/3.x' of https://github.com/Discord-Net-Labs/Discord.Net-Labs into merger-labs Update requested changes of obsolete and references to labs. Added `Interaction` to `IMessage` Fixed grammar Fixed bugs relating to interactions. * Update docs * Update CHANGELOG.md * meta: docs building * Update docs.yml * Update docs.yml * Fix docfx version * Update docs.yml * Update docs.bat * Rename docs repo for clone * update docfx version * Update docs.bat * Update docfx version * Remove docs from pipeline * FAQ revamped, metadata updated (#241) * FAQ revamped, metadata updated * Update FAQ.md * Update README.md * Docs index improvement * Fix InvalidOperationException in modify channel * feature: guild avatars, closes #238 * feature: modify role icons * meta: changelog * meta: bump version * Update README.md * Fix non value type options not being included in autocomplete * Add new activity flags (#254) * Add new activity flags * Add missing commas * Added support for GUILD_JOIN_REQUEST_DELETE event (#253) Fixes #247 * Adding BotHTTPInteraction user flag (#252) * animated guild banner support (#255) * Docs work (WIP) (#242) * Main page work * Metadata logo dir * More main page edits * Naming change * Dnet guide entries pruned * Add student hub guild directory channel (#256) * animated guild banner support * Add guild directory channel * Fix followup with file overwrite having incorrect parameter locations * Merge labs 3.x * Update GUILD_JOIN_REQUEST_DELETE event * Update head.tmpl.partial * Removed BannerId and AccentColor (#260) * Removed BannerId property, GetBannerURL method, and AccentColor property from IUser and socket entities. * Fixed errors in IUser.cs * Added back summary for GetAvatarUrl method in IUser.cs * Support Guild Boost Progress Bars (#262) * Support Guild Boost Progress Bars * Update SocketChannel.cs * Fix non-optional and unnecessary values. * Spelling * Reordering and consistency. * Remove log for reconnect * Add missing flags to SystemChannelMessageDeny (#267) * Fix labs reference in analyzer project and provider project * Rename new activity flags * Guild feature revamp and smart gateway intent checks * Get thread user implementation * Amend creating slash command guide (#269) * Adding BotHTTPInteraction user flag * Added comments explaining the Global command create stipulations. * Fix numeric type check for options * Add state checking to ConnectionManager.StartAsync (#272) * initial interface changes * Multi file upload + attachment editing * meta: bump versions * Update CHANGELOG.md * Update CHANGELOG.md * Support Min and Max values on ApplicationCommandOptions (#273) * Support Min and Max values on ApplicationCommandOptions * Support decimal min/max values * Docs imrpovments + use ToNullable * Logomark, doc settings edit (#258) * Logomark, doc settings edit * Replace standard logo * Bumping docfx plugins to latest release * Bump version metadata * Logo svg fix * Change default sticker behavior and add AlwaysResolveSticker to the config * Implement rest based interactions. Added ED25519 checks. Updated summaries. * Update package logo * Automatically fix ordering of optional command options (#276) * auto fix optional command option order * clean up indentation * Fix maximum number of Select Menu Options (#282) As of https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-menu-structure the maximum number of options is 25, not less than 25. Hopefully the change catches all necessary locations * Add voice region to modify voice channels * Update summaries on rest interactions * Interaction Specific Interfaces (#283) * added interaction specific interfaces * fix build error * implement change requests * Update application * Add Guild Scheduled Events (#279) * guild events initial * sharded events * Add new gateway intents and fix bugs * More work on new changes to guild events * Update guild scheduled events * Added events to extended guild and add event start event * Update preconditions * Implement breaking changes guild guild events. Add guild event permissions * Update tests and change privacy level requirements * Update summaries and add docs for guild events * meta: bump version * Increment meta version (#285) * Increment meta version * Update docfx.json * Fix #289 and add configureawaits to rest based interactions * meta: bump version * Add GUILD_SCHEDULED_EVENT_USER_ADD and GUILD_SCHEDULED_EVENT_USER_REMOVE (#287) * Remove newline * Fix autocomplete result value * meta: bump versions * Add `GuildScheduledEventUserAdd` and `GuildScheduledEventUserRemove` to sharded client * Make RestUserCommand public (#292) * Fix Components not showing on FUWF (#288) (#293) Adds Components to Payload JSON Generation * Implement smarter rest resolvable interaction data. Fixes #294 * Add UseInteractionSnowflakeDate to config #286 * Implement Better Discord Errors (#291) * Initial error parsing * Implement better errors * Add missing error codes * Add voice disconnect opcodes * Remove unused class, add summaries to discordjsonerror, and remove public constructor of slash command properties * Add error code summary * Update error message summary * Update src/Discord.Net.Core/DiscordJsonError.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Update src/Discord.Net.WebSocket/API/Voice/VoiceCloseCode.cs Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Fix autocomplete result value Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> * Change the minimum length of slash commands to 1 (#284) * Change the minimum length of slash commands to 1. This is the correct value according to the docs and it has been changed after user feedback. * Fix the limit in 3 other places Co-authored-by: quin lynch <lynchquin@gmail.com> * Add new thread creation properties * Add role emoji. Fixes #295 * Fix mocked text channel * Fix precondition checks. Closes #281 * Initial fix (#297) * meta: bump version * Update from release/3.x * Remove more labs references * Remove doc file for Discord.Net.Analyzers Co-authored-by: Simon Hjorthøj <sh2@live.dk> Co-authored-by: drobbins329 <drobbins329@gmail.com> Co-authored-by: MrCakeSlayer <13650699+MrCakeSlayer@users.noreply.github.com> Co-authored-by: d4n3436 <dan3436@hotmail.com> Co-authored-by: Will <WilliamWelsh@users.noreply.github.com> Co-authored-by: Eugene Garbuzov <kkxo.mail@gmail.com> Co-authored-by: CottageDwellingCat <80918250+CottageDwellingCat@users.noreply.github.com> Co-authored-by: Emily <89871431+emillly-b@users.noreply.github.com> Co-authored-by: marens101 <marens101@gmail.com> Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> Co-authored-by: Armano den Boef <68127614+Rozen4334@users.noreply.github.com> Co-authored-by: Bill <billchirico@gmail.com> Co-authored-by: Liege72 <65319395+Liege72@users.noreply.github.com> Co-authored-by: Floowey <floowey@gmx.at> Co-authored-by: Cenk Ergen <57065323+Cenngo@users.noreply.github.com> Co-authored-by: exsersewo <exsersewo@systemexit.co.uk> Co-authored-by: Dennis Fischer <fischer_dennis@live.de> commit3395700720Author: Nikon <47792796+INikonI@users.noreply.github.com> Date: Mon Aug 23 02:00:18 2021 +0500 feature: IVoiceChannel implements IMentionable (#1896) commit 41b4686b5e77cd9986006866b9ac7ac418bc05f2 Author: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Tue Aug 3 20:43:10 2021 -0300 Update README.md commit 5fc31451a1fafdc471acfe3a08269d371b20b70b Author: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Tue Aug 3 20:28:15 2021 -0300 Update README.md commit56d16397f7Author: roridev <t3ctotalmenterandom1@outlook.com> Date: Fri Nov 27 18:42:23 2020 -0300 Fixes Azure linux build failing due to a CS8652. commitc455b50331Author: roridev <t3ctotalmenterandom1@outlook.com> Date: Fri Nov 27 14:10:39 2020 -0300 Make use of new ValidateAndGetBestMatch api on ExecuteAsync commit7955a09090Author: roridev <t3ctotalmenterandom1@outlook.com> Date: Fri Nov 27 13:52:53 2020 -0300 Creates ValidateAndGetBestMatch function This function will validate all commands from a SearchResult and return the result of said validation, along with the command matched, if a valid match was found. commit574b503e9eAuthor: roridev <t3ctotalmenterandom1@outlook.com> Date: Fri Nov 27 13:38:00 2020 -0300 Moves CalculateScore function to outer scope. * Update from Discord.Net dev - fix merge conflicts * meta: .net6 support * meta: pipelines use .net 6 * meta: bump tests framework versions * Invoke SlashCommandExecuted event on failed type conversion (#314) * added interaction specific interfaces * fix build error * implement change requests * add autocomplete respond method to IAutocompleteInteraction * fix sharded client current user * fix generic typeconverter picking priority * Revert "fix sharded client current user" This reverts commit a9c15ffd6ab02651e83e72c275889502b60cfddc. * Revert "add autocomplete respond method to IAutocompleteInteraction" This reverts commit f2fc50f1f19a0b41144b6dc93080d2f3a01282fc. * fix command parsing for names with spaces * add SlashCommandExecuted event invoke to failed type conversion * update interactions sample app * Revert "update interactions sample app" This reverts commit 6ac8cd0da60b440874cf29abc7202cdc49fd0538. * meta: bump to exclusive net.5 and net6 versions Co-Authored-By: JT <Hawxy@users.noreply.github.com> * meta: bump versions * meta: add net461 support back * Add System.Collections.Immutable back to core * Fix presence NRE * meta: bump versions * Fix presence NRE again... * meta: bump version * Fix current user presence * meta: bump version * Fix NRE on service providerless command execution (#322) * fix not set to an instance of an object exception for service providerless command execution * add methods for manually registering global comands (#325) * fix dependency injection link in docs (#326) * Add back netstandard2.0 / 2.1. Closes #324 * meta: bump version * Add not supported exception on news channels when creating threads, #296 * Revert thread block for news channel. Add check for news channel Co-Authored-By: Nova Fox <novamaday@gmail.com> * Make autocomplete log virtual (#328) * Fix #300 again * Update GUILD_SCHEDULED_EVENT_CREATE (#330) Changed _guildScheduledEventCancelled to _guildScheduledEventCreated in GUILD_SCHEDULED_EVENT_CREATE * correct the number of allowed autocomplete choices (#333) * correct the number of allowed autocomplete choices (#334) * Add FollowupWithFileAsync to IDiscordInteraction (#336) * Add uppercase character check to SlashCommandBuilder and ApplicationCommandOptionProperties (#339) * Make IModuleBase and IInteractionModuleBase public (#341) * fix command validation (#335) * fix autocomplete command traversal and use IList<string> in command map instead of stirng[] (#342) * Refactor Interactions (#340) * Refactor Interactions * Remove ApplicationCommandException * Fix Module Preconditions (#343) * fix module preconditions * fix module preconditions * meta: bump version * Update autocomplete docs * Initial preps * Fix #347 This comit makes `Content` optional for webhook execution. This comit also adds null checks to content when creating the api args to properly specify the optional struct to the model. This is done so the message entity doesn't try to parse a null string. * Fix merge errors * meta: net5 and 6 support * Update README.md * meta: bump version * Trim SlashCommandInfo.ToString() (#346) Co-authored-by: TheStachelfisch <TheStachelfisch@users.noreply.github.com> * Ensure User Left Event (#349) * Update README.md * Add 50055 Error code (#352) Co-authored-by: quin lynch <lynchquin@gmail.com> * remove DeleteUnknownSlashCommandAck (#353) * [Robot] Add missing json error (#354) * Add 20029 Error code * Update DiscordErrorCode.cs Co-authored-by: Robot Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com> * Fix #355 and make UpdateAsync return a RestInteractionResponse * fix: unclear parameter naming for MessageCommand (#361) * Update DiscordRestApiClient.cs (#357) Add missing check to Content value to prevent NRE on empty message. Also made `ModifyInteractionFollowupMessageAsync`'s check consistent with `CreateInteractionFollowupMessageAsync` * Introduce emoji role property into rolehelper (#360) * Introduce emoji role property into rolehelper * Add check for exclusive properties * Oversight resolved * Valid order for error responses * Appending suggestions * Rename component to components (#363) * Adding BotHTTPInteraction user flag * change component -> components * added Interactions project * make SearchResult public (#365) * add missing coin emoji (#367) https://github.com/Discord-Net-Labs/Discord.Net-Labs/issues/364 * Add `IsAutocomplete` to rest command options (#368) * Make RestMessageComponent public (#369) * Docs rework, prep for merge into DNET (#359) * Appending previous changes * Deprecating unique feature listing & unused branch * Getting rid of old faq * Add all missed changelog entries This was painful :'') * Appending suggestions, large interior rework * Deleting unused entries * Removing more unused entries * Recover accidental deletion & append docfx file * Resolve a few docfx errors * Resolving more docfx errors * Clearing up final warnings * Appending suggestions * Removing main nightly for dnetlabs * Discord link updates * Add migration guide * Update v2_to_v3_guide.md * Fix spelling mistake Co-authored-by: quin lynch <lynchquin@gmail.com> * Update docFX plugins and xrefs * Add changelog and remove old docs Co-authored-by: Simon Hjorthøj <sh2@live.dk> Co-authored-by: Eugene Garbuzov <kkxo.mail@gmail.com> Co-authored-by: CottageDwellingCat <80918250+CottageDwellingCat@users.noreply.github.com> Co-authored-by: MrCakeSlayer <13650699+MrCakeSlayer@users.noreply.github.com> Co-authored-by: Will <WilliamWelsh@users.noreply.github.com> Co-authored-by: Emily <89871431+emillly-b@users.noreply.github.com> Co-authored-by: marens101 <marens101@gmail.com> Co-authored-by: d4n3436 <dan3436@hotmail.com> Co-authored-by: Jared L <48422312+lhjt@users.noreply.github.com> Co-authored-by: Armano den Boef <68127614+Rozen4334@users.noreply.github.com> Co-authored-by: Bill <billchirico@gmail.com> Co-authored-by: KeylAmi <drobbins329@gmail.com> Co-authored-by: Liege72 <65319395+Liege72@users.noreply.github.com> Co-authored-by: Floowey <floowey@gmx.at> Co-authored-by: Cenk Ergen <57065323+Cenngo@users.noreply.github.com> Co-authored-by: exsersewo <exsersewo@systemexit.co.uk> Co-authored-by: Dennis Fischer <fischer_dennis@live.de> Co-authored-by: PoolPirate <94938310+PoolPirate@users.noreply.github.com> Co-authored-by: Playwo <eliaswolf2001@t-online.de> Co-authored-by: JT <Hawxy@users.noreply.github.com> Co-authored-by: Nova Fox <novamaday@gmail.com> Co-authored-by: Daan van den Hoek <28300783+daanvandenhoek@users.noreply.github.com> Co-authored-by: nev-r <gh@f-m.fm> Co-authored-by: TheStachelfisch <50026847+TheStachelfisch@users.noreply.github.com> Co-authored-by: TheStachelfisch <TheStachelfisch@users.noreply.github.com> Co-authored-by: Discord-NET-Robot <95661365+Discord-NET-Robot@users.noreply.github.com> Co-authored-by: Xeno <eliotd@gmail.com>
@@ -0,0 +1,110 @@
|
||||
---
|
||||
uid: Guides.ContextCommands.Creating
|
||||
title: Creating Context Commands
|
||||
---
|
||||
|
||||
# Creating context menu commands.
|
||||
|
||||
There are two kinds of Context Menu Commands: User Commands and Message Commands.
|
||||
Each of these have a Global and Guild variant.
|
||||
Global menu commands are available for every guild that adds your app. An individual app's global commands are also available in DMs if that app has a bot that shares a mutual guild with the user.
|
||||
|
||||
Guild commands are specific to the guild you specify when making them. Guild commands are not available in DMs. Command names are unique per application within each scope (global and guild). That means:
|
||||
|
||||
- Your app cannot have two global commands with the same name
|
||||
- Your app cannot have two guild commands within the same name on the same guild
|
||||
- Your app can have a global and guild command with the same name
|
||||
- Multiple apps can have commands with the same names
|
||||
|
||||
[!IMPORTANT]
|
||||
> Apps can have a maximum of 5 global context menu commands,
|
||||
> and an additional 5 guild-specific context menu commands per guild.
|
||||
|
||||
## UserCommandBuilder
|
||||
|
||||
The context menu user command builder will help you create user commands. The builder has these available fields and methods:
|
||||
|
||||
| Name | Type | Description |
|
||||
| -------- | -------- | ------------------------------------------------------------------------------------------------ |
|
||||
| Name | string | The name of this context menu command. |
|
||||
| WithName | Function | Sets the field name. |
|
||||
| Build | Function | Builds the builder into the appropriate `UserCommandProperties` class used to make Menu commands |
|
||||
|
||||
## MessageCommandBuilder
|
||||
|
||||
The context menu message command builder will help you create message commands. The builder has these available fields and methods:
|
||||
|
||||
| Name | Type | Description |
|
||||
| -------- | -------- | --------------------------------------------------------------------------------------------------- |
|
||||
| Name | string | The name of this context menu command. |
|
||||
| WithName | Function | Sets the field name. |
|
||||
| Build | Function | Builds the builder into the appropriate `MessageCommandProperties` class used to make Menu commands |
|
||||
|
||||
> [!NOTE]
|
||||
> Context Menu command names can be upper and lowercase, and use spaces.
|
||||
> They cannot be registered pre-ready.
|
||||
|
||||
Let's use the user command builder to make a global and guild command.
|
||||
|
||||
```cs
|
||||
// Let's hook the ready event for creating our commands in.
|
||||
client.Ready += Client_Ready;
|
||||
|
||||
...
|
||||
|
||||
public async Task Client_Ready()
|
||||
{
|
||||
// Let's build a guild command! We're going to need a guild so lets just put that in a variable.
|
||||
var guild = client.GetGuild(guildId);
|
||||
|
||||
// Next, lets create our user and message command builder. This is like the embed builder but for context menu commands.
|
||||
var guildUserCommand = new UserCommandBuilder();
|
||||
var guildMessageCommand = new MessageCommandBuilder();
|
||||
|
||||
// Note: Names have to be all lowercase and match the regular expression ^[\w -]{3,32}$
|
||||
guildUserCommand.WithName("Guild User Command");
|
||||
guildMessageCommand.WithName("Guild Message Command");
|
||||
|
||||
// Descriptions are not used with User and Message commands
|
||||
//guildCommand.WithDescription("");
|
||||
|
||||
// Let's do our global commands
|
||||
var globalUserCommand = new UserCommandBuilder();
|
||||
globalCommand.WithName("Global User Command");
|
||||
var globalMessageCommand = new MessageCommandBuilder();
|
||||
globalMessageCommand.WithName("Global Message Command");
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// Now that we have our builder, we can call the BulkOverwriteApplicationCommandAsync to make our context commands. Note: this will overwrite all your previous commands with this array.
|
||||
await guild.BulkOverwriteApplicationCommandAsync(new ApplicationCommandProperties[]
|
||||
{
|
||||
guildUserCommand.Build(),
|
||||
guildMessageCommand.Build()
|
||||
});
|
||||
|
||||
// With global commands we dont need the guild.
|
||||
await client.BulkOverwriteGlobalApplicationCommandsAsync(new ApplicationCommandProperties[]
|
||||
{
|
||||
globalUserCommand.Build(),
|
||||
globalMessageCommand.Build()
|
||||
})
|
||||
}
|
||||
catch(ApplicationCommandException exception)
|
||||
{
|
||||
// If our command was invalid, we should catch an ApplicationCommandException. This exception contains the path of the error as well as the error message. You can serialize the Error field in the exception to get a visual of where your error is.
|
||||
var json = JsonConvert.SerializeObject(exception.Error, Formatting.Indented);
|
||||
|
||||
// You can send this error somewhere or just print it to the console, for this example we're just going to print it.
|
||||
Console.WriteLine(json);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Application commands only need to be created once. They do _not_ have to be
|
||||
> 'created' on every startup or connection.
|
||||
> The example simple shows creating them in the ready event
|
||||
> as it's simpler than creating normal bot commands to register application commands.
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
uid: Guides.ContextCommands.Reveiving
|
||||
title: Receiving Context Commands
|
||||
---
|
||||
|
||||
# Receiving Context Menu events
|
||||
|
||||
User commands and Message commands have their own unique event just like the other interaction types. For user commands the event is `UserCommandExecuted` and for message commands the event is `MessageCommandExecuted`.
|
||||
|
||||
```cs
|
||||
// For message commands
|
||||
client.MessageCommandExecuted += MessageCommandHandler;
|
||||
|
||||
// For user commands
|
||||
client.UserCommandExecuted += UserCommandHandler;
|
||||
|
||||
...
|
||||
|
||||
public async Task MessageCommandHandler(SocketMessageCommand arg)
|
||||
{
|
||||
Console.Writeline("Message command received!");
|
||||
}
|
||||
|
||||
public async Task UserCommandHandler(SocketUserCommand arg)
|
||||
{
|
||||
Console.Writeline("User command received!");
|
||||
}
|
||||
```
|
||||
|
||||
User commands contain a SocketUser object called `Member` in their data class, showing the user that was clicked to run the command.
|
||||
Message commands contain a SocketMessage object called `Message` in their data class, showing the message that was clicked to run the command.
|
||||
|
||||
Both return the user who ran the command, the guild (if any), channel, etc.
|
||||
51
docs/guides/int_basics/application-commands/intro.md
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
uid: Guides.SlashCommands.Intro
|
||||
title: Introduction to slash commands
|
||||
---
|
||||
|
||||
|
||||
# Getting started with application commands.
|
||||
|
||||
This guide will show you how to use application commands.
|
||||
If you have extra questions that aren't covered here you can come to our
|
||||
[Discord](https://discord.com/invite/dvSfUTet3K) server and ask around there.
|
||||
|
||||
## What is an application command?
|
||||
|
||||
Application commands consist of three different types. Slash commands, context menu User commands and context menu Message commands.
|
||||
Slash commands are made up of a name, description, and a block of options, which you can think of like arguments to a function.
|
||||
The name and description help users find your command among many others, and the options validate user input as they fill out your command.
|
||||
Message and User commands are only a name, to the user. So try to make the name descriptive.
|
||||
They're accessed by right clicking (or long press, on mobile) a user or a message, respectively.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Context menu commands are currently not supported on mobile.
|
||||
|
||||
All three varieties of application commands have both Global and Guild variants.
|
||||
Your global commands are available in every guild that adds your application.
|
||||
You can also make commands for a specific guild; they're only available in that guild.
|
||||
The User and Message commands are more limited in quantity than the slash commands.
|
||||
For specifics, check out their respective guide pages.
|
||||
|
||||
An Interaction is the message that your application receives when a user uses a command.
|
||||
It includes the values that the user submitted, as well as some metadata about this particular instance of the command being used:
|
||||
the guild_id,
|
||||
channel_id,
|
||||
member and other fields.
|
||||
You can find all the values in our data models.
|
||||
|
||||
## Authorizing your bot for application commands
|
||||
|
||||
There is a new special OAuth2 scope for applications called `applications.commands`.
|
||||
In order to make Application Commands work within a guild, the guild must authorize your application
|
||||
with the `applications.commands` scope. The bot scope is not enough.
|
||||
|
||||
Head over to your discord applications OAuth2 screen and make sure to select the `application.commands` scope.
|
||||
|
||||

|
||||
|
||||
From there you can then use the link to add your bot to a server.
|
||||
|
||||
> [!NOTE]
|
||||
> In order for users in your guild to use your slash commands, they need to have
|
||||
> the "Use Application Commands" permission on the guild.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
uid: Guides.SlashCommands.BulkOverwrite
|
||||
title: Slash Command Bulk Overwrites
|
||||
---
|
||||
|
||||
If you have too many global commands then you might want to consider using the bulk overwrite function.
|
||||
|
||||
```cs
|
||||
public async Task Client_Ready()
|
||||
{
|
||||
List<ApplicationCommandProperties> applicationCommandProperties = new();
|
||||
try
|
||||
{
|
||||
// Simple help slash command.
|
||||
SlashCommandBuilder globalCommandHelp = new SlashCommandBuilder();
|
||||
globalCommandHelp.WithName("help");
|
||||
globalCommandHelp.WithDescription("Shows information about the bot.");
|
||||
applicationCommandProperties.Add(globalCommandHelp.Build());
|
||||
|
||||
// Slash command with name as its parameter.
|
||||
SlashCommandOptionBuilder slashCommandOptionBuilder = new();
|
||||
slashCommandOptionBuilder.WithName("name");
|
||||
slashCommandOptionBuilder.WithType(ApplicationCommandOptionType.String);
|
||||
slashCommandOptionBuilder.WithDescription("Add a family");
|
||||
slashCommandOptionBuilder.WithRequired(true); // Only add this if you want it to be required
|
||||
|
||||
SlashCommandBuilder globalCommandAddFamily = new SlashCommandBuilder();
|
||||
globalCommandAddFamily.WithName("add-family");
|
||||
globalCommandAddFamily.WithDescription("Add a family");
|
||||
applicationCommandProperties.Add(globalCommandAddFamily.Build());
|
||||
|
||||
await _client.BulkOverwriteGlobalApplicationCommandsAsync(applicationCommandProperties.ToArray());
|
||||
}
|
||||
catch (ApplicationCommandException exception)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(exception.Error, Formatting.Indented);
|
||||
Console.WriteLine(json);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
uid: Guides.SlashCommands.Choices
|
||||
title: Slash Command Choices
|
||||
---
|
||||
|
||||
# Slash Command Choices.
|
||||
|
||||
With slash command options you can add choices, making the user select between some set values. Lets create a command that asks how much they like our bot!
|
||||
|
||||
Let's set up our slash command:
|
||||
|
||||
```cs
|
||||
private async Task Client_Ready()
|
||||
{
|
||||
ulong guildId = 848176216011046962;
|
||||
|
||||
var guildCommand = new SlashCommandBuilder()
|
||||
.WithName("feedback")
|
||||
.WithDescription("Tell us how much you are enjoying this bot!")
|
||||
.AddOption(new SlashCommandOptionBuilder()
|
||||
.WithName("rating")
|
||||
.WithDescription("The rating your willing to give our bot")
|
||||
.WithRequired(true)
|
||||
.AddChoice("Terrible", 1)
|
||||
.AddChoice("Meh", 2)
|
||||
.AddChoice("Good", 3)
|
||||
.AddChoice("Lovely", 4)
|
||||
.AddChoice("Excellent!", 5)
|
||||
.WithType(ApplicationCommandOptionType.Integer)
|
||||
).Build();
|
||||
|
||||
try
|
||||
{
|
||||
await client.Rest.CreateGuildCommand(guildCommand.Build(), guildId);
|
||||
}
|
||||
catch(ApplicationCommandException exception)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(exception.Error, Formatting.Indented);
|
||||
Console.WriteLine(json);
|
||||
}
|
||||
}
|
||||
```
|
||||
> [!NOTE]
|
||||
> Your `ApplicationCommandOptionType` specifies which type your choices are, you need to use `ApplicationCommandOptionType.Integer` for choices whos values are whole numbers, `ApplicationCommandOptionType.Number` for choices whos values are doubles, and `ApplicationCommandOptionType.String` for string values.
|
||||
|
||||
We have defined 5 choices for the user to pick from, each choice has a value assigned to it. The value can either be a string or an int. In our case we're going to use an int. This is what the command looks like:
|
||||
|
||||

|
||||
|
||||
Lets add our code for handling the interaction.
|
||||
|
||||
```cs
|
||||
private async Task SlashCommandHandler(SocketSlashCommand command)
|
||||
{
|
||||
// Let's add a switch statement for the command name so we can handle multiple commands in one event.
|
||||
switch(command.Data.Name)
|
||||
{
|
||||
case "list-roles":
|
||||
await HandleListRoleCommand(command);
|
||||
break;
|
||||
case "settings":
|
||||
await HandleSettingsCommand(command);
|
||||
break;
|
||||
case "feedback":
|
||||
await HandleFeedbackCommand(command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleFeedbackCommand(SocketSlashCommand command)
|
||||
{
|
||||
var embedBuilder = new EmbedBuilder()
|
||||
.WithAuthor(command.User)
|
||||
.WithTitle("Feedback")
|
||||
.WithDescription($"Thanks for your feedback! You rated us {command.Data.Options.First().Value}/5")
|
||||
.WithColor(Color.Green)
|
||||
.WithCurrentTimestamp();
|
||||
|
||||
await command.RespondAsync(embed: embedBuilder.Build());
|
||||
}
|
||||
```
|
||||
|
||||
And this is the result:
|
||||
|
||||

|
||||
@@ -0,0 +1,98 @@
|
||||
---
|
||||
uid: Guides.SlashCommands.Creating
|
||||
title: Creating Slash Commands
|
||||
---
|
||||
|
||||
# Creating your first slash commands.
|
||||
|
||||
There are two kinds of Slash Commands: global commands and guild commands.
|
||||
Global commands are available for every guild that adds your app. An individual app's global commands are also available in DMs if that app has a bot that shares a mutual guild with the user.
|
||||
|
||||
Guild commands are specific to the guild you specify when making them. Guild commands are not available in DMs. Command names are unique per application within each scope (global and guild). That means:
|
||||
|
||||
- Your app cannot have two global commands with the same name
|
||||
- Your app cannot have two guild commands within the same name on the same guild
|
||||
- Your app can have a global and guild command with the same name
|
||||
- Multiple apps can have commands with the same names
|
||||
|
||||
**Note**: Apps can have a maximum of 100 global commands, and an additional 100 guild-specific commands per guild.
|
||||
|
||||
**Note**: Global commands will take up to 1 hour to create, delete or modify on guilds. If you need to update a command quickly for testing you can create it as a guild command.
|
||||
|
||||
If you don't have the code for a bot ready yet please follow [this guide](https://docs.stillu.cc/guides/getting_started/first-bot.html).
|
||||
|
||||
## SlashCommandBuilder
|
||||
|
||||
The slash command builder will help you create slash commands. The builder has these available fields and methods:
|
||||
|
||||
| Name | Type | Description |
|
||||
| --------------------- | -------------------------------- | -------------------------------------------------------------------------------------------- |
|
||||
| MaxNameLength | const int | The maximum length of a name for a slash command allowed by Discord. |
|
||||
| MaxDescriptionLength | const int | The maximum length of a commands description allowed by Discord. |
|
||||
| MaxOptionsCount | const int | The maximum count of command options allowed by Discord |
|
||||
| Name | string | The name of this slash command. |
|
||||
| Description | string | A 1-100 length description of this slash command |
|
||||
| Options | List\<SlashCommandOptionBuilder> | The options for this command. |
|
||||
| DefaultPermission | bool | Whether the command is enabled by default when the app is added to a guild. |
|
||||
| WithName | Function | Sets the field name. |
|
||||
| WithDescription | Function | Sets the description of the current command. |
|
||||
| WithDefaultPermission | Function | Sets the default permission of the current command. |
|
||||
| AddOption | Function | Adds an option to the current slash command. |
|
||||
| Build | Function | Builds the builder into a `SlashCommandCreationProperties` class used to make slash commands |
|
||||
|
||||
> [!NOTE]
|
||||
> Slash command names must be all lowercase!
|
||||
|
||||
## Creating a Slash Command
|
||||
|
||||
Let's use the slash command builder to make a global and guild command.
|
||||
|
||||
```cs
|
||||
// Let's hook the ready event for creating our commands in.
|
||||
client.Ready += Client_Ready;
|
||||
|
||||
...
|
||||
|
||||
public async Task Client_Ready()
|
||||
{
|
||||
// Let's build a guild command! We're going to need a guild so lets just put that in a variable.
|
||||
var guild = client.GetGuild(guildId);
|
||||
|
||||
// Next, lets create our slash command builder. This is like the embed builder but for slash commands.
|
||||
var guildCommand = new SlashCommandBuilder();
|
||||
|
||||
// Note: Names have to be all lowercase and match the regular expression ^[\w-]{3,32}$
|
||||
guildCommand.WithName("first-command");
|
||||
|
||||
// Descriptions can have a max length of 100.
|
||||
guildCommand.WithDescription("This is my first guild slash command!");
|
||||
|
||||
// Let's do our global command
|
||||
var globalCommand = new SlashCommandBuilder();
|
||||
globalCommand.WithName("first-global-command");
|
||||
globalCommand.WithDescription("This is my frist global slash command");
|
||||
|
||||
try
|
||||
{
|
||||
// Now that we have our builder, we can call the CreateApplicationCommandAsync method to make our slash command.
|
||||
await guild.CreateApplicationCommandAsync(guildCommand.Build());
|
||||
|
||||
// With global commands we dont need the guild.
|
||||
await client.CreateGlobalApplicationCommandAsync(globalCommand.Build());
|
||||
// Using the ready event is a simple implementation for the sake of the example. Suitable for testing and development.
|
||||
// For a production bot, it is recommended to only run the CreateGlobalApplicationCommandAsync() once for each command.
|
||||
}
|
||||
catch(ApplicationCommandException exception)
|
||||
{
|
||||
// If our command was invalid, we should catch an ApplicationCommandException. This exception contains the path of the error as well as the error message. You can serialize the Error field in the exception to get a visual of where your error is.
|
||||
var json = JsonConvert.SerializeObject(exception.Error, Formatting.Indented);
|
||||
|
||||
// You can send this error somewhere or just print it to the console, for this example we're just going to print it.
|
||||
Console.WriteLine(json);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Slash commands only need to be created once. They do _not_ have to be 'created' on every startup or connection. The example simple shows creating them in the ready event as it's simpler than creating normal bot commands to register slash commands. The global commands take up to an hour to register every time the CreateGlobalApplicationCommandAsync() is called for a given command.
|
||||
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,102 @@
|
||||
---
|
||||
uid: Guides.SlashCommands.Parameters
|
||||
title: Slash Command Parameters
|
||||
---
|
||||
|
||||
# Slash command parameters
|
||||
|
||||
Slash commands can have a bunch of parameters, each their own type. Let's first go over the types of parameters we can have.
|
||||
|
||||
| Name | Description |
|
||||
| --------------- | -------------------------------------------------- |
|
||||
| SubCommand | A subcommand inside of a subcommand group. |
|
||||
| SubCommandGroup | The parent command group of subcommands. |
|
||||
| String | A string of text. |
|
||||
| Integer | A number. |
|
||||
| Boolean | True or False. |
|
||||
| User | A user |
|
||||
| Channel | A channel, this includes voice text and categories |
|
||||
| Role | A role. |
|
||||
| Mentionable | A role or a user. |
|
||||
|
||||
Each one of the parameter types has its own DNET type in the `SocketSlashCommandDataOption`'s Value field:
|
||||
| Name | C# Type |
|
||||
| --------------- | ------------------------------------------------ |
|
||||
| SubCommand | NA |
|
||||
| SubCommandGroup | NA |
|
||||
| String | `string` |
|
||||
| Integer | `int` |
|
||||
| Boolean | `bool` |
|
||||
| User | `SocketGuildUser` or `SocketUser` |
|
||||
| Role | `SocketRole` |
|
||||
| Channel | `SocketChannel` |
|
||||
| Mentionable | `SocketUser`, `SocketGuildUser`, or `SocketRole` |
|
||||
|
||||
Let's start by making a command that takes in a user and lists their roles.
|
||||
|
||||
```cs
|
||||
client.Ready += Client_Ready;
|
||||
|
||||
...
|
||||
|
||||
public async Task Client_Ready()
|
||||
{
|
||||
ulong guildId = 848176216011046962;
|
||||
|
||||
var guildCommand = new SlashCommandBuilder()
|
||||
.WithName("list-roles")
|
||||
.WithDescription("Lists all roles of a user.")
|
||||
.AddOption("user", ApplicationCommandOptionType.User, "The users whos roles you want to be listed", isRequired: true);
|
||||
|
||||
try
|
||||
{
|
||||
await client.Rest.CreateGuildCommand(guildCommand.Build(), guildId);
|
||||
}
|
||||
catch(ApplicationCommandException exception)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(exception.Error, Formatting.Indented);
|
||||
Console.WriteLine(json);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||

|
||||
|
||||
That seems to be working, now Let's handle the interaction.
|
||||
|
||||
```cs
|
||||
private async Task SlashCommandHandler(SocketSlashCommand command)
|
||||
{
|
||||
// Let's add a switch statement for the command name so we can handle multiple commands in one event.
|
||||
switch(command.Data.Name)
|
||||
{
|
||||
case "list-roles":
|
||||
await HandleListRoleCommand(command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleListRoleCommand(SocketSlashCommand command)
|
||||
{
|
||||
// We need to extract the user parameter from the command. since we only have one option and it's required, we can just use the first option.
|
||||
var guildUser = (SocketGuildUser)command.Data.Options.First().Value;
|
||||
|
||||
// We remove the everyone role and select the mention of each role.
|
||||
var roleList = string.Join(",\n", guildUser.Roles.Where(x => !x.IsEveryone).Select(x => x.Mention));
|
||||
|
||||
var embedBuiler = new EmbedBuilder()
|
||||
.WithAuthor(guildUser.ToString(), guildUser.GetAvatarUrl() ?? guildUser.GetDefaultAvatarUrl())
|
||||
.WithTitle("Roles")
|
||||
.WithDescription(roleList)
|
||||
.WithColor(Color.Green)
|
||||
.WithCurrentTimestamp();
|
||||
|
||||
// Now, Let's respond with the embed.
|
||||
await command.RespondAsync(embed: embedBuiler.Build());
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
That has worked! Next, we will go over responding ephemerally.
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
uid: Guides.SlashCommands.Ephemeral
|
||||
title: Ephemeral Responses
|
||||
---
|
||||
|
||||
# Responding ephemerally
|
||||
|
||||
What is an ephemeral response? Basically, only the user who executed the command can see the result of it, this is pretty simple to implement.
|
||||
|
||||
> [!NOTE]
|
||||
> You don't have to run arg.DeferAsync() to capture the interaction, you can use arg.RespondAsync() with a message to capture it, this also follows the ephemeral rule.
|
||||
|
||||
When responding with either `FollowupAsync` or `RespondAsync` you can pass in an `ephemeral` property. When setting it to true it will respond ephemerally, false and it will respond non-ephemerally.
|
||||
|
||||
Let's use this in our list role command.
|
||||
|
||||
```cs
|
||||
await command.RespondAsync(embed: embedBuiler.Build(), ephemeral: true);
|
||||
```
|
||||
|
||||
Running the command now only shows the message to us!
|
||||
|
||||

|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
uid: Guides.SlashCommands.Receiving
|
||||
title: Receiving and Responding to Slash Commands
|
||||
---
|
||||
|
||||
# Responding to interactions.
|
||||
|
||||
Interactions are the base thing sent over by Discord. Slash commands are one of the interaction types. We can listen to the `SlashCommandExecuted` event to respond to them. Lets add this to our code:
|
||||
|
||||
```cs
|
||||
client.SlashCommandExecuted += SlashCommandHandler;
|
||||
|
||||
...
|
||||
|
||||
private async Task SlashCommandHandler(SocketSlashCommand command)
|
||||
{
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
With every type of interaction there is a `Data` field. This is where the relevant information lives about our command that was executed. In our case, `Data` is a `SocketSlashCommandData` instance. In the data class, we can access the name of the command triggered as well as the options if there were any. For this example, we're just going to respond with the name of the command executed.
|
||||
|
||||
```cs
|
||||
private async Task SlashCommandHandler(SocketSlashCommand command)
|
||||
{
|
||||
await command.RespondAsync($"You executed {command.Data.Name}");
|
||||
}
|
||||
```
|
||||
|
||||
Let's try this out!
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
> [!NOTE]
|
||||
> After receiving an interaction, you must respond to acknowledge it. You can choose to respond with a message immediately using `RespondAsync()` or you can choose to send a deferred response with `DeferAsync()`.
|
||||
> If choosing a deferred response, the user will see a loading state for the interaction, and you'll have up to 15 minutes to edit the original deferred response using `ModifyOriginalResponseAsync()`. You can read more about response types [here](https://discord.com/developers/docs/interactions/slash-commands#interaction-response)
|
||||
|
||||
This seems to be working! Next, we will look at parameters for slash commands.
|
||||
@@ -0,0 +1,219 @@
|
||||
---
|
||||
uid: Guides.SlashCommands.SubCommand
|
||||
title: Sub Commands
|
||||
---
|
||||
|
||||
# Subcommands
|
||||
|
||||
Subcommands allow you to have multiple commands available in a single command. They can be useful for representing sub options for a command. For example: A settings command. Let's first look at some limitations with subcommands set by discord.
|
||||
|
||||
- An app can have up to 25 subcommand groups on a top-level command
|
||||
- An app can have up to 25 subcommands within a subcommand group
|
||||
- commands can have up to 25 `options`
|
||||
- options can have up to 25 `choices`
|
||||
|
||||
```
|
||||
VALID
|
||||
|
||||
command
|
||||
|
|
||||
|__ subcommand
|
||||
|
|
||||
|__ subcommand
|
||||
|
||||
----
|
||||
|
||||
command
|
||||
|
|
||||
|__ subcommand-group
|
||||
|
|
||||
|__ subcommand
|
||||
|
|
||||
|__ subcommand-group
|
||||
|
|
||||
|__ subcommand
|
||||
|
||||
|
||||
-------
|
||||
|
||||
INVALID
|
||||
|
||||
|
||||
command
|
||||
|
|
||||
|__ subcommand-group
|
||||
|
|
||||
|__ subcommand-group
|
||||
|
|
||||
|__ subcommand-group
|
||||
|
|
||||
|__ subcommand-group
|
||||
|
||||
----
|
||||
|
||||
INVALID
|
||||
|
||||
command
|
||||
|
|
||||
|__ subcommand
|
||||
|
|
||||
|__ subcommand-group
|
||||
|
|
||||
|__ subcommand
|
||||
|
|
||||
|__ subcommand-group
|
||||
```
|
||||
|
||||
Let's write a settings command that can change 3 fields in our bot.
|
||||
|
||||
```cs
|
||||
public string FieldA { get; set; } = "test";
|
||||
public int FieldB { get; set; } = 10;
|
||||
public bool FieldC { get; set; } = true;
|
||||
|
||||
public async Task Client_Ready()
|
||||
{
|
||||
ulong guildId = 848176216011046962;
|
||||
|
||||
var guildCommand = new SlashCommandBuilder()
|
||||
.WithName("settings")
|
||||
.WithDescription("Changes some settings within the bot.")
|
||||
.AddOption(new SlashCommandOptionBuilder()
|
||||
.WithName("field-a")
|
||||
.WithDescription("Gets or sets the field A")
|
||||
.WithType(ApplicationCommandOptionType.SubCommandGroup)
|
||||
.AddOption(new SlashCommandOptionBuilder()
|
||||
.WithName("set")
|
||||
.WithDescription("Sets the field A")
|
||||
.WithType(ApplicationCommandOptionType.SubCommand)
|
||||
.AddOption("value", ApplicationCommandOptionType.String, "the value to set the field", isRequired: true)
|
||||
).AddOption(new SlashCommandOptionBuilder()
|
||||
.WithName("get")
|
||||
.WithDescription("Gets the value of field A.")
|
||||
.WithType(ApplicationCommandOptionType.SubCommand)
|
||||
)
|
||||
).AddOption(new SlashCommandOptionBuilder()
|
||||
.WithName("field-b")
|
||||
.WithDescription("Gets or sets the field B")
|
||||
.WithType(ApplicationCommandOptionType.SubCommandGroup)
|
||||
.AddOption(new SlashCommandOptionBuilder()
|
||||
.WithName("set")
|
||||
.WithDescription("Sets the field B")
|
||||
.WithType(ApplicationCommandOptionType.SubCommand)
|
||||
.AddOption("value", ApplicationCommandOptionType.Integer, "the value to set the fie to.", isRequired: true)
|
||||
).AddOption(new SlashCommandOptionBuilder()
|
||||
.WithName("get")
|
||||
.WithDescription("Gets the value of field B.")
|
||||
.WithType(ApplicationCommandOptionType.SubCommand)
|
||||
)
|
||||
).AddOption(new SlashCommandOptionBuilder()
|
||||
.WithName("field-c")
|
||||
.WithDescription("Gets or sets the field C")
|
||||
.WithType(ApplicationCommandOptionType.SubCommandGroup)
|
||||
.AddOption(new SlashCommandOptionBuilder()
|
||||
.WithName("set")
|
||||
.WithDescription("Sets the field C")
|
||||
.WithType(ApplicationCommandOptionType.SubCommand)
|
||||
.AddOption("value", ApplicationCommandOptionType.Boolean, "the value to set the fie to.", isRequired: true)
|
||||
).AddOption(new SlashCommandOptionBuilder()
|
||||
.WithName("get")
|
||||
.WithDescription("Gets the value of field C.")
|
||||
.WithType(ApplicationCommandOptionType.SubCommand)
|
||||
)
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
await client.Rest.CreateGuildCommand(guildCommand.Build(), guildId);
|
||||
}
|
||||
catch(ApplicationCommandException exception)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(exception.Error, Formatting.Indented);
|
||||
Console.WriteLine(json);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
All that code generates a command that looks like this:
|
||||

|
||||
|
||||
Now that we have our command made, we need to handle the multiple options with this command. So lets add this into our handler:
|
||||
|
||||
```cs
|
||||
private async Task SlashCommandHandler(SocketSlashCommand command)
|
||||
{
|
||||
// Let's add a switch statement for the command name so we can handle multiple commands in one event.
|
||||
switch(command.Data.Name)
|
||||
{
|
||||
case "list-roles":
|
||||
await HandleListRoleCommand(command);
|
||||
break;
|
||||
case "settings":
|
||||
await HandleSettingsCommand(command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleSettingsCommand(SocketSlashCommand command)
|
||||
{
|
||||
// First lets extract our variables
|
||||
var fieldName = command.Data.Options.First().Name;
|
||||
var getOrSet = command.Data.Options.First().Options.First().Name;
|
||||
// Since there is no value on a get command, we use the ? operator because "Options" can be null.
|
||||
var value = command.Data.Options.First().Options.First().Options?.FirstOrDefault().Value;
|
||||
|
||||
switch (fieldName)
|
||||
{
|
||||
case "field-a":
|
||||
{
|
||||
if(getOrSet == "get")
|
||||
{
|
||||
await command.RespondAsync($"The value of `field-a` is `{FieldA}`");
|
||||
}
|
||||
else if (getOrSet == "set")
|
||||
{
|
||||
this.FieldA = (string)value;
|
||||
await command.RespondAsync($"`field-a` has been set to `{FieldA}`");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "field-b":
|
||||
{
|
||||
if (getOrSet == "get")
|
||||
{
|
||||
await command.RespondAsync($"The value of `field-b` is `{FieldB}`");
|
||||
}
|
||||
else if (getOrSet == "set")
|
||||
{
|
||||
this.FieldB = (int)value;
|
||||
await command.RespondAsync($"`field-b` has been set to `{FieldB}`");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "field-c":
|
||||
{
|
||||
if (getOrSet == "get")
|
||||
{
|
||||
await command.RespondAsync($"The value of `field-c` is `{FieldC}`");
|
||||
}
|
||||
else if (getOrSet == "set")
|
||||
{
|
||||
this.FieldC = (bool)value;
|
||||
await command.RespondAsync($"`field-c` has been set to `{FieldC}`");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Now, let's try this out! Running the 3 get commands seems to get the default values we set.
|
||||
|
||||

|
||||
|
||||
Now let's try changing each to a different value.
|
||||
|
||||

|
||||
|
||||
That has worked! Next, let't look at choices in commands.
|
||||
10
docs/guides/int_basics/intro.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
uid: Guides.Interactions.Intro
|
||||
title: Introduction to Interactions
|
||||
---
|
||||
|
||||
# Interactions
|
||||
|
||||
Placeholder text does the brrr.
|
||||
|
||||
Links to different sections of guides: msg comp / slash commands.
|
||||
87
docs/guides/int_basics/message-components/advanced.md
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
uid: Guides.MessageComponents.Advanced
|
||||
title: Advanced Concepts
|
||||
---
|
||||
|
||||
# Advanced
|
||||
|
||||
Lets say you have some components on an ephemeral slash command, and you want to modify the message that the button is on. The issue with this is that ephemeral messages are not stored and can not be get via rest or other means.
|
||||
|
||||
Luckily, Discord thought of this and introduced a way to modify them with interactions.
|
||||
|
||||
### Using the UpdateAsync method
|
||||
|
||||
Components come with an `UpdateAsync` method that can update the message that the component was on. You can use it like a `ModifyAsync` method.
|
||||
|
||||
Lets use it with a command, we first create our command, in this example im just going to use a message command:
|
||||
|
||||
```cs
|
||||
var command = new MessageCommandBuilder()
|
||||
.WithName("testing").Build();
|
||||
|
||||
await client.GetGuild(guildId).BulkOverwriteApplicationCommandAsync(new [] { command, buttonCommand });
|
||||
```
|
||||
|
||||
Next, we listen for this command, and respond with some components when its used:
|
||||
|
||||
```cs
|
||||
var menu = new SelectMenuBuilder()
|
||||
{
|
||||
CustomId = "select-1",
|
||||
Placeholder = "Select Somthing!",
|
||||
MaxValues = 1,
|
||||
MinValues = 1,
|
||||
};
|
||||
|
||||
menu.AddOption("Meh", "1", "Its not gaming.")
|
||||
.AddOption("Ish", "2", "Some would say that this is gaming.")
|
||||
.AddOption("Moderate", "3", "It could pass as gaming")
|
||||
.AddOption("Confirmed", "4", "We are gaming")
|
||||
.AddOption("Excellent", "5", "It is renowned as gaming nation wide", new Emoji("🔥"));
|
||||
|
||||
var components = new ComponentBuilder()
|
||||
.WithSelectMenu(menu);
|
||||
|
||||
|
||||
await arg.RespondAsync("On a scale of one to five, how gaming is this?", component: componBuild(), ephemeral: true);
|
||||
break;
|
||||
```
|
||||
|
||||
Now, let's listen to the select menu executed event and add a case for `select-1`
|
||||
|
||||
```cs
|
||||
client.SelectMenuExecuted += SelectMenuHandler;
|
||||
|
||||
...
|
||||
|
||||
public async Task SelectMenuHandler(SocketMessageComponent arg)
|
||||
{
|
||||
switch (arg.Data.CustomId)
|
||||
{
|
||||
case "select-1":
|
||||
var value = arg.Data.Values.First();
|
||||
var menu = new SelectMenuBuilder()
|
||||
{
|
||||
CustomId = "select-1",
|
||||
Placeholder = $"{(arg.Message.Components.First().Components.First() as SelectMenu).Options.FirstOrDefault(x => x.Value == value).Label}",
|
||||
MaxValues = 1,
|
||||
MinValues = 1,
|
||||
Disabled = true
|
||||
};
|
||||
|
||||
menu.AddOption("Meh", "1", "Its not gaming.")
|
||||
.AddOption("Ish", "2", "Some would say that this is gaming.")
|
||||
.AddOption("Moderate", "3", "It could pass as gaming")
|
||||
.AddOption("Confirmed", "4", "We are gaming")
|
||||
.AddOption("Excellent", "5", "It is renowned as gaming nation wide", new Emoji("🔥"));
|
||||
|
||||
// We use UpdateAsync to update the message and its original content and components.
|
||||
await arg.UpdateAsync(x =>
|
||||
{
|
||||
x.Content = $"Thank you {arg.User.Mention} for rating us {value}/5 on the gaming scale";
|
||||
x.Components = new ComponentBuilder().WithSelectMenu(menu).Build();
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
uid: Guides.MessageComponents.Buttons
|
||||
title: Buttons in Depth
|
||||
---
|
||||
|
||||
# Buttons in depth
|
||||
|
||||
There are many changes you can make to buttons, lets take a look at the parameters in the `WithButton` function"
|
||||
| Name | Type | Description |
|
||||
|----------|---------------|----------------------------------------------------------------|
|
||||
| label | `string` | The label text for the button. |
|
||||
| customId | `string` | The custom id of the button. |
|
||||
| style | `ButtonStyle` | The style of the button. |
|
||||
| emote | `IEmote` | A IEmote to be used with this button. |
|
||||
| url | `string` | A URL to be used only if the `ButtonStyle` is a Link. |
|
||||
| disabled | `bool` | Whether or not the button is disabled. |
|
||||
| row | `int` | The row to place the button if it has enough room, otherwise 0 |
|
||||
|
||||
### Label
|
||||
|
||||
This is the front facing text that the user sees. The maximum length is 80 characters.
|
||||
|
||||
### CustomId
|
||||
|
||||
This is the property sent to you by discord when a button is clicked. It is not required for link buttons as they do not emit an event. The maximum length is 100 characters.
|
||||
|
||||
### Style
|
||||
|
||||
Styling your buttons are important for indicating different actions:
|
||||
|
||||

|
||||
|
||||
You can do this by using the `ButtonStyle` which has all the styles defined.
|
||||
|
||||
### Emote
|
||||
|
||||
You can specify an `IEmote` when creating buttons to add them to your button. They have the same restrictions as putting guild based emotes in messages.
|
||||
|
||||
### Url
|
||||
|
||||
If you use the link style with your button you can specify a url. When this button is clicked the user is taken to that url.
|
||||
|
||||
### Disabled
|
||||
|
||||
You can specify if your button is disabled, meaning users won't be able to click on it.
|
||||
BIN
docs/guides/int_basics/message-components/images/image1.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
docs/guides/int_basics/message-components/images/image2.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
docs/guides/int_basics/message-components/images/image3.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
docs/guides/int_basics/message-components/images/image4.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
docs/guides/int_basics/message-components/images/image5.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
docs/guides/int_basics/message-components/images/image6.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
66
docs/guides/int_basics/message-components/intro.md
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
uid: Guides.MessageComponents.Intro
|
||||
title: Getting Started with Components
|
||||
---
|
||||
|
||||
# Message Components
|
||||
|
||||
Message components are a framework for adding interactive elements to a message your app or bot sends. They're accessible, customizable, and easy to use.
|
||||
|
||||
## What is a Component
|
||||
|
||||
Components are a new parameter you can use when sending messages with your bot. There are currently 2 different types of components you can use: Buttons and Select Menus.
|
||||
|
||||
## Creating components
|
||||
|
||||
Lets create a simple component that has a button. First thing we need is a way to trigger the message, this can be done via commands or simply a ready event. Lets make a command that triggers our button message.
|
||||
|
||||
```cs
|
||||
[Command("spawner")]
|
||||
public async Task Spawn()
|
||||
{
|
||||
// Reply with some components
|
||||
}
|
||||
```
|
||||
|
||||
We now have our command, but we need to actually send the buttons with the command. To do that, lets look at the `ComponentBuilder` class:
|
||||
|
||||
| Name | Description |
|
||||
| ---------------- | --------------------------------------------------------------------------- |
|
||||
| `FromMessage` | Creates a new builder from a message. |
|
||||
| `FromComponents` | Creates a new builder from the provided list of components. |
|
||||
| `WithSelectMenu` | Adds a `SelectMenuBuilder` to the `ComponentBuilder` at the specific row. |
|
||||
| `WithButton` | Adds a `ButtonBuilder` to the `ComponentBuilder` at the specific row. |
|
||||
| `Build` | Builds this builder into a `MessageComponent` used to send your components. |
|
||||
|
||||
We see that we can use the `WithButton` function so lets do that. looking at its parameters it takes:
|
||||
|
||||
- `label` - The display text of the button.
|
||||
- `customId` - The custom id of the button, this is whats sent by discord when your button is clicked.
|
||||
- `style` - The discord defined style of the button.
|
||||
- `emote` - An emote to be displayed with the button.
|
||||
- `url` - The url of the button if its a link button.
|
||||
- `disabled` - Whether or not the button is disabled.
|
||||
- `row` - The row the button will occupy.
|
||||
|
||||
Since were just making a busic button, we dont have to specify anything else besides the label and custom id.
|
||||
|
||||
```cs
|
||||
var builder = new ComponentBuilder()
|
||||
.WithButton("label", "custom-id");
|
||||
```
|
||||
|
||||
Lets add this to our command:
|
||||
|
||||
```cs
|
||||
[Command("spawner")]
|
||||
public async Task Spawn()
|
||||
{
|
||||
var builder = new ComponentBuilder()
|
||||
.WithButton("label", "custom-id");
|
||||
|
||||
await ReplyAsync("Here is a button!", components: builder.Build());
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
uid: Guides.MessageComponents.Responding
|
||||
title: Responding to Components
|
||||
---
|
||||
|
||||
# Responding to button clicks
|
||||
|
||||
Responding to buttons is pretty simple, there are a couple ways of doing it and we can cover both.
|
||||
|
||||
### Method 1: Hooking the InteractionCreated Event
|
||||
|
||||
We can hook the `ButtonExecuted` event for button type interactions:
|
||||
|
||||
```cs
|
||||
client.ButtonExecuted += MyButtonHandler;
|
||||
```
|
||||
|
||||
Now, lets write our handler.
|
||||
|
||||
```cs
|
||||
public async Task MyButtonHandler(SocketMessageComponent component)
|
||||
{
|
||||
// We can now check for our custom id
|
||||
switch(component.Data.CustomId)
|
||||
{
|
||||
// Since we set our buttons custom id as 'custom-id', we can check for it like this:
|
||||
case "custom-id":
|
||||
// Lets respond by sending a message saying they clicked the button
|
||||
await component.RespondAsync($"{component.User.Mention} has clicked the button!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Running it and clicking the button:
|
||||
|
||||

|
||||
76
docs/guides/int_basics/message-components/select-menus.md
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
uid: Guides.MessageComponents.SelectMenus
|
||||
title: Select Menus
|
||||
---
|
||||
|
||||
# Select menus
|
||||
|
||||
Select menus allow users to select from a range of options, this can be quite useful with configuration commands etc.
|
||||
|
||||
## Creating a select menu
|
||||
|
||||
We can use a `SelectMenuBuilder` to create our menu.
|
||||
|
||||
```cs
|
||||
var menuBuilder = new SelectMenuBuilder()
|
||||
.WithPlaceholder("Select an option")
|
||||
.WithCustomId("menu-1")
|
||||
.WithMinValues(1)
|
||||
.WithMaxValues(1)
|
||||
.AddOption("Option A", "opt-a", "Option B is lying!")
|
||||
.AddOption("Option B", "opt-b", "Option A is telling the truth!");
|
||||
|
||||
var builder = new ComponentBuilder()
|
||||
.WithSelectMenu(menuBuilder);
|
||||
```
|
||||
|
||||
Lets add this to a command:
|
||||
|
||||
```cs
|
||||
[Command("spawner")]
|
||||
public async Task Spawn()
|
||||
{
|
||||
var menuBuilder = new SelectMenuBuilder()
|
||||
.WithPlaceholder("Select an option")
|
||||
.WithCustomId("menu-1")
|
||||
.WithMinValues(1)
|
||||
.WithMaxValues(1)
|
||||
.AddOption("Option A", "opt-a", "Option B is lying!")
|
||||
.AddOption("Option B", "opt-b", "Option A is telling the truth!");
|
||||
|
||||
var builder = new ComponentBuilder()
|
||||
.WithSelectMenu(menuBuilder);
|
||||
|
||||
await ReplyAsync("Whos really lying?", components: builder.Build());
|
||||
}
|
||||
```
|
||||
|
||||
Running this produces this result:
|
||||
|
||||

|
||||
|
||||
And opening the menu we see:
|
||||
|
||||

|
||||
|
||||
Lets handle the selection of an option, We can hook the `SelectMenuExecuted` event to handle our select menu:
|
||||
|
||||
```cs
|
||||
client.SelectMenuExecuted += MyMenuHandler;
|
||||
```
|
||||
|
||||
The `SelectMenuExecuted` also supplies a `SocketMessageComponent` argument, we can confirm that its a select menu by checking the `ComponentType` inside of the data field if we need, but the library will do that for us and only execute our handler if its a select menu.
|
||||
|
||||
The values that the user has selected will be inside of the `Values` collection in the Data field. we can list all of them back to the user for this example.
|
||||
|
||||
```cs
|
||||
public async Task MyMenuHandler(SocketMessageComponent arg)
|
||||
{
|
||||
var text = string.Join(", ", arg.Data.Values);
|
||||
await arg.RespondAsync($"You have selected {text}");
|
||||
}
|
||||
```
|
||||
|
||||
Running this produces this result:
|
||||
|
||||

|
||||