From e025a229fd24de14955f8ab67c75a59472fd62d3 Mon Sep 17 00:00:00 2001 From: quin lynch Date: Mon, 13 Dec 2021 03:10:04 -0400 Subject: [PATCH] Add changelog and remove old docs --- CHANGELOG.md | 129 ++++++- .../partials/head.tmpl.partial | 2 +- docs/guides/getting_started/installing.md | 66 ++-- .../interactions_framework/autocompleters.md | 27 -- .../dependency-injection.md | 27 -- docs/guides/interactions_framework/intro.md | 360 ------------------ .../interactions_framework/post_execution.md | 73 ---- .../interactions_framework/preconditions.md | 8 - .../interactions_framework/typeconverters.md | 130 ------- docs/index.md | 30 +- 10 files changed, 176 insertions(+), 676 deletions(-) delete mode 100644 docs/guides/interactions_framework/autocompleters.md delete mode 100644 docs/guides/interactions_framework/dependency-injection.md delete mode 100644 docs/guides/interactions_framework/intro.md delete mode 100644 docs/guides/interactions_framework/post_execution.md delete mode 100644 docs/guides/interactions_framework/preconditions.md delete mode 100644 docs/guides/interactions_framework/typeconverters.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 21e37b295..dd07045e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,98 @@ # Changelog +## [3.0.0] - 2021-12-13 + +### Added + +- #1767 Add method to clear guild user cache (19a66bf) +- #1847 Bump API version to 9 (06a64b7) +- #1848 Remove obsolete sync voice regions methods and properties (ed8e573) +- #1851 Remove DM cache and fix references (7a201e9) +- #1860 Remove /users/@me call for socket and rework sharded client a bit (384ad85) +- #1863 Change GuildMemberUpdate before state to cacheable (c2e87f5) +- #1879 Add Name property to Teams (c5b4b64) +- #1896 IVoiceChannel implements IMentionable (3395700) +- #1943 Handle bidirectional usernames (10afd96) +- #1948 warn on invalid gateway intents (51e06e9) +- #1949 default application games (82276e3) +- #1923 Added Interaction Support (933ea42). +- #1923 Added Application commands (933ea42). +- #1923 Added Message Components (933ea42). +- #1923 Added Thread Channels (933ea42). +- #1923 Added Stage Channels (933ea42). +- #1923 Added Guild Events (933ea42). +- #1923 Revamped Stickers (933ea42). +- #1923 Added `TimestampTag` (933ea42). +- #1923 Added `Name` property to teams (933ea42). +- #1923 Added url validation to embeds (933ea42). +- #1923 Added `NsfwLevel` to Guilds (933ea42). +- #1923 Added helpers to `Emoji` for parsing (933ea42). +- #1923 Added banner and accent color to guild users (933ea42). +- #1923 Added `RatelimitCallback` to `RequestOptions` (933ea42). +- #1923 Added `Emoji` to roles (933ea42). +- #1923 Added `UseInteractionSnowflakeDate` to config (933ea42). +- #1923 Added checks for gateway intent in some methods. DownloadUsersAsync will throw an exception if you don't have the gateway intent enabled locally now, this will help with the vauge error that was given before (933ea42). +- #1923 Added SendFilesAsync to channels (933ea42). +- #1923 Added Attachments property to MessageProperties (933ea42). +- #1958 Added NET5.0 and NET6.0 builds (aa6bb5e). +- #1958 Added `Discord.Interactions` (aa6bb5e). + +### Fixed + +- #1832 Grab correct Uses value for vanity urls (8ed8714) +- #1849 Remove obsolete methods and properties (70aab6c) +- #1850 Create DM channel with id and author alone (95bae78) +- #1853 Fire GuildMemberUpdated without cached user (d176fef) +- #1854 Gateway events for DMs (a7ff6ce) +- #1858 MessageUpdated without author (8b29e0f) +- #1859 Add missing AddRef and related (de7f9b5) +- #1862 Message update without author (fabe034) +- #1864 ApiClient.CurrentUser being null (08507c0) +- #1871 Add empty role list if not present (f47001a) +- #1872 Connection deadlock when trying to Send and Disconnect (97d90b9) +- #1873 Remove OperationCanceledException handling in connecting logic (7cf8499) +- #1876 Message type (ac52a11) +- #1877 Rest message type (22bb1b0) +- #1886 Change embed description max length to 4096 (8349cd7) +- #1890 Add default avatar to WithAuthor extension (c200861) + +### Misc + +- #20 Update EmbedBuilder.Overwrites.md (76a878a) +- #21 Fix line about PriorityAttribute (75b74e1) +- #1152 Add characters commonly use in links to Sanitize (b9274d1) +- #1518 Add default nullable enum typereader (f7a07ae) +- #1666 Added negative TimeSpan handling (6abdfcb) +- #1852 Internal change to GetOrCreateUser (dfaaa21) +- #1861 Add MaxBitrate to the interface (e0dbe7c) +- #1865 Add null check to AllowedMentions.ToModel() (3cb662f) +- #1923 Merge Labs 3.X into dev (933ea42) +- #1941 Fix emoto try parse (900c1f4) +- #1942 Implement multi-file upload to webhooks (bc440ab) +- #1944 Add Voice binaries (b5c150d) +- #1945 Update socket presence and add new presence event (9d6dc62) +- #1946 fix NRE when adding parameters thru builders (143ca6d) +- #1947 fix sharded client current user (d5f5ae1) +- #1950 Add custom setter to Group property of ModuleBuilder to automatically invoke AddAliases (ba656e9) +- #1958 Update from Discord .Net Labs 3.4.8 (aa6bb5e) +- #1959 Update isRequired (98b03be) +- Add `MatchResult` (d1b31c8) +- Add requested changes (a92ec56) +- Fix incorrect casing on `HandleCommandPipeline` (adf3a9c) +- Merge branch 'commands/validate-get-best-match' of https://github.com/siscodeorg/Discord.Net into siscodeorg-commands/validate-get-best-match (3cd9f39) +- Merge branch 'siscodeorg-commands/validate-get-best-match' into dev (4f1fe2b) +- Remove docs build from azure pipelines (2336b98) +- use async main (125f6c7) +- #1923 Made `Hierarchy` a `IGuildUser` property. +- #1923 Changed embed discription length to 4096 (933ea42). +- #1923 Fixed gateway serialization to include nulls for API v9 (933ea42). +- #1923 Removed error log for gateway reconnects (933ea42). +- #1966 Updated docs. + ## [2.4.0] - 2021-05-22 + ### Added + - #1726 Add stickers (91a9063) - #1753 Webhook message edit & delete functionality (f67cd8e) - #1757 Add ability to add/remove roles by id (4c9910c) @@ -12,15 +103,19 @@ - #1844 Add Discord Certified Moderator user flag (4b8d444) ### Fixed + - #1486 Add type reader when entity type reader exists (c46daaa) - #1835 Cached message emoji cleanup at MESSAGE_REACTION_REMOVE_EMOJI (8afef82) ### Misc + - #1778 Remove URI check from EmbedBuilder (25b04c4) - #1800 Fix spelling in SnowflakeUtils.FromSnowflake (6aff419) ## [2.3.1] - 2021-03-10 + ### Fixed + - #1761 Deadlock in DiscordShardedClient when Ready is never received (73e5cc2) - #1773 Private methods aren't added as commands (0fc713a) - #1780 NullReferenceException in pin/unpin audit logs (f794163) @@ -29,10 +124,13 @@ - #1794 Audit log UserId can be null (d41aeee) ### Misc + - #1774 Add remark regarding CustomStatus as the activity (51b7afe) ## [2.3.0] - 2021-01-28 + ### Added + - #1491 Add INVITE_CREATE and INVITE_DELETE events (1ab670b) - #1520 Support reading multiple activities (421a0c1) - #1521 Allow for inherited commands in modules (a51cdf6) @@ -57,6 +155,7 @@ - #1690 Add max bitrate value to SocketGuild (aacfea0) ### Fixed + - #1244 Missing AddReactions permission for DM channels. (e40ca4a) - #1469 unsupported property causes an exception (468f826) - #1525 AllowedMentions and AllowedMentionTypes (3325031) @@ -99,6 +198,7 @@ - Missing MessageReference when sending files (2095701) ### Misc + - #1545 MutualGuilds optimization (323a677) - #1551 Update webhook regex to support discord.com (7585789) - #1556 Add SearchUsersAsync (57880de) @@ -123,7 +223,9 @@ - Move bulk deletes remarks from to (62539f0) ## [2.2.0] - 2020-04-16 + ### Added + - #1247 Implement Client Status Support (9da11b4) - #1310 id overload for RemoveReactionAsync (c88b1da) - #1319 BOOST (faf23de) @@ -146,6 +248,7 @@ - suppress messages (cd28892) ### Fixed + - #1318 #1314 Don't parse tags within code blocks (c977f2e) - #1333 Remove null coalescing on ToEmbedBuilder Color (120c0f7) - #1337 Fixed attempting to access a non-present optional value (4edda5b) @@ -161,11 +264,13 @@ - include MessageFlags and SuppressEmbedParams (d6d4429) ### Changed + - #1368 Update ISystemMessage interface to allow reactions (07f4d5f) - #1417 fix #1415 Re-add support for overwrite permissions for news channels (e627f07) - use millisecond precision by default (bcb3534) ### Misc + - #1290 Split Unit and Integration tests into separate projects (a797be9) - #1328 Fix #1327 Color.ToString returns wrong value (1e8aa08) - #1329 Fix invalid cref values in docs (363d1c6) @@ -190,14 +295,16 @@ - 2.2.0 (4b602b4) - target the Process env-var scope (3c6b376) - fix metapackage build (1794f95) -- copy only _site to docs-static (a8cdadc) +- copy only \_site to docs-static (a8cdadc) - do not exit on failed robocopy (fd204ee) - add idn debugger (91aec9f) - rename IsStream to IsStreaming (dcd9cdd) - feature (40844b9) ## [2.1.1] - 2019-06-08 + ### Fixed + - #994: Remainder parameters now ignore character escaping, as there is no reason to escape characters here (2e95c49) - #1316: `Emote.Equals` now pays no respect to the Name property, since Discord's API does not care about an emote's name (abf3e90) - #1317: `Emote.GetHashCode` now pays no respect to the Name property, see above (1b54883) @@ -206,16 +313,20 @@ - News embeds will be processed as `EmbedType.Unknown`, rather than throwing an error and dropping the message (d287ed1) ### Changed + - #1311: Members may now be disconnected from voice channels by passing `null` as `GuildUserProperties.Channel` (fc48c66) - #1313: `IMessage.Tags` now includes the EveryoneRole on @everyone and @here mentions (1f55f01) - #1320: The maximum value for setting slow-mode has been updated to 6 hours, per the new API limit (4433ca7) ### Misc + - This library's compatibility with Semantic Versioning has been clarified. Please see the README (4d7de17) - The depency on System.Interactive.Async has been bumped to `3.2.0` (3e65e03) ## [2.1.0] - 2019-05-18 + ### Added + - #1236: Bulk deletes (for messages) may now be accessed via the `MessagesBulkDeleted` event (dec353e) - #1240: OAuth applications utilizing the `guilds.join` scope may now add users to guilds through any client (1356ea9) - #1255: Message and attachment spoilers may now be set or detected (f3b20b2) @@ -227,9 +338,11 @@ - `ExclusiveBulkDelete` configuration setting can be used to control bulk delete event behavior (03e6401) ### Removed + - #1294: The `IGuildUser` overload of `EmbedBuilder.WithAuthor` no longer exists (b52b54d) ### Fixed + - #1256: Fetching audit logs no longer raises null reference exceptions when a webhook has been deleted (049b014) - #1268: Null reference exceptions on `MESSAGE_CREATE` concerning partial member objects no longer occur (377622b) - #1278: The token validator now internally pads tokens to the proper length (48b327b) @@ -238,9 +351,11 @@ - Exceptions in event handlers are now always logged (f6e3200) ### Changed + - #1305: Token validation will fail when tokens contain whitespace (bb61efa) ### Misc + - #1241: Added documentation samples for Webhooks (655a006) - #1243: Happy new year 🎉 (0275f7d) - #1257: Improved clarity in comments in the command samples (2473619) @@ -251,16 +366,20 @@ - IDisposableAnalyzers should now be a development dependency (8003ac8) ## [2.0.1] - 2019-01-04 + ### Fixed + - #1226: Only escape the closing quotation mark of non-remainder strings (65b8c09) - Commands with async RunModes will now propagate exceptions up to CommandExecuted (497918e) ### Misc + - #1225: Commands sample no longer hooks the log event twice (552f34c) - #1227: The logo on the docs index page should scale responsively (d39bf6e) - #1230: Replaced precondition sample on docs (feed4fd) ## [2.0.0] - 2018-12-28 + ### Added - #747: `CommandService` now has a `CommandExecuted` event (e991715) @@ -316,6 +435,7 @@ - Reactions can now be added to messages in bulk (5421df1) ### Fixed + - #742: `DiscordShardedClient#GetGuildFor` will now direct null guilds to Shard 0 (d5e9d6f) - #743: Various issues with permissions and inheritance of permissions (f996338) - #755: `IRole.Mention` will correctly tag the @everyone role (6b5a6e7) @@ -363,6 +483,7 @@ - The default WebSocket will now close correctly (ac389f5) ### Changed + - #731: `IUserMessage#GetReactionUsersAsync` now takes an `IEmote` instead of a `string` (5d7f2fc) - #744: IAsyncEnumerable has been redesigned (5bbd9bb) - #777: `IGuild#DefaultChannel` will now resolve the first accessible channel, per changes to Discord (1ffcd4b) @@ -397,14 +518,15 @@ - The socket client will now use additional fields to fill in member/guild information on messages (8fb2c71) - The Audio Client now uses Voice WS v3 (9ba38d7) - ### Removed + - #790: Redundant overloads for `AddField` removed from EmbedBuilder (479361b) - #925: RPC is no longer being maintained nor packaged (b30af57) - #958: Remove support for user tokens (2fd4f56) - User logins (including selfbots) are no longer supported (fc5adca) ### Misc + - #786: Unit tests for the Color structure (22b969c) - #828: We now include a contributing guide (cd82a0f) - #876: We now include a standard editorconfig (5c8c784) @@ -425,11 +547,13 @@ - Fixed documentation layout for the logo (bafdce4) ## [1.0.2] - 2017-09-09 + ### Fixed - Guilds utilizing Channel Categories will no longer crash bots on the `READY` event. ## [1.0.1] - 2017-07-05 + ### Fixed - #732: Fixed parameter preconditions not being loaded from class-based modules (b6dcc9e) @@ -438,4 +562,5 @@ - Fixed module auto-detection for nested modules (d2afb06) ### Changed + - ShardedCommandContext now inherits from SocketCommandContext (8cd99be) diff --git a/docs/_template/light-dark-theme/partials/head.tmpl.partial b/docs/_template/light-dark-theme/partials/head.tmpl.partial index 5de762b66..8a01b48cf 100644 --- a/docs/_template/light-dark-theme/partials/head.tmpl.partial +++ b/docs/_template/light-dark-theme/partials/head.tmpl.partial @@ -10,7 +10,7 @@ - + diff --git a/docs/guides/getting_started/installing.md b/docs/guides/getting_started/installing.md index 58ebeda34..09dc32837 100644 --- a/docs/guides/getting_started/installing.md +++ b/docs/guides/getting_started/installing.md @@ -22,12 +22,12 @@ other limitations, you may also consider targeting [.NET Framework] > notice. It is known to have issues with the library's WebSockets > implementation and may crash the application upon startup. -[Mono]: https://www.mono-project.com/ -[.NET 6.0]: https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-6 -[.NET 5.0]: https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-5 -[.NET Standard]: https://docs.microsoft.com/en-us/dotnet/articles/standard/library -[.NET Core]: https://docs.microsoft.com/en-us/dotnet/articles/core/ -[.NET Framework]: https://docs.microsoft.com/en-us/dotnet/framework/get-started/ +[mono]: https://www.mono-project.com/ +[.net 6.0]: https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-6 +[.net 5.0]: https://docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-5 +[.net standard]: https://docs.microsoft.com/en-us/dotnet/articles/standard/library +[.net core]: https://docs.microsoft.com/en-us/dotnet/articles/core/ +[.net framework]: https://docs.microsoft.com/en-us/dotnet/framework/get-started/ [additional steps]: #installing-on-net-standard-11 ## Installing with NuGet @@ -39,37 +39,37 @@ Development builds of Discord.Net, as well as add-ons, will be published to our [MyGet feed]. See @Guides.GettingStarted.Installation.Nightlies to learn more. -[official NuGet feed]: https://nuget.org -[MyGet feed]: https://www.myget.org/feed/Packages/discord-net +[official nuget feed]: https://nuget.org +[myget feed]: https://www.myget.org/feed/Packages/discord-net ### [Using Visual Studio](#tab/vs-install) 1. Create a new solution for your bot 2. In the Solution Explorer, find the "Dependencies" element under your - bot's project + bot's project 3. Right click on "Dependencies", and select "Manage NuGet packages" - ![Step 3](images/install-vs-deps.png) + ![Step 3](images/install-vs-deps.png) 4. In the "Browse" tab, search for `Discord.Net` 5. Install the `Discord.Net` package - ![Step 5](images/install-vs-nuget.png) + ![Step 5](images/install-vs-nuget.png) ### [Using JetBrains Rider](#tab/rider-install) 1. Create a new solution for your bot 2. Open the NuGet window (Tools > NuGet > Manage NuGet packages for Solution) - ![Step 2](images/install-rider-nuget-manager.png) + ![Step 2](images/install-rider-nuget-manager.png) 3. In the "Packages" tab, search for `Discord.Net` - ![Step 3](images/install-rider-search.png) + ![Step 3](images/install-rider-search.png) 4. Install by adding the package to your project - ![Step 4](images/install-rider-add.png) + ![Step 4](images/install-rider-add.png) ### [Using Visual Studio Code](#tab/vs-code) @@ -84,7 +84,7 @@ published to our [MyGet feed]. See 2. Navigate to where your `*.csproj` is located 3. Enter `dotnet add package Discord.Net` -*** +--- ## Compiling from Source @@ -92,15 +92,15 @@ In order to compile Discord.Net, you will need the following: ### Using Visual Studio -* [Visual Studio 2019](https://visualstudio.microsoft.com/) or later. -* [.NET 5 SDK] +- [Visual Studio 2019](https://visualstudio.microsoft.com/) or later. +- [.NET 5 SDK] -The .NET 5 and Docker workload is required during Visual Studio +The .NET 5 workload is required during Visual Studio installation. ### Using Command Line -* [.NET 5 SDK] +- [.NET 5 SDK] ## Additional Information @@ -119,28 +119,28 @@ by installing one or more custom packages as listed below. 1. Download the latest [.NET Core SDK]. 2. Create or move your existing project to use .NET Core. 3. Modify your `` tag to at least `netcoreapp2.1`, or - by adding the `--framework netcoreapp2.1` switch when building. + by adding the `--framework netcoreapp2.1` switch when building. #### [Custom Packages](#tab/custom-pkg) -1. Install or compile the following packages: +1. Install or compile the following packages: - * `Discord.Net.Providers.WS4Net` - * `Discord.Net.Providers.UDPClient` (Optional) - * This is _only_ required if your bot will be utilizing voice chat. + - `Discord.Net.Providers.WS4Net` + - `Discord.Net.Providers.UDPClient` (Optional) + - This is _only_ required if your bot will be utilizing voice chat. -2. Configure your [DiscordSocketClient] to use these custom providers -over the default ones. +2. Configure your [DiscordSocketClient] to use these custom providers + over the default ones. - * To do this, set the `WebSocketProvider` and the optional - `UdpSocketProvider` properties on the [DiscordSocketConfig] that you - are passing into your client. + * To do this, set the `WebSocketProvider` and the optional + `UdpSocketProvider` properties on the [DiscordSocketConfig] that you + are passing into your client. [!code-csharp[Example](samples/netstd11.cs)] -[DiscordSocketClient]: xref:Discord.WebSocket.DiscordSocketClient -[DiscordSocketConfig]: xref:Discord.WebSocket.DiscordSocketConfig +[discordsocketclient]: xref:Discord.WebSocket.DiscordSocketClient +[discordsocketconfig]: xref:Discord.WebSocket.DiscordSocketConfig -*** +--- -[.NET 5 SDK]: https://dotnet.microsoft.com/download +[.net 5 sdk]: https://dotnet.microsoft.com/download diff --git a/docs/guides/interactions_framework/autocompleters.md b/docs/guides/interactions_framework/autocompleters.md deleted file mode 100644 index 9f84ace75..000000000 --- a/docs/guides/interactions_framework/autocompleters.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -uid: Guides.InteractionsFramework.Autocompleters -title: Autocompleters ---- - -# Autocompleters - -Autocompleters provide a similar pattern to TypeConverters. Autocompleters are cached, singleton services and they are used by the Interaction Service to handle Autocomplete Interations targeted to a specific Slash Command parameter. - -To start using Autocompleters, use the `[AutocompleteAttribute(Type autocompleterType)]` overload of the `[AutocompleteAttribute]`. This will dynamically link the parameter to the Autocompleter type. - -## Creating Autocompleters - -A valid Autocompleter must inherit `AutocompleteHandler` base type and implement all of its abstract methods. - -### GenerateSuggestionsAsync() - -Interactions Service uses this method to generate a response to a Autocomplete Interaction. This method should return `AutocompletionResult.FromSuccess(IEnumerable)` to display parameter sugesstions to the user. If there are no suggestions to be presented to the user, you have two options: - -1. Returning the parameterless `AutocompletionResult.FromSuccess()` will display "No options match your search." message to the user. -2. Returning `AutocompleteResult.FromError()` will make the Interaction Service not respond to the interation, consequently displaying the user "Loading options failed." message. - -## Resolving Autocompleter Dependencies - -Autocompleter dependencies are resolved using the same dependency injection pattern as the Interaction Modules. Property injection and constructor injection are both valid ways to get service dependencies. - -Because Autocompleters are constructed at service startup, class dependencies are resolved only once. If you need to access per-request dependencies you can use the IServiceProvider parameter of the `GenerateSuggestionsAsync()` method. diff --git a/docs/guides/interactions_framework/dependency-injection.md b/docs/guides/interactions_framework/dependency-injection.md deleted file mode 100644 index bed58e1c3..000000000 --- a/docs/guides/interactions_framework/dependency-injection.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -uid: Guides.InteractionsFramework.DependencyInjection -title: Dependency Injection ---- - -# Dependency Injection - -Interaction Service uses dependency injection to perform most of its operations. This way, you can access service dependencies throughout the framework. - -## Setup - -1. Create a `Microsoft.Extensions.DependencyInjection.ServiceCollection`. -2. Add the dependencies you wish to use in the modules. -3. Build a `IServiceProvider` using the `BuildServiceProvider()` method of the `ServiceCollection`. -4. Pass the `IServiceProvider` to `AddModulesAsync()`, `AddModuleAsync()` and `ExecuteAsync()` methods. - -## Accessing the Dependencies - -Services of a `IServiceProvider` can be accessed using *Contructor Injection* and *Property Injection*. - -Interaction Service will populate the constructor parameters using the provided `IServiceProvider`. Any public settable class Property will also be populated in the same manner. - -## Service Scopes - -Interaction Service has built-in support for scoped service types. Scoped lifetime services are instantiated once per command execution. Including the Preconditon checks, every module operation is executed within a single service scope (which is sepearate from the global service scope). - -> For more in-depth information about service lifetimes check out [Microsoft Docs](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-5.0#service-lifetimes-1). diff --git a/docs/guides/interactions_framework/intro.md b/docs/guides/interactions_framework/intro.md deleted file mode 100644 index f240eddd0..000000000 --- a/docs/guides/interactions_framework/intro.md +++ /dev/null @@ -1,360 +0,0 @@ ---- -uid: Guides.InteractionsFramework.Intro -title: Introduction to the Interaction Framework ---- - -# Getting Started - -Interaction Service provides an attribute based framework for creating Discord Interaction handlers. - -To start using the Interaction Service, you need to create a service instance. Optionally you can provide the `InterctionService` constructor with a `InteractionServiceConfig` to change the services behaviour to suit your needs. - -```csharp -... - -var commands = new InteractionService(discord); - -... -``` - -## Modules - -Attribute based Interaction handlers must be defined within a command module class. Command modules are responsible for executing the Interaction handlers and providing them with the necessary execution info and helper functions. - -Command modules are transient objects. A new module instance is created before a command execution starts then it will be disposed right after the method returns. - -Every module class must: - -- be public -- inherit `InteractionModuleBase` - -Optionally you can override the included : - -- OnModuleBuilding (executed after the module is built) -- BeforeExecute (executed before a command execution starts) -- AfterExecute (executed after a command execution concludes) - -methods to configure the modules behaviour. - -Every command module exposes a set of helper methods, namely: - -- `RespondAsync()` => Respond to the interaction -- `FollowupAsync()` => Create a followup message for an interaction -- `ReplyAsync()` => Send a message to the origin channel of the interaction -- `DeleteOriginalResponseAsync()` => Delete the original interaction response - -## Commands - -Valid **Interaction Commands** must comply with the following requirements: - -| | return type | max parameter count | allowed parameter types | attribute | -|-------------------------------|------------------------------|---------------------|-------------------------------|--------------------------| -|[Slash Command](#slash-commands)| `Task`/`Task` | 25 | any* | `[SlashCommand]` | -|[User Command](#user-commands) | `Task`/`Task` | 1 | Implementations of `IUser` | `[UserCommand]` | -|[Message Command](#message-commands)| `Task`/`Task` | 1 | Implementations of `IMessage` | `[MessageCommand]` | -|[Component Interaction Command](#component-interaction-commands)| `Task`/`Task` | inf | `string` or `string[]` | `[ComponentInteraction]` | -|[Autocomplete Command](#autocomplete-commands)| `Task`/`Task` | - | - | `[AutocompleteCommand]`| - -> [!NOTE] -> a `TypeConverter` that is capable of parsing type in question must be registered to the `InteractionService` instance. - -You should avoid using long running code in your command module. Depending on your setup, long running code may block the Gateway thread of your bot, interrupting its connection to Discord. - -### Slash Commands - -Slash Commands are created using the `[SlashCommandAttribute]`. Every Slash Command must declare a name and a description. You can check Discords **Application Command Naming Guidelines** [here](https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-naming). - -```csharp -[SlashCommand("echo", "Echo an input")] -public async Task Echo(string input) -{ - await RespondAsync(input); -} -``` - -#### Parameters - -Slash Commands can have up to 25 method parameters. You must name your parameters in accordance with [Discords Naming Guidelines](https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-naming). Interaction Service also features a pascal casing seperator for formatting parameter names with pascal casing into Discord compliant parameter names('parameterName' => 'parameter-name'). By default, your methods can feature the following parameter types: - -- Implementations of `IUser` -- Implementations of `IChannel`* -- Implementations of `IRole` -- Implementations of `IMentionable` -- `string` -- `float`, `double`, `decimal` -- `bool` -- `char` -- `sbyte`, `byte` -- `int16`, `int32`, `int64` -- `uint16`, `uint32`, `uint64` -- `enum` (Values are registered as multiple choice options and are enforced by Discord. Use `[HideAttribute]' on enum values to prevent them from getting registered.) -- `DateTime` -- `TimeSpan` - ---- - -**You can use more specialized implementations of `IChannel` to restrict the allowed channel types for a channel type option.* -| interface | Channel Type | -|---------------------|-------------------------------| -| `IStageChannel` | Stage Channels | -| `IVoiceChannel` | Voice Channels | -| `IDMChannel` | DM Channels | -| `IGroupChannel` | Group Channels | -| `ICategory Channel` | Category Channels | -| `INewsChannel` | News Channels | -| `IThreadChannel` | Public, Private, News Threads | -| `ITextChannel` | Text Channels | - ---- - -##### Optional Parameters - -Parameters with default values (ie. `int count = 0`) will be displayed as optional parameters on Discord Client. - -##### Parameter Summary - -By using the `[SummaryAttribute]` you can customize the displayed name and description of a parameter - -```csharp -[Summary(description: "this is a parameter description")] string input -``` - -##### Parameter Choices - -`[ChoiceAttribute]` can be used to add choices to a parameter. - -```csharp -[SlashCommand("blep", "Send a random adorable animal photo")] -public async Task Blep([Choice("Dog","dog"), Choice("Cat", "cat"), Choice("Penguin", "penguin")] string animal) -{ - ... -} -``` - -In most cases, instead of relying on this attribute, you should use an `Enum` to create multiple choice parameters. Ex. - -```csharp -public enum Animal -{ - Cat, - Dog, - Penguin -} - -[SlashCommand("blep", "Send a random adorable animal photo")] -public async Task Blep(Animal animal) -{ - ... -} -``` - -This Slash Command will be displayed exactly the same as the previous example. - -##### Channel Types - -Channel types for an `IChannel` parameter can also be restricted using the `[ChannelTypesAttribute]`. - -```csharp -[SlashCommand("name", "Description")] -public async Task Command([ChannelTypes(ChannelType.Stage, ChannelType.Text)]IChannel channel) -{ - ... -} -``` - -In this case, user can only input Stage Channels and Text Channels to this parameter. - -##### Autocomplete - -You can enable Autocomple Interactions for a Slash Command parameter using the `[AutocompleteAttribute]`. To handle the Autocomplete Interactions raised by this parameter you can either create [Autocomplete Commands](#autocomplete-commands) or you can opt to use the [Autocompleters Pattern](./autocompleters) - -##### Min/Max Value - -You can specify the permitted max/min value for a number type parameter using the `[MaxValueAttribute]` and `[MinValueAttribute]`. - -### User Commands - -A valid User Command must have the following structure: - -```csharp -[UserCommand("Say Hello")] -public async Task SayHello(IUser user) -{ - ... -} -``` - -User commands can only have one parameter and its type must be an implementation of `IUser`. - -### Message Commands - -A valid Message Command must have the following structure: - -```csharp -[MessageCommand("Bookmark")] -public async Task Bookmark(IMessage user) -{ - ... -} -``` - -Message commands can only have one parameter and its type must be an implementation of `IMessage`. - -### Component Interaction Commands - -Component Interaction Commands are used to handle interactions that originate from **Discord Message Component**s. This pattern is particularly useful if you will be reusing a set a **Custom ID**s. - -```csharp -[ComponentInteraction("custom_id")] -public async Task RoleSelection() -{ - ... -} -``` - -Component Interaction Commands support wild card matching, by default `*` character can be used to create a wild card pattern. Interaction Service will use lazy matching to capture the words corresponding to the wild card character. And the captured words will be passed on to the command method in the same order they were captured. - -*Ex.* - -If Interaction Service recieves a component interaction with **player:play,rickroll** custom id, `op` will be *play* and `name` will be *rickroll* - -```csharp -[ComponentInteraction("player:*,*")] -public async Task Play(string op, string name) -{ - ... -} -``` - -You may use as many wild card characters as you want. - -#### Select Menus - -Unlike button interactions, select menu interactions also contain the values of the selected menu items. In this case, you should structure your method to accept a string array. - -```csharp -[ComponentInteraction("role_selection")] -public async Task RoleSelection(string[] selectedRoles) -{ - ... -} -``` - - Wild card pattern can also be used to match select menu custom ids but remember that the array containing the select menu values should be the last parameter. - -```csharp -[ComponentInteraction("role_selection_*")] -public async Task RoleSelection(string id, string[] selectedRoles) -{ - ... -} -``` - -### Autocomplete Commands - -Autocomplete commands must be parameterless methods. A valid Autocomplete command must have the following structure: - -```csharp -[AutocompleteCommand("command_name", "parameter_name")] -public async Task Autocomplete() -{ - IEnumerable results; - - ... - - await (Context.Interaction as SocketAutocompleteInteraction).RespondAsync(results); -} -``` - -Alternatively, you can use the *Autocompleters* to simplify this workflow. - -## Interaction Context - -Every command module provides its commands with an execution context. This context property includes general information about the underlying interaction that triggered the command execution. The base command context. - -You can design your modules to work with different implementation types of `IInteractionContext`. To achieve this, make sure your module classes inherit from the generic variant of the `InteractionModuleBase`. - -> Context type must be consistent throughout the project, or you will run into issues during runtime. - -Interaction Service ships with 4 different kinds of `InteractionContext`s: - -1. InteractionContext: A bare-bones execution context consisting of only implementation netural interfaces -2. SocketInteractionContext: An execution context for use with `DiscordSocketClient`. Socket entities are exposed in this context without the need of casting them. -3. ShardedInteractionContext: `DiscordShardedClient` variant of the `SocketInteractionContext` -4. RestInteractionContext: An execution context designed to be used with a `DiscordRestClient` and webhook based interactions pattern - -You can create custom Interaction Contexts by implementing the `IInteracitonContext` interface. - -One problem with using the concrete type InteractionContexts is that you cannot access the information that is specific to different interaction types without casting. Concrete type interaction contexts are great for creating shared interaction modules but you can also use the generic variants of the built-in interaction contexts to create interaction specific interaction modules. - -Ex. -Message component interactions have access to a special method called `UpdateAsync()` to update the body of the method the interaction originated from. Normally this wouldn't be accessable without casting the `Context.Interaction`. - -```csharp -discordClient.ButtonExecuted += async (interaction) => -{ - var ctx = new SocketInteractionContext(discordClient, interaction); - await interactionService.ExecuteAsync(ctx, serviceProvider); -}; - -public class MessageComponentModule : InteractionModuleBase> -{ - [ComponentInteraction("custom_id")] - public async Command() - { - Context.Interaction.UpdateAsync(...); - } -} -``` - -## Loading Modules - -Interaction Service can automatically discover and load modules that inherit `InteractionModuleBase` from an `Assembly`. Call `InteractionService.AddModulesAsync()` to use this functionality. - -You can also manually add Interaction modules using the `InteractionService.AddModuleAsync()` method by providing the module type you want to load. - -## Resolving Module Dependencies - -Module dependencies are resolved using the Constructor Injection and Property Injection patterns. Meaning, the constructor parameters and public settable properties of a module will be assigned using the `IServiceProvider`. For more information on dependency injection, check out [Dependency Injection](./dependency-injection.md) - -## Module Groups - -Module groups allow you to create sub-commands and sub-commands groups. By nesting commands inside a module that is tagged with `[GroupAttribute]` you can create prefixed commands. - -Although creating nested module stuctures are allowed, you are not permitted to use more than 2 `[GroupAttribute]`s in module hierarchy. - -## Executing Commands - -Any of the following socket events can be used to execute commands: - -- InteractionCreated -- ButtonExecuted -- SelectMenuExecuted -- AutocompleteExecuted -- UserCommandExecuted -- MessageCommandExecuted - -Commands can be either executed on the gateway thread or on a seperate thread from the thread pool. This behaviour can be configured by changing the *RunMode* property of `InteractionServiceConfig` or by setting the *runMode* parameter of a command attribute. - -You can also configure the way `InteractionService` executes the commands. By default, commands are executed using `ConstructorInfo.Invoke()` to create module instances and `MethodInfo.Invoke()` method for executing the method bodies. By setting, `InteractionServiceConfig.UseCompiledLambda` to `true`, you can make `InteractionService` create module instances and execute commands using *Compiled Lambda* expressions. This cuts down on command execution time but it might add some memory overhead. - -Time it takes to create a module instance and execute a `Task.Delay(0)` method using the Reflection methods compared to Compiled Lambda expressions: - -| Method | Mean | Error | StdDev | -|----------------- |----------:|---------:|---------:| -| ReflectionInvoke | 225.93 ns | 4.522 ns | 7.040 ns | -| CompiledLambda | 48.79 ns | 0.981 ns | 1.276 ns | - -## Registering Commands to Discord - -Application commands loaded to the Interaction Service can be registered to Discord using a number of different methods. In most cases `RegisterCommandsGloballyAsync()` and `RegisterCommandsToGuildAsync()` are the methods to use. Command registration methods can only be used after the gateway client is ready or the rest client is logged in. - -In debug environment, since Global commands can take up to 1 hour to register/update, you should register your commands to a test guild for your changes to take effect immediately. You can use the preprocessor directives to create a simple logic for registering commands: - -```csharp -#if DEBUG - await interactionService.RegisterCommandsToGuildAsync(); -#else - await interactionService.RegisterCommandsGloballyAsync(); -#endif -``` diff --git a/docs/guides/interactions_framework/post_execution.md b/docs/guides/interactions_framework/post_execution.md deleted file mode 100644 index f34ba5cfe..000000000 --- a/docs/guides/interactions_framework/post_execution.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -uid: Guides.InteractionsFramework.PostEx -title: Post-Execution ---- - -# Post-Execution Logic - -Interaction Service uses `IResult`s to provide information about the state of command execution. These can be used to log internal exceptions or provide some insight to the command user. - -If you are running your commands using `RunMode.Sync` these command results can be retrieved from the return value of `InteractionService.ExecuteCommandAsync()` method or by registering delegates to Interaction Service events. - -If you are using the `RunMode.Async` to run your commands, you must use the Interaction Service events to get the execution results. When using `RunMode.Async`, `InteractionService.ExecuteCommandAsync()` will always return a successful result. - -## Results - -Interaction Result come in a handful of different flavours: - -1. `AutocompletionResult`: returned by Autocompleters -2. `ExecuteResult`: contains the result of method body execution process -3. `PreconditionGroupResult`: returned by Precondition groups -4. `PreconditionResult`: returned by preconditions -5. `RuntimeResult`: a user implementable result for returning user defined results -6. `SearchResult`: returned by command lookup map -7. `TypeConverterResult`: returned by TypeConverters - -You can either use the `IResult.Error` property of an Interaction result or create type check for the afformentioned result types to branch out your post-execution logic to handle different situations. - -## CommandExecuted Events - -Every time a command gets executed, Interaction Service raises a *CommandExecuted event. These events can be used to create a post-execution pipeline. - -```csharp -interactionService.SlashCommandExecuted += SlashCommandExecuted; - -async Task SlashCommandExecuted (SlashCommandInfo arg1, Discord.IInteractionContext arg2, IResult arg3) - { - if (!arg3.IsSuccess) - { - switch (arg3.Error) - { - case InteractionCommandError.UnmetPrecondition: - await arg2.Interaction.RespondAsync($"Unmet Precondition: {arg3.ErrorReason}"); - break; - case InteractionCommandError.UnknownCommand: - await arg2.Interaction.RespondAsync("Unknown command"); - break; - case InteractionCommandError.BadArgs: - await arg2.Interaction.RespondAsync("Invalid number or arguments"); - break; - case InteractionCommandError.Exception: - await arg2.Interaction.RespondAsync($"Command exception:{arg3.ErrorReason}"); - break; - case InteractionCommandError.Unsuccessful: - await arg2.Interaction.RespondAsync("Command could not be executed"); - break; - default: - break; - } - } - } -``` - -## Log Event - -InteractionService regularly outputs information about the occuring events to keep the developer informed. - -## Runtime Result - -Interaction commands allow you to return `Task` to pass on additional information about the command execution process back to your post-execution logic. - -Custom `RuntimeResult` classes can be created by inheriting the base `RuntimeResult` class. - -If command execution process reaches the method body of the command and no exceptions are thrown during the execution of the method body, `RuntimeResult` returned by your command will be accessible by casting/type-checking the `IResult` parameter of the *CommandExecuted event delegate. diff --git a/docs/guides/interactions_framework/preconditions.md b/docs/guides/interactions_framework/preconditions.md deleted file mode 100644 index e9b5d73b6..000000000 --- a/docs/guides/interactions_framework/preconditions.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -uid: Guides.InteractionsFramework.Preconditions -title: Preconditions ---- - -# Preconditions - -Preconditions in Interaction Service work exactly the same as they do in ***Discord.Net.Commands***. For more information, check out [Preconditions](../commands/preconditions.md) \ No newline at end of file diff --git a/docs/guides/interactions_framework/typeconverters.md b/docs/guides/interactions_framework/typeconverters.md deleted file mode 100644 index 12ca7dab5..000000000 --- a/docs/guides/interactions_framework/typeconverters.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -uid: Guides.InteractionsFramework.TypeConverters -title: Type Converters ---- - -# TypeConverters - -TypeConverters are responsible for registering command parameters to Discord and parsing the user inputs into method parameters. - -By default, TypeConverters for the following types are provided with `Discord.Net.Interactions` library. - -- Implementations of `IUser` -- Implementations of `IChannel` -- Implementations of `IRole` -- Implementations of `IMentionable` -- `string` -- `float`, `double`, `decimal` -- `bool` -- `char` -- `sbyte`, `byte` -- `int16`, `int32`, `int64` -- `uint16`, `uint32`, `uint64` -- `enum` -- `DateTime` -- `TimeSpan` - -## Creating TypeConverters - -Depending on your needs, there are two types of `TypeConverter`s you can create: - -- Concrete type -- Generic type - -A valid converter must inherit `TypeConverter` base type. And override the abstract base methods. - -### CanConvertTo() Method - -This method is used by Interaction Service to search for alternative Type Converters. - -Interaction Services determines the most suitable `TypeConverter` for a parameter type in the following order: - -1. It searches for a `TypeConverter` that is registered to specifically target that parameter type -2. It searches for a generic `TypeConverter` with a matching type constraint. If there are more multiple matches, the one whose type constraint is the most specialized will be chosen. -3. It searches for a `TypeConverter` that returns `true` when its `CanConvertTo()` method is invoked for thaty parameter type. - -> Alternatively, you can use the generic variant (`TypeConverter`) of the `TypeConverter` base class which implements the following method body for `CanConvertTo()` method - -```csharp -public sealed override bool CanConvertTo (Type type) => - typeof(T).IsAssignableFrom(type); -``` - -### GetDiscordType() Method - -This method is used by Interaction Service to determine the [Discord Application Command Option type](https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-type) of a parameter type. - -### ReadAsync() Method - -This method is used by Interaction Service to parse the user input. This method should return `TypeConverterResult.FromSuccess` if the parsing operation is successful, otherwise it should return `TypeConverterResult.FromError`. The inner logic of this method is totally up to you, however you should avoid using long running code. - -### Write() Method - -This method is used to configure the **Discord Application Command Option** before it gets registered to Discord. Command Option is configured by modifying the `ApplicationCommandOptionProperties` instance. - -The default parameter building pipeline is isolated and will not be disturbed by the `TypeConverter` workflow. But changes made in this method will override the values generated by the Interaction Service for a **Discord Application Command Option**. - ---- - -### Example Enum TypeConverter - -```csharp -internal sealed class EnumConverter : TypeConverter where T : struct, Enum -{ - public override ApplicationCommandOptionType GetDiscordType ( ) => ApplicationCommandOptionType.String; - - public override Task ReadAsync (IInteractionCommandContext context, SocketSlashCommandDataOption option, IServiceProvider services) - { - if (Enum.TryParse((string)option.Value, out var result)) - return Task.FromResult(TypeConverterResult.FromSuccess(result)); - else - return Task.FromResult(TypeConverterResult.FromError(InteractionCommandError.ConvertFailed, $"Value {option.Value} cannot be converted to {nameof(T)}")); - } - - public override void Write (ApplicationCommandOptionProperties properties, IParameterInfo parameterInfo) - { - var names = Enum.GetNames(typeof(T)); - if (names.Length <= 25) - { - var choices = new List(); - - foreach (var name in names) - choices.Add(new ApplicationCommandOptionChoiceProperties - { - Name = name, - Value = name - }); - - properties.Choices = choices; - } - } -} -``` - ---- - -## Registering TypeConverters - -> TypeConverters must be registered prior to module discovery. If Interaction Service encounters a parameter type that doesn't belong to any of the registered `TypeConverter`s during this phase, it will throw an exception. - -### Concrete TypeConverters - -Registering Concrete TypeConverters are as simple as creating an instance of your custom converter and invoking `AddTypeConverter()` method. - -```csharp -interactionService.AddTypeConverter(new StringArrayConverter()); -``` - -### Generic TypeConverters - -To register a generic TypeConverter, you need to invoke the `AddGenericTypeConverter()` method of the Interaction Service class. You need to pass the type of your `TypeConverter` and a target base type to this method. - -For instance, to register the previously mentioned [Example Enum Converter](#example-enum-converter) the following can be used: - -```csharp -interactionService.AddGenericTypeConverter(typeof(EnumConverter<>)); -``` - -Interaction service checks if the target base type satisfies the type constraints of the Generic TypeConverter class. - -> Dependencies of Generic TypeConverters are also resolved using the Dependency Injection pattern. diff --git a/docs/index.md b/docs/index.md index b63369f6e..8a87963ea 100644 --- a/docs/index.md +++ b/docs/index.md @@ -7,7 +7,7 @@ title: Home -[![GitHub](https://img.shields.io/github/last-commit/discord-net/Discord.Net?style=plastic)](https://github.com/Discord-Net-Labs/Discord.Net-Labs) +[![GitHub](https://img.shields.io/github/last-commit/discord-net/Discord.Net?style=plastic)](https://github.com/discord-net/Discord.Net) [![NuGet](https://img.shields.io/nuget/vpre/Discord.Net.svg?maxAge=2592000?style=plastic)](https://www.nuget.org/packages/Discord.Net) [![MyGet](https://img.shields.io/myget/discord-net/vpre/Discord.Net.svg)](https://www.myget.org/feed/Packages/discord-net) [![Build Status](https://dev.azure.com/discord-net/Discord.Net/_apis/build/status/discord-net.Discord.Net?branchName=dev)](https://dev.azure.com/discord-net/Discord.Net/_build/latest?definitionId=1&branchName=dev) @@ -37,14 +37,14 @@ for testing and development to eventually get merged into Discord.NET. [Installing Discord.NET Labs](xref:Guides.GettingStarted.Installation.Labs) -[Discord.NET Labs]: https://github.com/Discord-Net-Labs/Discord.Net-Labs +[discord.net labs]: https://github.com/Discord-Net-Labs/Discord.Net-Labs ## Questions? -Frequently asked questions are covered in the -FAQ. Read it thoroughly because most common questions are already answered there. +Frequently asked questions are covered in the +FAQ. Read it thoroughly because most common questions are already answered there. -If you still have unanswered questions after reading the [FAQ](xref:FAQ.Basics.GetStarted), further support is available on +If you still have unanswered questions after reading the [FAQ](xref:FAQ.Basics.GetStarted), further support is available on [Discord](https://discord.gg/dnet). ## Commonly used features @@ -55,28 +55,28 @@ A counterpart to staple command service of Discord.NET, the Interaction Framewor feature-rich structure to register & handle interactions like Slash commands & buttons. - Read about the Interaction Framework -[here](xref:Guides.IntFw.Intro) + [here](xref:Guides.IntFw.Intro) #### Slash Commands -Slash commands are purposed to take over the normal prefixed commands in Discord and comes with good functionality to serve as a replacement. +Slash commands are purposed to take over the normal prefixed commands in Discord and comes with good functionality to serve as a replacement. Being interactions, they are handled as SocketInteractions. Creating and receiving slashcommands is covered below. -- Find out more about slash commands in the -[Slash Command Guides](xref:Guides.SlashCommands.Intro) +- Find out more about slash commands in the + [Slash Command Guides](xref:Guides.SlashCommands.Intro) #### Context Message & User Ccommands -These commands can be pointed at messages and users, in custom application tabs. +These commands can be pointed at messages and users, in custom application tabs. Being interactions as well, they are able to be handled just like slash commands. They do not have options however. -- Learn how to create and handle these commands in the -[Context Command Guides](xref:Guides.ContextCommands.Creating) +- Learn how to create and handle these commands in the + [Context Command Guides](xref:Guides.ContextCommands.Creating) #### Message Components -Components of a message such as buttons and dropdowns, which can be interacted with and responded to. +Components of a message such as buttons and dropdowns, which can be interacted with and responded to. Message components can be set in rows and multiple can exist on a single message! -- Explanation on how to add & respond to message components can be found in the -[Message Component Guides](xref:Guides.MessageComponents.Intro) \ No newline at end of file +- Explanation on how to add & respond to message components can be found in the + [Message Component Guides](xref:Guides.MessageComponents.Intro)