Browse Source

Merge branch 'refactor/3.x' into release/3.x

pull/1923/head
quin lynch 3 years ago
parent
commit
eb42e04386
67 changed files with 1017 additions and 563 deletions
  1. +8
    -3
      src/Discord.Net.Commands/Builders/CommandBuilder.cs
  2. +7
    -2
      src/Discord.Net.Commands/Builders/ModuleBuilder.cs
  3. +7
    -2
      src/Discord.Net.Commands/Builders/ParameterBuilder.cs
  4. +10
    -3
      src/Discord.Net.Commands/CommandService.cs
  5. +3
    -1
      src/Discord.Net.Commands/Discord.Net.Commands.xml
  6. +8
    -3
      src/Discord.Net.Commands/ModuleBase.cs
  7. +1
    -2
      src/Discord.Net.Core/CDN.cs
  8. +135
    -52
      src/Discord.Net.Core/Discord.Net.Core.xml
  9. +6
    -3
      src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs
  10. +26
    -0
      src/Discord.Net.Core/Entities/Guilds/IGuild.cs
  11. +2
    -2
      src/Discord.Net.Core/Entities/Interactions/InteractionResponseType.cs
  12. +89
    -36
      src/Discord.Net.Core/Entities/Interactions/Message Components/ComponentBuilder.cs
  13. +2
    -2
      src/Discord.Net.Core/Entities/Interactions/Message Components/SelectMenuComponent.cs
  14. +1
    -1
      src/Discord.Net.Core/Entities/Interactions/Message Components/SelectMenuOption.cs
  15. +14
    -15
      src/Discord.Net.Core/Entities/Stickers/ISticker.cs
  16. +24
    -0
      src/Discord.Net.Core/Entities/Stickers/StickerType.cs
  17. +1
    -1
      src/Discord.Net.Rest/API/Common/ActionRowComponent.cs
  18. +0
    -20
      src/Discord.Net.Rest/API/Common/InteractionFollowupMessage.cs
  19. +1
    -1
      src/Discord.Net.Rest/API/Common/SelectMenuComponent.cs
  20. +6
    -4
      src/Discord.Net.Rest/API/Common/Sticker.cs
  21. +4
    -0
      src/Discord.Net.Rest/API/Rest/CreateMessageParams.cs
  22. +3
    -0
      src/Discord.Net.Rest/API/Rest/UploadFileParams.cs
  23. +4
    -1
      src/Discord.Net.Rest/BaseDiscordClient.cs
  24. +2
    -1
      src/Discord.Net.Rest/ClientHelper.cs
  25. +65
    -26
      src/Discord.Net.Rest/Discord.Net.Rest.xml
  26. +83
    -52
      src/Discord.Net.Rest/DiscordRestApiClient.cs
  27. +5
    -1
      src/Discord.Net.Rest/DiscordRestClient.cs
  28. +16
    -6
      src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs
  29. +11
    -5
      src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs
  30. +4
    -1
      src/Discord.Net.Rest/Entities/Channels/RestCategoryChannel.cs
  31. +4
    -1
      src/Discord.Net.Rest/Entities/Channels/RestChannel.cs
  32. +12
    -12
      src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs
  33. +12
    -12
      src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs
  34. +6
    -2
      src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs
  35. +26
    -18
      src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs
  36. +10
    -4
      src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs
  37. +52
    -12
      src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
  38. +60
    -14
      src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
  39. +25
    -19
      src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs
  40. +4
    -1
      src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs
  41. +1
    -1
      src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
  42. +12
    -9
      src/Discord.Net.Rest/Entities/Messages/Sticker.cs
  43. +6
    -2
      src/Discord.Net.Rest/Entities/Roles/RestRole.cs
  44. +2
    -1
      src/Discord.Net.Rest/Entities/Roles/RoleHelper.cs
  45. +6
    -2
      src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs
  46. +4
    -1
      src/Discord.Net.Rest/Entities/Users/RestUser.cs
  47. +6
    -2
      src/Discord.Net.Rest/Entities/Users/RestWebhookUser.cs
  48. +4
    -1
      src/Discord.Net.Rest/Entities/Webhooks/RestWebhook.cs
  49. +4
    -1
      src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs
  50. +74
    -65
      src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml
  51. +0
    -6
      src/Discord.Net.WebSocket/DiscordSocketClient.cs
  52. +0
    -23
      src/Discord.Net.WebSocket/DiscordSocketConfig.cs
  53. +8
    -5
      src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs
  54. +12
    -12
      src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs
  55. +13
    -12
      src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs
  56. +12
    -12
      src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs
  57. +56
    -14
      src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
  58. +2
    -8
      src/Discord.Net.WebSocket/Entities/Interaction/Message Components/SocketMessageComponent.cs
  59. +1
    -1
      src/Discord.Net.WebSocket/Entities/Interaction/Message Components/SocketMessageComponentData.cs
  60. +1
    -7
      src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBase.cs
  61. +1
    -1
      src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
  62. +1
    -1
      src/Discord.Net.WebSocket/Entities/Stickers/SocketCustomSticker.cs
  63. +13
    -8
      src/Discord.Net.WebSocket/Entities/Stickers/SocketSticker.cs
  64. +9
    -6
      src/Discord.Net.WebSocket/Entities/Stickers/SocketUnknownSticker.cs
  65. +4
    -15
      test/Discord.Net.Tests.Unit/MockedEntities/MockedDMChannel.cs
  66. +3
    -3
      test/Discord.Net.Tests.Unit/MockedEntities/MockedGroupChannel.cs
  67. +3
    -3
      test/Discord.Net.Tests.Unit/MockedEntities/MockedTextChannel.cs

+ 8
- 3
src/Discord.Net.Commands/Builders/CommandBuilder.cs View File

@@ -7,6 +7,7 @@ namespace Discord.Commands.Builders
{ {
public class CommandBuilder public class CommandBuilder
{ {
#region CommandBuilder
private readonly List<PreconditionAttribute> _preconditions; private readonly List<PreconditionAttribute> _preconditions;
private readonly List<ParameterBuilder> _parameters; private readonly List<ParameterBuilder> _parameters;
private readonly List<Attribute> _attributes; private readonly List<Attribute> _attributes;
@@ -27,8 +28,9 @@ namespace Discord.Commands.Builders
public IReadOnlyList<ParameterBuilder> Parameters => _parameters; public IReadOnlyList<ParameterBuilder> Parameters => _parameters;
public IReadOnlyList<Attribute> Attributes => _attributes; public IReadOnlyList<Attribute> Attributes => _attributes;
public IReadOnlyList<string> Aliases => _aliases; public IReadOnlyList<string> Aliases => _aliases;
#endregion


//Automatic
#region Automatic
internal CommandBuilder(ModuleBuilder module) internal CommandBuilder(ModuleBuilder module)
{ {
Module = module; Module = module;
@@ -38,7 +40,9 @@ namespace Discord.Commands.Builders
_attributes = new List<Attribute>(); _attributes = new List<Attribute>();
_aliases = new List<string>(); _aliases = new List<string>();
} }
//User-defined
#endregion

#region User-defined
internal CommandBuilder(ModuleBuilder module, string primaryAlias, Func<ICommandContext, object[], IServiceProvider, CommandInfo, Task> callback) internal CommandBuilder(ModuleBuilder module, string primaryAlias, Func<ICommandContext, object[], IServiceProvider, CommandInfo, Task> callback)
: this(module) : this(module)
{ {
@@ -132,7 +136,7 @@ namespace Discord.Commands.Builders
var firstMultipleParam = _parameters.FirstOrDefault(x => x.IsMultiple); var firstMultipleParam = _parameters.FirstOrDefault(x => x.IsMultiple);
if ((firstMultipleParam != null) && (firstMultipleParam != lastParam)) if ((firstMultipleParam != null) && (firstMultipleParam != lastParam))
throw new InvalidOperationException($"Only the last parameter in a command may have the Multiple flag. Parameter: {firstMultipleParam.Name} in {PrimaryAlias}"); throw new InvalidOperationException($"Only the last parameter in a command may have the Multiple flag. Parameter: {firstMultipleParam.Name} in {PrimaryAlias}");
var firstRemainderParam = _parameters.FirstOrDefault(x => x.IsRemainder); var firstRemainderParam = _parameters.FirstOrDefault(x => x.IsRemainder);
if ((firstRemainderParam != null) && (firstRemainderParam != lastParam)) if ((firstRemainderParam != null) && (firstRemainderParam != lastParam))
throw new InvalidOperationException($"Only the last parameter in a command may have the Remainder flag. Parameter: {firstRemainderParam.Name} in {PrimaryAlias}"); throw new InvalidOperationException($"Only the last parameter in a command may have the Remainder flag. Parameter: {firstRemainderParam.Name} in {PrimaryAlias}");
@@ -140,5 +144,6 @@ namespace Discord.Commands.Builders


return new CommandInfo(this, info, service); return new CommandInfo(this, info, service);
} }
#endregion
} }
} }

+ 7
- 2
src/Discord.Net.Commands/Builders/ModuleBuilder.cs View File

@@ -7,6 +7,7 @@ namespace Discord.Commands.Builders
{ {
public class ModuleBuilder public class ModuleBuilder
{ {
#region ModuleBuilder
private readonly List<CommandBuilder> _commands; private readonly List<CommandBuilder> _commands;
private readonly List<ModuleBuilder> _submodules; private readonly List<ModuleBuilder> _submodules;
private readonly List<PreconditionAttribute> _preconditions; private readonly List<PreconditionAttribute> _preconditions;
@@ -27,8 +28,9 @@ namespace Discord.Commands.Builders
public IReadOnlyList<string> Aliases => _aliases; public IReadOnlyList<string> Aliases => _aliases;


internal TypeInfo TypeInfo { get; set; } internal TypeInfo TypeInfo { get; set; }
#endregion


//Automatic
#region Automatic
internal ModuleBuilder(CommandService service, ModuleBuilder parent) internal ModuleBuilder(CommandService service, ModuleBuilder parent)
{ {
Service = service; Service = service;
@@ -40,7 +42,9 @@ namespace Discord.Commands.Builders
_attributes = new List<Attribute>(); _attributes = new List<Attribute>();
_aliases = new List<string>(); _aliases = new List<string>();
} }
//User-defined
#endregion

#region User-defined
internal ModuleBuilder(CommandService service, ModuleBuilder parent, string primaryAlias) internal ModuleBuilder(CommandService service, ModuleBuilder parent, string primaryAlias)
: this(service, parent) : this(service, parent)
{ {
@@ -132,5 +136,6 @@ namespace Discord.Commands.Builders
public ModuleInfo Build(CommandService service, IServiceProvider services) => BuildImpl(service, services); public ModuleInfo Build(CommandService service, IServiceProvider services) => BuildImpl(service, services);


internal ModuleInfo Build(CommandService service, IServiceProvider services, ModuleInfo parent) => BuildImpl(service, services, parent); internal ModuleInfo Build(CommandService service, IServiceProvider services, ModuleInfo parent) => BuildImpl(service, services, parent);
#endregion
} }
} }

+ 7
- 2
src/Discord.Net.Commands/Builders/ParameterBuilder.cs View File

@@ -8,6 +8,7 @@ namespace Discord.Commands.Builders
{ {
public class ParameterBuilder public class ParameterBuilder
{ {
#region ParameterBuilder
private readonly List<ParameterPreconditionAttribute> _preconditions; private readonly List<ParameterPreconditionAttribute> _preconditions;
private readonly List<Attribute> _attributes; private readonly List<Attribute> _attributes;


@@ -24,8 +25,9 @@ namespace Discord.Commands.Builders


public IReadOnlyList<ParameterPreconditionAttribute> Preconditions => _preconditions; public IReadOnlyList<ParameterPreconditionAttribute> Preconditions => _preconditions;
public IReadOnlyList<Attribute> Attributes => _attributes; public IReadOnlyList<Attribute> Attributes => _attributes;
#endregion


//Automatic
#region Automatic
internal ParameterBuilder(CommandBuilder command) internal ParameterBuilder(CommandBuilder command)
{ {
_preconditions = new List<ParameterPreconditionAttribute>(); _preconditions = new List<ParameterPreconditionAttribute>();
@@ -33,7 +35,9 @@ namespace Discord.Commands.Builders


Command = command; Command = command;
} }
//User-defined
#endregion

#region User-defined
internal ParameterBuilder(CommandBuilder command, string name, Type type) internal ParameterBuilder(CommandBuilder command, string name, Type type)
: this(command) : this(command)
{ {
@@ -132,5 +136,6 @@ namespace Discord.Commands.Builders


return new ParameterInfo(this, info, Command.Module.Service); return new ParameterInfo(this, info, Command.Module.Service);
} }
#endregion
} }
} }

+ 10
- 3
src/Discord.Net.Commands/CommandService.cs View File

@@ -29,6 +29,7 @@ namespace Discord.Commands
/// </remarks> /// </remarks>
public class CommandService : IDisposable public class CommandService : IDisposable
{ {
#region CommandService
/// <summary> /// <summary>
/// Occurs when a command-related information is received. /// Occurs when a command-related information is received.
/// </summary> /// </summary>
@@ -131,8 +132,9 @@ namespace Discord.Commands
entityTypeReaders.Add((typeof(IUser), typeof(UserTypeReader<>))); entityTypeReaders.Add((typeof(IUser), typeof(UserTypeReader<>)));
_entityTypeReaders = entityTypeReaders.ToImmutable(); _entityTypeReaders = entityTypeReaders.ToImmutable();
} }
#endregion


//Modules
#region Modules
public async Task<ModuleInfo> CreateModuleAsync(string primaryAlias, Action<ModuleBuilder> buildFunc) public async Task<ModuleInfo> CreateModuleAsync(string primaryAlias, Action<ModuleBuilder> buildFunc)
{ {
await _moduleLock.WaitAsync().ConfigureAwait(false); await _moduleLock.WaitAsync().ConfigureAwait(false);
@@ -322,8 +324,9 @@ namespace Discord.Commands


return true; return true;
} }
#endregion


//Type Readers
#region Type Readers
/// <summary> /// <summary>
/// Adds a custom <see cref="TypeReader" /> to this <see cref="CommandService" /> for the supplied object /// Adds a custom <see cref="TypeReader" /> to this <see cref="CommandService" /> for the supplied object
/// type. /// type.
@@ -448,8 +451,9 @@ namespace Discord.Commands
} }
return null; return null;
} }
#endregion


//Execution
#region Execution
/// <summary> /// <summary>
/// Searches for the command. /// Searches for the command.
/// </summary> /// </summary>
@@ -602,7 +606,9 @@ namespace Discord.Commands
await _commandExecutedEvent.InvokeAsync(chosenOverload.Key.Command, context, result); await _commandExecutedEvent.InvokeAsync(chosenOverload.Key.Command, context, result);
return result; return result;
} }
#endregion


#region Dispose
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
if (!_isDisposed) if (!_isDisposed)
@@ -620,5 +626,6 @@ namespace Discord.Commands
{ {
Dispose(true); Dispose(true);
} }
#endregion
} }
} }

+ 3
- 1
src/Discord.Net.Commands/Discord.Net.Commands.xml View File

@@ -1129,7 +1129,7 @@
<seealso cref="T:Discord.Commands.ICommandContext" /> <seealso cref="T:Discord.Commands.ICommandContext" />
<seealso cref="T:Discord.Commands.CommandContext" /> <seealso cref="T:Discord.Commands.CommandContext" />
</member> </member>
<member name="M:Discord.Commands.ModuleBase`1.ReplyAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Commands.ModuleBase`1.ReplyAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<summary> <summary>
Sends a message to the source channel. Sends a message to the source channel.
</summary> </summary>
@@ -1143,6 +1143,8 @@
If <c>null</c>, all mentioned roles and users will be notified. If <c>null</c>, all mentioned roles and users will be notified.
</param> </param>
<param name="messageReference">The message references to be included. Used to reply to specific messages.</param> <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
<param name="component">The message components to be included with this message. Used for interactions</param>
<param name="stickers">A collection of stickers to send with the file.</param>
</member> </member>
<member name="M:Discord.Commands.ModuleBase`1.BeforeExecute(Discord.Commands.CommandInfo)"> <member name="M:Discord.Commands.ModuleBase`1.BeforeExecute(Discord.Commands.CommandInfo)">
<summary> <summary>


+ 8
- 3
src/Discord.Net.Commands/ModuleBase.cs View File

@@ -16,6 +16,7 @@ namespace Discord.Commands
public abstract class ModuleBase<T> : IModuleBase public abstract class ModuleBase<T> : IModuleBase
where T : class, ICommandContext where T : class, ICommandContext
{ {
#region ModuleBase
/// <summary> /// <summary>
/// The underlying context of the command. /// The underlying context of the command.
/// </summary> /// </summary>
@@ -36,9 +37,11 @@ namespace Discord.Commands
/// If <c>null</c>, all mentioned roles and users will be notified. /// If <c>null</c>, all mentioned roles and users will be notified.
/// </param> /// </param>
/// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param> /// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
protected virtual async Task<IUserMessage> ReplyAsync(string message = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
/// <param name="component">The message components to be included with this message. Used for interactions</param>
/// <param name="stickers">A collection of stickers to send with the file.</param>
protected virtual async Task<IUserMessage> ReplyAsync(string message = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
{ {
return await Context.Channel.SendMessageAsync(message, isTTS, embed, options, allowedMentions, messageReference, component).ConfigureAwait(false);
return await Context.Channel.SendMessageAsync(message, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
} }
/// <summary> /// <summary>
/// The method to execute before executing the command. /// The method to execute before executing the command.
@@ -63,8 +66,9 @@ namespace Discord.Commands
protected virtual void OnModuleBuilding(CommandService commandService, ModuleBuilder builder) protected virtual void OnModuleBuilding(CommandService commandService, ModuleBuilder builder)
{ {
} }
#endregion


//IModuleBase
#region IModuleBase
void IModuleBase.SetContext(ICommandContext context) void IModuleBase.SetContext(ICommandContext context)
{ {
var newValue = context as T; var newValue = context as T;
@@ -73,5 +77,6 @@ namespace Discord.Commands
void IModuleBase.BeforeExecute(CommandInfo command) => BeforeExecute(command); void IModuleBase.BeforeExecute(CommandInfo command) => BeforeExecute(command);
void IModuleBase.AfterExecute(CommandInfo command) => AfterExecute(command); void IModuleBase.AfterExecute(CommandInfo command) => AfterExecute(command);
void IModuleBase.OnModuleBuilding(CommandService commandService, ModuleBuilder builder) => OnModuleBuilding(commandService, builder); void IModuleBase.OnModuleBuilding(CommandService commandService, ModuleBuilder builder) => OnModuleBuilding(commandService, builder);
#endregion
} }
} }

+ 1
- 2
src/Discord.Net.Core/CDN.cs View File

@@ -194,11 +194,10 @@ namespace Discord
{ {
case StickerFormatType.None: case StickerFormatType.None:
case StickerFormatType.Png: case StickerFormatType.Png:
case StickerFormatType.Apng: // In the case of the Sticker endpoint, the sticker will be available as PNG if its format_type is PNG or APNG, and as Lottie if its format_type is LOTTIE.
return "png"; return "png";
case StickerFormatType.Lottie: case StickerFormatType.Lottie:
return "lottie"; return "lottie";
case StickerFormatType.Apng:
return "apng";
default: default:
throw new ArgumentException(nameof(format)); throw new ArgumentException(nameof(format));




+ 135
- 52
src/Discord.Net.Core/Discord.Net.Core.xml View File

@@ -1507,7 +1507,7 @@
Represents a generic channel that can send and receive messages. Represents a generic channel that can send and receive messages.
</summary> </summary>
</member> </member>
<member name="M:Discord.IMessageChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.IMessageChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<summary> <summary>
Sends a message to this message channel. Sends a message to this message channel.
</summary> </summary>
@@ -1527,12 +1527,13 @@
</param> </param>
<param name="messageReference">The message references to be included. Used to reply to specific messages.</param> <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
<param name="component">The message components to be included with this message. Used for interactions</param> <param name="component">The message components to be included with this message. Used for interactions</param>
<param name="stickers">A collection of stickers to send with the message.</param>
<returns> <returns>
A task that represents an asynchronous send operation for delivering the message. The task result A task that represents an asynchronous send operation for delivering the message. The task result
contains the sent message. contains the sent message.
</returns> </returns>
</member> </member>
<member name="M:Discord.IMessageChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.IMessageChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<summary> <summary>
Sends a file to this message channel with an optional caption. Sends a file to this message channel with an optional caption.
</summary> </summary>
@@ -1566,12 +1567,13 @@
</param> </param>
<param name="messageReference">The message references to be included. Used to reply to specific messages.</param> <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
<param name="component">The message components to be included with this message. Used for interactions</param> <param name="component">The message components to be included with this message. Used for interactions</param>
<param name="stickers">A collection of stickers to send with the file.</param>
<returns> <returns>
A task that represents an asynchronous send operation for delivering the message. The task result A task that represents an asynchronous send operation for delivering the message. The task result
contains the sent message. contains the sent message.
</returns> </returns>
</member> </member>
<member name="M:Discord.IMessageChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.IMessageChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<summary> <summary>
Sends a file to this message channel with an optional caption. Sends a file to this message channel with an optional caption.
</summary> </summary>
@@ -1602,6 +1604,7 @@
</param> </param>
<param name="messageReference">The message references to be included. Used to reply to specific messages.</param> <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
<param name="component">The message components to be included with this message. Used for interactions</param> <param name="component">The message components to be included with this message. Used for interactions</param>
<param name="stickers">A collection of stickers to send with the file.</param>
<returns> <returns>
A task that represents an asynchronous send operation for delivering the message. The task result A task that represents an asynchronous send operation for delivering the message. The task result
contains the sent message. contains the sent message.
@@ -3639,6 +3642,18 @@
voice channel. voice channel.
</returns> </returns>
</member> </member>
<member name="M:Discord.IGuild.CreateStageChannelAsync(System.String,System.Action{Discord.VoiceChannelProperties},Discord.RequestOptions)">
<summary>
Creates a new stage channel in this guild.
</summary>
<param name="name">The new name for the stage channel.</param>
<param name="func">The delegate containing the properties to be applied to the channel upon its creation.</param>
<param name="options">The options to be used when sending the request.</param>
<returns>
A task that represents the asynchronous creation operation. The task result contains the newly created
stage channel.
</returns>
</member>
<member name="M:Discord.IGuild.CreateCategoryAsync(System.String,System.Action{Discord.GuildChannelProperties},Discord.RequestOptions)"> <member name="M:Discord.IGuild.CreateCategoryAsync(System.String,System.Action{Discord.GuildChannelProperties},Discord.RequestOptions)">
<summary> <summary>
Creates a new channel category in this guild. Creates a new channel category in this guild.
@@ -3732,6 +3747,13 @@
<param name="options">The options to be used when sending the request.</param> <param name="options">The options to be used when sending the request.</param>
<returns>A guild user associated with the specified <paramref name="userId" />; <see langword="null" /> if the user is already in the guild.</returns> <returns>A guild user associated with the specified <paramref name="userId" />; <see langword="null" /> if the user is already in the guild.</returns>
</member> </member>
<member name="M:Discord.IGuild.DisconnectAsync(Discord.IGuildUser)">
<summary>
Disconnects the user from its current voice channel
</summary>
<param name="user">The user to disconnect.</param>
<returns>A task that represents the asynchronous operation for disconnecting a user.</returns>
</member>
<member name="M:Discord.IGuild.GetUsersAsync(Discord.CacheMode,Discord.RequestOptions)"> <member name="M:Discord.IGuild.GetUsersAsync(Discord.CacheMode,Discord.RequestOptions)">
<summary> <summary>
Gets a collection of all users in this guild. Gets a collection of all users in this guild.
@@ -3921,6 +3943,14 @@
emote. emote.
</returns> </returns>
</member> </member>
<member name="M:Discord.IGuild.MoveAsync(Discord.IGuildUser,Discord.IVoiceChannel)">
<summary>
Moves the user to the voice channel.
</summary>
<param name="user">The user to move.</param>
<param name="targetChannel">the channel where the user gets moved to.</param>
<returns>A task that represents the asynchronous operation for moving a user.</returns>
</member>
<member name="M:Discord.IGuild.DeleteEmoteAsync(Discord.GuildEmote,Discord.RequestOptions)"> <member name="M:Discord.IGuild.DeleteEmoteAsync(Discord.GuildEmote,Discord.RequestOptions)">
<summary> <summary>
Deletes an existing <see cref="T:Discord.GuildEmote"/> from this guild. Deletes an existing <see cref="T:Discord.GuildEmote"/> from this guild.
@@ -4524,6 +4554,9 @@
<member name="P:Discord.ApplicationCommandOptionChoiceProperties.Value"> <member name="P:Discord.ApplicationCommandOptionChoiceProperties.Value">
<summary> <summary>
The value of this choice. The value of this choice.
<note type="warning">
Discord only accepts int and string as the input.
</note>
</summary> </summary>
</member> </member>
<member name="T:Discord.ApplicationCommandOptionType"> <member name="T:Discord.ApplicationCommandOptionType">
@@ -4591,6 +4624,11 @@
Gets or sets the name of this command. Gets or sets the name of this command.
</summary> </summary>
</member> </member>
<member name="P:Discord.ApplicationCommandProperties.DefaultPermission">
<summary>
Whether the command is enabled by default when the app is added to a guild. Default is <see langword="true"/>
</summary>
</member>
<member name="T:Discord.ApplicationCommandType"> <member name="T:Discord.ApplicationCommandType">
<summary> <summary>
ApplicationCommandType is enum of current valid Application Command Types: Slash, User, Message ApplicationCommandType is enum of current valid Application Command Types: Slash, User, Message
@@ -4626,6 +4664,11 @@
The name of this Message command. The name of this Message command.
</summary> </summary>
</member> </member>
<member name="P:Discord.MessageCommandBuilder.DefaultPermission">
<summary>
Whether the command is enabled by default when the app is added to a guild
</summary>
</member>
<member name="M:Discord.MessageCommandBuilder.Build"> <member name="M:Discord.MessageCommandBuilder.Build">
<summary> <summary>
Build the current builder into a <see cref="T:Discord.MessageCommandProperties"/> class. Build the current builder into a <see cref="T:Discord.MessageCommandProperties"/> class.
@@ -4643,6 +4686,13 @@
The current builder. The current builder.
</returns> </returns>
</member> </member>
<member name="M:Discord.MessageCommandBuilder.WithDefaultPermission(System.Boolean)">
<summary>
Sets the default permission of the current command.
</summary>
<param name="value">The default permission value to set.</param>
<returns>The current builder.</returns>
</member>
<member name="T:Discord.MessageCommandProperties"> <member name="T:Discord.MessageCommandProperties">
<summary> <summary>
A class used to create message commands. A class used to create message commands.
@@ -4663,6 +4713,11 @@
The name of this User command. The name of this User command.
</summary> </summary>
</member> </member>
<member name="P:Discord.UserCommandBuilder.DefaultPermission">
<summary>
Whether the command is enabled by default when the app is added to a guild
</summary>
</member>
<member name="M:Discord.UserCommandBuilder.Build"> <member name="M:Discord.UserCommandBuilder.Build">
<summary> <summary>
Build the current builder into a <see cref="T:Discord.UserCommandProperties"/> class. Build the current builder into a <see cref="T:Discord.UserCommandProperties"/> class.
@@ -4678,6 +4733,13 @@
The current builder. The current builder.
</returns> </returns>
</member> </member>
<member name="M:Discord.UserCommandBuilder.WithDefaultPermission(System.Boolean)">
<summary>
Sets the default permission of the current command.
</summary>
<param name="value">The default permission value to set.</param>
<returns>The current builder.</returns>
</member>
<member name="T:Discord.UserCommandProperties"> <member name="T:Discord.UserCommandProperties">
<summary> <summary>
A class used to create User commands. A class used to create User commands.
@@ -4945,6 +5007,16 @@
ACK a Ping. ACK a Ping.
</summary> </summary>
</member> </member>
<member name="F:Discord.InteractionResponseType.Acknowledge">
<summary>
ACK a command without sending a message, eating the user's input.
</summary>
</member>
<member name="F:Discord.InteractionResponseType.ChannelMessage">
<summary>
Respond with a message, showing the user's input.
</summary>
</member>
<member name="F:Discord.InteractionResponseType.ChannelMessageWithSource"> <member name="F:Discord.InteractionResponseType.ChannelMessageWithSource">
<summary> <summary>
Respond to an interaction with a message. Respond to an interaction with a message.
@@ -5082,11 +5154,6 @@
Represents a builder for creating a <see cref="T:Discord.MessageComponent"/>. Represents a builder for creating a <see cref="T:Discord.MessageComponent"/>.
</summary> </summary>
</member> </member>
<member name="F:Discord.ComponentBuilder.MaxButtonLabelLength">
<summary>
The max length of a <see cref="P:Discord.ButtonComponent.Label"/>.
</summary>
</member>
<member name="F:Discord.ComponentBuilder.MaxCustomIdLength"> <member name="F:Discord.ComponentBuilder.MaxCustomIdLength">
<summary> <summary>
The max length of a <see cref="P:Discord.ButtonComponent.CustomId"/>. The max length of a <see cref="P:Discord.ButtonComponent.CustomId"/>.
@@ -5173,7 +5240,7 @@
<summary> <summary>
Builds this builder into a <see cref="T:Discord.MessageComponent"/> used to send your components. Builds this builder into a <see cref="T:Discord.MessageComponent"/> used to send your components.
</summary> </summary>
<returns>A <see cref="T:Discord.MessageComponent"/> that can be sent with <see cref="M:Discord.IMessageChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)"/>.</returns>
<returns>A <see cref="T:Discord.MessageComponent"/> that can be sent with <see cref="!:IMessageChannel.SendMessageAsync(string, bool, Embed, RequestOptions, AllowedMentions, MessageReference, MessageComponent)"/>.</returns>
</member> </member>
<member name="T:Discord.ActionRowBuilder"> <member name="T:Discord.ActionRowBuilder">
<summary> <summary>
@@ -5219,7 +5286,7 @@
Represents a class used to build <see cref="T:Discord.ButtonComponent"/>'s. Represents a class used to build <see cref="T:Discord.ButtonComponent"/>'s.
</summary> </summary>
</member> </member>
<member name="F:Discord.ButtonBuilder.MaxLabelLength">
<member name="F:Discord.ButtonBuilder.MaxButtonLabelLength">
<summary> <summary>
The max length of a <see cref="P:Discord.ButtonComponent.Label"/>. The max length of a <see cref="P:Discord.ButtonComponent.Label"/>.
</summary> </summary>
@@ -5228,13 +5295,15 @@
<summary> <summary>
Gets or sets the label of the current button. Gets or sets the label of the current button.
</summary> </summary>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.ButtonBuilder.Label"/> length exceeds <see cref="F:Discord.ComponentBuilder.MaxButtonLabelLength"/>.</exception>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.ButtonBuilder.Label"/> length exceeds <see cref="F:Discord.ButtonBuilder.MaxButtonLabelLength"/>.</exception>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.ButtonBuilder.Label"/> length exceeds <see cref="F:Discord.ButtonBuilder.MaxButtonLabelLength"/>.</exception>
</member> </member>
<member name="P:Discord.ButtonBuilder.CustomId"> <member name="P:Discord.ButtonBuilder.CustomId">
<summary> <summary>
Gets or sets the custom id of the current button. Gets or sets the custom id of the current button.
</summary> </summary>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.ButtonBuilder.CustomId"/> length exceeds <see cref="F:Discord.ComponentBuilder.MaxCustomIdLength"/></exception> <exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.ButtonBuilder.CustomId"/> length exceeds <see cref="F:Discord.ComponentBuilder.MaxCustomIdLength"/></exception>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.ButtonBuilder.CustomId"/> length subceeds 1.</exception>
</member> </member>
<member name="P:Discord.ButtonBuilder.Style"> <member name="P:Discord.ButtonBuilder.Style">
<summary> <summary>
@@ -5379,35 +5448,37 @@
</member> </member>
<member name="T:Discord.SelectMenuBuilder"> <member name="T:Discord.SelectMenuBuilder">
<summary> <summary>
Represents a class used to build <see cref="T:Discord.SelectMenu"/>'s.
Represents a class used to build <see cref="T:Discord.SelectMenuComponent"/>'s.
</summary> </summary>
</member> </member>
<member name="F:Discord.SelectMenuBuilder.MaxPlaceholderLength"> <member name="F:Discord.SelectMenuBuilder.MaxPlaceholderLength">
<summary> <summary>
The max length of a <see cref="P:Discord.SelectMenu.Placeholder"/>.
The max length of a <see cref="P:Discord.SelectMenuComponent.Placeholder"/>.
</summary> </summary>
</member> </member>
<member name="F:Discord.SelectMenuBuilder.MaxValuesCount"> <member name="F:Discord.SelectMenuBuilder.MaxValuesCount">
<summary> <summary>
The maximum number of values for the <see cref="P:Discord.SelectMenu.MinValues"/> and <see cref="P:Discord.SelectMenu.MaxValues"/> properties.
The maximum number of values for the <see cref="P:Discord.SelectMenuComponent.MinValues"/> and <see cref="P:Discord.SelectMenuComponent.MaxValues"/> properties.
</summary> </summary>
</member> </member>
<member name="F:Discord.SelectMenuBuilder.MaxOptionCount"> <member name="F:Discord.SelectMenuBuilder.MaxOptionCount">
<summary> <summary>
The maximum number of options a <see cref="T:Discord.SelectMenu"/> can have.
The maximum number of options a <see cref="T:Discord.SelectMenuComponent"/> can have.
</summary> </summary>
</member> </member>
<member name="P:Discord.SelectMenuBuilder.CustomId"> <member name="P:Discord.SelectMenuBuilder.CustomId">
<summary> <summary>
Gets or sets the custom id of the current select menu. Gets or sets the custom id of the current select menu.
</summary> </summary>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuBuilder.CustomId"/> length exceeds <see cref="F:Discord.ComponentBuilder.MaxCustomIdLength"/>.</exception>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuBuilder.CustomId"/> length exceeds <see cref="F:Discord.ComponentBuilder.MaxCustomIdLength"/></exception>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuBuilder.CustomId"/> length subceeds 1.</exception>
</member> </member>
<member name="P:Discord.SelectMenuBuilder.Placeholder"> <member name="P:Discord.SelectMenuBuilder.Placeholder">
<summary> <summary>
Gets or sets the placeholder text of the current select menu. Gets or sets the placeholder text of the current select menu.
</summary> </summary>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuBuilder.Placeholder"/> length exceeds <see cref="F:Discord.SelectMenuBuilder.MaxPlaceholderLength"/>.</exception> <exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuBuilder.Placeholder"/> length exceeds <see cref="F:Discord.SelectMenuBuilder.MaxPlaceholderLength"/>.</exception>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuBuilder.Placeholder"/> length subceeds 1.</exception>
</member> </member>
<member name="P:Discord.SelectMenuBuilder.MinValues"> <member name="P:Discord.SelectMenuBuilder.MinValues">
<summary> <summary>
@@ -5438,9 +5509,9 @@
Creates a new instance of a <see cref="T:Discord.SelectMenuBuilder"/>. Creates a new instance of a <see cref="T:Discord.SelectMenuBuilder"/>.
</summary> </summary>
</member> </member>
<member name="M:Discord.SelectMenuBuilder.#ctor(Discord.SelectMenu)">
<member name="M:Discord.SelectMenuBuilder.#ctor(Discord.SelectMenuComponent)">
<summary> <summary>
Creates a new instance of a <see cref="T:Discord.SelectMenuBuilder"/> from instance of <see cref="T:Discord.SelectMenu"/>.
Creates a new instance of a <see cref="T:Discord.SelectMenuBuilder"/> from instance of <see cref="T:Discord.SelectMenuComponent"/>.
</summary> </summary>
</member> </member>
<member name="M:Discord.SelectMenuBuilder.#ctor(System.String,System.Collections.Generic.List{Discord.SelectMenuOptionBuilder},System.String,System.Int32,System.Int32,System.Boolean)"> <member name="M:Discord.SelectMenuBuilder.#ctor(System.String,System.Collections.Generic.List{Discord.SelectMenuOptionBuilder},System.String,System.Int32,System.Int32,System.Boolean)">
@@ -5539,16 +5610,16 @@
</member> </member>
<member name="M:Discord.SelectMenuBuilder.Build"> <member name="M:Discord.SelectMenuBuilder.Build">
<summary> <summary>
Builds a <see cref="T:Discord.SelectMenu"/>
Builds a <see cref="T:Discord.SelectMenuComponent"/>
</summary> </summary>
<returns>The newly built <see cref="T:Discord.SelectMenu"/></returns>
<returns>The newly built <see cref="T:Discord.SelectMenuComponent"/></returns>
</member> </member>
<member name="T:Discord.SelectMenuOptionBuilder"> <member name="T:Discord.SelectMenuOptionBuilder">
<summary> <summary>
Represents a class used to build <see cref="T:Discord.SelectMenuOption"/>'s. Represents a class used to build <see cref="T:Discord.SelectMenuOption"/>'s.
</summary> </summary>
</member> </member>
<member name="F:Discord.SelectMenuOptionBuilder.MaxLabelLength">
<member name="F:Discord.SelectMenuOptionBuilder.MaxSelectLabelLength">
<summary> <summary>
The maximum length of a <see cref="P:Discord.SelectMenuOption.Label"/>. The maximum length of a <see cref="P:Discord.SelectMenuOption.Label"/>.
</summary> </summary>
@@ -5558,9 +5629,9 @@
The maximum length of a <see cref="P:Discord.SelectMenuOption.Description"/>. The maximum length of a <see cref="P:Discord.SelectMenuOption.Description"/>.
</summary> </summary>
</member> </member>
<member name="F:Discord.SelectMenuOptionBuilder.MaxSelectLabelLength">
<member name="F:Discord.SelectMenuOptionBuilder.MaxSelectValueLength">
<summary> <summary>
The maximum length of a <see cref="P:Discord.SelectMenuOption.Label"/>.
The maximum length of a <see cref="P:Discord.SelectMenuOption.Value"/>.
</summary> </summary>
</member> </member>
<member name="P:Discord.SelectMenuOptionBuilder.Label"> <member name="P:Discord.SelectMenuOptionBuilder.Label">
@@ -5568,18 +5639,21 @@
Gets or sets the label of the current select menu. Gets or sets the label of the current select menu.
</summary> </summary>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuOptionBuilder.Label"/> length exceeds <see cref="F:Discord.SelectMenuOptionBuilder.MaxSelectLabelLength"/></exception> <exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuOptionBuilder.Label"/> length exceeds <see cref="F:Discord.SelectMenuOptionBuilder.MaxSelectLabelLength"/></exception>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuOptionBuilder.Label"/> length subceeds 1.</exception>
</member> </member>
<member name="P:Discord.SelectMenuOptionBuilder.Value"> <member name="P:Discord.SelectMenuOptionBuilder.Value">
<summary> <summary>
Gets or sets the custom id of the current select menu. Gets or sets the custom id of the current select menu.
</summary> </summary>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuOptionBuilder.Value"/> length exceeds <see cref="F:Discord.ComponentBuilder.MaxCustomIdLength"/>.</exception>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuOptionBuilder.Value"/> length exceeds <see cref="F:Discord.SelectMenuOptionBuilder.MaxSelectValueLength"/>.</exception>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuOptionBuilder.Value"/> length subceeds 1.</exception>
</member> </member>
<member name="P:Discord.SelectMenuOptionBuilder.Description"> <member name="P:Discord.SelectMenuOptionBuilder.Description">
<summary> <summary>
Gets or sets this menu options description. Gets or sets this menu options description.
</summary> </summary>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuOptionBuilder.Description"/> length exceeds <see cref="F:Discord.SelectMenuOptionBuilder.MaxDescriptionLength"/>.</exception> <exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuOptionBuilder.Description"/> length exceeds <see cref="F:Discord.SelectMenuOptionBuilder.MaxDescriptionLength"/>.</exception>
<exception cref="T:System.ArgumentException" accessor="set"><see cref="P:Discord.SelectMenuOptionBuilder.Label"/> length subceeds 1.</exception>
</member> </member>
<member name="P:Discord.SelectMenuOptionBuilder.Emote"> <member name="P:Discord.SelectMenuOptionBuilder.Emote">
<summary> <summary>
@@ -5715,45 +5789,45 @@
Returns a empty <see cref="T:Discord.MessageComponent"/>. Returns a empty <see cref="T:Discord.MessageComponent"/>.
</summary> </summary>
</member> </member>
<member name="T:Discord.SelectMenu">
<member name="T:Discord.SelectMenuComponent">
<summary> <summary>
Represents a select menu component defined at <see href="https://discord.com/developers/docs/interactions/message-components#select-menu-object"/> Represents a select menu component defined at <see href="https://discord.com/developers/docs/interactions/message-components#select-menu-object"/>
</summary> </summary>
</member> </member>
<member name="P:Discord.SelectMenu.Type">
<member name="P:Discord.SelectMenuComponent.Type">
<inheritdoc/> <inheritdoc/>
</member> </member>
<member name="P:Discord.SelectMenu.CustomId">
<member name="P:Discord.SelectMenuComponent.CustomId">
<summary> <summary>
The custom id of this Select menu that will be sent with a <see cref="T:Discord.IDiscordInteraction"/>. The custom id of this Select menu that will be sent with a <see cref="T:Discord.IDiscordInteraction"/>.
</summary> </summary>
</member> </member>
<member name="P:Discord.SelectMenu.Options">
<member name="P:Discord.SelectMenuComponent.Options">
<summary> <summary>
The menus options to select from. The menus options to select from.
</summary> </summary>
</member> </member>
<member name="P:Discord.SelectMenu.Placeholder">
<member name="P:Discord.SelectMenuComponent.Placeholder">
<summary> <summary>
A custom placeholder text if nothing is selected, max 100 characters. A custom placeholder text if nothing is selected, max 100 characters.
</summary> </summary>
</member> </member>
<member name="P:Discord.SelectMenu.MinValues">
<member name="P:Discord.SelectMenuComponent.MinValues">
<summary> <summary>
The minimum number of items that must be chosen; default 1, min 0, max 25 The minimum number of items that must be chosen; default 1, min 0, max 25
</summary> </summary>
</member> </member>
<member name="P:Discord.SelectMenu.MaxValues">
<member name="P:Discord.SelectMenuComponent.MaxValues">
<summary> <summary>
The maximum number of items that can be chosen; default 1, max 25 The maximum number of items that can be chosen; default 1, max 25
</summary> </summary>
</member> </member>
<member name="P:Discord.SelectMenu.Disabled">
<member name="P:Discord.SelectMenuComponent.Disabled">
<summary> <summary>
Whether this menu is disabled or not. Whether this menu is disabled or not.
</summary> </summary>
</member> </member>
<member name="M:Discord.SelectMenu.ToBuilder">
<member name="M:Discord.SelectMenuComponent.ToBuilder">
<summary> <summary>
Turns this select menu into a builder. Turns this select menu into a builder.
</summary> </summary>
@@ -5763,7 +5837,7 @@
</member> </member>
<member name="T:Discord.SelectMenuOption"> <member name="T:Discord.SelectMenuOption">
<summary> <summary>
Represents a choice for a <see cref="T:Discord.SelectMenu"/>.
Represents a choice for a <see cref="T:Discord.SelectMenuComponent"/>.
</summary> </summary>
</member> </member>
<member name="P:Discord.SelectMenuOption.Label"> <member name="P:Discord.SelectMenuOption.Label">
@@ -6038,11 +6112,6 @@
Gets or sets the options for this command. Gets or sets the options for this command.
</summary> </summary>
</member> </member>
<member name="P:Discord.SlashCommandProperties.DefaultPermission">
<summary>
Whether the command is enabled by default when the app is added to a guild. Default is <see langword="true"/>
</summary>
</member>
<member name="T:Discord.IInvite"> <member name="T:Discord.IInvite">
<summary> <summary>
Represents a generic invite object. Represents a generic invite object.
@@ -9625,21 +9694,10 @@
A read-only list with the tags of this sticker. A read-only list with the tags of this sticker.
</returns> </returns>
</member> </member>
<member name="P:Discord.ISticker.Asset">
<member name="P:Discord.ISticker.Type">
<summary> <summary>
Gets the asset hash of this sticker.
Gets the type of this sticker.
</summary> </summary>
<returns>
A <see langword="string"/> with the asset hash of this sticker.
</returns>
</member>
<member name="P:Discord.ISticker.PreviewAsset">
<summary>
Gets the preview asset hash of this sticker.
</summary>
<returns>
A <see langword="string"/> with the preview asset hash of this sticker.
</returns>
</member> </member>
<member name="P:Discord.ISticker.Format"> <member name="P:Discord.ISticker.Format">
<summary> <summary>
@@ -9649,6 +9707,16 @@
A <see cref="T:Discord.StickerFormatType"/> with the format type of this sticker. A <see cref="T:Discord.StickerFormatType"/> with the format type of this sticker.
</returns> </returns>
</member> </member>
<member name="P:Discord.ISticker.Available">
<summary>
Gets whether this guild sticker can be used, may be false due to loss of Server Boosts
</summary>
</member>
<member name="P:Discord.ISticker.SortOrder">
<summary>
Gets the standard sticker's sort order within its pack
</summary>
</member>
<member name="M:Discord.ISticker.GetStickerUrl"> <member name="M:Discord.ISticker.GetStickerUrl">
<summary> <summary>
Gets the image url for this sticker. Gets the image url for this sticker.
@@ -9735,6 +9803,21 @@
Gets or sets the tags of the sticker. Gets or sets the tags of the sticker.
</summary> </summary>
</member> </member>
<member name="T:Discord.StickerType">
<summary>
Represents a type of sticker
</summary>
</member>
<member name="F:Discord.StickerType.Standard">
<summary>
Represents a discord standard sticker, this type of sticker cannot be modified by an application.
</summary>
</member>
<member name="F:Discord.StickerType.Guild">
<summary>
Represents a sticker that was created within a guild.
</summary>
</member>
<member name="T:Discord.ITeam"> <member name="T:Discord.ITeam">
<summary> <summary>
Represents a Discord Team. Represents a Discord Team.


+ 6
- 3
src/Discord.Net.Core/Entities/Channels/IMessageChannel.cs View File

@@ -29,11 +29,12 @@ namespace Discord
/// </param> /// </param>
/// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param> /// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
/// <param name="component">The message components to be included with this message. Used for interactions</param> /// <param name="component">The message components to be included with this message. Used for interactions</param>
/// <param name="stickers">A collection of stickers to send with the message.</param>
/// <returns> /// <returns>
/// A task that represents an asynchronous send operation for delivering the message. The task result /// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message. /// contains the sent message.
/// </returns> /// </returns>
Task<IUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null);
Task<IUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null);
/// <summary> /// <summary>
/// Sends a file to this message channel with an optional caption. /// Sends a file to this message channel with an optional caption.
/// </summary> /// </summary>
@@ -67,11 +68,12 @@ namespace Discord
/// </param> /// </param>
/// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param> /// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
/// <param name="component">The message components to be included with this message. Used for interactions</param> /// <param name="component">The message components to be included with this message. Used for interactions</param>
/// <param name="stickers">A collection of stickers to send with the file.</param>
/// <returns> /// <returns>
/// A task that represents an asynchronous send operation for delivering the message. The task result /// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message. /// contains the sent message.
/// </returns> /// </returns>
Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null);
Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null);
/// <summary> /// <summary>
/// Sends a file to this message channel with an optional caption. /// Sends a file to this message channel with an optional caption.
/// </summary> /// </summary>
@@ -102,11 +104,12 @@ namespace Discord
/// </param> /// </param>
/// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param> /// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
/// <param name="component">The message components to be included with this message. Used for interactions</param> /// <param name="component">The message components to be included with this message. Used for interactions</param>
/// <param name="stickers">A collection of stickers to send with the file.</param>
/// <returns> /// <returns>
/// A task that represents an asynchronous send operation for delivering the message. The task result /// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message. /// contains the sent message.
/// </returns> /// </returns>
Task<IUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null);
Task<IUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null);


/// <summary> /// <summary>
/// Gets a message from this message channel. /// Gets a message from this message channel.


+ 26
- 0
src/Discord.Net.Core/Entities/Guilds/IGuild.cs View File

@@ -667,6 +667,17 @@ namespace Discord
/// </returns> /// </returns>
Task<IVoiceChannel> CreateVoiceChannelAsync(string name, Action<VoiceChannelProperties> func = null, RequestOptions options = null); Task<IVoiceChannel> CreateVoiceChannelAsync(string name, Action<VoiceChannelProperties> func = null, RequestOptions options = null);
/// <summary> /// <summary>
/// Creates a new stage channel in this guild.
/// </summary>
/// <param name="name">The new name for the stage channel.</param>
/// <param name="func">The delegate containing the properties to be applied to the channel upon its creation.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous creation operation. The task result contains the newly created
/// stage channel.
/// </returns>
Task<IStageChannel> CreateStageChannelAsync(string name, Action<VoiceChannelProperties> func = null, RequestOptions options = null);
/// <summary>
/// Creates a new channel category in this guild. /// Creates a new channel category in this guild.
/// </summary> /// </summary>
/// <param name="name">The new name for the category.</param> /// <param name="name">The new name for the category.</param>
@@ -760,6 +771,12 @@ namespace Discord
/// <returns>A guild user associated with the specified <paramref name="userId" />; <see langword="null" /> if the user is already in the guild.</returns> /// <returns>A guild user associated with the specified <paramref name="userId" />; <see langword="null" /> if the user is already in the guild.</returns>
Task<IGuildUser> AddGuildUserAsync(ulong userId, string accessToken, Action<AddGuildUserProperties> func = null, RequestOptions options = null); Task<IGuildUser> AddGuildUserAsync(ulong userId, string accessToken, Action<AddGuildUserProperties> func = null, RequestOptions options = null);
/// <summary> /// <summary>
/// Disconnects the user from its current voice channel
/// </summary>
/// <param name="user">The user to disconnect.</param>
/// <returns>A task that represents the asynchronous operation for disconnecting a user.</returns>
Task DisconnectAsync(IGuildUser user);
/// <summary>
/// Gets a collection of all users in this guild. /// Gets a collection of all users in this guild.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
@@ -940,6 +957,15 @@ namespace Discord
/// emote. /// emote.
/// </returns> /// </returns>
Task<GuildEmote> ModifyEmoteAsync(GuildEmote emote, Action<EmoteProperties> func, RequestOptions options = null); Task<GuildEmote> ModifyEmoteAsync(GuildEmote emote, Action<EmoteProperties> func, RequestOptions options = null);

/// <summary>
/// Moves the user to the voice channel.
/// </summary>
/// <param name="user">The user to move.</param>
/// <param name="targetChannel">the channel where the user gets moved to.</param>
/// <returns>A task that represents the asynchronous operation for moving a user.</returns>
Task MoveAsync(IGuildUser user, IVoiceChannel targetChannel);

/// <summary> /// <summary>
/// Deletes an existing <see cref="GuildEmote"/> from this guild. /// Deletes an existing <see cref="GuildEmote"/> from this guild.
/// </summary> /// </summary>


+ 2
- 2
src/Discord.Net.Core/Entities/Interactions/InteractionResponseType.cs View File

@@ -22,16 +22,16 @@ namespace Discord
/// </summary> /// </summary>
Pong = 1, Pong = 1,


[Obsolete("This response type has been depricated by discord. Either use ChannelMessageWithSource or DeferredChannelMessageWithSource", true)]
/// <summary> /// <summary>
/// ACK a command without sending a message, eating the user's input. /// ACK a command without sending a message, eating the user's input.
/// </summary> /// </summary>
[Obsolete("This response type has been depricated by discord. Either use ChannelMessageWithSource or DeferredChannelMessageWithSource", true)]
Acknowledge = 2, Acknowledge = 2,


[Obsolete("This response type has been depricated by discord. Either use ChannelMessageWithSource or DeferredChannelMessageWithSource", true)]
/// <summary> /// <summary>
/// Respond with a message, showing the user's input. /// Respond with a message, showing the user's input.
/// </summary> /// </summary>
[Obsolete("This response type has been depricated by discord. Either use ChannelMessageWithSource or DeferredChannelMessageWithSource", true)]
ChannelMessage = 3, ChannelMessage = 3,


/// <summary> /// <summary>


+ 89
- 36
src/Discord.Net.Core/Entities/Interactions/Message Components/ComponentBuilder.cs View File

@@ -10,11 +10,6 @@ namespace Discord
/// </summary> /// </summary>
public class ComponentBuilder public class ComponentBuilder
{ {
/// <summary>
/// The max length of a <see cref="ButtonComponent.Label"/>.
/// </summary>
public const int MaxButtonLabelLength = 80;

/// <summary> /// <summary>
/// The max length of a <see cref="ButtonComponent.CustomId"/>. /// The max length of a <see cref="ButtonComponent.CustomId"/>.
/// </summary> /// </summary>
@@ -80,7 +75,7 @@ namespace Discord
foreach (var cmp in actionRow.Components) foreach (var cmp in actionRow.Components)
AddComponent(cmp, row); AddComponent(cmp, row);
break; break;
case SelectMenu menu:
case SelectMenuComponent menu:
this.WithSelectMenu(menu.Placeholder, menu.CustomId, menu.Options.Select(x => new SelectMenuOptionBuilder(x.Label, x.Value, x.Description, x.Emote, x.Default)).ToList(), menu.Placeholder, menu.MinValues, menu.MaxValues, menu.Disabled, row); this.WithSelectMenu(menu.Placeholder, menu.CustomId, menu.Options.Select(x => new SelectMenuOptionBuilder(x.Label, x.Value, x.Description, x.Emote, x.Default)).ToList(), menu.Placeholder, menu.MinValues, menu.MaxValues, menu.Disabled, row);
break; break;
} }
@@ -124,6 +119,8 @@ namespace Discord
public ComponentBuilder WithSelectMenu(SelectMenuBuilder menu, int row = 0) public ComponentBuilder WithSelectMenu(SelectMenuBuilder menu, int row = 0)
{ {
Preconditions.LessThan(row, MaxActionRowCount, nameof(row)); Preconditions.LessThan(row, MaxActionRowCount, nameof(row));
if (menu.Options.Distinct().Count() != menu.Options.Count())
throw new InvalidOperationException("Please make sure that there is no duplicates values.");


var builtMenu = menu.Build(); var builtMenu = menu.Build();


@@ -351,19 +348,27 @@ namespace Discord
/// <summary> /// <summary>
/// The max length of a <see cref="ButtonComponent.Label"/>. /// The max length of a <see cref="ButtonComponent.Label"/>.
/// </summary> /// </summary>
public const int MaxLabelLength = 80;
public const int MaxButtonLabelLength = 80;


/// <summary> /// <summary>
/// Gets or sets the label of the current button. /// Gets or sets the label of the current button.
/// </summary> /// </summary>
/// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="ComponentBuilder.MaxButtonLabelLength"/>.</exception>
/// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="MaxButtonLabelLength"/>.</exception>
/// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="MaxButtonLabelLength"/>.</exception>
public string Label public string Label
{ {
get => _label; get => _label;
set set
{ {
if (value != null && value.Length > ComponentBuilder.MaxButtonLabelLength)
throw new ArgumentException(message: $"Button label must be {ComponentBuilder.MaxButtonLabelLength} characters or less!", paramName: nameof(Label));
if (value != null)
{
if (value.Length > MaxButtonLabelLength)
throw new ArgumentException($"Button label must be {MaxButtonLabelLength} characters or less!", paramName: nameof(Label));
if (value.Length < 1)
throw new ArgumentException("Button label must be 1 character or more!", paramName: nameof(Label));
}
else
throw new ArgumentException("Button label must not be null or empty!", paramName: nameof(Label));


_label = value; _label = value;
} }
@@ -373,13 +378,21 @@ namespace Discord
/// Gets or sets the custom id of the current button. /// Gets or sets the custom id of the current button.
/// </summary> /// </summary>
/// <exception cref="ArgumentException" accessor="set"><see cref="CustomId"/> length exceeds <see cref="ComponentBuilder.MaxCustomIdLength"/></exception> /// <exception cref="ArgumentException" accessor="set"><see cref="CustomId"/> length exceeds <see cref="ComponentBuilder.MaxCustomIdLength"/></exception>
/// <exception cref="ArgumentException" accessor="set"><see cref="CustomId"/> length subceeds 1.</exception>
public string CustomId public string CustomId
{ {
get => _customId; get => _customId;
set set
{ {
if (value != null && value.Length > ComponentBuilder.MaxCustomIdLength)
throw new ArgumentException(message: $"Custom Id must be {ComponentBuilder.MaxCustomIdLength} characters or less!", paramName: nameof(CustomId));
if (value != null)
{
if (value.Length > ComponentBuilder.MaxCustomIdLength)
throw new ArgumentException($"Custom Id must be {ComponentBuilder.MaxCustomIdLength} characters or less!", paramName: nameof(CustomId));
if (value.Length < 1)
throw new ArgumentException("Custom Id must be 1 character or more!", paramName: nameof(CustomId));
}
else
throw new ArgumentException("Custom Id must not be null or empty!", paramName: nameof(CustomId));
_customId = value; _customId = value;
} }
} }
@@ -595,36 +608,44 @@ namespace Discord
} }


/// <summary> /// <summary>
/// Represents a class used to build <see cref="SelectMenu"/>'s.
/// Represents a class used to build <see cref="SelectMenuComponent"/>'s.
/// </summary> /// </summary>
public class SelectMenuBuilder public class SelectMenuBuilder
{ {
/// <summary> /// <summary>
/// The max length of a <see cref="SelectMenu.Placeholder"/>.
/// The max length of a <see cref="SelectMenuComponent.Placeholder"/>.
/// </summary> /// </summary>
public const int MaxPlaceholderLength = 100; public const int MaxPlaceholderLength = 100;


/// <summary> /// <summary>
/// The maximum number of values for the <see cref="SelectMenu.MinValues"/> and <see cref="SelectMenu.MaxValues"/> properties.
/// The maximum number of values for the <see cref="SelectMenuComponent.MinValues"/> and <see cref="SelectMenuComponent.MaxValues"/> properties.
/// </summary> /// </summary>
public const int MaxValuesCount = 25; public const int MaxValuesCount = 25;


/// <summary> /// <summary>
/// The maximum number of options a <see cref="SelectMenu"/> can have.
/// The maximum number of options a <see cref="SelectMenuComponent"/> can have.
/// </summary> /// </summary>
public const int MaxOptionCount = 25; public const int MaxOptionCount = 25;


/// <summary> /// <summary>
/// Gets or sets the custom id of the current select menu. /// Gets or sets the custom id of the current select menu.
/// </summary> /// </summary>
/// <exception cref="ArgumentException" accessor="set"><see cref="CustomId"/> length exceeds <see cref="ComponentBuilder.MaxCustomIdLength"/>.</exception>
/// <exception cref="ArgumentException" accessor="set"><see cref="CustomId"/> length exceeds <see cref="ComponentBuilder.MaxCustomIdLength"/></exception>
/// <exception cref="ArgumentException" accessor="set"><see cref="CustomId"/> length subceeds 1.</exception>
public string CustomId public string CustomId
{ {
get => _customId; get => _customId;
set set
{ {
if (value != null && value.Length > ComponentBuilder.MaxCustomIdLength)
throw new ArgumentException(message: $"Custom Id must be {ComponentBuilder.MaxCustomIdLength} characters or less!", paramName: nameof(CustomId));
if (value != null)
{
if (value.Length > ComponentBuilder.MaxCustomIdLength)
throw new ArgumentException($"Custom Id must be {ComponentBuilder.MaxCustomIdLength} characters or less!", paramName: nameof(CustomId));
if (value.Length < 1)
throw new ArgumentException("Custom Id must be 1 character or more!", paramName: nameof(CustomId));
}
else
throw new ArgumentException("Custom Id must not be null or empty!", paramName: nameof(CustomId));
_customId = value; _customId = value;
} }
} }
@@ -633,13 +654,21 @@ namespace Discord
/// Gets or sets the placeholder text of the current select menu. /// Gets or sets the placeholder text of the current select menu.
/// </summary> /// </summary>
/// <exception cref="ArgumentException" accessor="set"><see cref="Placeholder"/> length exceeds <see cref="MaxPlaceholderLength"/>.</exception> /// <exception cref="ArgumentException" accessor="set"><see cref="Placeholder"/> length exceeds <see cref="MaxPlaceholderLength"/>.</exception>
/// <exception cref="ArgumentException" accessor="set"><see cref="Placeholder"/> length subceeds 1.</exception>
public string Placeholder public string Placeholder
{ {
get => _placeholder; get => _placeholder;
set set
{ {
if (value?.Length > MaxPlaceholderLength)
throw new ArgumentException(message: $"Placeholder must be {MaxPlaceholderLength} characters or less!", paramName: nameof(Placeholder));
if (value != null)
{
if (value.Length > MaxPlaceholderLength)
throw new ArgumentException($"The placeholder must be {MaxPlaceholderLength} characters or less!", paramName: nameof(Placeholder));
if (value.Length < 1)
throw new ArgumentException("The placeholder must be 1 character or more!", paramName: nameof(Placeholder));
}
else
throw new ArgumentException("The placeholder must not be null or empty!", paramName: nameof(Placeholder));


_placeholder = value; _placeholder = value;
} }
@@ -709,9 +738,9 @@ namespace Discord
public SelectMenuBuilder() { } public SelectMenuBuilder() { }


/// <summary> /// <summary>
/// Creates a new instance of a <see cref="SelectMenuBuilder"/> from instance of <see cref="SelectMenu"/>.
/// Creates a new instance of a <see cref="SelectMenuBuilder"/> from instance of <see cref="SelectMenuComponent"/>.
/// </summary> /// </summary>
public SelectMenuBuilder(SelectMenu selectMenu)
public SelectMenuBuilder(SelectMenuComponent selectMenu)
{ {
this.Placeholder = selectMenu.Placeholder; this.Placeholder = selectMenu.Placeholder;
this.CustomId = selectMenu.Placeholder; this.CustomId = selectMenu.Placeholder;
@@ -861,14 +890,14 @@ namespace Discord
} }


/// <summary> /// <summary>
/// Builds a <see cref="SelectMenu"/>
/// Builds a <see cref="SelectMenuComponent"/>
/// </summary> /// </summary>
/// <returns>The newly built <see cref="SelectMenu"/></returns>
public SelectMenu Build()
/// <returns>The newly built <see cref="SelectMenuComponent"/></returns>
public SelectMenuComponent Build()
{ {
var options = this.Options?.Select(x => x.Build()).ToList(); var options = this.Options?.Select(x => x.Build()).ToList();


return new SelectMenu(this.CustomId, options, this.Placeholder, this.MinValues, this.MaxValues, this.Disabled);
return new SelectMenuComponent(this.CustomId, options, this.Placeholder, this.MinValues, this.MaxValues, this.Disabled);
} }
} }


@@ -880,7 +909,7 @@ namespace Discord
/// <summary> /// <summary>
/// The maximum length of a <see cref="SelectMenuOption.Label"/>. /// The maximum length of a <see cref="SelectMenuOption.Label"/>.
/// </summary> /// </summary>
public const int MaxLabelLength = 100;
public const int MaxSelectLabelLength = 100;


/// <summary> /// <summary>
/// The maximum length of a <see cref="SelectMenuOption.Description"/>. /// The maximum length of a <see cref="SelectMenuOption.Description"/>.
@@ -888,22 +917,29 @@ namespace Discord
public const int MaxDescriptionLength = 100; public const int MaxDescriptionLength = 100;
/// <summary> /// <summary>
/// The maximum length of a <see cref="SelectMenuOption.Label"/>.
/// The maximum length of a <see cref="SelectMenuOption.Value"/>.
/// </summary> /// </summary>
public const int MaxSelectLabelLength = 100;
public const int MaxSelectValueLength = 100;


/// <summary> /// <summary>
/// Gets or sets the label of the current select menu. /// Gets or sets the label of the current select menu.
/// </summary> /// </summary>
/// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="MaxSelectLabelLength"/></exception> /// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="MaxSelectLabelLength"/></exception>
/// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length subceeds 1.</exception>
public string Label public string Label
{ {
get => _label; get => _label;
set set
{ {
if (value != null) if (value != null)
{
if (value.Length > MaxSelectLabelLength) if (value.Length > MaxSelectLabelLength)
throw new ArgumentException(message: $"Button label must be {MaxSelectLabelLength} characters or less!", paramName: nameof(Label));
throw new ArgumentException($"Select option label must be {MaxSelectLabelLength} characters or less!", paramName: nameof(Label));
if (value.Length < 1)
throw new ArgumentException("Select option label must be 1 character or more!", paramName: nameof(Label));
}
else
throw new ArgumentException("Select option label must not be null or empty!", paramName: nameof(Label));


_label = value; _label = value;
} }
@@ -912,14 +948,23 @@ namespace Discord
/// <summary> /// <summary>
/// Gets or sets the custom id of the current select menu. /// Gets or sets the custom id of the current select menu.
/// </summary> /// </summary>
/// <exception cref="ArgumentException" accessor="set"><see cref="Value"/> length exceeds <see cref="ComponentBuilder.MaxCustomIdLength"/>.</exception>
/// <exception cref="ArgumentException" accessor="set"><see cref="Value"/> length exceeds <see cref="MaxSelectValueLength"/>.</exception>
/// <exception cref="ArgumentException" accessor="set"><see cref="Value"/> length subceeds 1.</exception>
public string Value public string Value
{ {
get => _value; get => _value;
set set
{ {
if (value != null && value.Length > ComponentBuilder.MaxCustomIdLength)
throw new ArgumentException(message: $"Value must be {ComponentBuilder.MaxCustomIdLength} characters or less!", paramName: nameof(Value));
if (value != null)
{
if (value.Length > MaxSelectValueLength)
throw new ArgumentException($"Select option value must be {MaxSelectValueLength} characters or less!", paramName: nameof(Label));
if (value.Length < 1)
throw new ArgumentException("Select option value must be 1 character or more!", paramName: nameof(Label));
}
else
throw new ArgumentException("Select option value must not be null or empty!", paramName: nameof(Label));

_value = value; _value = value;
} }
} }
@@ -928,13 +973,21 @@ namespace Discord
/// Gets or sets this menu options description. /// Gets or sets this menu options description.
/// </summary> /// </summary>
/// <exception cref="ArgumentException" accessor="set"><see cref="Description"/> length exceeds <see cref="MaxDescriptionLength"/>.</exception> /// <exception cref="ArgumentException" accessor="set"><see cref="Description"/> length exceeds <see cref="MaxDescriptionLength"/>.</exception>
/// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length subceeds 1.</exception>
public string Description public string Description
{ {
get => _description; get => _description;
set set
{ {
if (value != null && value.Length > MaxDescriptionLength)
throw new ArgumentException($"Description must be {MaxDescriptionLength} characters or less!", nameof(Description));
if (value != null)
{
if (value.Length > MaxDescriptionLength)
throw new ArgumentException($"The description must be {MaxDescriptionLength} characters or less!", paramName: nameof(Label));
if (value.Length < 1)
throw new ArgumentException("The description must be 1 character or more!", paramName: nameof(Label));
}
else
throw new ArgumentException("The description must not be null or empty!", paramName: nameof(Label));


_description = value; _description = value;
} }


src/Discord.Net.Core/Entities/Interactions/Message Components/SelectMenu.cs → src/Discord.Net.Core/Entities/Interactions/Message Components/SelectMenuComponent.cs View File

@@ -9,7 +9,7 @@ namespace Discord
/// <summary> /// <summary>
/// Represents a select menu component defined at <see href="https://discord.com/developers/docs/interactions/message-components#select-menu-object"/> /// Represents a select menu component defined at <see href="https://discord.com/developers/docs/interactions/message-components#select-menu-object"/>
/// </summary> /// </summary>
public class SelectMenu : IMessageComponent
public class SelectMenuComponent : IMessageComponent
{ {
/// <inheritdoc/> /// <inheritdoc/>
public ComponentType Type => ComponentType.SelectMenu; public ComponentType Type => ComponentType.SelectMenu;
@@ -59,7 +59,7 @@ namespace Discord
this.MinValues, this.MinValues,
this.Disabled); this.Disabled);


internal SelectMenu(string customId, List<SelectMenuOption> options, string placeholder, int minValues, int maxValues, bool disabled)
internal SelectMenuComponent(string customId, List<SelectMenuOption> options, string placeholder, int minValues, int maxValues, bool disabled)
{ {
this.CustomId = customId; this.CustomId = customId;
this.Options = options; this.Options = options;

+ 1
- 1
src/Discord.Net.Core/Entities/Interactions/Message Components/SelectMenuOption.cs View File

@@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace Discord namespace Discord
{ {
/// <summary> /// <summary>
/// Represents a choice for a <see cref="SelectMenu"/>.
/// Represents a choice for a <see cref="SelectMenuComponent"/>.
/// </summary> /// </summary>
public class SelectMenuOption public class SelectMenuOption
{ {


+ 14
- 15
src/Discord.Net.Core/Entities/Stickers/ISticker.cs View File

@@ -15,7 +15,7 @@ namespace Discord
/// <returns> /// <returns>
/// A snowflake ID associated with this sticker. /// A snowflake ID associated with this sticker.
/// </returns> /// </returns>
ulong Id { get; }
new ulong Id { get; }
/// <summary> /// <summary>
/// Gets the ID of the pack of this sticker. /// Gets the ID of the pack of this sticker.
/// </summary> /// </summary>
@@ -29,7 +29,7 @@ namespace Discord
/// <returns> /// <returns>
/// A <see langword="string"/> with the name of this sticker. /// A <see langword="string"/> with the name of this sticker.
/// </returns> /// </returns>
string Name { get; }
new string Name { get; }
/// <summary> /// <summary>
/// Gets the description of this sticker. /// Gets the description of this sticker.
/// </summary> /// </summary>
@@ -45,27 +45,26 @@ namespace Discord
/// </returns> /// </returns>
IReadOnlyCollection<string> Tags { get; } IReadOnlyCollection<string> Tags { get; }
/// <summary> /// <summary>
/// Gets the asset hash of this sticker.
/// Gets the type of this sticker.
/// </summary> /// </summary>
/// <returns>
/// A <see langword="string"/> with the asset hash of this sticker.
/// </returns>
string Asset { get; }
/// <summary>
/// Gets the preview asset hash of this sticker.
/// </summary>
/// <returns>
/// A <see langword="string"/> with the preview asset hash of this sticker.
/// </returns>
string PreviewAsset { get; }
StickerType Type { get; }
/// <summary> /// <summary>
/// Gets the format type of this sticker. /// Gets the format type of this sticker.
/// </summary> /// </summary>
/// <returns> /// <returns>
/// A <see cref="StickerFormatType"/> with the format type of this sticker. /// A <see cref="StickerFormatType"/> with the format type of this sticker.
/// </returns> /// </returns>
StickerFormatType Format { get; }
new StickerFormatType Format { get; }


/// <summary>
/// Gets whether this guild sticker can be used, may be false due to loss of Server Boosts
/// </summary>
bool? Available { get; }

/// <summary>
/// Gets the standard sticker's sort order within its pack
/// </summary>
int? SortOrder { get; }
/// <summary> /// <summary>
/// Gets the image url for this sticker. /// Gets the image url for this sticker.
/// </summary> /// </summary>


+ 24
- 0
src/Discord.Net.Core/Entities/Stickers/StickerType.cs View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Discord
{
/// <summary>
/// Represents a type of sticker
/// </summary>
public enum StickerType
{
/// <summary>
/// Represents a discord standard sticker, this type of sticker cannot be modified by an application.
/// </summary>
Standard = 1,

/// <summary>
/// Represents a sticker that was created within a guild.
/// </summary>
Guild = 2,
}
}

+ 1
- 1
src/Discord.Net.Rest/API/Common/ActionRowComponent.cs View File

@@ -27,7 +27,7 @@ namespace Discord.API
case ComponentType.Button: case ComponentType.Button:
return new ButtonComponent(x as Discord.ButtonComponent); return new ButtonComponent(x as Discord.ButtonComponent);
case ComponentType.SelectMenu: case ComponentType.SelectMenu:
return new SelectMenuComponent(x as Discord.SelectMenu);
return new SelectMenuComponent(x as Discord.SelectMenuComponent);
default: return null; default: return null;


} }


+ 0
- 20
src/Discord.Net.Rest/API/Common/InteractionFollowupMessage.cs View File

@@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Discord.API
{
internal class InteractionFollowupMessage
{
public string Content { get; set; }
public Optional<string> Username { get; set; }
public Optional<string> AvatarUrl { get; set; }
public Optional<bool> TTS { get; set; }
public Optional<Stream> File { get; set; }
public Embed[] Embeds { get; set; }

}
}

+ 1
- 1
src/Discord.Net.Rest/API/Common/SelectMenuComponent.cs View File

@@ -32,7 +32,7 @@ namespace Discord.API


public SelectMenuComponent() { } public SelectMenuComponent() { }


public SelectMenuComponent(Discord.SelectMenu component)
public SelectMenuComponent(Discord.SelectMenuComponent component)
{ {
this.Type = component.Type; this.Type = component.Type;
this.CustomId = component.CustomId; this.CustomId = component.CustomId;


+ 6
- 4
src/Discord.Net.Rest/API/Common/Sticker.cs View File

@@ -15,15 +15,17 @@ namespace Discord.API
public string Desription { get; set; } public string Desription { get; set; }
[JsonProperty("tags")] [JsonProperty("tags")]
public Optional<string> Tags { get; set; } public Optional<string> Tags { get; set; }
[JsonProperty("asset")]
public string Asset { get; set; }
[JsonProperty("preview_asset")]
public string PreviewAsset { get; set; }
[JsonProperty("type")]
public StickerType Type { get; set; }
[JsonProperty("format_type")] [JsonProperty("format_type")]
public StickerFormatType FormatType { get; set; } public StickerFormatType FormatType { get; set; }
[JsonProperty("available")]
public bool? Available { get; set; }
[JsonProperty("guild_id")] [JsonProperty("guild_id")]
public Optional<ulong> GuildId { get; set; } public Optional<ulong> GuildId { get; set; }
[JsonProperty("user")] [JsonProperty("user")]
public Optional<User> User { get; set; } public Optional<User> User { get; set; }
[JsonProperty("sort_value")]
public int? SortValue { get; set; }
} }
} }

+ 4
- 0
src/Discord.Net.Rest/API/Rest/CreateMessageParams.cs View File

@@ -26,6 +26,10 @@ namespace Discord.API.Rest


[JsonProperty("components")] [JsonProperty("components")]
public Optional<API.ActionRowComponent[]> Components { get; set; } public Optional<API.ActionRowComponent[]> Components { get; set; }

[JsonProperty("sticker_ids")]
public Optional<ulong[]> Stickers { get; set; }

public CreateMessageParams(string content) public CreateMessageParams(string content)
{ {
Content = content; Content = content;


+ 3
- 0
src/Discord.Net.Rest/API/Rest/UploadFileParams.cs View File

@@ -22,6 +22,7 @@ namespace Discord.API.Rest
public Optional<AllowedMentions> AllowedMentions { get; set; } public Optional<AllowedMentions> AllowedMentions { get; set; }
public Optional<MessageReference> MessageReference { get; set; } public Optional<MessageReference> MessageReference { get; set; }
public Optional<ActionRowComponent[]> MessageComponent { get; set; } public Optional<ActionRowComponent[]> MessageComponent { get; set; }
public Optional<ulong[]> Stickers { get; set; }
public bool IsSpoiler { get; set; } = false; public bool IsSpoiler { get; set; } = false;


public UploadFileParams(Stream file) public UploadFileParams(Stream file)
@@ -54,6 +55,8 @@ namespace Discord.API.Rest
payload["hasSpoiler"] = IsSpoiler.ToString(); payload["hasSpoiler"] = IsSpoiler.ToString();
if (MessageReference.IsSpecified) if (MessageReference.IsSpecified)
payload["message_reference"] = MessageReference.Value; payload["message_reference"] = MessageReference.Value;
if (Stickers.IsSpecified)
payload["sticker_ids"] = Stickers.Value;


var json = new StringBuilder(); var json = new StringBuilder();
using (var text = new StringWriter(json)) using (var text = new StringWriter(json))


+ 4
- 1
src/Discord.Net.Rest/BaseDiscordClient.cs View File

@@ -10,6 +10,7 @@ namespace Discord.Rest
{ {
public abstract class BaseDiscordClient : IDiscordClient public abstract class BaseDiscordClient : IDiscordClient
{ {
#region BaseDiscordClient
public event Func<LogMessage, Task> Log { add { _logEvent.Add(value); } remove { _logEvent.Remove(value); } } public event Func<LogMessage, Task> Log { add { _logEvent.Add(value); } remove { _logEvent.Remove(value); } }
internal readonly AsyncEvent<Func<LogMessage, Task>> _logEvent = new AsyncEvent<Func<LogMessage, Task>>(); internal readonly AsyncEvent<Func<LogMessage, Task>> _logEvent = new AsyncEvent<Func<LogMessage, Task>>();


@@ -155,8 +156,9 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
public Task<BotGateway> GetBotGatewayAsync(RequestOptions options = null) public Task<BotGateway> GetBotGatewayAsync(RequestOptions options = null)
=> ClientHelper.GetBotGatewayAsync(this, options); => ClientHelper.GetBotGatewayAsync(this, options);
#endregion


//IDiscordClient
#region IDiscordClient
/// <inheritdoc /> /// <inheritdoc />
ConnectionState IDiscordClient.ConnectionState => ConnectionState.Disconnected; ConnectionState IDiscordClient.ConnectionState => ConnectionState.Disconnected;
/// <inheritdoc /> /// <inheritdoc />
@@ -235,5 +237,6 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
Task IDiscordClient.StopAsync() Task IDiscordClient.StopAsync()
=> Task.Delay(0); => Task.Delay(0);
#endregion
} }
} }

+ 2
- 1
src/Discord.Net.Rest/ClientHelper.cs View File

@@ -10,7 +10,7 @@ namespace Discord.Rest
{ {
internal static class ClientHelper internal static class ClientHelper
{ {
//Applications
#region Applications
public static async Task<RestApplication> GetApplicationInfoAsync(BaseDiscordClient client, RequestOptions options) public static async Task<RestApplication> GetApplicationInfoAsync(BaseDiscordClient client, RequestOptions options)
{ {
var model = await client.ApiClient.GetMyApplicationAsync(options).ConfigureAwait(false); var model = await client.ApiClient.GetMyApplicationAsync(options).ConfigureAwait(false);
@@ -263,5 +263,6 @@ namespace Discord.Rest
public static Task RemoveRoleAsync(BaseDiscordClient client, ulong guildId, ulong userId, ulong roleId, RequestOptions options = null) public static Task RemoveRoleAsync(BaseDiscordClient client, ulong guildId, ulong userId, ulong roleId, RequestOptions options = null)
=> client.ApiClient.RemoveRoleAsync(guildId, userId, roleId, options); => client.ApiClient.RemoveRoleAsync(guildId, userId, roleId, options);
#endregion
} }
} }

+ 65
- 26
src/Discord.Net.Rest/Discord.Net.Rest.xml View File

@@ -1718,10 +1718,10 @@
<paramref name="maxAge"/> must be lesser than 86400. <paramref name="maxAge"/> must be lesser than 86400.
</exception> </exception>
</member> </member>
<member name="M:Discord.Rest.ChannelHelper.SendMessageAsync(Discord.IMessageChannel,Discord.Rest.BaseDiscordClient,System.String,System.Boolean,Discord.Embed,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.RequestOptions)">
<member name="M:Discord.Rest.ChannelHelper.SendMessageAsync(Discord.IMessageChannel,Discord.Rest.BaseDiscordClient,System.String,System.Boolean,Discord.Embed,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[],Discord.RequestOptions)">
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
<member name="M:Discord.Rest.ChannelHelper.SendFileAsync(Discord.IMessageChannel,Discord.Rest.BaseDiscordClient,System.String,System.String,System.Boolean,Discord.Embed,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.RequestOptions,System.Boolean)">
<member name="M:Discord.Rest.ChannelHelper.SendFileAsync(Discord.IMessageChannel,Discord.Rest.BaseDiscordClient,System.String,System.String,System.Boolean,Discord.Embed,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[],Discord.RequestOptions,System.Boolean)">
<exception cref="T:System.ArgumentException"> <exception cref="T:System.ArgumentException">
<paramref name="filePath" /> is a zero-length string, contains only white space, or contains one or more <paramref name="filePath" /> is a zero-length string, contains only white space, or contains one or more
invalid characters as defined by <see cref="M:System.IO.Path.GetInvalidPathChars"/>. invalid characters as defined by <see cref="M:System.IO.Path.GetInvalidPathChars"/>.
@@ -1747,7 +1747,7 @@
<exception cref="T:System.IO.IOException">An I/O error occurred while opening the file.</exception> <exception cref="T:System.IO.IOException">An I/O error occurred while opening the file.</exception>
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
<member name="M:Discord.Rest.ChannelHelper.SendFileAsync(Discord.IMessageChannel,Discord.Rest.BaseDiscordClient,System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.RequestOptions,System.Boolean)">
<member name="M:Discord.Rest.ChannelHelper.SendFileAsync(Discord.IMessageChannel,Discord.Rest.BaseDiscordClient,System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[],Discord.RequestOptions,System.Boolean)">
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
<member name="M:Discord.Rest.ChannelHelper.GetUserAsync(Discord.IGuildChannel,Discord.IGuild,Discord.Rest.BaseDiscordClient,System.UInt64,Discord.RequestOptions)"> <member name="M:Discord.Rest.ChannelHelper.GetUserAsync(Discord.IGuildChannel,Discord.IGuild,Discord.Rest.BaseDiscordClient,System.UInt64,Discord.RequestOptions)">
@@ -1764,12 +1764,12 @@
Represents a REST-based channel that can send and receive messages. Represents a REST-based channel that can send and receive messages.
</summary> </summary>
</member> </member>
<member name="M:Discord.Rest.IRestMessageChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.IRestMessageChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<summary> <summary>
Sends a message to this message channel. Sends a message to this message channel.
</summary> </summary>
<remarks> <remarks>
This method follows the same behavior as described in <see cref="M:Discord.IMessageChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)"/>.
This method follows the same behavior as described in <see cref="M:Discord.IMessageChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])"/>.
Please visit its documentation for more details on this method. Please visit its documentation for more details on this method.
</remarks> </remarks>
<param name="text">The message to be sent.</param> <param name="text">The message to be sent.</param>
@@ -1781,18 +1781,20 @@
If <c>null</c>, all mentioned roles and users will be notified. If <c>null</c>, all mentioned roles and users will be notified.
</param> </param>
<param name="messageReference">The message references to be included. Used to reply to specific messages.</param> <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
<param name="component">The message components to be included with this message. Used for interactions</param>
<param name="stickers">A collection of stickers to send with the message.</param>
<returns> <returns>
A task that represents an asynchronous send operation for delivering the message. The task result A task that represents an asynchronous send operation for delivering the message. The task result
contains the sent message. contains the sent message.
</returns> </returns>
</member> </member>
<member name="M:Discord.Rest.IRestMessageChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.IRestMessageChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<summary> <summary>
Sends a file to this message channel with an optional caption. Sends a file to this message channel with an optional caption.
</summary> </summary>
<remarks> <remarks>
This method follows the same behavior as described in This method follows the same behavior as described in
<see cref="!:IMessageChannel.SendFileAsync(string, string, bool, Embed, RequestOptions, bool, AllowedMentions, MessageReference)"/>. Please visit
<see cref="M:Discord.IMessageChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])"/>. Please visit
its documentation for more details on this method. its documentation for more details on this method.
</remarks> </remarks>
<param name="filePath">The file path of the file.</param> <param name="filePath">The file path of the file.</param>
@@ -1806,17 +1808,19 @@
If <c>null</c>, all mentioned roles and users will be notified. If <c>null</c>, all mentioned roles and users will be notified.
</param> </param>
<param name="messageReference">The message references to be included. Used to reply to specific messages.</param> <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
<param name="component">The message components to be included with this message. Used for interactions</param>
<param name="stickers">A collection of stickers to send with the message.</param>
<returns> <returns>
A task that represents an asynchronous send operation for delivering the message. The task result A task that represents an asynchronous send operation for delivering the message. The task result
contains the sent message. contains the sent message.
</returns> </returns>
</member> </member>
<member name="M:Discord.Rest.IRestMessageChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.IRestMessageChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<summary> <summary>
Sends a file to this message channel with an optional caption. Sends a file to this message channel with an optional caption.
</summary> </summary>
<remarks> <remarks>
This method follows the same behavior as described in <see cref="!:IMessageChannel.SendFileAsync(Stream, string, string, bool, Embed, RequestOptions, bool, AllowedMentions, MessageReference)"/>.
This method follows the same behavior as described in <see cref="M:Discord.IMessageChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])"/>.
Please visit its documentation for more details on this method. Please visit its documentation for more details on this method.
</remarks> </remarks>
<param name="stream">The <see cref="T:System.IO.Stream" /> of the file to be sent.</param> <param name="stream">The <see cref="T:System.IO.Stream" /> of the file to be sent.</param>
@@ -1831,6 +1835,8 @@
If <c>null</c>, all mentioned roles and users will be notified. If <c>null</c>, all mentioned roles and users will be notified.
</param> </param>
<param name="messageReference">The message references to be included. Used to reply to specific messages.</param> <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
<param name="component">The message components to be included with this message. Used for interactions</param>
<param name="stickers">A collection of stickers to send with the message.</param>
<returns> <returns>
A task that represents an asynchronous send operation for delivering the message. The task result A task that represents an asynchronous send operation for delivering the message. The task result
contains the sent message. contains the sent message.
@@ -2010,11 +2016,11 @@
<member name="M:Discord.Rest.RestDMChannel.GetPinnedMessagesAsync(Discord.RequestOptions)"> <member name="M:Discord.Rest.RestDMChannel.GetPinnedMessagesAsync(Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.Rest.RestDMChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestDMChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
<member name="M:Discord.Rest.RestDMChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestDMChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentException"> <exception cref="T:System.ArgumentException">
<paramref name="filePath" /> is a zero-length string, contains only white space, or contains one or more <paramref name="filePath" /> is a zero-length string, contains only white space, or contains one or more
@@ -2041,7 +2047,7 @@
<exception cref="T:System.IO.IOException">An I/O error occurred while opening the file.</exception> <exception cref="T:System.IO.IOException">An I/O error occurred while opening the file.</exception>
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
<member name="M:Discord.Rest.RestDMChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestDMChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
@@ -2092,13 +2098,13 @@
<member name="M:Discord.Rest.RestDMChannel.Discord#IMessageChannel#GetPinnedMessagesAsync(Discord.RequestOptions)"> <member name="M:Discord.Rest.RestDMChannel.Discord#IMessageChannel#GetPinnedMessagesAsync(Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.Rest.RestDMChannel.Discord#IMessageChannel#SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestDMChannel.Discord#IMessageChannel#SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.Rest.RestDMChannel.Discord#IMessageChannel#SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestDMChannel.Discord#IMessageChannel#SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.Rest.RestDMChannel.Discord#IMessageChannel#SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestDMChannel.Discord#IMessageChannel#SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="P:Discord.Rest.RestDMChannel.Discord#IChannel#Name"> <member name="P:Discord.Rest.RestDMChannel.Discord#IChannel#Name">
@@ -2148,11 +2154,11 @@
<member name="M:Discord.Rest.RestGroupChannel.ModifyMessageAsync(System.UInt64,System.Action{Discord.MessageProperties},Discord.RequestOptions)"> <member name="M:Discord.Rest.RestGroupChannel.ModifyMessageAsync(System.UInt64,System.Action{Discord.MessageProperties},Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.Rest.RestGroupChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestGroupChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
<member name="M:Discord.Rest.RestGroupChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestGroupChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentException"> <exception cref="T:System.ArgumentException">
<paramref name="filePath" /> is a zero-length string, contains only white space, or contains one or more <paramref name="filePath" /> is a zero-length string, contains only white space, or contains one or more
@@ -2179,7 +2185,7 @@
<exception cref="T:System.IO.IOException">An I/O error occurred while opening the file.</exception> <exception cref="T:System.IO.IOException">An I/O error occurred while opening the file.</exception>
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
<member name="M:Discord.Rest.RestGroupChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestGroupChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
@@ -2438,11 +2444,11 @@
<member name="M:Discord.Rest.RestTextChannel.GetPinnedMessagesAsync(Discord.RequestOptions)"> <member name="M:Discord.Rest.RestTextChannel.GetPinnedMessagesAsync(Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.Rest.RestTextChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestTextChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
<member name="M:Discord.Rest.RestTextChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestTextChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentException"> <exception cref="T:System.ArgumentException">
<paramref name="filePath" /> is a zero-length string, contains only white space, or contains one or more <paramref name="filePath" /> is a zero-length string, contains only white space, or contains one or more
@@ -2469,7 +2475,7 @@
<exception cref="T:System.IO.IOException">An I/O error occurred while opening the file.</exception> <exception cref="T:System.IO.IOException">An I/O error occurred while opening the file.</exception>
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
<member name="M:Discord.Rest.RestTextChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestTextChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
@@ -2602,13 +2608,13 @@
<member name="M:Discord.Rest.RestTextChannel.Discord#IMessageChannel#GetPinnedMessagesAsync(Discord.RequestOptions)"> <member name="M:Discord.Rest.RestTextChannel.Discord#IMessageChannel#GetPinnedMessagesAsync(Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.Rest.RestTextChannel.Discord#IMessageChannel#SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestTextChannel.Discord#IMessageChannel#SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.Rest.RestTextChannel.Discord#IMessageChannel#SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestTextChannel.Discord#IMessageChannel#SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.Rest.RestTextChannel.Discord#IMessageChannel#SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.Rest.RestTextChannel.Discord#IMessageChannel#SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.Rest.RestTextChannel.Discord#IGuildChannel#GetUserAsync(System.UInt64,Discord.CacheMode,Discord.RequestOptions)"> <member name="M:Discord.Rest.RestTextChannel.Discord#IGuildChannel#GetUserAsync(System.UInt64,Discord.CacheMode,Discord.RequestOptions)">
@@ -3347,6 +3353,18 @@
The created voice channel. The created voice channel.
</returns> </returns>
</member> </member>
<member name="M:Discord.Rest.RestGuild.CreateStageChannelAsync(System.String,System.Action{Discord.VoiceChannelProperties},Discord.RequestOptions)">
<summary>
Creates a new stage channel in this guild.
</summary>
<param name="name">The new name for the stage channel.</param>
<param name="func">The delegate containing the properties to be applied to the channel upon its creation.</param>
<param name="options">The options to be used when sending the request.</param>
<returns>
A task that represents the asynchronous creation operation. The task result contains the newly created
stage channel.
</returns>
</member>
<member name="M:Discord.Rest.RestGuild.CreateCategoryChannelAsync(System.String,System.Action{Discord.GuildChannelProperties},Discord.RequestOptions)"> <member name="M:Discord.Rest.RestGuild.CreateCategoryChannelAsync(System.String,System.Action{Discord.GuildChannelProperties},Discord.RequestOptions)">
<summary> <summary>
Creates a category channel with the provided name. Creates a category channel with the provided name.
@@ -3599,6 +3617,14 @@
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentNullException"><paramref name="func"/> is <see langword="null"/>.</exception> <exception cref="T:System.ArgumentNullException"><paramref name="func"/> is <see langword="null"/>.</exception>
</member> </member>
<member name="M:Discord.Rest.RestGuild.MoveAsync(Discord.IGuildUser,Discord.IVoiceChannel)">
<summary>
Moves the user to the voice channel.
</summary>
<param name="user">The user to move.</param>
<param name="targetChannel">the channel where the user gets moved to.</param>
<returns>A task that represents the asynchronous operation for moving a user.</returns>
</member>
<member name="M:Discord.Rest.RestGuild.DeleteEmoteAsync(Discord.GuildEmote,Discord.RequestOptions)"> <member name="M:Discord.Rest.RestGuild.DeleteEmoteAsync(Discord.GuildEmote,Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
@@ -3751,6 +3777,9 @@
<member name="M:Discord.Rest.RestGuild.Discord#IGuild#CreateVoiceChannelAsync(System.String,System.Action{Discord.VoiceChannelProperties},Discord.RequestOptions)"> <member name="M:Discord.Rest.RestGuild.Discord#IGuild#CreateVoiceChannelAsync(System.String,System.Action{Discord.VoiceChannelProperties},Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.Rest.RestGuild.Discord#IGuild#CreateStageChannelAsync(System.String,System.Action{Discord.VoiceChannelProperties},Discord.RequestOptions)">
<inheritdoc />
</member>
<member name="M:Discord.Rest.RestGuild.Discord#IGuild#CreateCategoryAsync(System.String,System.Action{Discord.GuildChannelProperties},Discord.RequestOptions)"> <member name="M:Discord.Rest.RestGuild.Discord#IGuild#CreateCategoryAsync(System.String,System.Action{Discord.GuildChannelProperties},Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
@@ -3781,6 +3810,13 @@
<member name="M:Discord.Rest.RestGuild.Discord#IGuild#AddGuildUserAsync(System.UInt64,System.String,System.Action{Discord.AddGuildUserProperties},Discord.RequestOptions)"> <member name="M:Discord.Rest.RestGuild.Discord#IGuild#AddGuildUserAsync(System.UInt64,System.String,System.Action{Discord.AddGuildUserProperties},Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.Rest.RestGuild.Discord#IGuild#DisconnectAsync(Discord.IGuildUser)">
<summary>
Disconnects the user from its current voice channel
</summary>
<param name="user">The user to disconnect.</param>
<returns>A task that represents the asynchronous operation for disconnecting a user.</returns>
</member>
<member name="M:Discord.Rest.RestGuild.Discord#IGuild#GetUserAsync(System.UInt64,Discord.CacheMode,Discord.RequestOptions)"> <member name="M:Discord.Rest.RestGuild.Discord#IGuild#GetUserAsync(System.UInt64,Discord.CacheMode,Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
@@ -4472,10 +4508,13 @@
<member name="P:Discord.Rest.Sticker.Tags"> <member name="P:Discord.Rest.Sticker.Tags">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="P:Discord.Rest.Sticker.Asset">
<member name="P:Discord.Rest.Sticker.Type">
<inheritdoc />
</member>
<member name="P:Discord.Rest.Sticker.Available">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="P:Discord.Rest.Sticker.PreviewAsset">
<member name="P:Discord.Rest.Sticker.SortOrder">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="P:Discord.Rest.Sticker.Format"> <member name="P:Discord.Rest.Sticker.Format">


+ 83
- 52
src/Discord.Net.Rest/DiscordRestApiClient.cs View File

@@ -24,6 +24,7 @@ namespace Discord.API
{ {
internal class DiscordRestApiClient : IDisposable internal class DiscordRestApiClient : IDisposable
{ {
#region DiscordRestApiClient
private static readonly ConcurrentDictionary<string, Func<BucketIds, BucketId>> _bucketIdGenerators = new ConcurrentDictionary<string, Func<BucketIds, BucketId>>(); private static readonly ConcurrentDictionary<string, Func<BucketIds, BucketId>> _bucketIdGenerators = new ConcurrentDictionary<string, Func<BucketIds, BucketId>>();


public event Func<string, string, double, Task> SentRequest { add { _sentRequestEvent.Add(value); } remove { _sentRequestEvent.Remove(value); } } public event Func<string, string, double, Task> SentRequest { add { _sentRequestEvent.Add(value); } remove { _sentRequestEvent.Remove(value); } }
@@ -167,8 +168,9 @@ namespace Discord.API


internal virtual Task ConnectInternalAsync() => Task.Delay(0); internal virtual Task ConnectInternalAsync() => Task.Delay(0);
internal virtual Task DisconnectInternalAsync(Exception ex = null) => Task.Delay(0); internal virtual Task DisconnectInternalAsync(Exception ex = null) => Task.Delay(0);
#endregion


//Core
#region Core
internal Task SendAsync(string method, Expression<Func<string>> endpointExpr, BucketIds ids, internal Task SendAsync(string method, Expression<Func<string>> endpointExpr, BucketIds ids,
ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null)
=> SendAsync(method, GetEndpoint(endpointExpr), GetBucketId(method, ids, endpointExpr, funcName), clientBucket, options); => SendAsync(method, GetEndpoint(endpointExpr), GetBucketId(method, ids, endpointExpr, funcName), clientBucket, options);
@@ -271,15 +273,17 @@ namespace Discord.API


return responseStream; return responseStream;
} }
#endregion


//Auth
#region Auth
public async Task ValidateTokenAsync(RequestOptions options = null) public async Task ValidateTokenAsync(RequestOptions options = null)
{ {
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);
await SendAsync("GET", () => "auth/login", new BucketIds(), options: options).ConfigureAwait(false); await SendAsync("GET", () => "auth/login", new BucketIds(), options: options).ConfigureAwait(false);
} }
#endregion


//Gateway
#region Gateway
public async Task<GetGatewayResponse> GetGatewayAsync(RequestOptions options = null) public async Task<GetGatewayResponse> GetGatewayAsync(RequestOptions options = null)
{ {
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);
@@ -290,8 +294,9 @@ namespace Discord.API
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);
return await SendAsync<GetBotGatewayResponse>("GET", () => "gateway/bot", new BucketIds(), options: options).ConfigureAwait(false); return await SendAsync<GetBotGatewayResponse>("GET", () => "gateway/bot", new BucketIds(), options: options).ConfigureAwait(false);
} }
#endregion


//Channels
#region Channels
public async Task<Channel> GetChannelAsync(ulong channelId, RequestOptions options = null) public async Task<Channel> GetChannelAsync(ulong channelId, RequestOptions options = null)
{ {
Preconditions.NotEqual(channelId, 0, nameof(channelId)); Preconditions.NotEqual(channelId, 0, nameof(channelId));
@@ -414,8 +419,9 @@ namespace Discord.API
break; break;
} }
} }
#endregion


// Threads
#region Threads
public async Task<Channel> ModifyThreadAsync(ulong channelId, ModifyThreadParams args, RequestOptions options = null) public async Task<Channel> ModifyThreadAsync(ulong channelId, ModifyThreadParams args, RequestOptions options = null)
{ {
Preconditions.NotEqual(channelId, 0, nameof(channelId)); Preconditions.NotEqual(channelId, 0, nameof(channelId));
@@ -582,8 +588,9 @@ namespace Discord.API


return await SendAsync<ChannelThreads>("GET", () => $"channels/{channelId}/users/@me/threads/archived/private{query}", bucket, options: options); return await SendAsync<ChannelThreads>("GET", () => $"channels/{channelId}/users/@me/threads/archived/private{query}", bucket, options: options);
} }
#endregion


// stage
#region Stage
public async Task<StageInstance> CreateStageInstanceAsync(CreateStageInstanceParams args, RequestOptions options = null) public async Task<StageInstance> CreateStageInstanceAsync(CreateStageInstanceParams args, RequestOptions options = null)
{ {
@@ -658,8 +665,9 @@ namespace Discord.API


await SendJsonAsync("PATCH", () => $"guilds/{guildId}/voice-states/{userId}", args, bucket, options: options).ConfigureAwait(false); await SendJsonAsync("PATCH", () => $"guilds/{guildId}/voice-states/{userId}", args, bucket, options: options).ConfigureAwait(false);
} }
#endregion


// roles
#region Roles
public async Task AddRoleAsync(ulong guildId, ulong userId, ulong roleId, RequestOptions options = null) public async Task AddRoleAsync(ulong guildId, ulong userId, ulong roleId, RequestOptions options = null)
{ {
Preconditions.NotEqual(guildId, 0, nameof(guildId)); Preconditions.NotEqual(guildId, 0, nameof(guildId));
@@ -682,8 +690,9 @@ namespace Discord.API
var ids = new BucketIds(guildId: guildId); var ids = new BucketIds(guildId: guildId);
await SendAsync("DELETE", () => $"guilds/{guildId}/members/{userId}/roles/{roleId}", ids, options: options).ConfigureAwait(false); await SendAsync("DELETE", () => $"guilds/{guildId}/members/{userId}/roles/{roleId}", ids, options: options).ConfigureAwait(false);
} }
#endregion


//Channel Messages
#region Channel Messages
public async Task<Message> GetChannelMessageAsync(ulong channelId, ulong messageId, RequestOptions options = null) public async Task<Message> GetChannelMessageAsync(ulong channelId, ulong messageId, RequestOptions options = null)
{ {
Preconditions.NotEqual(channelId, 0, nameof(channelId)); Preconditions.NotEqual(channelId, 0, nameof(channelId));
@@ -886,8 +895,9 @@ namespace Discord.API
var ids = new BucketIds(channelId: channelId); var ids = new BucketIds(channelId: channelId);
return await SendJsonAsync<Message>("PATCH", () => $"channels/{channelId}/messages/{messageId}", args, ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false); return await SendJsonAsync<Message>("PATCH", () => $"channels/{channelId}/messages/{messageId}", args, ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false);
} }
#endregion


// Stickers
#region Stickers, Reactions, Crosspost, and Acks
public async Task<Sticker> GetStickerAsync(ulong id, RequestOptions options = null) public async Task<Sticker> GetStickerAsync(ulong id, RequestOptions options = null)
{ {
Preconditions.NotEqual(id, 0, nameof(id)); Preconditions.NotEqual(id, 0, nameof(id));
@@ -1044,8 +1054,9 @@ namespace Discord.API
var ids = new BucketIds(channelId: channelId); var ids = new BucketIds(channelId: channelId);
await SendAsync("POST", () => $"channels/{channelId}/messages/{messageId}/crosspost", ids, options: options).ConfigureAwait(false); await SendAsync("POST", () => $"channels/{channelId}/messages/{messageId}/crosspost", ids, options: options).ConfigureAwait(false);
} }
#endregion


//Channel Permissions
#region Channel Permissions
public async Task ModifyChannelPermissionsAsync(ulong channelId, ulong targetId, ModifyChannelPermissionsParams args, RequestOptions options = null) public async Task ModifyChannelPermissionsAsync(ulong channelId, ulong targetId, ModifyChannelPermissionsParams args, RequestOptions options = null)
{ {
Preconditions.NotEqual(channelId, 0, nameof(channelId)); Preconditions.NotEqual(channelId, 0, nameof(channelId));
@@ -1065,8 +1076,9 @@ namespace Discord.API
var ids = new BucketIds(channelId: channelId); var ids = new BucketIds(channelId: channelId);
await SendAsync("DELETE", () => $"channels/{channelId}/permissions/{targetId}", ids, options: options).ConfigureAwait(false); await SendAsync("DELETE", () => $"channels/{channelId}/permissions/{targetId}", ids, options: options).ConfigureAwait(false);
} }
#endregion


//Channel Pins
#region Channel Pins
public async Task AddPinAsync(ulong channelId, ulong messageId, RequestOptions options = null) public async Task AddPinAsync(ulong channelId, ulong messageId, RequestOptions options = null)
{ {
Preconditions.GreaterThan(channelId, 0, nameof(channelId)); Preconditions.GreaterThan(channelId, 0, nameof(channelId));
@@ -1094,8 +1106,9 @@ namespace Discord.API
var ids = new BucketIds(channelId: channelId); var ids = new BucketIds(channelId: channelId);
return await SendAsync<IReadOnlyCollection<Message>>("GET", () => $"channels/{channelId}/pins", ids, options: options).ConfigureAwait(false); return await SendAsync<IReadOnlyCollection<Message>>("GET", () => $"channels/{channelId}/pins", ids, options: options).ConfigureAwait(false);
} }
#endregion


//Channel Recipients
#region Channel Recipients
public async Task AddGroupRecipientAsync(ulong channelId, ulong userId, RequestOptions options = null) public async Task AddGroupRecipientAsync(ulong channelId, ulong userId, RequestOptions options = null)
{ {
Preconditions.GreaterThan(channelId, 0, nameof(channelId)); Preconditions.GreaterThan(channelId, 0, nameof(channelId));
@@ -1115,8 +1128,9 @@ namespace Discord.API
var ids = new BucketIds(channelId: channelId); var ids = new BucketIds(channelId: channelId);
await SendAsync("DELETE", () => $"channels/{channelId}/recipients/{userId}", ids, options: options).ConfigureAwait(false); await SendAsync("DELETE", () => $"channels/{channelId}/recipients/{userId}", ids, options: options).ConfigureAwait(false);
} }
#endregion


//Interactions
#region Interactions
public async Task<ApplicationCommand[]> GetGlobalApplicationCommandsAsync(RequestOptions options = null) public async Task<ApplicationCommand[]> GetGlobalApplicationCommandsAsync(RequestOptions options = null)
{ {
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);
@@ -1152,25 +1166,25 @@ namespace Discord.API


options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);


return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("POST", () => $"applications/{this.CurrentUserId}/commands", command, new BucketIds(), options: options)).ConfigureAwait(false);
return await TrySendApplicationCommandAsync(SendJsonAsync<ApplicationCommand>("POST", () => $"applications/{this.CurrentUserId}/commands", command, new BucketIds(), options: options)).ConfigureAwait(false);
} }
public async Task<ApplicationCommand> ModifyGlobalApplicationCommandAsync(ModifyApplicationCommandParams command, ulong commandId, RequestOptions options = null) public async Task<ApplicationCommand> ModifyGlobalApplicationCommandAsync(ModifyApplicationCommandParams command, ulong commandId, RequestOptions options = null)
{ {
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);


return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options)).ConfigureAwait(false);
return await TrySendApplicationCommandAsync(SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options)).ConfigureAwait(false);
} }
public async Task<ApplicationCommand> ModifyGlobalApplicationUserCommandAsync(ModifyApplicationCommandParams command, ulong commandId, RequestOptions options = null) public async Task<ApplicationCommand> ModifyGlobalApplicationUserCommandAsync(ModifyApplicationCommandParams command, ulong commandId, RequestOptions options = null)
{ {
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);


return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options)).ConfigureAwait(false);
return await TrySendApplicationCommandAsync(SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options)).ConfigureAwait(false);
} }
public async Task<ApplicationCommand> ModifyGlobalApplicationMessageCommandAsync(ModifyApplicationCommandParams command, ulong commandId, RequestOptions options = null) public async Task<ApplicationCommand> ModifyGlobalApplicationMessageCommandAsync(ModifyApplicationCommandParams command, ulong commandId, RequestOptions options = null)
{ {
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);


return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options)).ConfigureAwait(false);
return await TrySendApplicationCommandAsync(SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/commands/{commandId}", command, new BucketIds(), options: options)).ConfigureAwait(false);
} }
public async Task DeleteGlobalApplicationCommandAsync(ulong commandId, RequestOptions options = null) public async Task DeleteGlobalApplicationCommandAsync(ulong commandId, RequestOptions options = null)
{ {
@@ -1179,11 +1193,11 @@ namespace Discord.API
await SendAsync("DELETE", () => $"applications/{this.CurrentUserId}/commands/{commandId}", new BucketIds(), options: options).ConfigureAwait(false); await SendAsync("DELETE", () => $"applications/{this.CurrentUserId}/commands/{commandId}", new BucketIds(), options: options).ConfigureAwait(false);
} }


public async Task<ApplicationCommand[]> BulkOverwriteGlobalApplicationCommands(CreateApplicationCommandParams[] commands, RequestOptions options = null)
public async Task<ApplicationCommand[]> BulkOverwriteGlobalApplicationCommandsAsync(CreateApplicationCommandParams[] commands, RequestOptions options = null)
{ {
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);


return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand[]>("PUT", () => $"applications/{this.CurrentUserId}/commands", commands, new BucketIds(), options: options)).ConfigureAwait(false);
return await TrySendApplicationCommandAsync(SendJsonAsync<ApplicationCommand[]>("PUT", () => $"applications/{this.CurrentUserId}/commands", commands, new BucketIds(), options: options)).ConfigureAwait(false);
} }


public async Task<ApplicationCommand[]> GetGuildApplicationCommandsAsync(ulong guildId, RequestOptions options = null) public async Task<ApplicationCommand[]> GetGuildApplicationCommandsAsync(ulong guildId, RequestOptions options = null)
@@ -1225,7 +1239,7 @@ namespace Discord.API


var bucket = new BucketIds(guildId: guildId); var bucket = new BucketIds(guildId: guildId);


return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("POST", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", command, bucket, options: options)).ConfigureAwait(false);
return await TrySendApplicationCommandAsync(SendJsonAsync<ApplicationCommand>("POST", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", command, bucket, options: options)).ConfigureAwait(false);
} }
public async Task<ApplicationCommand> ModifyGuildApplicationCommandAsync(ModifyApplicationCommandParams command, ulong guildId, ulong commandId, RequestOptions options = null) public async Task<ApplicationCommand> ModifyGuildApplicationCommandAsync(ModifyApplicationCommandParams command, ulong guildId, ulong commandId, RequestOptions options = null)
{ {
@@ -1233,7 +1247,7 @@ namespace Discord.API


var bucket = new BucketIds(guildId: guildId); var bucket = new BucketIds(guildId: guildId);


return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}", command, bucket, options: options)).ConfigureAwait(false);
return await TrySendApplicationCommandAsync(SendJsonAsync<ApplicationCommand>("PATCH", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}", command, bucket, options: options)).ConfigureAwait(false);
} }
public async Task DeleteGuildApplicationCommandAsync(ulong guildId, ulong commandId, RequestOptions options = null) public async Task DeleteGuildApplicationCommandAsync(ulong guildId, ulong commandId, RequestOptions options = null)
{ {
@@ -1244,17 +1258,18 @@ namespace Discord.API
await SendAsync<ApplicationCommand>("DELETE", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}", bucket, options: options).ConfigureAwait(false); await SendAsync<ApplicationCommand>("DELETE", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}", bucket, options: options).ConfigureAwait(false);
} }


public async Task<ApplicationCommand[]> BulkOverwriteGuildApplicationCommands(ulong guildId, CreateApplicationCommandParams[] commands, RequestOptions options = null)
public async Task<ApplicationCommand[]> BulkOverwriteGuildApplicationCommandsAsync(ulong guildId, CreateApplicationCommandParams[] commands, RequestOptions options = null)
{ {
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);


var bucket = new BucketIds(guildId: guildId); var bucket = new BucketIds(guildId: guildId);


return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand[]>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", commands, bucket, options: options)).ConfigureAwait(false);
return await TrySendApplicationCommandAsync(SendJsonAsync<ApplicationCommand[]>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", commands, bucket, options: options)).ConfigureAwait(false);
} }
#endregion


//Interaction Responses
public async Task CreateInteractionResponse(InteractionResponse response, ulong interactionId, string interactionToken, RequestOptions options = null)
#region Interaction Responses
public async Task CreateInteractionResponseAsync(InteractionResponse response, ulong interactionId, string interactionToken, RequestOptions options = null)
{ {
if(response.Data.IsSpecified && response.Data.Value.Content.IsSpecified) if(response.Data.IsSpecified && response.Data.Value.Content.IsSpecified)
Preconditions.AtMost(response.Data.Value.Content.Value?.Length ?? 0, 2000, nameof(response.Data.Value.Content)); Preconditions.AtMost(response.Data.Value.Content.Value?.Length ?? 0, 2000, nameof(response.Data.Value.Content));
@@ -1263,7 +1278,7 @@ namespace Discord.API


await SendJsonAsync<Message>("POST", () => $"interactions/{interactionId}/{interactionToken}/callback", response, new BucketIds(), options: options); await SendJsonAsync<Message>("POST", () => $"interactions/{interactionId}/{interactionToken}/callback", response, new BucketIds(), options: options);
} }
public async Task<Message> GetInteractionResponse(string interactionToken, RequestOptions options = null)
public async Task<Message> GetInteractionResponseAsync(string interactionToken, RequestOptions options = null)
{ {
Preconditions.NotNullOrEmpty(interactionToken, nameof(interactionToken)); Preconditions.NotNullOrEmpty(interactionToken, nameof(interactionToken));


@@ -1271,20 +1286,20 @@ namespace Discord.API


return await SendAsync<Message>("GET", () => $"webhooks/{this.CurrentUserId}/{interactionToken}/messages/@original", new BucketIds(), options: options).ConfigureAwait(false); return await SendAsync<Message>("GET", () => $"webhooks/{this.CurrentUserId}/{interactionToken}/messages/@original", new BucketIds(), options: options).ConfigureAwait(false);
} }
public async Task<Message> ModifyInteractionResponse(ModifyInteractionResponseParams args, string interactionToken, RequestOptions options = null)
public async Task<Message> ModifyInteractionResponseAsync(ModifyInteractionResponseParams args, string interactionToken, RequestOptions options = null)
{ {
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);


return await SendJsonAsync<Message>("PATCH", () => $"webhooks/{this.CurrentUserId}/{interactionToken}/messages/@original", args, new BucketIds(), options: options); return await SendJsonAsync<Message>("PATCH", () => $"webhooks/{this.CurrentUserId}/{interactionToken}/messages/@original", args, new BucketIds(), options: options);
} }
public async Task DeleteInteractionResponse(string interactionToken, RequestOptions options = null)
public async Task DeleteInteractionResponseAsync(string interactionToken, RequestOptions options = null)
{ {
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);


await SendAsync("DELETE", () => $"webhooks/{this.CurrentUserId}/{interactionToken}/messages/@original", new BucketIds(), options: options); await SendAsync("DELETE", () => $"webhooks/{this.CurrentUserId}/{interactionToken}/messages/@original", new BucketIds(), options: options);
} }


public async Task<Message> CreateInteractionFollowupMessage(CreateWebhookMessageParams args, string token, RequestOptions options = null)
public async Task<Message> CreateInteractionFollowupMessageAsync(CreateWebhookMessageParams args, string token, RequestOptions options = null)
{ {
if ((!args.Embeds.IsSpecified || args.Embeds.Value == null || args.Embeds.Value.Length == 0) && !args.File.IsSpecified) if ((!args.Embeds.IsSpecified || args.Embeds.Value == null || args.Embeds.Value.Length == 0) && !args.File.IsSpecified)
Preconditions.NotNullOrEmpty(args.Content, nameof(args.Content)); Preconditions.NotNullOrEmpty(args.Content, nameof(args.Content));
@@ -1300,7 +1315,7 @@ namespace Discord.API
return await SendMultipartAsync<Message>("POST", () => $"webhooks/{CurrentUserId}/{token}?wait=true", args.ToDictionary(), new BucketIds(), options: options).ConfigureAwait(false); return await SendMultipartAsync<Message>("POST", () => $"webhooks/{CurrentUserId}/{token}?wait=true", args.ToDictionary(), new BucketIds(), options: options).ConfigureAwait(false);
} }


public async Task<Message> ModifyInteractionFollowupMessage(ModifyInteractionResponseParams args, ulong id, string token, RequestOptions options = null)
public async Task<Message> ModifyInteractionFollowupMessageAsync(ModifyInteractionResponseParams args, ulong id, string token, RequestOptions options = null)
{ {
Preconditions.NotNull(args, nameof(args)); Preconditions.NotNull(args, nameof(args));
Preconditions.NotEqual(id, 0, nameof(id)); Preconditions.NotEqual(id, 0, nameof(id));
@@ -1314,7 +1329,7 @@ namespace Discord.API
return await SendJsonAsync<Message>("PATCH", () => $"webhooks/{CurrentUserId}/{token}/messages/{id}", args, new BucketIds(), options: options).ConfigureAwait(false); return await SendJsonAsync<Message>("PATCH", () => $"webhooks/{CurrentUserId}/{token}/messages/{id}", args, new BucketIds(), options: options).ConfigureAwait(false);
} }


public async Task DeleteInteractionFollowupMessage(ulong id, string token, RequestOptions options = null)
public async Task DeleteInteractionFollowupMessageAsync(ulong id, string token, RequestOptions options = null)
{ {
Preconditions.NotEqual(id, 0, nameof(id)); Preconditions.NotEqual(id, 0, nameof(id));


@@ -1322,9 +1337,10 @@ namespace Discord.API


await SendAsync("DELETE", () => $"webhooks/{CurrentUserId}/{token}/messages/{id}", new BucketIds(), options: options).ConfigureAwait(false); await SendAsync("DELETE", () => $"webhooks/{CurrentUserId}/{token}/messages/{id}", new BucketIds(), options: options).ConfigureAwait(false);
} }
#endregion


// Application Command permissions
public async Task<GuildApplicationCommandPermission[]> GetGuildApplicationCommandPermissions(ulong guildId, RequestOptions options = null)
#region Application Command permissions
public async Task<GuildApplicationCommandPermission[]> GetGuildApplicationCommandPermissionsAsync(ulong guildId, RequestOptions options = null)
{ {
Preconditions.NotEqual(guildId, 0, nameof(guildId)); Preconditions.NotEqual(guildId, 0, nameof(guildId));


@@ -1333,7 +1349,7 @@ namespace Discord.API
return await SendAsync<GuildApplicationCommandPermission[]>("GET", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/permissions", new BucketIds(), options: options).ConfigureAwait(false); return await SendAsync<GuildApplicationCommandPermission[]>("GET", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/permissions", new BucketIds(), options: options).ConfigureAwait(false);
} }


public async Task<GuildApplicationCommandPermission> GetGuildApplicationCommandPermission(ulong guildId, ulong commandId, RequestOptions options = null)
public async Task<GuildApplicationCommandPermission> GetGuildApplicationCommandPermissionAsync(ulong guildId, ulong commandId, RequestOptions options = null)
{ {
Preconditions.NotEqual(guildId, 0, nameof(guildId)); Preconditions.NotEqual(guildId, 0, nameof(guildId));
Preconditions.NotEqual(commandId, 0, nameof(commandId)); Preconditions.NotEqual(commandId, 0, nameof(commandId));
@@ -1343,7 +1359,7 @@ namespace Discord.API
return await SendAsync<GuildApplicationCommandPermission>("GET", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}/permissions", new BucketIds(), options: options).ConfigureAwait(false); return await SendAsync<GuildApplicationCommandPermission>("GET", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}/permissions", new BucketIds(), options: options).ConfigureAwait(false);
} }


public async Task<GuildApplicationCommandPermission> ModifyApplicationCommandPermissions(ModifyGuildApplicationCommandPermissionsParams permissions, ulong guildId, ulong commandId, RequestOptions options = null)
public async Task<GuildApplicationCommandPermission> ModifyApplicationCommandPermissionsAsync(ModifyGuildApplicationCommandPermissionsParams permissions, ulong guildId, ulong commandId, RequestOptions options = null)
{ {
Preconditions.NotEqual(guildId, 0, nameof(guildId)); Preconditions.NotEqual(guildId, 0, nameof(guildId));
Preconditions.NotEqual(commandId, 0, nameof(commandId)); Preconditions.NotEqual(commandId, 0, nameof(commandId));
@@ -1353,7 +1369,7 @@ namespace Discord.API
return await SendJsonAsync<GuildApplicationCommandPermission>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}/permissions", permissions, new BucketIds(), options: options).ConfigureAwait(false); return await SendJsonAsync<GuildApplicationCommandPermission>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/{commandId}/permissions", permissions, new BucketIds(), options: options).ConfigureAwait(false);
} }


public async Task<IReadOnlyCollection<GuildApplicationCommandPermission>> BatchModifyApplicationCommandPermissions(ModifyGuildApplicationCommandPermissions[] permissions, ulong guildId, RequestOptions options = null)
public async Task<IReadOnlyCollection<GuildApplicationCommandPermission>> BatchModifyApplicationCommandPermissionsAsync(ModifyGuildApplicationCommandPermissions[] permissions, ulong guildId, RequestOptions options = null)
{ {
Preconditions.NotEqual(guildId, 0, nameof(guildId)); Preconditions.NotEqual(guildId, 0, nameof(guildId));
Preconditions.NotNull(permissions, nameof(permissions)); Preconditions.NotNull(permissions, nameof(permissions));
@@ -1362,8 +1378,9 @@ namespace Discord.API


return await SendJsonAsync<GuildApplicationCommandPermission[]>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/permissions", permissions, new BucketIds(), options: options).ConfigureAwait(false); return await SendJsonAsync<GuildApplicationCommandPermission[]>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/permissions", permissions, new BucketIds(), options: options).ConfigureAwait(false);
} }
#endregion


//Guilds
#region Guilds
public async Task<Guild> GetGuildAsync(ulong guildId, bool withCounts, RequestOptions options = null) public async Task<Guild> GetGuildAsync(ulong guildId, bool withCounts, RequestOptions options = null)
{ {
Preconditions.NotEqual(guildId, 0, nameof(guildId)); Preconditions.NotEqual(guildId, 0, nameof(guildId));
@@ -1436,8 +1453,9 @@ namespace Discord.API
var ids = new BucketIds(guildId: guildId); var ids = new BucketIds(guildId: guildId);
return await SendAsync<GetGuildPruneCountResponse>("GET", () => $"guilds/{guildId}/prune?days={args.Days}{endpointRoleIds}", ids, options: options).ConfigureAwait(false); return await SendAsync<GetGuildPruneCountResponse>("GET", () => $"guilds/{guildId}/prune?days={args.Days}{endpointRoleIds}", ids, options: options).ConfigureAwait(false);
} }
#endregion


//Guild Bans
#region Guild Bans
public async Task<IReadOnlyCollection<Ban>> GetGuildBansAsync(ulong guildId, RequestOptions options = null) public async Task<IReadOnlyCollection<Ban>> GetGuildBansAsync(ulong guildId, RequestOptions options = null)
{ {
Preconditions.NotEqual(guildId, 0, nameof(guildId)); Preconditions.NotEqual(guildId, 0, nameof(guildId));
@@ -1488,8 +1506,9 @@ namespace Discord.API
var ids = new BucketIds(guildId: guildId); var ids = new BucketIds(guildId: guildId);
await SendAsync("DELETE", () => $"guilds/{guildId}/bans/{userId}", ids, options: options).ConfigureAwait(false); await SendAsync("DELETE", () => $"guilds/{guildId}/bans/{userId}", ids, options: options).ConfigureAwait(false);
} }
#endregion


//Guild Widget
#region Guild Widget
/// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception> /// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception>
public async Task<GuildWidget> GetGuildWidgetAsync(ulong guildId, RequestOptions options = null) public async Task<GuildWidget> GetGuildWidgetAsync(ulong guildId, RequestOptions options = null)
{ {
@@ -1514,8 +1533,9 @@ namespace Discord.API
var ids = new BucketIds(guildId: guildId); var ids = new BucketIds(guildId: guildId);
return await SendJsonAsync<GuildWidget>("PATCH", () => $"guilds/{guildId}/widget", args, ids, options: options).ConfigureAwait(false); return await SendJsonAsync<GuildWidget>("PATCH", () => $"guilds/{guildId}/widget", args, ids, options: options).ConfigureAwait(false);
} }
#endregion


//Guild Integrations
#region Guild Integrations
/// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception> /// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception>
public async Task<IReadOnlyCollection<Integration>> GetGuildIntegrationsAsync(ulong guildId, RequestOptions options = null) public async Task<IReadOnlyCollection<Integration>> GetGuildIntegrationsAsync(ulong guildId, RequestOptions options = null)
{ {
@@ -1567,8 +1587,9 @@ namespace Discord.API
var ids = new BucketIds(guildId: guildId); var ids = new BucketIds(guildId: guildId);
return await SendAsync<Integration>("POST", () => $"guilds/{guildId}/integrations/{integrationId}/sync", ids, options: options).ConfigureAwait(false); return await SendAsync<Integration>("POST", () => $"guilds/{guildId}/integrations/{integrationId}/sync", ids, options: options).ConfigureAwait(false);
} }
#endregion


//Guild Invites
#region Guild Invites
/// <exception cref="ArgumentException"><paramref name="inviteId"/> cannot be blank.</exception> /// <exception cref="ArgumentException"><paramref name="inviteId"/> cannot be blank.</exception>
/// <exception cref="ArgumentNullException"><paramref name="inviteId"/> must not be <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException"><paramref name="inviteId"/> must not be <see langword="null"/>.</exception>
public async Task<InviteMetadata> GetInviteAsync(string inviteId, RequestOptions options = null) public async Task<InviteMetadata> GetInviteAsync(string inviteId, RequestOptions options = null)
@@ -1651,8 +1672,9 @@ namespace Discord.API


return await SendAsync<Invite>("DELETE", () => $"invites/{inviteId}", new BucketIds(), options: options).ConfigureAwait(false); return await SendAsync<Invite>("DELETE", () => $"invites/{inviteId}", new BucketIds(), options: options).ConfigureAwait(false);
} }
#endregion


//Guild Members
#region Guild Members
public async Task<GuildMember> AddGuildMemberAsync(ulong guildId, ulong userId, AddGuildMemberParams args, RequestOptions options = null) public async Task<GuildMember> AddGuildMemberAsync(ulong guildId, ulong userId, AddGuildMemberParams args, RequestOptions options = null)
{ {
Preconditions.NotEqual(guildId, 0, nameof(guildId)); Preconditions.NotEqual(guildId, 0, nameof(guildId));
@@ -1750,8 +1772,9 @@ namespace Discord.API
Expression<Func<string>> endpoint = () => $"guilds/{guildId}/members/search?limit={limit}&query={query}"; Expression<Func<string>> endpoint = () => $"guilds/{guildId}/members/search?limit={limit}&query={query}";
return await SendAsync<IReadOnlyCollection<GuildMember>>("GET", endpoint, ids, options: options).ConfigureAwait(false); return await SendAsync<IReadOnlyCollection<GuildMember>>("GET", endpoint, ids, options: options).ConfigureAwait(false);
} }
#endregion


//Guild Roles
#region Guild Roles
public async Task<IReadOnlyCollection<Role>> GetGuildRolesAsync(ulong guildId, RequestOptions options = null) public async Task<IReadOnlyCollection<Role>> GetGuildRolesAsync(ulong guildId, RequestOptions options = null)
{ {
Preconditions.NotEqual(guildId, 0, nameof(guildId)); Preconditions.NotEqual(guildId, 0, nameof(guildId));
@@ -1798,8 +1821,9 @@ namespace Discord.API
var ids = new BucketIds(guildId: guildId); var ids = new BucketIds(guildId: guildId);
return await SendJsonAsync<IReadOnlyCollection<Role>>("PATCH", () => $"guilds/{guildId}/roles", args, ids, options: options).ConfigureAwait(false); return await SendJsonAsync<IReadOnlyCollection<Role>>("PATCH", () => $"guilds/{guildId}/roles", args, ids, options: options).ConfigureAwait(false);
} }
#endregion


//Guild emoji
#region Guild emoji
public async Task<IReadOnlyCollection<Emoji>> GetGuildEmotesAsync(ulong guildId, RequestOptions options = null) public async Task<IReadOnlyCollection<Emoji>> GetGuildEmotesAsync(ulong guildId, RequestOptions options = null)
{ {
Preconditions.NotEqual(guildId, 0, nameof(guildId)); Preconditions.NotEqual(guildId, 0, nameof(guildId));
@@ -1851,8 +1875,9 @@ namespace Discord.API
var ids = new BucketIds(guildId: guildId); var ids = new BucketIds(guildId: guildId);
await SendAsync("DELETE", () => $"guilds/{guildId}/emojis/{emoteId}", ids, options: options).ConfigureAwait(false); await SendAsync("DELETE", () => $"guilds/{guildId}/emojis/{emoteId}", ids, options: options).ConfigureAwait(false);
} }
#endregion


//Users
#region Users
public async Task<User> GetUserAsync(ulong userId, RequestOptions options = null) public async Task<User> GetUserAsync(ulong userId, RequestOptions options = null)
{ {
Preconditions.NotEqual(userId, 0, nameof(userId)); Preconditions.NotEqual(userId, 0, nameof(userId));
@@ -1864,8 +1889,9 @@ namespace Discord.API
} }
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; } catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; }
} }
#endregion


//Current User/DMs
#region Current User/DMs
public async Task<User> GetMyUserAsync(RequestOptions options = null) public async Task<User> GetMyUserAsync(RequestOptions options = null)
{ {
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);
@@ -1924,8 +1950,9 @@ namespace Discord.API


return await SendJsonAsync<Channel>("POST", () => "users/@me/channels", args, new BucketIds(), options: options).ConfigureAwait(false); return await SendJsonAsync<Channel>("POST", () => "users/@me/channels", args, new BucketIds(), options: options).ConfigureAwait(false);
} }
#endregion


//Voice Regions
#region Voice Regions
public async Task<IReadOnlyCollection<VoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null) public async Task<IReadOnlyCollection<VoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null)
{ {
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);
@@ -1939,8 +1966,9 @@ namespace Discord.API
var ids = new BucketIds(guildId: guildId); var ids = new BucketIds(guildId: guildId);
return await SendAsync<IReadOnlyCollection<VoiceRegion>>("GET", () => $"guilds/{guildId}/regions", ids, options: options).ConfigureAwait(false); return await SendAsync<IReadOnlyCollection<VoiceRegion>>("GET", () => $"guilds/{guildId}/regions", ids, options: options).ConfigureAwait(false);
} }
#endregion


//Audit logs
#region Audit logs
public async Task<AuditLog> GetAuditLogsAsync(ulong guildId, GetAuditLogsParams args, RequestOptions options = null) public async Task<AuditLog> GetAuditLogsAsync(ulong guildId, GetAuditLogsParams args, RequestOptions options = null)
{ {
Preconditions.NotEqual(guildId, 0, nameof(guildId)); Preconditions.NotEqual(guildId, 0, nameof(guildId));
@@ -1969,12 +1997,13 @@ namespace Discord.API
.Append(args.ActionType.Value); .Append(args.ActionType.Value);
} }


// still use string interp for the query w/o params, as this is necessary for CreateBucketId
// Still use string interp for the query w/o params, as this is necessary for CreateBucketId
endpoint = () => $"guilds/{guildId}/audit-logs?limit={limit}{queryArgs.ToString()}"; endpoint = () => $"guilds/{guildId}/audit-logs?limit={limit}{queryArgs.ToString()}";
return await SendAsync<AuditLog>("GET", endpoint, ids, options: options).ConfigureAwait(false); return await SendAsync<AuditLog>("GET", endpoint, ids, options: options).ConfigureAwait(false);
} }
#endregion


//Webhooks
#region Webhooks
public async Task<Webhook> CreateWebhookAsync(ulong channelId, CreateWebhookParams args, RequestOptions options = null) public async Task<Webhook> CreateWebhookAsync(ulong channelId, CreateWebhookParams args, RequestOptions options = null)
{ {
Preconditions.NotEqual(channelId, 0, nameof(channelId)); Preconditions.NotEqual(channelId, 0, nameof(channelId));
@@ -2037,8 +2066,9 @@ namespace Discord.API
var ids = new BucketIds(channelId: channelId); var ids = new BucketIds(channelId: channelId);
return await SendAsync<IReadOnlyCollection<Webhook>>("GET", () => $"channels/{channelId}/webhooks", ids, options: options).ConfigureAwait(false); return await SendAsync<IReadOnlyCollection<Webhook>>("GET", () => $"channels/{channelId}/webhooks", ids, options: options).ConfigureAwait(false);
} }
#endregion


//Helpers
#region Helpers
/// <exception cref="InvalidOperationException">Client is not logged in.</exception> /// <exception cref="InvalidOperationException">Client is not logged in.</exception>
protected void CheckState() protected void CheckState()
{ {
@@ -2061,7 +2091,7 @@ namespace Discord.API
return _serializer.Deserialize<T>(reader); return _serializer.Deserialize<T>(reader);
} }


protected async Task<T> TrySendApplicationCommand<T>(Task<T> sendTask)
protected async Task<T> TrySendApplicationCommandAsync<T>(Task<T> sendTask)
{ {
try try
{ {
@@ -2248,5 +2278,6 @@ namespace Discord.API


return (expr as MemberExpression).Member.Name; return (expr as MemberExpression).Member.Name;
} }
#endregion
} }
} }

+ 5
- 1
src/Discord.Net.Rest/DiscordRestClient.cs View File

@@ -12,6 +12,7 @@ namespace Discord.Rest
/// </summary> /// </summary>
public class DiscordRestClient : BaseDiscordClient, IDiscordClient public class DiscordRestClient : BaseDiscordClient, IDiscordClient
{ {
#region DiscordRestClient
private RestApplication _applicationInfo; private RestApplication _applicationInfo;


/// <summary> /// <summary>
@@ -138,7 +139,9 @@ namespace Discord.Rest
=> MessageHelper.RemoveAllReactionsAsync(channelId, messageId, this, options); => MessageHelper.RemoveAllReactionsAsync(channelId, messageId, this, options);
public Task RemoveAllReactionsForEmoteAsync(ulong channelId, ulong messageId, IEmote emote, RequestOptions options = null) public Task RemoveAllReactionsForEmoteAsync(ulong channelId, ulong messageId, IEmote emote, RequestOptions options = null)
=> MessageHelper.RemoveAllReactionsForEmoteAsync(channelId, messageId, emote, this, options); => MessageHelper.RemoveAllReactionsForEmoteAsync(channelId, messageId, emote, this, options);
//IDiscordClient
#endregion

#region IDiscordClient
/// <inheritdoc /> /// <inheritdoc />
async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options) async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options)
=> await GetApplicationInfoAsync(options).ConfigureAwait(false); => await GetApplicationInfoAsync(options).ConfigureAwait(false);
@@ -229,5 +232,6 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
async Task<IApplicationCommand> IDiscordClient.GetGlobalApplicationCommandAsync(ulong id, RequestOptions options) async Task<IApplicationCommand> IDiscordClient.GetGlobalApplicationCommandAsync(ulong id, RequestOptions options)
=> await ClientHelper.GetGlobalApplicationCommand(this, id, options).ConfigureAwait(false); => await ClientHelper.GetGlobalApplicationCommand(this, id, options).ConfigureAwait(false);
#endregion
} }
} }

+ 16
- 6
src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs View File

@@ -264,7 +264,7 @@ namespace Discord.Rest


/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public static async Task<RestUserMessage> SendMessageAsync(IMessageChannel channel, BaseDiscordClient client, public static async Task<RestUserMessage> SendMessageAsync(IMessageChannel channel, BaseDiscordClient client,
string text, bool isTTS, Embed embed, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, RequestOptions options)
string text, bool isTTS, Embed embed, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers, RequestOptions options)
{ {
Preconditions.AtMost(allowedMentions?.RoleIds?.Count ?? 0, 100, nameof(allowedMentions.RoleIds), "A max of 100 role Ids are allowed."); Preconditions.AtMost(allowedMentions?.RoleIds?.Count ?? 0, 100, nameof(allowedMentions.RoleIds), "A max of 100 role Ids are allowed.");
Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed."); Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed.");
@@ -285,7 +285,12 @@ namespace Discord.Rest
} }
} }


var args = new CreateMessageParams(text) { IsTTS = isTTS, Embed = embed?.ToModel(), AllowedMentions = allowedMentions?.ToModel(), MessageReference = messageReference?.ToModel(), Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional<API.ActionRowComponent[]>.Unspecified };
if(stickers != null)
{
Preconditions.AtMost(stickers.Length, 3, nameof(stickers), "A max of 3 stickers are allowed.");
}

var args = new CreateMessageParams(text) { IsTTS = isTTS, Embed = embed?.ToModel(), AllowedMentions = allowedMentions?.ToModel(), MessageReference = messageReference?.ToModel(), Components = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional<API.ActionRowComponent[]>.Unspecified, Stickers = stickers?.Any() ?? false ? stickers.Select(x => x.Id).ToArray() : Optional<ulong[]>.Unspecified};
var model = await client.ApiClient.CreateMessageAsync(channel.Id, args, options).ConfigureAwait(false); var model = await client.ApiClient.CreateMessageAsync(channel.Id, args, options).ConfigureAwait(false);
return RestUserMessage.Create(client, channel, client.CurrentUser, model); return RestUserMessage.Create(client, channel, client.CurrentUser, model);
} }
@@ -315,16 +320,16 @@ namespace Discord.Rest
/// <exception cref="IOException">An I/O error occurred while opening the file.</exception> /// <exception cref="IOException">An I/O error occurred while opening the file.</exception>
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public static async Task<RestUserMessage> SendFileAsync(IMessageChannel channel, BaseDiscordClient client, public static async Task<RestUserMessage> SendFileAsync(IMessageChannel channel, BaseDiscordClient client,
string filePath, string text, bool isTTS, Embed embed, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, RequestOptions options, bool isSpoiler)
string filePath, string text, bool isTTS, Embed embed, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers, RequestOptions options, bool isSpoiler)
{ {
string filename = Path.GetFileName(filePath); string filename = Path.GetFileName(filePath);
using (var file = File.OpenRead(filePath)) using (var file = File.OpenRead(filePath))
return await SendFileAsync(channel, client, file, filename, text, isTTS, embed, allowedMentions, messageReference, component, options, isSpoiler).ConfigureAwait(false);
return await SendFileAsync(channel, client, file, filename, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options, isSpoiler).ConfigureAwait(false);
} }


/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public static async Task<RestUserMessage> SendFileAsync(IMessageChannel channel, BaseDiscordClient client, public static async Task<RestUserMessage> SendFileAsync(IMessageChannel channel, BaseDiscordClient client,
Stream stream, string filename, string text, bool isTTS, Embed embed, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, RequestOptions options, bool isSpoiler)
Stream stream, string filename, string text, bool isTTS, Embed embed, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers, RequestOptions options, bool isSpoiler)
{ {
Preconditions.AtMost(allowedMentions?.RoleIds?.Count ?? 0, 100, nameof(allowedMentions.RoleIds), "A max of 100 role Ids are allowed."); Preconditions.AtMost(allowedMentions?.RoleIds?.Count ?? 0, 100, nameof(allowedMentions.RoleIds), "A max of 100 role Ids are allowed.");
Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed."); Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed.");
@@ -345,7 +350,12 @@ namespace Discord.Rest
} }
} }


var args = new UploadFileParams(stream) { Filename = filename, Content = text, IsTTS = isTTS, Embed = embed?.ToModel() ?? Optional<API.Embed>.Unspecified, AllowedMentions = allowedMentions?.ToModel() ?? Optional<API.AllowedMentions>.Unspecified, MessageReference = messageReference?.ToModel() ?? Optional<API.MessageReference>.Unspecified, MessageComponent = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional<API.ActionRowComponent[]>.Unspecified, IsSpoiler = isSpoiler };
if (stickers != null)
{
Preconditions.AtMost(stickers.Length, 3, nameof(stickers), "A max of 3 stickers are allowed.");
}

var args = new UploadFileParams(stream) { Filename = filename, Content = text, IsTTS = isTTS, Embed = embed?.ToModel() ?? Optional<API.Embed>.Unspecified, AllowedMentions = allowedMentions?.ToModel() ?? Optional<API.AllowedMentions>.Unspecified, MessageReference = messageReference?.ToModel() ?? Optional<API.MessageReference>.Unspecified, MessageComponent = component?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() ?? Optional<API.ActionRowComponent[]>.Unspecified, IsSpoiler = isSpoiler, Stickers = stickers?.Any() ?? false ? stickers.Select(x => x.Id).ToArray() : Optional<ulong[]>.Unspecified };
var model = await client.ApiClient.UploadFileAsync(channel.Id, args, options).ConfigureAwait(false); var model = await client.ApiClient.UploadFileAsync(channel.Id, args, options).ConfigureAwait(false);
return RestUserMessage.Create(client, channel, client.CurrentUser, model); return RestUserMessage.Create(client, channel, client.CurrentUser, model);
} }


+ 11
- 5
src/Discord.Net.Rest/Entities/Channels/IRestMessageChannel.cs View File

@@ -25,17 +25,19 @@ namespace Discord.Rest
/// If <c>null</c>, all mentioned roles and users will be notified. /// If <c>null</c>, all mentioned roles and users will be notified.
/// </param> /// </param>
/// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param> /// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
/// <param name="component">The message components to be included with this message. Used for interactions</param>
/// <param name="stickers">A collection of stickers to send with the message.</param>
/// <returns> /// <returns>
/// A task that represents an asynchronous send operation for delivering the message. The task result /// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message. /// contains the sent message.
/// </returns> /// </returns>
new Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null);
new Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null);
/// <summary> /// <summary>
/// Sends a file to this message channel with an optional caption. /// Sends a file to this message channel with an optional caption.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This method follows the same behavior as described in /// This method follows the same behavior as described in
/// <see cref="IMessageChannel.SendFileAsync(string, string, bool, Embed, RequestOptions, bool, AllowedMentions, MessageReference)"/>. Please visit
/// <see cref="IMessageChannel.SendFileAsync(string, string, bool, Embed, RequestOptions, bool, AllowedMentions, MessageReference, MessageComponent, ISticker[])"/>. Please visit
/// its documentation for more details on this method. /// its documentation for more details on this method.
/// </remarks> /// </remarks>
/// <param name="filePath">The file path of the file.</param> /// <param name="filePath">The file path of the file.</param>
@@ -49,16 +51,18 @@ namespace Discord.Rest
/// If <c>null</c>, all mentioned roles and users will be notified. /// If <c>null</c>, all mentioned roles and users will be notified.
/// </param> /// </param>
/// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param> /// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
/// <param name="component">The message components to be included with this message. Used for interactions</param>
/// <param name="stickers">A collection of stickers to send with the message.</param>
/// <returns> /// <returns>
/// A task that represents an asynchronous send operation for delivering the message. The task result /// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message. /// contains the sent message.
/// </returns> /// </returns>
new Task<RestUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null);
new Task<RestUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null);
/// <summary> /// <summary>
/// Sends a file to this message channel with an optional caption. /// Sends a file to this message channel with an optional caption.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This method follows the same behavior as described in <see cref="IMessageChannel.SendFileAsync(Stream, string, string, bool, Embed, RequestOptions, bool, AllowedMentions, MessageReference)"/>.
/// This method follows the same behavior as described in <see cref="IMessageChannel.SendFileAsync(Stream, string, string, bool, Embed, RequestOptions, bool, AllowedMentions, MessageReference, MessageComponent, ISticker[])"/>.
/// Please visit its documentation for more details on this method. /// Please visit its documentation for more details on this method.
/// </remarks> /// </remarks>
/// <param name="stream">The <see cref="Stream" /> of the file to be sent.</param> /// <param name="stream">The <see cref="Stream" /> of the file to be sent.</param>
@@ -73,11 +77,13 @@ namespace Discord.Rest
/// If <c>null</c>, all mentioned roles and users will be notified. /// If <c>null</c>, all mentioned roles and users will be notified.
/// </param> /// </param>
/// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param> /// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
/// <param name="component">The message components to be included with this message. Used for interactions</param>
/// <param name="stickers">A collection of stickers to send with the message.</param>
/// <returns> /// <returns>
/// A task that represents an asynchronous send operation for delivering the message. The task result /// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message. /// contains the sent message.
/// </returns> /// </returns>
new Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null);
new Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null);


/// <summary> /// <summary>
/// Gets a message from this message channel. /// Gets a message from this message channel.


+ 4
- 1
src/Discord.Net.Rest/Entities/Channels/RestCategoryChannel.cs View File

@@ -12,6 +12,7 @@ namespace Discord.Rest
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestCategoryChannel : RestGuildChannel, ICategoryChannel public class RestCategoryChannel : RestGuildChannel, ICategoryChannel
{ {
#region RestCategoryChannel
internal RestCategoryChannel(BaseDiscordClient discord, IGuild guild, ulong id) internal RestCategoryChannel(BaseDiscordClient discord, IGuild guild, ulong id)
: base(discord, guild, id) : base(discord, guild, id)
{ {
@@ -24,8 +25,9 @@ namespace Discord.Rest
} }


private string DebuggerDisplay => $"{Name} ({Id}, Category)"; private string DebuggerDisplay => $"{Name} ({Id}, Category)";
#endregion


//IChannel
#region IChannel
/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> /// <exception cref="NotSupportedException">This method is not supported with category channels.</exception>
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
@@ -34,5 +36,6 @@ namespace Discord.Rest
/// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> /// <exception cref="NotSupportedException">This method is not supported with category channels.</exception>
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> throw new NotSupportedException(); => throw new NotSupportedException();
#endregion
} }
} }

+ 4
- 1
src/Discord.Net.Rest/Entities/Channels/RestChannel.cs View File

@@ -11,6 +11,7 @@ namespace Discord.Rest
/// </summary> /// </summary>
public class RestChannel : RestEntity<ulong>, IChannel, IUpdateable public class RestChannel : RestEntity<ulong>, IChannel, IUpdateable
{ {
#region RestChannel
/// <inheritdoc /> /// <inheritdoc />
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);


@@ -53,8 +54,9 @@ namespace Discord.Rest


/// <inheritdoc /> /// <inheritdoc />
public virtual Task UpdateAsync(RequestOptions options = null) => Task.Delay(0); public virtual Task UpdateAsync(RequestOptions options = null) => Task.Delay(0);
#endregion


//IChannel
#region IChannel
/// <inheritdoc /> /// <inheritdoc />
string IChannel.Name => null; string IChannel.Name => null;


@@ -64,5 +66,6 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden => AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden
#endregion
} }
} }

+ 12
- 12
src/Discord.Net.Rest/Entities/Channels/RestDMChannel.cs View File

@@ -93,8 +93,8 @@ namespace Discord.Rest


/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, component, options);
public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options);


/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
@@ -121,12 +121,12 @@ namespace Discord.Rest
/// <exception cref="NotSupportedException"><paramref name="filePath" /> is in an invalid format.</exception> /// <exception cref="NotSupportedException"><paramref name="filePath" /> is in an invalid format.</exception>
/// <exception cref="IOException">An I/O error occurred while opening the file.</exception> /// <exception cref="IOException">An I/O error occurred while opening the file.</exception>
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, allowedMentions, messageReference, component, options, isSpoiler);
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options, isSpoiler);
/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, allowedMentions, messageReference, component, options, isSpoiler);
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options, isSpoiler);


/// <inheritdoc /> /// <inheritdoc />
public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
@@ -204,14 +204,14 @@ namespace Discord.Rest
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false); => await GetPinnedMessagesAsync(options).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);


//IChannel //IChannel
/// <inheritdoc /> /// <inheritdoc />


+ 12
- 12
src/Discord.Net.Rest/Entities/Channels/RestGroupChannel.cs View File

@@ -99,8 +99,8 @@ namespace Discord.Rest


/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, component, options);
public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options);


/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
@@ -127,12 +127,12 @@ namespace Discord.Rest
/// <exception cref="NotSupportedException"><paramref name="filePath" /> is in an invalid format.</exception> /// <exception cref="NotSupportedException"><paramref name="filePath" /> is in an invalid format.</exception>
/// <exception cref="IOException">An I/O error occurred while opening the file.</exception> /// <exception cref="IOException">An I/O error occurred while opening the file.</exception>
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, allowedMentions, messageReference, component, options, isSpoiler);
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options, isSpoiler);
/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, allowedMentions, messageReference, component, options, isSpoiler);
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, allowedMentions, messageReference, component, stickers,options, isSpoiler);


/// <inheritdoc /> /// <inheritdoc />
public Task TriggerTypingAsync(RequestOptions options = null) public Task TriggerTypingAsync(RequestOptions options = null)
@@ -182,14 +182,14 @@ namespace Discord.Rest
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false); => await GetPinnedMessagesAsync(options).ConfigureAwait(false);


async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);


async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);


async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);


//IAudioChannel //IAudioChannel
/// <inheritdoc /> /// <inheritdoc />


+ 6
- 2
src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs View File

@@ -12,6 +12,7 @@ namespace Discord.Rest
/// </summary> /// </summary>
public class RestGuildChannel : RestChannel, IGuildChannel public class RestGuildChannel : RestChannel, IGuildChannel
{ {
#region RestGuildChannel
private ImmutableArray<Overwrite> _overwrites; private ImmutableArray<Overwrite> _overwrites;


/// <inheritdoc /> /// <inheritdoc />
@@ -191,8 +192,9 @@ namespace Discord.Rest
/// A string that is the name of this channel. /// A string that is the name of this channel.
/// </returns> /// </returns>
public override string ToString() => Name; public override string ToString() => Name;
#endregion


//IGuildChannel
#region IGuildChannel
/// <inheritdoc /> /// <inheritdoc />
IGuild IGuildChannel.Guild IGuild IGuildChannel.Guild
{ {
@@ -229,13 +231,15 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IGuildUser>(null); //Overridden in Text/Voice => Task.FromResult<IGuildUser>(null); //Overridden in Text/Voice
#endregion


//IChannel
#region IChannel
/// <inheritdoc /> /// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden in Text/Voice => AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden in Text/Voice
/// <inheritdoc /> /// <inheritdoc />
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IUser>(null); //Overridden in Text/Voice => Task.FromResult<IUser>(null); //Overridden in Text/Voice
#endregion
} }
} }

+ 26
- 18
src/Discord.Net.Rest/Entities/Channels/RestTextChannel.cs View File

@@ -14,6 +14,7 @@ namespace Discord.Rest
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestTextChannel : RestGuildChannel, IRestMessageChannel, ITextChannel public class RestTextChannel : RestGuildChannel, IRestMessageChannel, ITextChannel
{ {
#region RestTextChannel
/// <inheritdoc /> /// <inheritdoc />
public string Topic { get; private set; } public string Topic { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
@@ -102,8 +103,8 @@ namespace Discord.Rest


/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, component, options);
public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options);


/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
@@ -130,13 +131,13 @@ namespace Discord.Rest
/// <exception cref="NotSupportedException"><paramref name="filePath" /> is in an invalid format.</exception> /// <exception cref="NotSupportedException"><paramref name="filePath" /> is in an invalid format.</exception>
/// <exception cref="IOException">An I/O error occurred while opening the file.</exception> /// <exception cref="IOException">An I/O error occurred while opening the file.</exception>
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, allowedMentions, messageReference, component, options, isSpoiler);
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options, isSpoiler);


/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, allowedMentions, messageReference, component, options, isSpoiler);
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options, isSpoiler);


/// <inheritdoc /> /// <inheritdoc />
public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
@@ -210,8 +211,9 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
public Task SyncPermissionsAsync(RequestOptions options = null) public Task SyncPermissionsAsync(RequestOptions options = null)
=> ChannelHelper.SyncPermissionsAsync(this, Discord, options); => ChannelHelper.SyncPermissionsAsync(this, Discord, options);
#endregion


//Invites
#region Invites
/// <inheritdoc /> /// <inheritdoc />
public virtual async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) public virtual async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
=> await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false); => await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false);
@@ -261,8 +263,9 @@ namespace Discord.Rest
var model = await ThreadHelper.CreateThreadAsync(Discord, this, name, type, autoArchiveDuration, message, options); var model = await ThreadHelper.CreateThreadAsync(Discord, this, name, type, autoArchiveDuration, message, options);
return RestThreadChannel.Create(Discord, this.Guild, model); return RestThreadChannel.Create(Discord, this.Guild, model);
} }
#endregion


//ITextChannel
#region ITextChannel
/// <inheritdoc /> /// <inheritdoc />
async Task<IWebhook> ITextChannel.CreateWebhookAsync(string name, Stream avatar, RequestOptions options) async Task<IWebhook> ITextChannel.CreateWebhookAsync(string name, Stream avatar, RequestOptions options)
=> await CreateWebhookAsync(name, avatar, options).ConfigureAwait(false); => await CreateWebhookAsync(name, avatar, options).ConfigureAwait(false);
@@ -275,8 +278,9 @@ namespace Discord.Rest


async Task<IThreadChannel> ITextChannel.CreateThreadAsync(string name, ThreadType type, ThreadArchiveDuration autoArchiveDuration, IMessage message, RequestOptions options) async Task<IThreadChannel> ITextChannel.CreateThreadAsync(string name, ThreadType type, ThreadArchiveDuration autoArchiveDuration, IMessage message, RequestOptions options)
=> await CreateThreadAsync(name, type, autoArchiveDuration, message, options); => await CreateThreadAsync(name, type, autoArchiveDuration, message, options);
#endregion


//IMessageChannel
#region IMessageChannel
/// <inheritdoc /> /// <inheritdoc />
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options) async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options)
{ {
@@ -315,17 +319,18 @@ namespace Discord.Rest
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false); => await GetPinnedMessagesAsync(options).ConfigureAwait(false);


/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);


/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
#endregion


//IGuildChannel
#region IGuildChannel
/// <inheritdoc /> /// <inheritdoc />
async Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) async Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
{ {
@@ -342,8 +347,9 @@ namespace Discord.Rest
else else
return AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); return AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>();
} }
#endregion


//IChannel
#region IChannel
/// <inheritdoc /> /// <inheritdoc />
async Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) async Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
{ {
@@ -360,8 +366,9 @@ namespace Discord.Rest
else else
return AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); return AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>();
} }
#endregion


// INestedChannel
#region ITextChannel
/// <inheritdoc /> /// <inheritdoc />
async Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options) async Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options)
{ {
@@ -369,5 +376,6 @@ namespace Discord.Rest
return (await Guild.GetChannelAsync(CategoryId.Value, mode, options).ConfigureAwait(false)) as ICategoryChannel; return (await Guild.GetChannelAsync(CategoryId.Value, mode, options).ConfigureAwait(false)) as ICategoryChannel;
return null; return null;
} }
#endregion
} }
} }

+ 10
- 4
src/Discord.Net.Rest/Entities/Channels/RestVoiceChannel.cs View File

@@ -14,6 +14,7 @@ namespace Discord.Rest
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestVoiceChannel : RestGuildChannel, IVoiceChannel, IRestAudioChannel public class RestVoiceChannel : RestGuildChannel, IVoiceChannel, IRestAudioChannel
{ {
#region RestVoiceChannel
/// <inheritdoc /> /// <inheritdoc />
public int Bitrate { get; private set; } public int Bitrate { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
@@ -60,8 +61,9 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
public Task SyncPermissionsAsync(RequestOptions options = null) public Task SyncPermissionsAsync(RequestOptions options = null)
=> ChannelHelper.SyncPermissionsAsync(this, Discord, options); => ChannelHelper.SyncPermissionsAsync(this, Discord, options);
#endregion


//Invites
#region Invites
/// <inheritdoc /> /// <inheritdoc />
public async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) public async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null)
=> await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false); => await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false);
@@ -76,22 +78,25 @@ namespace Discord.Rest
=> await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false); => await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false);


private string DebuggerDisplay => $"{Name} ({Id}, Voice)"; private string DebuggerDisplay => $"{Name} ({Id}, Voice)";
#endregion


//IAudioChannel
#region IAudioChannel
/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="NotSupportedException">Connecting to a REST-based channel is not supported.</exception> /// <exception cref="NotSupportedException">Connecting to a REST-based channel is not supported.</exception>
Task<IAudioClient> IAudioChannel.ConnectAsync(bool selfDeaf, bool selfMute, bool external) { throw new NotSupportedException(); } Task<IAudioClient> IAudioChannel.ConnectAsync(bool selfDeaf, bool selfMute, bool external) { throw new NotSupportedException(); }
Task IAudioChannel.DisconnectAsync() { throw new NotSupportedException(); } Task IAudioChannel.DisconnectAsync() { throw new NotSupportedException(); }
#endregion


//IGuildChannel
#region IGuildChannel
/// <inheritdoc /> /// <inheritdoc />
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IGuildUser>(null); => Task.FromResult<IGuildUser>(null);
/// <inheritdoc /> /// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options) IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); => AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>();
#endregion


// INestedChannel
#region INestedChannel
/// <inheritdoc /> /// <inheritdoc />
async Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options) async Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options)
{ {
@@ -99,5 +104,6 @@ namespace Discord.Rest
return (await Guild.GetChannelAsync(CategoryId.Value, mode, options).ConfigureAwait(false)) as ICategoryChannel; return (await Guild.GetChannelAsync(CategoryId.Value, mode, options).ConfigureAwait(false)) as ICategoryChannel;
return null; return null;
} }
#endregion
} }
} }

+ 52
- 12
src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs View File

@@ -14,7 +14,7 @@ namespace Discord.Rest
{ {
internal static class GuildHelper internal static class GuildHelper
{ {
//General
#region General
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception>
public static async Task<Model> ModifyAsync(IGuild guild, BaseDiscordClient client, public static async Task<Model> ModifyAsync(IGuild guild, BaseDiscordClient client,
Action<GuildProperties> func, RequestOptions options) Action<GuildProperties> func, RequestOptions options)
@@ -123,8 +123,9 @@ namespace Discord.Rest
{ {
await client.ApiClient.DeleteGuildAsync(guild.Id, options).ConfigureAwait(false); await client.ApiClient.DeleteGuildAsync(guild.Id, options).ConfigureAwait(false);
} }
#endregion


//Bans
#region Bans
public static async Task<IReadOnlyCollection<RestBan>> GetBansAsync(IGuild guild, BaseDiscordClient client, public static async Task<IReadOnlyCollection<RestBan>> GetBansAsync(IGuild guild, BaseDiscordClient client,
RequestOptions options) RequestOptions options)
{ {
@@ -148,8 +149,9 @@ namespace Discord.Rest
{ {
await client.ApiClient.RemoveGuildBanAsync(guild.Id, userId, options).ConfigureAwait(false); await client.ApiClient.RemoveGuildBanAsync(guild.Id, userId, options).ConfigureAwait(false);
} }
#endregion


//Channels
#region Channels
public static async Task<RestGuildChannel> GetChannelAsync(IGuild guild, BaseDiscordClient client, public static async Task<RestGuildChannel> GetChannelAsync(IGuild guild, BaseDiscordClient client,
ulong id, RequestOptions options) ulong id, RequestOptions options)
{ {
@@ -221,6 +223,34 @@ namespace Discord.Rest
var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false); var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false);
return RestVoiceChannel.Create(client, guild, model); return RestVoiceChannel.Create(client, guild, model);
} }
public static async Task<RestStageChannel> CreateStageChannelAsync(IGuild guild, BaseDiscordClient client,
string name, RequestOptions options, Action<VoiceChannelProperties> func = null)
{
if (name == null)
throw new ArgumentNullException(paramName: nameof(name));

var props = new VoiceChannelProperties();
func?.Invoke(props);

var args = new CreateGuildChannelParams(name, ChannelType.Stage)
{
CategoryId = props.CategoryId,
Bitrate = props.Bitrate,
UserLimit = props.UserLimit,
Position = props.Position,
Overwrites = props.PermissionOverwrites.IsSpecified
? props.PermissionOverwrites.Value.Select(overwrite => new API.Overwrite
{
TargetId = overwrite.TargetId,
TargetType = overwrite.TargetType,
Allow = overwrite.Permissions.AllowValue.ToString(),
Deny = overwrite.Permissions.DenyValue.ToString()
}).ToArray()
: Optional.Create<API.Overwrite[]>(),
};
var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false);
return RestStageChannel.Create(client, guild, model);
}
/// <exception cref="ArgumentNullException"><paramref name="name"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException"><paramref name="name"/> is <c>null</c>.</exception>
public static async Task<RestCategoryChannel> CreateCategoryChannelAsync(IGuild guild, BaseDiscordClient client, public static async Task<RestCategoryChannel> CreateCategoryChannelAsync(IGuild guild, BaseDiscordClient client,
string name, RequestOptions options, Action<GuildChannelProperties> func = null) string name, RequestOptions options, Action<GuildChannelProperties> func = null)
@@ -247,16 +277,18 @@ namespace Discord.Rest
var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false); var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false);
return RestCategoryChannel.Create(client, guild, model); return RestCategoryChannel.Create(client, guild, model);
} }
#endregion


//Voice Regions
#region Voice Regions
public static async Task<IReadOnlyCollection<RestVoiceRegion>> GetVoiceRegionsAsync(IGuild guild, BaseDiscordClient client, public static async Task<IReadOnlyCollection<RestVoiceRegion>> GetVoiceRegionsAsync(IGuild guild, BaseDiscordClient client,
RequestOptions options) RequestOptions options)
{ {
var models = await client.ApiClient.GetGuildVoiceRegionsAsync(guild.Id, options).ConfigureAwait(false); var models = await client.ApiClient.GetGuildVoiceRegionsAsync(guild.Id, options).ConfigureAwait(false);
return models.Select(x => RestVoiceRegion.Create(client, x)).ToImmutableArray(); return models.Select(x => RestVoiceRegion.Create(client, x)).ToImmutableArray();
} }
#endregion


//Integrations
#region Integrations
public static async Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(IGuild guild, BaseDiscordClient client, public static async Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(IGuild guild, BaseDiscordClient client,
RequestOptions options) RequestOptions options)
{ {
@@ -270,8 +302,9 @@ namespace Discord.Rest
var model = await client.ApiClient.CreateGuildIntegrationAsync(guild.Id, args, options).ConfigureAwait(false); var model = await client.ApiClient.CreateGuildIntegrationAsync(guild.Id, args, options).ConfigureAwait(false);
return RestGuildIntegration.Create(client, guild, model); return RestGuildIntegration.Create(client, guild, model);
} }
#endregion


//Interactions
#region Interactions
public static async Task<IReadOnlyCollection<RestGuildCommand>> GetSlashCommandsAsync(IGuild guild, BaseDiscordClient client, public static async Task<IReadOnlyCollection<RestGuildCommand>> GetSlashCommandsAsync(IGuild guild, BaseDiscordClient client,
RequestOptions options) RequestOptions options)
{ {
@@ -284,8 +317,9 @@ namespace Discord.Rest
var model = await client.ApiClient.GetGuildApplicationCommandAsync(guild.Id, id, options); var model = await client.ApiClient.GetGuildApplicationCommandAsync(guild.Id, id, options);
return RestGuildCommand.Create(client, model, guild.Id); return RestGuildCommand.Create(client, model, guild.Id);
} }
#endregion


//Invites
#region Invites
public static async Task<IReadOnlyCollection<RestInviteMetadata>> GetInvitesAsync(IGuild guild, BaseDiscordClient client, public static async Task<IReadOnlyCollection<RestInviteMetadata>> GetInvitesAsync(IGuild guild, BaseDiscordClient client,
RequestOptions options) RequestOptions options)
{ {
@@ -301,8 +335,9 @@ namespace Discord.Rest
inviteModel.Uses = vanityModel.Uses; inviteModel.Uses = vanityModel.Uses;
return RestInviteMetadata.Create(client, guild, null, inviteModel); return RestInviteMetadata.Create(client, guild, null, inviteModel);
} }
#endregion


//Roles
#region Roles
/// <exception cref="ArgumentNullException"><paramref name="name"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException"><paramref name="name"/> is <c>null</c>.</exception>
public static async Task<RestRole> CreateRoleAsync(IGuild guild, BaseDiscordClient client, public static async Task<RestRole> CreateRoleAsync(IGuild guild, BaseDiscordClient client,
string name, GuildPermissions? permissions, Color? color, bool isHoisted, bool isMentionable, RequestOptions options) string name, GuildPermissions? permissions, Color? color, bool isHoisted, bool isMentionable, RequestOptions options)
@@ -322,8 +357,9 @@ namespace Discord.Rest


return RestRole.Create(client, guild, model); return RestRole.Create(client, guild, model);
} }
#endregion


//Users
#region Users
public static async Task<RestGuildUser> AddGuildUserAsync(IGuild guild, BaseDiscordClient client, ulong userId, string accessToken, public static async Task<RestGuildUser> AddGuildUserAsync(IGuild guild, BaseDiscordClient client, ulong userId, string accessToken,
Action<AddGuildUserProperties> func, RequestOptions options) Action<AddGuildUserProperties> func, RequestOptions options)
{ {
@@ -442,8 +478,9 @@ namespace Discord.Rest
var models = await client.ApiClient.SearchGuildMembersAsync(guild.Id, apiArgs, options).ConfigureAwait(false); var models = await client.ApiClient.SearchGuildMembersAsync(guild.Id, apiArgs, options).ConfigureAwait(false);
return models.Select(x => RestGuildUser.Create(client, guild, x)).ToImmutableArray(); return models.Select(x => RestGuildUser.Create(client, guild, x)).ToImmutableArray();
} }
#endregion


// Audit logs
#region Audit logs
public static IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(IGuild guild, BaseDiscordClient client, public static IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(IGuild guild, BaseDiscordClient client,
ulong? from, int? limit, RequestOptions options, ulong? userId = null, ActionType? actionType = null) ulong? from, int? limit, RequestOptions options, ulong? userId = null, ActionType? actionType = null)
{ {
@@ -475,8 +512,9 @@ namespace Discord.Rest
count: limit count: limit
); );
} }
#endregion


//Webhooks
#region Webhooks
public static async Task<RestWebhook> GetWebhookAsync(IGuild guild, BaseDiscordClient client, ulong id, RequestOptions options) public static async Task<RestWebhook> GetWebhookAsync(IGuild guild, BaseDiscordClient client, ulong id, RequestOptions options)
{ {
var model = await client.ApiClient.GetWebhookAsync(id, options: options).ConfigureAwait(false); var model = await client.ApiClient.GetWebhookAsync(id, options: options).ConfigureAwait(false);
@@ -489,8 +527,9 @@ namespace Discord.Rest
var models = await client.ApiClient.GetGuildWebhooksAsync(guild.Id, options).ConfigureAwait(false); var models = await client.ApiClient.GetGuildWebhooksAsync(guild.Id, options).ConfigureAwait(false);
return models.Select(x => RestWebhook.Create(client, guild, x)).ToImmutableArray(); return models.Select(x => RestWebhook.Create(client, guild, x)).ToImmutableArray();
} }
#endregion


//Emotes
#region Emotes
public static async Task<IReadOnlyCollection<GuildEmote>> GetEmotesAsync(IGuild guild, BaseDiscordClient client, RequestOptions options) public static async Task<IReadOnlyCollection<GuildEmote>> GetEmotesAsync(IGuild guild, BaseDiscordClient client, RequestOptions options)
{ {
var models = await client.ApiClient.GetGuildEmotesAsync(guild.Id, options).ConfigureAwait(false); var models = await client.ApiClient.GetGuildEmotesAsync(guild.Id, options).ConfigureAwait(false);
@@ -609,5 +648,6 @@ namespace Discord.Rest


public static async Task DeleteStickerAsync(BaseDiscordClient client, ulong guildId, ISticker sticker, RequestOptions options = null) public static async Task DeleteStickerAsync(BaseDiscordClient client, ulong guildId, ISticker sticker, RequestOptions options = null)
=> await client.ApiClient.DeleteStickerAsync(guildId, sticker.Id, options).ConfigureAwait(false); => await client.ApiClient.DeleteStickerAsync(guildId, sticker.Id, options).ConfigureAwait(false);
#endregion
} }
} }

+ 60
- 14
src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs View File

@@ -18,6 +18,7 @@ namespace Discord.Rest
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestGuild : RestEntity<ulong>, IGuild, IUpdateable public class RestGuild : RestEntity<ulong>, IGuild, IUpdateable
{ {
#region RestGuild
private ImmutableDictionary<ulong, RestRole> _roles; private ImmutableDictionary<ulong, RestRole> _roles;
private ImmutableArray<GuildEmote> _emotes; private ImmutableArray<GuildEmote> _emotes;
private ImmutableArray<CustomSticker> _stickers; private ImmutableArray<CustomSticker> _stickers;
@@ -217,8 +218,9 @@ namespace Discord.Rest
WidgetChannelId = model.ChannelId; WidgetChannelId = model.ChannelId;
IsWidgetEnabled = model.Enabled; IsWidgetEnabled = model.Enabled;
} }
#endregion


//General
#region General
/// <inheritdoc /> /// <inheritdoc />
public async Task UpdateAsync(RequestOptions options = null) public async Task UpdateAsync(RequestOptions options = null)
=> Update(await Discord.ApiClient.GetGuildAsync(Id, false, options).ConfigureAwait(false)); => Update(await Discord.ApiClient.GetGuildAsync(Id, false, options).ConfigureAwait(false));
@@ -277,8 +279,9 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
public Task LeaveAsync(RequestOptions options = null) public Task LeaveAsync(RequestOptions options = null)
=> GuildHelper.LeaveAsync(this, Discord, options); => GuildHelper.LeaveAsync(this, Discord, options);
#endregion


//Interactions
#region Interactions
/// <summary> /// <summary>
/// Deletes all slash commands in the current guild. /// Deletes all slash commands in the current guild.
/// </summary> /// </summary>
@@ -311,8 +314,9 @@ namespace Discord.Rest
/// </returns> /// </returns>
public Task<RestGuildCommand> GetSlashCommandAsync(ulong id, RequestOptions options = null) public Task<RestGuildCommand> GetSlashCommandAsync(ulong id, RequestOptions options = null)
=> GuildHelper.GetSlashCommandAsync(this, id, Discord, options); => GuildHelper.GetSlashCommandAsync(this, id, Discord, options);
#endregion


//Bans
#region Bans
/// <summary> /// <summary>
/// Gets a collection of all users banned in this guild. /// Gets a collection of all users banned in this guild.
/// </summary> /// </summary>
@@ -360,8 +364,9 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
public Task RemoveBanAsync(ulong userId, RequestOptions options = null) public Task RemoveBanAsync(ulong userId, RequestOptions options = null)
=> GuildHelper.RemoveBanAsync(this, Discord, userId, options); => GuildHelper.RemoveBanAsync(this, Discord, userId, options);
#endregion


//Channels
#region Channels
/// <summary> /// <summary>
/// Gets a collection of all channels in this guild. /// Gets a collection of all channels in this guild.
/// </summary> /// </summary>
@@ -663,6 +668,18 @@ namespace Discord.Rest
public Task<RestVoiceChannel> CreateVoiceChannelAsync(string name, Action<VoiceChannelProperties> func = null, RequestOptions options = null) public Task<RestVoiceChannel> CreateVoiceChannelAsync(string name, Action<VoiceChannelProperties> func = null, RequestOptions options = null)
=> GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options, func); => GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options, func);
/// <summary> /// <summary>
/// Creates a new stage channel in this guild.
/// </summary>
/// <param name="name">The new name for the stage channel.</param>
/// <param name="func">The delegate containing the properties to be applied to the channel upon its creation.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous creation operation. The task result contains the newly created
/// stage channel.
/// </returns>
public Task<RestStageChannel> CreateStageChannelAsync(string name, Action<VoiceChannelProperties> func = null, RequestOptions options = null)
=> GuildHelper.CreateStageChannelAsync(this, Discord, name, options, func);
/// <summary>
/// Creates a category channel with the provided name. /// Creates a category channel with the provided name.
/// </summary> /// </summary>
/// <param name="name">The name of the new channel.</param> /// <param name="name">The name of the new channel.</param>
@@ -685,14 +702,16 @@ namespace Discord.Rest
/// </returns> /// </returns>
public Task<IReadOnlyCollection<RestVoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null) public Task<IReadOnlyCollection<RestVoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null)
=> GuildHelper.GetVoiceRegionsAsync(this, Discord, options); => GuildHelper.GetVoiceRegionsAsync(this, Discord, options);
#endregion


//Integrations
#region Integrations
public Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null) public Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null)
=> GuildHelper.GetIntegrationsAsync(this, Discord, options); => GuildHelper.GetIntegrationsAsync(this, Discord, options);
public Task<RestGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null) public Task<RestGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null)
=> GuildHelper.CreateIntegrationAsync(this, Discord, id, type, options); => GuildHelper.CreateIntegrationAsync(this, Discord, id, type, options);
#endregion


//Invites
#region Invites
/// <summary> /// <summary>
/// Gets a collection of all invites in this guild. /// Gets a collection of all invites in this guild.
/// </summary> /// </summary>
@@ -712,8 +731,9 @@ namespace Discord.Rest
/// </returns> /// </returns>
public Task<RestInviteMetadata> GetVanityInviteAsync(RequestOptions options = null) public Task<RestInviteMetadata> GetVanityInviteAsync(RequestOptions options = null)
=> GuildHelper.GetVanityInviteAsync(this, Discord, options); => GuildHelper.GetVanityInviteAsync(this, Discord, options);
#endregion


//Roles
#region Roles
/// <summary> /// <summary>
/// Gets a role in this guild. /// Gets a role in this guild.
/// </summary> /// </summary>
@@ -753,8 +773,9 @@ namespace Discord.Rest
_roles = _roles.Add(role.Id, role); _roles = _roles.Add(role.Id, role);
return role; return role;
} }
#endregion


//Users
#region Users
/// <summary> /// <summary>
/// Gets a collection of all users in this guild. /// Gets a collection of all users in this guild.
/// </summary> /// </summary>
@@ -848,8 +869,9 @@ namespace Discord.Rest
/// </returns> /// </returns>
public Task<IReadOnlyCollection<RestGuildUser>> SearchUsersAsync(string query, int limit = DiscordConfig.MaxUsersPerBatch, RequestOptions options = null) public Task<IReadOnlyCollection<RestGuildUser>> SearchUsersAsync(string query, int limit = DiscordConfig.MaxUsersPerBatch, RequestOptions options = null)
=> GuildHelper.SearchUsersAsync(this, Discord, query, limit, options); => GuildHelper.SearchUsersAsync(this, Discord, query, limit, options);
#endregion


//Audit logs
#region Audit logs
/// <summary> /// <summary>
/// Gets the specified number of audit log entries for this guild. /// Gets the specified number of audit log entries for this guild.
/// </summary> /// </summary>
@@ -864,8 +886,9 @@ namespace Discord.Rest
/// </returns> /// </returns>
public IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(int limit, RequestOptions options = null, ulong? beforeId = null, ulong? userId = null, ActionType? actionType = null) public IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(int limit, RequestOptions options = null, ulong? beforeId = null, ulong? userId = null, ActionType? actionType = null)
=> GuildHelper.GetAuditLogsAsync(this, Discord, beforeId, limit, options, userId: userId, actionType: actionType); => GuildHelper.GetAuditLogsAsync(this, Discord, beforeId, limit, options, userId: userId, actionType: actionType);
#endregion


//Webhooks
#region Webhooks
/// <summary> /// <summary>
/// Gets a webhook found within this guild. /// Gets a webhook found within this guild.
/// </summary> /// </summary>
@@ -888,8 +911,9 @@ namespace Discord.Rest
/// </returns> /// </returns>
public Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null) public Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null)
=> GuildHelper.GetWebhooksAsync(this, Discord, options); => GuildHelper.GetWebhooksAsync(this, Discord, options);
#endregion


//Interactions
#region Interactions
/// <summary> /// <summary>
/// Gets this guilds slash commands commands /// Gets this guilds slash commands commands
/// </summary> /// </summary>
@@ -949,8 +973,9 @@ namespace Discord.Rest
/// </returns> /// </returns>
public override string ToString() => Name; public override string ToString() => Name;
private string DebuggerDisplay => $"{Name} ({Id})"; private string DebuggerDisplay => $"{Name} ({Id})";
#endregion


//Emotes
#region Emotes
/// <inheritdoc /> /// <inheritdoc />
public Task<IReadOnlyCollection<GuildEmote>> GetEmotesAsync(RequestOptions options = null) public Task<IReadOnlyCollection<GuildEmote>> GetEmotesAsync(RequestOptions options = null)
=> GuildHelper.GetEmotesAsync(this, Discord, options); => GuildHelper.GetEmotesAsync(this, Discord, options);
@@ -964,11 +989,20 @@ namespace Discord.Rest
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentNullException"><paramref name="func"/> is <see langword="null"/>.</exception>
public Task<GuildEmote> ModifyEmoteAsync(GuildEmote emote, Action<EmoteProperties> func, RequestOptions options = null) public Task<GuildEmote> ModifyEmoteAsync(GuildEmote emote, Action<EmoteProperties> func, RequestOptions options = null)
=> GuildHelper.ModifyEmoteAsync(this, Discord, emote.Id, func, options); => GuildHelper.ModifyEmoteAsync(this, Discord, emote.Id, func, options);
/// <summary>
/// Moves the user to the voice channel.
/// </summary>
/// <param name="user">The user to move.</param>
/// <param name="targetChannel">the channel where the user gets moved to.</param>
/// <returns>A task that represents the asynchronous operation for moving a user.</returns>
public Task MoveAsync(IGuildUser user, IVoiceChannel targetChannel)
=> user.ModifyAsync(x => x.Channel = new Optional<IVoiceChannel>(targetChannel));
/// <inheritdoc /> /// <inheritdoc />
public Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null) public Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null)
=> GuildHelper.DeleteEmoteAsync(this, Discord, emote.Id, options); => GuildHelper.DeleteEmoteAsync(this, Discord, emote.Id, options);
#endregion


//Stickers
#region Stickers
/// <summary> /// <summary>
/// Creates a new sticker in this guild. /// Creates a new sticker in this guild.
/// </summary> /// </summary>
@@ -1075,8 +1109,9 @@ namespace Discord.Rest
/// </returns> /// </returns>
public Task DeleteStickerAsync(CustomSticker sticker, RequestOptions options = null) public Task DeleteStickerAsync(CustomSticker sticker, RequestOptions options = null)
=> sticker.DeleteAsync(options); => sticker.DeleteAsync(options);
#endregion


//IGuild
#region IGuild
/// <inheritdoc /> /// <inheritdoc />
bool IGuild.Available => Available; bool IGuild.Available => Available;
/// <inheritdoc /> /// <inheritdoc />
@@ -1241,6 +1276,9 @@ namespace Discord.Rest
async Task<IVoiceChannel> IGuild.CreateVoiceChannelAsync(string name, Action<VoiceChannelProperties> func, RequestOptions options) async Task<IVoiceChannel> IGuild.CreateVoiceChannelAsync(string name, Action<VoiceChannelProperties> func, RequestOptions options)
=> await CreateVoiceChannelAsync(name, func, options).ConfigureAwait(false); => await CreateVoiceChannelAsync(name, func, options).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />
async Task<IStageChannel> IGuild.CreateStageChannelAsync(string name, Action<VoiceChannelProperties> func, RequestOptions options)
=> await CreateStageChannelAsync(name, func, options).ConfigureAwait(false);
/// <inheritdoc />
async Task<ICategoryChannel> IGuild.CreateCategoryAsync(string name, Action<GuildChannelProperties> func, RequestOptions options) async Task<ICategoryChannel> IGuild.CreateCategoryAsync(string name, Action<GuildChannelProperties> func, RequestOptions options)
=> await CreateCategoryChannelAsync(name, func, options).ConfigureAwait(false); => await CreateCategoryChannelAsync(name, func, options).ConfigureAwait(false);


@@ -1276,6 +1314,13 @@ namespace Discord.Rest
async Task<IGuildUser> IGuild.AddGuildUserAsync(ulong userId, string accessToken, Action<AddGuildUserProperties> func, RequestOptions options) async Task<IGuildUser> IGuild.AddGuildUserAsync(ulong userId, string accessToken, Action<AddGuildUserProperties> func, RequestOptions options)
=> await AddGuildUserAsync(userId, accessToken, func, options); => await AddGuildUserAsync(userId, accessToken, func, options);


/// <summary>
/// Disconnects the user from its current voice channel
/// </summary>
/// <param name="user">The user to disconnect.</param>
/// <returns>A task that represents the asynchronous operation for disconnecting a user.</returns>
async Task IGuild.DisconnectAsync(IGuildUser user) => await user.ModifyAsync(x => x.Channel = new Optional<IVoiceChannel>());

/// <inheritdoc /> /// <inheritdoc />
async Task<IGuildUser> IGuild.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) async Task<IGuildUser> IGuild.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
{ {
@@ -1384,5 +1429,6 @@ namespace Discord.Rest
else else
return null; return null;
} }
#endregion
} }
} }

+ 25
- 19
src/Discord.Net.Rest/Entities/Interactions/InteractionHelper.cs View File

@@ -11,39 +11,41 @@ namespace Discord.Rest
{ {
internal static class InteractionHelper internal static class InteractionHelper
{ {
#region InteractionHelper
public static Task DeleteAllGuildCommandsAsync(BaseDiscordClient client, ulong guildId, RequestOptions options = null) public static Task DeleteAllGuildCommandsAsync(BaseDiscordClient client, ulong guildId, RequestOptions options = null)
{ {
return client.ApiClient.BulkOverwriteGuildApplicationCommands(guildId, new CreateApplicationCommandParams[0], options);
return client.ApiClient.BulkOverwriteGuildApplicationCommandsAsync(guildId, new CreateApplicationCommandParams[0], options);
} }


public static Task DeleteAllGlobalCommandsAsync(BaseDiscordClient client, RequestOptions options = null) public static Task DeleteAllGlobalCommandsAsync(BaseDiscordClient client, RequestOptions options = null)
{ {
return client.ApiClient.BulkOverwriteGlobalApplicationCommands(new CreateApplicationCommandParams[0], options);
return client.ApiClient.BulkOverwriteGlobalApplicationCommandsAsync(new CreateApplicationCommandParams[0], options);
} }


public static Task SendInteractionResponse(BaseDiscordClient client, InteractionResponse response, public static Task SendInteractionResponse(BaseDiscordClient client, InteractionResponse response,
ulong interactionId, string interactionToken, RequestOptions options = null) ulong interactionId, string interactionToken, RequestOptions options = null)
{ {
return client.ApiClient.CreateInteractionResponse(response, interactionId, interactionToken, options);
return client.ApiClient.CreateInteractionResponseAsync(response, interactionId, interactionToken, options);
} }


public static async Task<RestInteractionMessage> GetOriginalResponseAsync(BaseDiscordClient client, IMessageChannel channel, public static async Task<RestInteractionMessage> GetOriginalResponseAsync(BaseDiscordClient client, IMessageChannel channel,
IDiscordInteraction interaction, RequestOptions options = null) IDiscordInteraction interaction, RequestOptions options = null)
{ {
var model = await client.ApiClient.GetInteractionResponse(interaction.Token, options).ConfigureAwait(false);
var model = await client.ApiClient.GetInteractionResponseAsync(interaction.Token, options).ConfigureAwait(false);
return RestInteractionMessage.Create(client, model, interaction.Token, channel); return RestInteractionMessage.Create(client, model, interaction.Token, channel);
} }


public static async Task<RestFollowupMessage> SendFollowupAsync(BaseDiscordClient client, CreateWebhookMessageParams args, public static async Task<RestFollowupMessage> SendFollowupAsync(BaseDiscordClient client, CreateWebhookMessageParams args,
string token, IMessageChannel channel, RequestOptions options = null) string token, IMessageChannel channel, RequestOptions options = null)
{ {
var model = await client.ApiClient.CreateInteractionFollowupMessage(args, token, options).ConfigureAwait(false);
var model = await client.ApiClient.CreateInteractionFollowupMessageAsync(args, token, options).ConfigureAwait(false);


RestFollowupMessage entity = RestFollowupMessage.Create(client, model, token, channel); RestFollowupMessage entity = RestFollowupMessage.Create(client, model, token, channel);
return entity; return entity;
} }
#endregion


// Global commands
#region Global commands
public static async Task<RestGlobalCommand> GetGlobalCommandAsync(BaseDiscordClient client, ulong id, public static async Task<RestGlobalCommand> GetGlobalCommandAsync(BaseDiscordClient client, ulong id,
RequestOptions options = null) RequestOptions options = null)
{ {
@@ -121,7 +123,7 @@ namespace Discord.Rest
models.Add(model); models.Add(model);
} }


return await client.ApiClient.BulkOverwriteGlobalApplicationCommands(models.ToArray(), options).ConfigureAwait(false);
return await client.ApiClient.BulkOverwriteGlobalApplicationCommandsAsync(models.ToArray(), options).ConfigureAwait(false);
} }


public static async Task<IReadOnlyCollection<ApplicationCommand>> BulkOverwriteGuildCommands(BaseDiscordClient client, ulong guildId, public static async Task<IReadOnlyCollection<ApplicationCommand>> BulkOverwriteGuildCommands(BaseDiscordClient client, ulong guildId,
@@ -158,7 +160,7 @@ namespace Discord.Rest
models.Add(model); models.Add(model);
} }


return await client.ApiClient.BulkOverwriteGuildApplicationCommands(guildId, models.ToArray(), options).ConfigureAwait(false);
return await client.ApiClient.BulkOverwriteGuildApplicationCommandsAsync(guildId, models.ToArray(), options).ConfigureAwait(false);
} }


private static TArg GetApplicationCommandProperties<TArg>(IApplicationCommand command) private static TArg GetApplicationCommandProperties<TArg>(IApplicationCommand command)
@@ -236,8 +238,9 @@ namespace Discord.Rest


await client.ApiClient.DeleteGlobalApplicationCommandAsync(command.Id, options).ConfigureAwait(false); await client.ApiClient.DeleteGlobalApplicationCommandAsync(command.Id, options).ConfigureAwait(false);
} }
#endregion


// Guild Commands
#region Guild Commands
public static Task<ApplicationCommand> CreateGuildCommand<TArg>(BaseDiscordClient client, ulong guildId, public static Task<ApplicationCommand> CreateGuildCommand<TArg>(BaseDiscordClient client, ulong guildId,
Action<TArg> func, RequestOptions options) where TArg : ApplicationCommandProperties Action<TArg> func, RequestOptions options) where TArg : ApplicationCommandProperties
{ {
@@ -324,8 +327,9 @@ namespace Discord.Rest
return DeleteGlobalCommand(client, command, options); return DeleteGlobalCommand(client, command, options);
} }
} }
#endregion


// Responses
#region Responses
public static async Task<Discord.API.Message> ModifyFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, Action<MessageProperties> func, public static async Task<Discord.API.Message> ModifyFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, Action<MessageProperties> func,
RequestOptions options = null) RequestOptions options = null)
{ {
@@ -363,11 +367,11 @@ namespace Discord.Rest
Components = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional<API.ActionRowComponent[]>.Unspecified, Components = args.Components.IsSpecified ? args.Components.Value?.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional<API.ActionRowComponent[]>.Unspecified,
}; };


return await client.ApiClient.ModifyInteractionFollowupMessage(apiArgs, message.Id, message.Token, options).ConfigureAwait(false);
return await client.ApiClient.ModifyInteractionFollowupMessageAsync(apiArgs, message.Id, message.Token, options).ConfigureAwait(false);
} }


public static async Task DeleteFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, RequestOptions options = null) public static async Task DeleteFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, RequestOptions options = null)
=> await client.ApiClient.DeleteInteractionFollowupMessage(message.Id, message.Token, options);
=> await client.ApiClient.DeleteInteractionFollowupMessageAsync(message.Id, message.Token, options);


public static async Task<Message> ModifyInteractionResponse(BaseDiscordClient client, string token, Action<MessageProperties> func, public static async Task<Message> ModifyInteractionResponse(BaseDiscordClient client, string token, Action<MessageProperties> func,
RequestOptions options = null) RequestOptions options = null)
@@ -407,17 +411,18 @@ namespace Discord.Rest
Flags = args.Flags Flags = args.Flags
}; };


return await client.ApiClient.ModifyInteractionResponse(apiArgs, token, options).ConfigureAwait(false);
return await client.ApiClient.ModifyInteractionResponseAsync(apiArgs, token, options).ConfigureAwait(false);
} }


public static async Task DeletedInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, RequestOptions options = null) public static async Task DeletedInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, RequestOptions options = null)
=> await client.ApiClient.DeleteInteractionFollowupMessage(message.Id, message.Token, options);
=> await client.ApiClient.DeleteInteractionFollowupMessageAsync(message.Id, message.Token, options);
#endregion


// Guild permissions
#region Guild permissions
public static async Task<IReadOnlyCollection<GuildApplicationCommandPermission>> GetGuildCommandPermissionsAsync(BaseDiscordClient client, public static async Task<IReadOnlyCollection<GuildApplicationCommandPermission>> GetGuildCommandPermissionsAsync(BaseDiscordClient client,
ulong guildId, RequestOptions options) ulong guildId, RequestOptions options)
{ {
var models = await client.ApiClient.GetGuildApplicationCommandPermissions(guildId, options);
var models = await client.ApiClient.GetGuildApplicationCommandPermissionsAsync(guildId, options);
return models.Select(x => return models.Select(x =>
new GuildApplicationCommandPermission(x.Id, x.ApplicationId, guildId, x.Permissions.Select( new GuildApplicationCommandPermission(x.Id, x.ApplicationId, guildId, x.Permissions.Select(
y => new Discord.ApplicationCommandPermission(y.Id, y.Type, y.Permission)) y => new Discord.ApplicationCommandPermission(y.Id, y.Type, y.Permission))
@@ -430,7 +435,7 @@ namespace Discord.Rest
{ {
try try
{ {
var model = await client.ApiClient.GetGuildApplicationCommandPermission(guildId, commandId, options);
var model = await client.ApiClient.GetGuildApplicationCommandPermissionAsync(guildId, commandId, options);
return new GuildApplicationCommandPermission(model.Id, model.ApplicationId, guildId, model.Permissions.Select( return new GuildApplicationCommandPermission(model.Id, model.ApplicationId, guildId, model.Permissions.Select(
y => new ApplicationCommandPermission(y.Id, y.Type, y.Permission)).ToArray()); y => new ApplicationCommandPermission(y.Id, y.Type, y.Permission)).ToArray());
} }
@@ -468,7 +473,7 @@ namespace Discord.Rest
Permissions = permissionsList.ToArray() Permissions = permissionsList.ToArray()
}; };


var apiModel = await client.ApiClient.ModifyApplicationCommandPermissions(model, guildId, commandId, options);
var apiModel = await client.ApiClient.ModifyApplicationCommandPermissionsAsync(model, guildId, commandId, options);


return new GuildApplicationCommandPermission(apiModel.Id, apiModel.ApplicationId, guildId, apiModel.Permissions.Select( return new GuildApplicationCommandPermission(apiModel.Id, apiModel.ApplicationId, guildId, apiModel.Permissions.Select(
x => new ApplicationCommandPermission(x.Id, x.Type, x.Permission)).ToArray()); x => new ApplicationCommandPermission(x.Id, x.Type, x.Permission)).ToArray());
@@ -500,11 +505,12 @@ namespace Discord.Rest
models.Add(model); models.Add(model);
} }


var apiModels = await client.ApiClient.BatchModifyApplicationCommandPermissions(models.ToArray(), guildId, options);
var apiModels = await client.ApiClient.BatchModifyApplicationCommandPermissionsAsync(models.ToArray(), guildId, options);


return apiModels.Select( return apiModels.Select(
x => new GuildApplicationCommandPermission(x.Id, x.ApplicationId, x.GuildId, x.Permissions.Select( x => new GuildApplicationCommandPermission(x.Id, x.ApplicationId, x.GuildId, x.Permissions.Select(
y => new ApplicationCommandPermission(y.Id, y.Type, y.Permission)).ToArray())).ToArray(); y => new ApplicationCommandPermission(y.Id, y.Type, y.Permission)).ToArray())).ToArray();
} }
#endregion
} }
} }

+ 4
- 1
src/Discord.Net.Rest/Entities/Interactions/RestApplicationCommandOption.cs View File

@@ -13,6 +13,7 @@ namespace Discord.Rest
/// </summary> /// </summary>
public class RestApplicationCommandOption : IApplicationCommandOption public class RestApplicationCommandOption : IApplicationCommandOption
{ {
#region RestApplicationCommandOption
/// <inheritdoc/> /// <inheritdoc/>
public ApplicationCommandOptionType Type { get; private set; } public ApplicationCommandOptionType Type { get; private set; }


@@ -67,11 +68,13 @@ namespace Discord.Rest
? model.Choices.Value.Select(x => new RestApplicationCommandChoice(x)).ToImmutableArray() ? model.Choices.Value.Select(x => new RestApplicationCommandChoice(x)).ToImmutableArray()
: null; : null;
} }
#endregion


//IApplicationCommandOption
#region IApplicationCommandOption
IReadOnlyCollection<IApplicationCommandOption> IApplicationCommandOption.Options IReadOnlyCollection<IApplicationCommandOption> IApplicationCommandOption.Options
=> Options; => Options;
IReadOnlyCollection<IApplicationCommandOptionChoice> IApplicationCommandOption.Choices IReadOnlyCollection<IApplicationCommandOptionChoice> IApplicationCommandOption.Choices
=> Choices; => Choices;
#endregion
} }
} }

+ 1
- 1
src/Discord.Net.Rest/Entities/Messages/RestMessage.cs View File

@@ -163,7 +163,7 @@ namespace Discord.Rest
case ComponentType.SelectMenu: case ComponentType.SelectMenu:
{ {
var parsed = (API.SelectMenuComponent)y; var parsed = (API.SelectMenuComponent)y;
return new SelectMenu(
return new SelectMenuComponent(
parsed.CustomId, parsed.CustomId,
parsed.Options.Select(z => new SelectMenuOption( parsed.Options.Select(z => new SelectMenuOption(
z.Label, z.Label,


+ 12
- 9
src/Discord.Net.Rest/Entities/Messages/Sticker.cs View File

@@ -10,19 +10,21 @@ namespace Discord.Rest
public class Sticker : RestEntity<ulong>, ISticker public class Sticker : RestEntity<ulong>, ISticker
{ {
/// <inheritdoc /> /// <inheritdoc />
public ulong PackId { get; internal set; }
public ulong PackId { get; protected set; }
/// <inheritdoc /> /// <inheritdoc />
public string Name { get; internal set; }
public string Name { get; protected set; }
/// <inheritdoc /> /// <inheritdoc />
public string Description { get; internal set; }
public string Description { get; protected set; }
/// <inheritdoc /> /// <inheritdoc />
public IReadOnlyCollection<string> Tags { get; internal set; }
public IReadOnlyCollection<string> Tags { get; protected set; }
/// <inheritdoc /> /// <inheritdoc />
public string Asset { get; internal set; }
public StickerType Type { get; protected set; }
/// <inheritdoc /> /// <inheritdoc />
public string PreviewAsset { get; internal set; }
public bool? Available { get; protected set; }
/// <inheritdoc /> /// <inheritdoc />
public StickerFormatType Format { get; internal set; }
public int? SortOrder { get; protected set; }
/// <inheritdoc />
public StickerFormatType Format { get; protected set; }


/// <inheritdoc/> /// <inheritdoc/>
public string GetStickerUrl() public string GetStickerUrl()
@@ -43,8 +45,9 @@ namespace Discord.Rest
Name = model.Name; Name = model.Name;
Description = model.Desription; Description = model.Desription;
Tags = model.Tags.IsSpecified ? model.Tags.Value.Split(',').Select(x => x.Trim()).ToArray() : new string[0]; Tags = model.Tags.IsSpecified ? model.Tags.Value.Split(',').Select(x => x.Trim()).ToArray() : new string[0];
Asset = model.Asset;
PreviewAsset = model.PreviewAsset;
Type = model.Type;
SortOrder = model.SortValue;
Available = model.Available;
Format = model.FormatType; Format = model.FormatType;
} }




+ 6
- 2
src/Discord.Net.Rest/Entities/Roles/RestRole.cs View File

@@ -11,6 +11,7 @@ namespace Discord.Rest
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestRole : RestEntity<ulong>, IRole public class RestRole : RestEntity<ulong>, IRole
{ {
#region RestRole
internal IGuild Guild { get; } internal IGuild Guild { get; }
/// <inheritdoc /> /// <inheritdoc />
public Color Color { get; private set; } public Color Color { get; private set; }
@@ -64,7 +65,7 @@ namespace Discord.Rest


/// <inheritdoc /> /// <inheritdoc />
public async Task ModifyAsync(Action<RoleProperties> func, RequestOptions options = null) public async Task ModifyAsync(Action<RoleProperties> func, RequestOptions options = null)
{
{
var model = await RoleHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false); var model = await RoleHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false);
Update(model); Update(model);
} }
@@ -83,8 +84,9 @@ namespace Discord.Rest
/// </returns> /// </returns>
public override string ToString() => Name; public override string ToString() => Name;
private string DebuggerDisplay => $"{Name} ({Id})"; private string DebuggerDisplay => $"{Name} ({Id})";
#endregion


//IRole
#region IRole
/// <inheritdoc /> /// <inheritdoc />
IGuild IRole.Guild IGuild IRole.Guild
{ {
@@ -95,5 +97,7 @@ namespace Discord.Rest
throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object.");
} }
} }

#endregion
} }
} }

+ 2
- 1
src/Discord.Net.Rest/Entities/Roles/RoleHelper.cs View File

@@ -7,7 +7,7 @@ namespace Discord.Rest
{ {
internal static class RoleHelper internal static class RoleHelper
{ {
//General
#region General
public static async Task DeleteAsync(IRole role, BaseDiscordClient client, public static async Task DeleteAsync(IRole role, BaseDiscordClient client,
RequestOptions options) RequestOptions options)
{ {
@@ -36,5 +36,6 @@ namespace Discord.Rest
} }
return model; return model;
} }
#endregion
} }
} }

+ 6
- 2
src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs View File

@@ -14,6 +14,7 @@ namespace Discord.Rest
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestGuildUser : RestUser, IGuildUser public class RestGuildUser : RestUser, IGuildUser
{ {
#region RestGuildUser
private long? _premiumSinceTicks; private long? _premiumSinceTicks;
private long? _joinedAtTicks; private long? _joinedAtTicks;
private ImmutableArray<ulong> _roleIds; private ImmutableArray<ulong> _roleIds;
@@ -155,8 +156,9 @@ namespace Discord.Rest
var guildPerms = GuildPermissions; var guildPerms = GuildPermissions;
return new ChannelPermissions(Permissions.ResolveChannel(Guild, this, channel, guildPerms.RawValue)); return new ChannelPermissions(Permissions.ResolveChannel(Guild, this, channel, guildPerms.RawValue));
} }
#endregion


//IGuildUser
#region IGuildUser
/// <inheritdoc /> /// <inheritdoc />
IGuild IGuildUser.Guild IGuild IGuildUser.Guild
{ {
@@ -167,8 +169,9 @@ namespace Discord.Rest
throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object.");
} }
} }
#endregion


//IVoiceState
#region IVoiceState
/// <inheritdoc /> /// <inheritdoc />
bool IVoiceState.IsSelfDeafened => false; bool IVoiceState.IsSelfDeafened => false;
/// <inheritdoc /> /// <inheritdoc />
@@ -183,5 +186,6 @@ namespace Discord.Rest
bool IVoiceState.IsStreaming => false; bool IVoiceState.IsStreaming => false;
/// <inheritdoc /> /// <inheritdoc />
DateTimeOffset? IVoiceState.RequestToSpeakTimestamp => null; DateTimeOffset? IVoiceState.RequestToSpeakTimestamp => null;
#endregion
} }
} }

+ 4
- 1
src/Discord.Net.Rest/Entities/Users/RestUser.cs View File

@@ -13,6 +13,7 @@ namespace Discord.Rest
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestUser : RestEntity<ulong>, IUser, IUpdateable public class RestUser : RestEntity<ulong>, IUser, IUpdateable
{ {
#region RestUser
/// <inheritdoc /> /// <inheritdoc />
public bool IsBot { get; private set; } public bool IsBot { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
@@ -116,10 +117,12 @@ namespace Discord.Rest
/// </returns> /// </returns>
public override string ToString() => $"{Username}#{Discriminator}"; public override string ToString() => $"{Username}#{Discriminator}";
private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")})"; private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")})";
#endregion


//IUser
#region IUser
/// <inheritdoc /> /// <inheritdoc />
async Task<IDMChannel> IUser.CreateDMChannelAsync(RequestOptions options) async Task<IDMChannel> IUser.CreateDMChannelAsync(RequestOptions options)
=> await CreateDMChannelAsync(options).ConfigureAwait(false); => await CreateDMChannelAsync(options).ConfigureAwait(false);
#endregion
} }
} }

+ 6
- 2
src/Discord.Net.Rest/Entities/Users/RestWebhookUser.cs View File

@@ -10,6 +10,7 @@ namespace Discord.Rest
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestWebhookUser : RestUser, IWebhookUser public class RestWebhookUser : RestUser, IWebhookUser
{ {
#region RestWebhookUser
/// <inheritdoc /> /// <inheritdoc />
public ulong WebhookId { get; } public ulong WebhookId { get; }
internal IGuild Guild { get; } internal IGuild Guild { get; }
@@ -33,8 +34,9 @@ namespace Discord.Rest
entity.Update(model); entity.Update(model);
return entity; return entity;
} }
#endregion


//IGuildUser
#region IGuildUser
/// <inheritdoc /> /// <inheritdoc />
IGuild IGuildUser.Guild IGuild IGuildUser.Guild
{ {
@@ -91,8 +93,9 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
Task IGuildUser.RemoveRolesAsync(IEnumerable<IRole> roles, RequestOptions options) => Task IGuildUser.RemoveRolesAsync(IEnumerable<IRole> roles, RequestOptions options) =>
throw new NotSupportedException("Roles are not supported on webhook users."); throw new NotSupportedException("Roles are not supported on webhook users.");
#endregion


//IVoiceState
#region IVoiceState
/// <inheritdoc /> /// <inheritdoc />
bool IVoiceState.IsDeafened => false; bool IVoiceState.IsDeafened => false;
/// <inheritdoc /> /// <inheritdoc />
@@ -111,5 +114,6 @@ namespace Discord.Rest
bool IVoiceState.IsStreaming => false; bool IVoiceState.IsStreaming => false;
/// <inheritdoc /> /// <inheritdoc />
DateTimeOffset? IVoiceState.RequestToSpeakTimestamp => null; DateTimeOffset? IVoiceState.RequestToSpeakTimestamp => null;
#endregion
} }
} }

+ 4
- 1
src/Discord.Net.Rest/Entities/Webhooks/RestWebhook.cs View File

@@ -8,6 +8,7 @@ namespace Discord.Rest
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestWebhook : RestEntity<ulong>, IWebhook, IUpdateable public class RestWebhook : RestEntity<ulong>, IWebhook, IUpdateable
{ {
#region RestWebhook
internal IGuild Guild { get; private set; } internal IGuild Guild { get; private set; }
internal ITextChannel Channel { get; private set; } internal ITextChannel Channel { get; private set; }


@@ -95,8 +96,9 @@ namespace Discord.Rest


public override string ToString() => $"Webhook: {Name}:{Id}"; public override string ToString() => $"Webhook: {Name}:{Id}";
private string DebuggerDisplay => $"Webhook: {Name} ({Id})"; private string DebuggerDisplay => $"Webhook: {Name} ({Id})";
#endregion


//IWebhook
#region IWebhook
/// <inheritdoc /> /// <inheritdoc />
IGuild IWebhook.Guild IGuild IWebhook.Guild
=> Guild ?? throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); => Guild ?? throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object.");
@@ -106,5 +108,6 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
Task IWebhook.ModifyAsync(Action<WebhookProperties> func, RequestOptions options) Task IWebhook.ModifyAsync(Action<WebhookProperties> func, RequestOptions options)
=> ModifyAsync(func, options); => ModifyAsync(func, options);
#endregion
} }
} }

+ 4
- 1
src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs View File

@@ -10,6 +10,7 @@ namespace Discord.Net.Converters
{ {
internal class DiscordContractResolver : DefaultContractResolver internal class DiscordContractResolver : DefaultContractResolver
{ {
#region DiscordContractResolver
private static readonly TypeInfo _ienumerable = typeof(IEnumerable<ulong[]>).GetTypeInfo(); private static readonly TypeInfo _ienumerable = typeof(IEnumerable<ulong[]>).GetTypeInfo();
private static readonly MethodInfo _shouldSerialize = typeof(DiscordContractResolver).GetTypeInfo().GetDeclaredMethod("ShouldSerialize"); private static readonly MethodInfo _shouldSerialize = typeof(DiscordContractResolver).GetTypeInfo().GetDeclaredMethod("ShouldSerialize");
@@ -57,8 +58,9 @@ namespace Discord.Net.Converters
else if (genericType == typeof(EntityOrId<>)) else if (genericType == typeof(EntityOrId<>))
return MakeGenericConverter(property, propInfo, typeof(UInt64EntityOrIdConverter<>), type.GenericTypeArguments[0], depth); return MakeGenericConverter(property, propInfo, typeof(UInt64EntityOrIdConverter<>), type.GenericTypeArguments[0], depth);
} }
#endregion


//Primitives
#region Primitives
bool hasInt53 = propInfo.GetCustomAttribute<Int53Attribute>() != null; bool hasInt53 = propInfo.GetCustomAttribute<Int53Attribute>() != null;
if (!hasInt53) if (!hasInt53)
{ {
@@ -107,5 +109,6 @@ namespace Discord.Net.Converters
var innerConverter = GetConverter(property, propInfo, innerType, depth + 1); var innerConverter = GetConverter(property, propInfo, innerType, depth + 1);
return genericType.DeclaredConstructors.First().Invoke(new object[] { innerConverter }) as JsonConverter; return genericType.DeclaredConstructors.First().Invoke(new object[] { innerConverter }) as JsonConverter;
} }
#endregion
} }
} }

+ 74
- 65
src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml View File

@@ -1393,29 +1393,6 @@
</note> </note>
</remarks> </remarks>
</member> </member>
<member name="P:Discord.WebSocket.DiscordSocketConfig.AlwaysAcknowledgeInteractions">
<summary>
Gets or sets whether or not interactions are acknowledge with source.
</summary>
<remarks>
<para>
Discord interactions will not appear in chat until the client responds to them. With this option set to
<see langword="true"/>, the client will automatically acknowledge the interaction with <see cref="F:Discord.InteractionResponseType.DeferredChannelMessageWithSource"/>.
See <see href="https://discord.com/developers/docs/interactions/slash-commands#interaction-interactionresponsetype">the docs</see> on
responding to interactions for more info.
</para>
<para>
With this option set to <see langword="false"/>, you will have to acknowledge the interaction with
<see cref="!:SocketInteraction.RespondAsync(string, bool, Embed, InteractionResponseType, AllowedMentions, RequestOptions)"/>.
Only after the interaction is acknowledged, the original slash command message will be visible.
</para>
<note>
Please note that manually acknowledging the interaction with a message reply will not provide any return data.
Automatically acknowledging the interaction without sending the message will allow for follow up responses to
be used; follow up responses return the message data sent.
</note>
</remarks>
</member>
<member name="P:Discord.WebSocket.DiscordSocketConfig.HandlerTimeout"> <member name="P:Discord.WebSocket.DiscordSocketConfig.HandlerTimeout">
<summary> <summary>
Gets or sets the timeout for event handlers, in milliseconds, after which a warning will be logged. Gets or sets the timeout for event handlers, in milliseconds, after which a warning will be logged.
@@ -1480,12 +1457,12 @@
A read-only collection of WebSocket-based messages. A read-only collection of WebSocket-based messages.
</returns> </returns>
</member> </member>
<member name="M:Discord.WebSocket.ISocketMessageChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.ISocketMessageChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<summary> <summary>
Sends a message to this message channel. Sends a message to this message channel.
</summary> </summary>
<remarks> <remarks>
This method follows the same behavior as described in <see cref="M:Discord.IMessageChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)"/>.
This method follows the same behavior as described in <see cref="M:Discord.IMessageChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])"/>.
Please visit its documentation for more details on this method. Please visit its documentation for more details on this method.
</remarks> </remarks>
<param name="text">The message to be sent.</param> <param name="text">The message to be sent.</param>
@@ -1498,17 +1475,18 @@
</param> </param>
<param name="messageReference">The message references to be included. Used to reply to specific messages.</param> <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
<param name="component">The message components to be included with this message. Used for interactions</param> <param name="component">The message components to be included with this message. Used for interactions</param>
<param name="stickers">A collection of stickers to send with the message.</param>
<returns> <returns>
A task that represents an asynchronous send operation for delivering the message. The task result A task that represents an asynchronous send operation for delivering the message. The task result
contains the sent message. contains the sent message.
</returns> </returns>
</member> </member>
<member name="M:Discord.WebSocket.ISocketMessageChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.ISocketMessageChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<summary> <summary>
Sends a file to this message channel with an optional caption. Sends a file to this message channel with an optional caption.
</summary> </summary>
<remarks> <remarks>
This method follows the same behavior as described in <see cref="M:Discord.IMessageChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)"/>.
This method follows the same behavior as described in <see cref="M:Discord.IMessageChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])"/>.
Please visit its documentation for more details on this method. Please visit its documentation for more details on this method.
</remarks> </remarks>
<param name="filePath">The file path of the file.</param> <param name="filePath">The file path of the file.</param>
@@ -1523,17 +1501,18 @@
</param> </param>
<param name="messageReference">The message references to be included. Used to reply to specific messages.</param> <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
<param name="component">The message components to be included with this message. Used for interactions</param> <param name="component">The message components to be included with this message. Used for interactions</param>
<param name="stickers">A collection of stickers to send with the file.</param>
<returns> <returns>
A task that represents an asynchronous send operation for delivering the message. The task result A task that represents an asynchronous send operation for delivering the message. The task result
contains the sent message. contains the sent message.
</returns> </returns>
</member> </member>
<member name="M:Discord.WebSocket.ISocketMessageChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.ISocketMessageChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<summary> <summary>
Sends a file to this message channel with an optional caption. Sends a file to this message channel with an optional caption.
</summary> </summary>
<remarks> <remarks>
This method follows the same behavior as described in <see cref="M:Discord.IMessageChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)"/>.
This method follows the same behavior as described in <see cref="M:Discord.IMessageChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])"/>.
Please visit its documentation for more details on this method. Please visit its documentation for more details on this method.
</remarks> </remarks>
<param name="stream">The <see cref="T:System.IO.Stream" /> of the file to be sent.</param> <param name="stream">The <see cref="T:System.IO.Stream" /> of the file to be sent.</param>
@@ -1549,6 +1528,7 @@
</param> </param>
<param name="messageReference">The message references to be included. Used to reply to specific messages.</param> <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
<param name="component">The message components to be included with this message. Used for interactions</param> <param name="component">The message components to be included with this message. Used for interactions</param>
<param name="stickers">A collection of stickers to send with the file.</param>
<returns> <returns>
A task that represents an asynchronous send operation for delivering the message. The task result A task that represents an asynchronous send operation for delivering the message. The task result
contains the sent message. contains the sent message.
@@ -1831,14 +1811,14 @@
<member name="M:Discord.WebSocket.SocketDMChannel.GetPinnedMessagesAsync(Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketDMChannel.GetPinnedMessagesAsync(Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketDMChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketDMChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
<member name="M:Discord.WebSocket.SocketDMChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketDMChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketDMChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketDMChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
@@ -1901,13 +1881,13 @@
<member name="M:Discord.WebSocket.SocketDMChannel.Discord#IMessageChannel#GetPinnedMessagesAsync(Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketDMChannel.Discord#IMessageChannel#GetPinnedMessagesAsync(Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketDMChannel.Discord#IMessageChannel#SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketDMChannel.Discord#IMessageChannel#SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketDMChannel.Discord#IMessageChannel#SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketDMChannel.Discord#IMessageChannel#SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketDMChannel.Discord#IMessageChannel#SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketDMChannel.Discord#IMessageChannel#SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="P:Discord.WebSocket.SocketDMChannel.Discord#IChannel#Name"> <member name="P:Discord.WebSocket.SocketDMChannel.Discord#IChannel#Name">
@@ -2022,15 +2002,16 @@
<member name="M:Discord.WebSocket.SocketGroupChannel.GetPinnedMessagesAsync(Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketGroupChannel.GetPinnedMessagesAsync(Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketGroupChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketGroupChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
<member name="M:Discord.WebSocket.SocketGroupChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketGroupChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketGroupChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketGroupChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
<member name="M:Discord.WebSocket.SocketGroupChannel.DeleteMessageAsync(System.UInt64,Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketGroupChannel.DeleteMessageAsync(System.UInt64,Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
@@ -2088,13 +2069,13 @@
<member name="M:Discord.WebSocket.SocketGroupChannel.Discord#IMessageChannel#GetPinnedMessagesAsync(Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketGroupChannel.Discord#IMessageChannel#GetPinnedMessagesAsync(Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketGroupChannel.Discord#IMessageChannel#SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketGroupChannel.Discord#IMessageChannel#SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketGroupChannel.Discord#IMessageChannel#SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketGroupChannel.Discord#IMessageChannel#SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketGroupChannel.Discord#IMessageChannel#SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketGroupChannel.Discord#IMessageChannel#SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketGroupChannel.Discord#IAudioChannel#ConnectAsync(System.Boolean,System.Boolean,System.Boolean)"> <member name="M:Discord.WebSocket.SocketGroupChannel.Discord#IAudioChannel#ConnectAsync(System.Boolean,System.Boolean,System.Boolean)">
@@ -2478,14 +2459,14 @@
<member name="M:Discord.WebSocket.SocketTextChannel.GetPinnedMessagesAsync(Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketTextChannel.GetPinnedMessagesAsync(Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketTextChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketTextChannel.SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
<member name="M:Discord.WebSocket.SocketTextChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketTextChannel.SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketTextChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketTextChannel.SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
<exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception> <exception cref="T:System.ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="F:Discord.DiscordConfig.MaxMessageSize"/>.</exception>
</member> </member>
@@ -2591,13 +2572,13 @@
<member name="M:Discord.WebSocket.SocketTextChannel.Discord#IMessageChannel#GetPinnedMessagesAsync(Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketTextChannel.Discord#IMessageChannel#GetPinnedMessagesAsync(Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketTextChannel.Discord#IMessageChannel#SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketTextChannel.Discord#IMessageChannel#SendFileAsync(System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketTextChannel.Discord#IMessageChannel#SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketTextChannel.Discord#IMessageChannel#SendFileAsync(System.IO.Stream,System.String,System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,System.Boolean,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketTextChannel.Discord#IMessageChannel#SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent)">
<member name="M:Discord.WebSocket.SocketTextChannel.Discord#IMessageChannel#SendMessageAsync(System.String,System.Boolean,Discord.Embed,Discord.RequestOptions,Discord.AllowedMentions,Discord.MessageReference,Discord.MessageComponent,Discord.ISticker[])">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketTextChannel.Discord#INestedChannel#GetCategoryAsync(Discord.CacheMode,Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketTextChannel.Discord#INestedChannel#GetCategoryAsync(Discord.CacheMode,Discord.RequestOptions)">
@@ -3328,6 +3309,18 @@
voice channel. voice channel.
</returns> </returns>
</member> </member>
<member name="M:Discord.WebSocket.SocketGuild.CreateStageChannelAsync(System.String,System.Action{Discord.VoiceChannelProperties},Discord.RequestOptions)">
<summary>
Creates a new stage channel in this guild.
</summary>
<param name="name">The new name for the stage channel.</param>
<param name="func">The delegate containing the properties to be applied to the channel upon its creation.</param>
<param name="options">The options to be used when sending the request.</param>
<returns>
A task that represents the asynchronous creation operation. The task result contains the newly created
stage channel.
</returns>
</member>
<member name="M:Discord.WebSocket.SocketGuild.CreateCategoryChannelAsync(System.String,System.Action{Discord.GuildChannelProperties},Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketGuild.CreateCategoryChannelAsync(System.String,System.Action{Discord.GuildChannelProperties},Discord.RequestOptions)">
<summary> <summary>
Creates a new channel category in this guild. Creates a new channel category in this guild.
@@ -3556,6 +3549,21 @@
<member name="M:Discord.WebSocket.SocketGuild.DeleteEmoteAsync(Discord.GuildEmote,Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketGuild.DeleteEmoteAsync(Discord.GuildEmote,Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketGuild.MoveAsync(Discord.IGuildUser,Discord.IVoiceChannel)">
<summary>
Moves the user to the voice channel.
</summary>
<param name="user">The user to move.</param>
<param name="targetChannel">the channel where the user gets moved to.</param>
<returns>A task that represents the asynchronous operation for moving a user.</returns>
</member>
<member name="M:Discord.WebSocket.SocketGuild.Discord#IGuild#DisconnectAsync(Discord.IGuildUser)">
<summary>
Disconnects the user from its current voice channel
</summary>
<param name="user">The user to disconnect.</param>
<returns>A task that represents the asynchronous operation for disconnecting a user.</returns>
</member>
<member name="M:Discord.WebSocket.SocketGuild.GetStickerAsync(System.UInt64,Discord.CacheMode,Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketGuild.GetStickerAsync(System.UInt64,Discord.CacheMode,Discord.RequestOptions)">
<summary> <summary>
Gets a specific sticker within this guild. Gets a specific sticker within this guild.
@@ -3746,6 +3754,9 @@
<member name="M:Discord.WebSocket.SocketGuild.Discord#IGuild#CreateVoiceChannelAsync(System.String,System.Action{Discord.VoiceChannelProperties},Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketGuild.Discord#IGuild#CreateVoiceChannelAsync(System.String,System.Action{Discord.VoiceChannelProperties},Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="M:Discord.WebSocket.SocketGuild.Discord#IGuild#CreateStageChannelAsync(System.String,System.Action{Discord.VoiceChannelProperties},Discord.RequestOptions)">
<inheritdoc />
</member>
<member name="M:Discord.WebSocket.SocketGuild.Discord#IGuild#CreateCategoryAsync(System.String,System.Action{Discord.GuildChannelProperties},Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketGuild.Discord#IGuild#CreateCategoryAsync(System.String,System.Action{Discord.GuildChannelProperties},Discord.RequestOptions)">
<inheritdoc /> <inheritdoc />
</member> </member>
@@ -3947,7 +3958,7 @@
</member> </member>
<member name="P:Discord.WebSocket.SocketMessageComponentData.Values"> <member name="P:Discord.WebSocket.SocketMessageComponentData.Values">
<summary> <summary>
The value(s) of a <see cref="T:Discord.SelectMenu"/> interaction response.
The value(s) of a <see cref="T:Discord.SelectMenuComponent"/> interaction response.
</summary> </summary>
</member> </member>
<member name="T:Discord.WebSocket.SocketSlashCommand"> <member name="T:Discord.WebSocket.SocketSlashCommand">
@@ -4170,7 +4181,7 @@
<summary> <summary>
Responds to an Interaction with type <see cref="F:Discord.InteractionResponseType.ChannelMessageWithSource"/>. Responds to an Interaction with type <see cref="F:Discord.InteractionResponseType.ChannelMessageWithSource"/>.
<para> <para>
If you have <see cref="P:Discord.WebSocket.DiscordSocketConfig.AlwaysAcknowledgeInteractions"/> set to <see langword="true"/>, You should use
If you have <see cref="!:DiscordSocketConfig.AlwaysAcknowledgeInteractions"/> set to <see langword="true"/>, You should use
<see cref="M:Discord.WebSocket.SocketInteraction.FollowupAsync(System.String,Discord.Embed[],System.Boolean,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent,Discord.Embed)"/> instead. <see cref="M:Discord.WebSocket.SocketInteraction.FollowupAsync(System.String,Discord.Embed[],System.Boolean,System.Boolean,Discord.AllowedMentions,Discord.RequestOptions,Discord.MessageComponent,Discord.Embed)"/> instead.
</para> </para>
</summary> </summary>
@@ -4252,14 +4263,6 @@
<param name="options">The request options for this async request.</param> <param name="options">The request options for this async request.</param>
<returns>A <see cref="T:Discord.Rest.RestInteractionMessage"/> that represents the initial response.</returns> <returns>A <see cref="T:Discord.Rest.RestInteractionMessage"/> that represents the initial response.</returns>
</member> </member>
<member name="M:Discord.WebSocket.SocketInteraction.AcknowledgeAsync(Discord.RequestOptions)">
<summary>
Acknowledges this interaction.
</summary>
<returns>
A task that represents the asynchronous operation of acknowledging the interaction.
</returns>
</member>
<member name="M:Discord.WebSocket.SocketInteraction.DeferAsync(System.Boolean,Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketInteraction.DeferAsync(System.Boolean,Discord.RequestOptions)">
<summary> <summary>
Acknowledges this interaction. Acknowledges this interaction.
@@ -4805,7 +4808,7 @@
</member> </member>
<member name="P:Discord.WebSocket.SocketCustomSticker.Guild"> <member name="P:Discord.WebSocket.SocketCustomSticker.Guild">
<summary> <summary>
Gets the guild the sticker lives in.
Gets the guild the sticker was created in.
</summary> </summary>
</member> </member>
<member name="P:Discord.WebSocket.SocketCustomSticker.AuthorId"> <member name="P:Discord.WebSocket.SocketCustomSticker.AuthorId">
@@ -4834,13 +4837,16 @@
<member name="P:Discord.WebSocket.SocketSticker.Tags"> <member name="P:Discord.WebSocket.SocketSticker.Tags">
<inheritdoc/> <inheritdoc/>
</member> </member>
<member name="P:Discord.WebSocket.SocketSticker.Asset">
<member name="P:Discord.WebSocket.SocketSticker.Type">
<inheritdoc/> <inheritdoc/>
</member> </member>
<member name="P:Discord.WebSocket.SocketSticker.PreviewAsset">
<member name="P:Discord.WebSocket.SocketSticker.Format">
<inheritdoc/> <inheritdoc/>
</member> </member>
<member name="P:Discord.WebSocket.SocketSticker.Format">
<member name="P:Discord.WebSocket.SocketSticker.Available">
<inheritdoc/>
</member>
<member name="P:Discord.WebSocket.SocketSticker.SortOrder">
<inheritdoc/> <inheritdoc/>
</member> </member>
<member name="M:Discord.WebSocket.SocketSticker.GetStickerUrl"> <member name="M:Discord.WebSocket.SocketSticker.GetStickerUrl">
@@ -4854,9 +4860,6 @@
Represents an unknown sticker received over the gateway. Represents an unknown sticker received over the gateway.
</summary> </summary>
</member> </member>
<member name="P:Discord.WebSocket.SocketUnknownSticker.Asset">
<inheritdoc/>
</member>
<member name="P:Discord.WebSocket.SocketUnknownSticker.Tags"> <member name="P:Discord.WebSocket.SocketUnknownSticker.Tags">
<inheritdoc/> <inheritdoc/>
</member> </member>
@@ -4866,7 +4869,13 @@
<member name="P:Discord.WebSocket.SocketUnknownSticker.PackId"> <member name="P:Discord.WebSocket.SocketUnknownSticker.PackId">
<inheritdoc/> <inheritdoc/>
</member> </member>
<member name="P:Discord.WebSocket.SocketUnknownSticker.PreviewAsset">
<member name="P:Discord.WebSocket.SocketUnknownSticker.Available">
<inheritdoc/>
</member>
<member name="P:Discord.WebSocket.SocketUnknownSticker.SortOrder">
<inheritdoc/>
</member>
<member name="P:Discord.WebSocket.SocketUnknownSticker.Type">
<inheritdoc/> <inheritdoc/>
</member> </member>
<member name="M:Discord.WebSocket.SocketUnknownSticker.ResolveAsync(Discord.CacheMode,Discord.RequestOptions)"> <member name="M:Discord.WebSocket.SocketUnknownSticker.ResolveAsync(Discord.CacheMode,Discord.RequestOptions)">


+ 0
- 6
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -72,8 +72,6 @@ namespace Discord.WebSocket
internal WebSocketProvider WebSocketProvider { get; private set; } internal WebSocketProvider WebSocketProvider { get; private set; }
internal bool AlwaysDownloadUsers { get; private set; } internal bool AlwaysDownloadUsers { get; private set; }
internal int? HandlerTimeout { get; private set; } internal int? HandlerTimeout { get; private set; }
internal bool AlwaysAcknowledgeInteractions { get; private set; }

internal new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient; internal new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient;
/// <inheritdoc /> /// <inheritdoc />
public override IReadOnlyCollection<SocketGuild> Guilds => State.Guilds; public override IReadOnlyCollection<SocketGuild> Guilds => State.Guilds;
@@ -143,7 +141,6 @@ namespace Discord.WebSocket
UdpSocketProvider = config.UdpSocketProvider; UdpSocketProvider = config.UdpSocketProvider;
WebSocketProvider = config.WebSocketProvider; WebSocketProvider = config.WebSocketProvider;
AlwaysDownloadUsers = config.AlwaysDownloadUsers; AlwaysDownloadUsers = config.AlwaysDownloadUsers;
AlwaysAcknowledgeInteractions = config.AlwaysAcknowledgeInteractions;
HandlerTimeout = config.HandlerTimeout; HandlerTimeout = config.HandlerTimeout;
State = new ClientState(0, 0); State = new ClientState(0, 0);
Rest = new DiscordSocketRestClient(config, ApiClient); Rest = new DiscordSocketRestClient(config, ApiClient);
@@ -2095,9 +2092,6 @@ namespace Discord.WebSocket


var interaction = SocketInteraction.Create(this, data, channel as ISocketMessageChannel); var interaction = SocketInteraction.Create(this, data, channel as ISocketMessageChannel);


if (this.AlwaysAcknowledgeInteractions)
await interaction.DeferAsync().ConfigureAwait(false);

await TimedInvokeAsync(_interactionCreatedEvent, nameof(InteractionCreated), interaction).ConfigureAwait(false); await TimedInvokeAsync(_interactionCreatedEvent, nameof(InteractionCreated), interaction).ConfigureAwait(false);


switch (interaction) switch (interaction)


+ 0
- 23
src/Discord.Net.WebSocket/DiscordSocketConfig.cs View File

@@ -105,29 +105,6 @@ namespace Discord.WebSocket
/// </remarks> /// </remarks>
public bool AlwaysDownloadUsers { get; set; } = false; public bool AlwaysDownloadUsers { get; set; } = false;


/// <summary>
/// Gets or sets whether or not interactions are acknowledge with source.
/// </summary>
/// <remarks>
/// <para>
/// Discord interactions will not appear in chat until the client responds to them. With this option set to
/// <see langword="true"/>, the client will automatically acknowledge the interaction with <see cref="InteractionResponseType.DeferredChannelMessageWithSource"/>.
/// See <see href="https://discord.com/developers/docs/interactions/slash-commands#interaction-interactionresponsetype">the docs</see> on
/// responding to interactions for more info.
/// </para>
/// <para>
/// With this option set to <see langword="false"/>, you will have to acknowledge the interaction with
/// <see cref="SocketInteraction.RespondAsync(string, bool, Embed, InteractionResponseType, AllowedMentions, RequestOptions)"/>.
/// Only after the interaction is acknowledged, the original slash command message will be visible.
/// </para>
/// <note>
/// Please note that manually acknowledging the interaction with a message reply will not provide any return data.
/// Automatically acknowledging the interaction without sending the message will allow for follow up responses to
/// be used; follow up responses return the message data sent.
/// </note>
/// </remarks>
public bool AlwaysAcknowledgeInteractions { get; set; } = true;

/// <summary> /// <summary>
/// Gets or sets the timeout for event handlers, in milliseconds, after which a warning will be logged. /// Gets or sets the timeout for event handlers, in milliseconds, after which a warning will be logged.
/// Setting this property to <c>null</c>disables this check. /// Setting this property to <c>null</c>disables this check.


+ 8
- 5
src/Discord.Net.WebSocket/Entities/Channels/ISocketMessageChannel.cs View File

@@ -35,16 +35,17 @@ namespace Discord.WebSocket
/// </param> /// </param>
/// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param> /// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
/// <param name="component">The message components to be included with this message. Used for interactions</param> /// <param name="component">The message components to be included with this message. Used for interactions</param>
/// <param name="stickers">A collection of stickers to send with the message.</param>
/// <returns> /// <returns>
/// A task that represents an asynchronous send operation for delivering the message. The task result /// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message. /// contains the sent message.
/// </returns> /// </returns>
new Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null);
new Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null);
/// <summary> /// <summary>
/// Sends a file to this message channel with an optional caption. /// Sends a file to this message channel with an optional caption.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This method follows the same behavior as described in <see cref="IMessageChannel.SendFileAsync(string, string, bool, Embed, RequestOptions, bool, AllowedMentions, MessageReference, MessageComponent)"/>.
/// This method follows the same behavior as described in <see cref="IMessageChannel.SendFileAsync(string, string, bool, Embed, RequestOptions, bool, AllowedMentions, MessageReference, MessageComponent, ISticker[])"/>.
/// Please visit its documentation for more details on this method. /// Please visit its documentation for more details on this method.
/// </remarks> /// </remarks>
/// <param name="filePath">The file path of the file.</param> /// <param name="filePath">The file path of the file.</param>
@@ -59,16 +60,17 @@ namespace Discord.WebSocket
/// </param> /// </param>
/// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param> /// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
/// <param name="component">The message components to be included with this message. Used for interactions</param> /// <param name="component">The message components to be included with this message. Used for interactions</param>
/// <param name="stickers">A collection of stickers to send with the file.</param>
/// <returns> /// <returns>
/// A task that represents an asynchronous send operation for delivering the message. The task result /// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message. /// contains the sent message.
/// </returns> /// </returns>
new Task<RestUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null);
new Task<RestUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null);
/// <summary> /// <summary>
/// Sends a file to this message channel with an optional caption. /// Sends a file to this message channel with an optional caption.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// This method follows the same behavior as described in <see cref="IMessageChannel.SendFileAsync(Stream, string, string, bool, Embed, RequestOptions, bool, AllowedMentions, MessageReference, MessageComponent)"/>.
/// This method follows the same behavior as described in <see cref="IMessageChannel.SendFileAsync(Stream, string, string, bool, Embed, RequestOptions, bool, AllowedMentions, MessageReference, MessageComponent, ISticker[])"/>.
/// Please visit its documentation for more details on this method. /// Please visit its documentation for more details on this method.
/// </remarks> /// </remarks>
/// <param name="stream">The <see cref="Stream" /> of the file to be sent.</param> /// <param name="stream">The <see cref="Stream" /> of the file to be sent.</param>
@@ -84,11 +86,12 @@ namespace Discord.WebSocket
/// </param> /// </param>
/// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param> /// <param name="messageReference">The message references to be included. Used to reply to specific messages.</param>
/// <param name="component">The message components to be included with this message. Used for interactions</param> /// <param name="component">The message components to be included with this message. Used for interactions</param>
/// <param name="stickers">A collection of stickers to send with the file.</param>
/// <returns> /// <returns>
/// A task that represents an asynchronous send operation for delivering the message. The task result /// A task that represents an asynchronous send operation for delivering the message. The task result
/// contains the sent message. /// contains the sent message.
/// </returns> /// </returns>
new Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null);
new Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null);


/// <summary> /// <summary>
/// Gets a cached message from this channel. /// Gets a cached message from this channel.


+ 12
- 12
src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs View File

@@ -137,16 +137,16 @@ namespace Discord.WebSocket


/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, component, options);
public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options);


/// <inheritdoc /> /// <inheritdoc />
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, allowedMentions, messageReference, component, options, isSpoiler);
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options, isSpoiler);
/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, allowedMentions, messageReference, component, options, isSpoiler);
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options, isSpoiler);
/// <inheritdoc /> /// <inheritdoc />
public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
=> ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options); => ChannelHelper.DeleteMessageAsync(this, messageId, Discord, options);
@@ -238,14 +238,14 @@ namespace Discord.WebSocket
async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options) async Task<IReadOnlyCollection<IMessage>> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false); => await GetPinnedMessagesAsync(options).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);


//IChannel //IChannel
/// <inheritdoc /> /// <inheritdoc />


+ 13
- 12
src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs View File

@@ -171,15 +171,16 @@ namespace Discord.WebSocket


/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, component, options);
public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options);


/// <inheritdoc /> /// <inheritdoc />
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, allowedMentions, messageReference, component, options, isSpoiler);
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options, isSpoiler);
/// <inheritdoc /> /// <inheritdoc />
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, allowedMentions, messageReference, component, options, isSpoiler);
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options, isSpoiler);


/// <inheritdoc /> /// <inheritdoc />
public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null) public Task DeleteMessageAsync(ulong messageId, RequestOptions options = null)
@@ -305,14 +306,14 @@ namespace Discord.WebSocket
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false); => await GetPinnedMessagesAsync(options).ConfigureAwait(false);


/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);


//IAudioChannel //IAudioChannel
/// <inheritdoc /> /// <inheritdoc />


+ 12
- 12
src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs View File

@@ -209,17 +209,17 @@ namespace Discord.WebSocket


/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, component, options);
public Task<RestUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendMessageAsync(this, Discord, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options);


/// <inheritdoc /> /// <inheritdoc />
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, allowedMentions, messageReference, component, options, isSpoiler);
public Task<RestUserMessage> SendFileAsync(string filePath, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendFileAsync(this, Discord, filePath, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options, isSpoiler);


/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, allowedMentions, messageReference, component, options, isSpoiler);
public Task<RestUserMessage> SendFileAsync(Stream stream, string filename, string text, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
=> ChannelHelper.SendFileAsync(this, Discord, stream, filename, text, isTTS, embed, allowedMentions, messageReference, component, stickers, options, isSpoiler);


/// <inheritdoc /> /// <inheritdoc />
public Task DeleteMessagesAsync(IEnumerable<IMessage> messages, RequestOptions options = null) public Task DeleteMessagesAsync(IEnumerable<IMessage> messages, RequestOptions options = null)
@@ -363,14 +363,14 @@ namespace Discord.WebSocket
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false); => await GetPinnedMessagesAsync(options).ConfigureAwait(false);


/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendFileAsync(string filePath, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendFileAsync(filePath, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendFileAsync(Stream stream, string filename, string text, bool isTTS, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendFileAsync(stream, filename, text, isTTS, embed, options, isSpoiler, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component).ConfigureAwait(false);
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);


// INestedChannel // INestedChannel
/// <inheritdoc /> /// <inheritdoc />


+ 56
- 14
src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs View File

@@ -572,7 +572,7 @@ namespace Discord.WebSocket
_emotes = emotes.ToImmutable(); _emotes = emotes.ToImmutable();
} }


//General
#region General
/// <inheritdoc /> /// <inheritdoc />
public Task DeleteAsync(RequestOptions options = null) public Task DeleteAsync(RequestOptions options = null)
=> GuildHelper.DeleteAsync(this, Discord, options); => GuildHelper.DeleteAsync(this, Discord, options);
@@ -596,8 +596,9 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
public Task LeaveAsync(RequestOptions options = null) public Task LeaveAsync(RequestOptions options = null)
=> GuildHelper.LeaveAsync(this, Discord, options); => GuildHelper.LeaveAsync(this, Discord, options);
#endregion


//Bans
#region Bans
/// <summary> /// <summary>
/// Gets a collection of all users banned in this guild. /// Gets a collection of all users banned in this guild.
/// </summary> /// </summary>
@@ -645,8 +646,9 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
public Task RemoveBanAsync(ulong userId, RequestOptions options = null) public Task RemoveBanAsync(ulong userId, RequestOptions options = null)
=> GuildHelper.RemoveBanAsync(this, Discord, userId, options); => GuildHelper.RemoveBanAsync(this, Discord, userId, options);
#endregion


//Channels
#region Channels
/// <summary> /// <summary>
/// Gets a channel in this guild. /// Gets a channel in this guild.
/// </summary> /// </summary>
@@ -746,6 +748,19 @@ namespace Discord.WebSocket
/// </returns> /// </returns>
public Task<RestVoiceChannel> CreateVoiceChannelAsync(string name, Action<VoiceChannelProperties> func = null, RequestOptions options = null) public Task<RestVoiceChannel> CreateVoiceChannelAsync(string name, Action<VoiceChannelProperties> func = null, RequestOptions options = null)
=> GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options, func); => GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options, func);

/// <summary>
/// Creates a new stage channel in this guild.
/// </summary>
/// <param name="name">The new name for the stage channel.</param>
/// <param name="func">The delegate containing the properties to be applied to the channel upon its creation.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous creation operation. The task result contains the newly created
/// stage channel.
/// </returns>
public Task<RestStageChannel> CreateStageChannelAsync(string name, Action<VoiceChannelProperties> func = null, RequestOptions options = null)
=> GuildHelper.CreateStageChannelAsync(this, Discord, name, options, func);
/// <summary> /// <summary>
/// Creates a new channel category in this guild. /// Creates a new channel category in this guild.
/// </summary> /// </summary>
@@ -794,8 +809,9 @@ namespace Discord.WebSocket


_channels.Clear(); _channels.Clear();
} }
#endregion


//Voice Regions
#region Voice Regions
/// <summary> /// <summary>
/// Gets a collection of all the voice regions this guild can access. /// Gets a collection of all the voice regions this guild can access.
/// </summary> /// </summary>
@@ -806,14 +822,16 @@ namespace Discord.WebSocket
/// </returns> /// </returns>
public Task<IReadOnlyCollection<RestVoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null) public Task<IReadOnlyCollection<RestVoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null)
=> GuildHelper.GetVoiceRegionsAsync(this, Discord, options); => GuildHelper.GetVoiceRegionsAsync(this, Discord, options);
#endregion


//Integrations
#region Integrations
public Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null) public Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null)
=> GuildHelper.GetIntegrationsAsync(this, Discord, options); => GuildHelper.GetIntegrationsAsync(this, Discord, options);
public Task<RestGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null) public Task<RestGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null)
=> GuildHelper.CreateIntegrationAsync(this, Discord, id, type, options); => GuildHelper.CreateIntegrationAsync(this, Discord, id, type, options);
#endregion


//Interactions
#region Interactions
/// <summary> /// <summary>
/// Deletes all application commands in the current guild. /// Deletes all application commands in the current guild.
/// </summary> /// </summary>
@@ -919,8 +937,9 @@ namespace Discord.WebSocket


return entities.ToImmutableArray(); return entities.ToImmutableArray();
} }
#endregion


//Invites
#region Invites
/// <summary> /// <summary>
/// Gets a collection of all invites in this guild. /// Gets a collection of all invites in this guild.
/// </summary> /// </summary>
@@ -1027,8 +1046,9 @@ namespace Discord.WebSocket
return sticker; return sticker;
return null; return null;
} }
#endregion


//Users
#region Users
/// <inheritdoc /> /// <inheritdoc />
public Task<RestGuildUser> AddGuildUserAsync(ulong id, string accessToken, Action<AddGuildUserProperties> func = null, RequestOptions options = null) public Task<RestGuildUser> AddGuildUserAsync(ulong id, string accessToken, Action<AddGuildUserProperties> func = null, RequestOptions options = null)
=> GuildHelper.AddGuildUserAsync(this, Discord, id, accessToken, func, options); => GuildHelper.AddGuildUserAsync(this, Discord, id, accessToken, func, options);
@@ -1227,7 +1247,24 @@ namespace Discord.WebSocket
public Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null) public Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null)
=> GuildHelper.DeleteEmoteAsync(this, Discord, emote.Id, options); => GuildHelper.DeleteEmoteAsync(this, Discord, emote.Id, options);


//Stickers
/// <summary>
/// Moves the user to the voice channel.
/// </summary>
/// <param name="user">The user to move.</param>
/// <param name="targetChannel">the channel where the user gets moved to.</param>
/// <returns>A task that represents the asynchronous operation for moving a user.</returns>
public Task MoveAsync(IGuildUser user, IVoiceChannel targetChannel)
=> user.ModifyAsync(x => x.Channel = new Optional<IVoiceChannel>(targetChannel));

/// <summary>
/// Disconnects the user from its current voice channel
/// </summary>
/// <param name="user">The user to disconnect.</param>
/// <returns>A task that represents the asynchronous operation for disconnecting a user.</returns>
async Task IGuild.DisconnectAsync(IGuildUser user) => await user.ModifyAsync(x => x.Channel = new Optional<IVoiceChannel>());
#endregion

#region Stickers
/// <summary> /// <summary>
/// Gets a specific sticker within this guild. /// Gets a specific sticker within this guild.
/// </summary> /// </summary>
@@ -1355,8 +1392,9 @@ namespace Discord.WebSocket
/// </returns> /// </returns>
public Task DeleteStickerAsync(SocketCustomSticker sticker, RequestOptions options = null) public Task DeleteStickerAsync(SocketCustomSticker sticker, RequestOptions options = null)
=> sticker.DeleteAsync(options); => sticker.DeleteAsync(options);
#endregion


//Voice States
#region Voice States
internal async Task<SocketVoiceState> AddOrUpdateVoiceStateAsync(ClientState state, VoiceStateModel model) internal async Task<SocketVoiceState> AddOrUpdateVoiceStateAsync(ClientState state, VoiceStateModel model)
{ {
var voiceChannel = state.GetChannel(model.ChannelId.Value) as SocketVoiceChannel; var voiceChannel = state.GetChannel(model.ChannelId.Value) as SocketVoiceChannel;
@@ -1400,8 +1438,9 @@ namespace Discord.WebSocket
} }
return null; return null;
} }
#endregion


//Audio
#region Audio
internal AudioInStream GetAudioStream(ulong userId) internal AudioInStream GetAudioStream(ulong userId)
{ {
return _audioClient?.GetInputStream(userId); return _audioClient?.GetInputStream(userId);
@@ -1555,8 +1594,9 @@ namespace Discord.WebSocket
public override string ToString() => Name; public override string ToString() => Name;
private string DebuggerDisplay => $"{Name} ({Id})"; private string DebuggerDisplay => $"{Name} ({Id})";
internal SocketGuild Clone() => MemberwiseClone() as SocketGuild; internal SocketGuild Clone() => MemberwiseClone() as SocketGuild;
#endregion


//IGuild
#region IGuild
/// <inheritdoc /> /// <inheritdoc />
ulong? IGuild.AFKChannelId => AFKChannelId; ulong? IGuild.AFKChannelId => AFKChannelId;
/// <inheritdoc /> /// <inheritdoc />
@@ -1650,6 +1690,9 @@ namespace Discord.WebSocket
async Task<IVoiceChannel> IGuild.CreateVoiceChannelAsync(string name, Action<VoiceChannelProperties> func, RequestOptions options) async Task<IVoiceChannel> IGuild.CreateVoiceChannelAsync(string name, Action<VoiceChannelProperties> func, RequestOptions options)
=> await CreateVoiceChannelAsync(name, func, options).ConfigureAwait(false); => await CreateVoiceChannelAsync(name, func, options).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />
async Task<IStageChannel> IGuild.CreateStageChannelAsync(string name, Action<VoiceChannelProperties> func, RequestOptions options)
=> await CreateStageChannelAsync(name, func, options).ConfigureAwait(false);
/// <inheritdoc />
async Task<ICategoryChannel> IGuild.CreateCategoryAsync(string name, Action<GuildChannelProperties> func, RequestOptions options) async Task<ICategoryChannel> IGuild.CreateCategoryAsync(string name, Action<GuildChannelProperties> func, RequestOptions options)
=> await CreateCategoryChannelAsync(name, func, options).ConfigureAwait(false); => await CreateCategoryChannelAsync(name, func, options).ConfigureAwait(false);


@@ -1765,7 +1808,6 @@ namespace Discord.WebSocket
_audioLock?.Dispose(); _audioLock?.Dispose();
_audioClient?.Dispose(); _audioClient?.Dispose();
} }

#endregion
} }
} }

+ 2
- 8
src/Discord.Net.WebSocket/Entities/Interaction/Message Components/SocketMessageComponent.cs View File

@@ -86,12 +86,6 @@ namespace Discord.WebSocket
if (embeds == null && embed != null) if (embeds == null && embed != null)
embeds = new[] { embed }; embeds = new[] { embed };


if (Discord.AlwaysAcknowledgeInteractions)
{
await FollowupAsync(text, embeds, isTTS, ephemeral, allowedMentions, options);
return;
}

Preconditions.AtMost(allowedMentions?.RoleIds?.Count ?? 0, 100, nameof(allowedMentions.RoleIds), "A max of 100 role Ids are allowed."); Preconditions.AtMost(allowedMentions?.RoleIds?.Count ?? 0, 100, nameof(allowedMentions.RoleIds), "A max of 100 role Ids are allowed.");
Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed."); Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed.");
Preconditions.AtMost(embeds?.Length ?? 0, 10, nameof(embeds), "A max of 10 embeds are allowed."); Preconditions.AtMost(embeds?.Length ?? 0, 10, nameof(embeds), "A max of 10 embeds are allowed.");
@@ -341,7 +335,7 @@ namespace Discord.WebSocket


}; };


return Discord.Rest.ApiClient.CreateInteractionResponse(response, this.Id, this.Token, options);
return Discord.Rest.ApiClient.CreateInteractionResponseAsync(response, this.Id, this.Token, options);
} }


/// <inheritdoc/> /// <inheritdoc/>
@@ -354,7 +348,7 @@ namespace Discord.WebSocket


}; };


return Discord.Rest.ApiClient.CreateInteractionResponse(response, this.Id, this.Token, options);
return Discord.Rest.ApiClient.CreateInteractionResponseAsync(response, this.Id, this.Token, options);
} }
} }
} }

+ 1
- 1
src/Discord.Net.WebSocket/Entities/Interaction/Message Components/SocketMessageComponentData.cs View File

@@ -23,7 +23,7 @@ namespace Discord.WebSocket
public ComponentType Type { get; } public ComponentType Type { get; }


/// <summary> /// <summary>
/// The value(s) of a <see cref="SelectMenu"/> interaction response.
/// The value(s) of a <see cref="SelectMenuComponent"/> interaction response.
/// </summary> /// </summary>
public IReadOnlyCollection<string> Values { get; } public IReadOnlyCollection<string> Values { get; }




+ 1
- 7
src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketCommandBase.cs View File

@@ -70,12 +70,6 @@ namespace Discord.WebSocket
if (embeds == null && embed != null) if (embeds == null && embed != null)
embeds = new[] { embed }; embeds = new[] { embed };


if (Discord.AlwaysAcknowledgeInteractions)
{
await FollowupAsync(text, embeds, isTTS, ephemeral, allowedMentions, options, component);
return;
}

Preconditions.AtMost(allowedMentions?.RoleIds?.Count ?? 0, 100, nameof(allowedMentions.RoleIds), "A max of 100 role Ids are allowed."); Preconditions.AtMost(allowedMentions?.RoleIds?.Count ?? 0, 100, nameof(allowedMentions.RoleIds), "A max of 100 role Ids are allowed.");
Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed."); Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed.");
Preconditions.AtMost(embeds?.Length ?? 0, 10, nameof(embeds), "A max of 10 embeds are allowed."); Preconditions.AtMost(embeds?.Length ?? 0, 10, nameof(embeds), "A max of 10 embeds are allowed.");
@@ -244,7 +238,7 @@ namespace Discord.WebSocket
} }
}; };


return Discord.Rest.ApiClient.CreateInteractionResponse(response, this.Id, this.Token, options);
return Discord.Rest.ApiClient.CreateInteractionResponseAsync(response, this.Id, this.Token, options);
} }
} }
} }

+ 1
- 1
src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs View File

@@ -198,7 +198,7 @@ namespace Discord.WebSocket
case ComponentType.SelectMenu: case ComponentType.SelectMenu:
{ {
var parsed = (API.SelectMenuComponent)y; var parsed = (API.SelectMenuComponent)y;
return new SelectMenu(
return new SelectMenuComponent(
parsed.CustomId, parsed.CustomId,
parsed.Options.Select(z => new SelectMenuOption( parsed.Options.Select(z => new SelectMenuOption(
z.Label, z.Label,


+ 1
- 1
src/Discord.Net.WebSocket/Entities/Stickers/SocketCustomSticker.cs View File

@@ -29,7 +29,7 @@ namespace Discord.WebSocket
=> this.AuthorId.HasValue ? Guild.GetUser(this.AuthorId.Value) : null; => this.AuthorId.HasValue ? Guild.GetUser(this.AuthorId.Value) : null;


/// <summary> /// <summary>
/// Gets the guild the sticker lives in.
/// Gets the guild the sticker was created in.
/// </summary> /// </summary>
public SocketGuild Guild { get; } public SocketGuild Guild { get; }




+ 13
- 8
src/Discord.Net.WebSocket/Entities/Stickers/SocketSticker.cs View File

@@ -20,7 +20,7 @@ namespace Discord.WebSocket
public virtual ulong PackId { get; private set; } public virtual ulong PackId { get; private set; }


/// <inheritdoc/> /// <inheritdoc/>
public string Name { get; internal set; }
public string Name { get; protected set; }


/// <inheritdoc/> /// <inheritdoc/>
public virtual string Description { get; private set; } public virtual string Description { get; private set; }
@@ -29,13 +29,16 @@ namespace Discord.WebSocket
public virtual IReadOnlyCollection<string> Tags { get; private set; } public virtual IReadOnlyCollection<string> Tags { get; private set; }


/// <inheritdoc/> /// <inheritdoc/>
public virtual string Asset { get; private set; }
public virtual StickerType Type { get; private set; }


/// <inheritdoc/> /// <inheritdoc/>
public virtual string PreviewAsset { get; private set; }
public StickerFormatType Format { get; protected set; }


/// <inheritdoc/> /// <inheritdoc/>
public StickerFormatType Format { get; internal set; }
public virtual bool? Available { get; protected set; }

/// <inheritdoc/>
public virtual int? SortOrder { get; private set; }


/// <inheritdoc/> /// <inheritdoc/>
public string GetStickerUrl() public string GetStickerUrl()
@@ -62,9 +65,10 @@ namespace Discord.WebSocket
this.Name = model.Name; this.Name = model.Name;
this.Description = model.Desription; this.Description = model.Desription;
this.PackId = model.PackId; this.PackId = model.PackId;
this.Asset = model.Asset;
this.PreviewAsset = model.PreviewAsset;
this.Available = model.Available;
this.Format = model.FormatType; this.Format = model.FormatType;
this.Type = model.Type;
this.SortOrder = model.SortValue;


if (model.Tags.IsSpecified) if (model.Tags.IsSpecified)
{ {
@@ -88,8 +92,9 @@ namespace Discord.WebSocket
stickerModel.FormatType == this.Format && stickerModel.FormatType == this.Format &&
stickerModel.Id == this.Id && stickerModel.Id == this.Id &&
stickerModel.PackId == this.PackId && stickerModel.PackId == this.PackId &&
stickerModel.Asset == this.Asset &&
stickerModel.PreviewAsset == this.PreviewAsset &&
stickerModel.Type == this.Type &&
stickerModel.SortValue == this.SortOrder &&
stickerModel.Available == this.Available &&
(stickerModel.Tags.IsSpecified ? (stickerModel.Tags.IsSpecified ?
stickerModel.Tags.Value == string.Join(", ", this.Tags) : stickerModel.Tags.Value == string.Join(", ", this.Tags) :
true); true);


+ 9
- 6
src/Discord.Net.WebSocket/Entities/Stickers/SocketUnknownSticker.cs View File

@@ -14,10 +14,6 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketUnknownSticker : SocketSticker public class SocketUnknownSticker : SocketSticker
{ {
/// <inheritdoc/>
public override string Asset
=> null;

/// <inheritdoc/> /// <inheritdoc/>
public override IReadOnlyCollection<string> Tags public override IReadOnlyCollection<string> Tags
=> null; => null;
@@ -29,9 +25,16 @@ namespace Discord.WebSocket
/// <inheritdoc/> /// <inheritdoc/>
public override ulong PackId public override ulong PackId
=> 0; => 0;
/// <inheritdoc/>
public override bool? Available
=> null;

/// <inheritdoc/>
public override int? SortOrder
=> null;


/// <inheritdoc/> /// <inheritdoc/>
public override string PreviewAsset
public new StickerType? Type
=> null; => null;


internal SocketUnknownSticker(DiscordSocketClient client, ulong id) internal SocketUnknownSticker(DiscordSocketClient client, ulong id)
@@ -59,6 +62,6 @@ namespace Discord.WebSocket
public Task<SocketSticker> ResolveAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null) public Task<SocketSticker> ResolveAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null)
=> Discord.GetStickerAsync(this.Id, mode, options); => Discord.GetStickerAsync(this.Id, mode, options);


private string DebuggerDisplay => $"{Name} ({Id})";
private new string DebuggerDisplay => $"{Name} ({Id})";
} }
} }

+ 4
- 15
test/Discord.Net.Tests.Unit/MockedEntities/MockedDMChannel.cs View File

@@ -78,24 +78,13 @@ namespace Discord
throw new NotImplementedException(); throw new NotImplementedException();
} }


public Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
{
throw new NotImplementedException();
}

public Task<IUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
{
throw new NotImplementedException();
}

public Task<IUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
{
throw new NotImplementedException();
}

public Task TriggerTypingAsync(RequestOptions options = null) public Task TriggerTypingAsync(RequestOptions options = null)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

public Task<IUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null) => throw new NotImplementedException();
public Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null) => throw new NotImplementedException();
public Task<IUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null) => throw new NotImplementedException();
} }
} }

+ 3
- 3
test/Discord.Net.Tests.Unit/MockedEntities/MockedGroupChannel.cs View File

@@ -86,17 +86,17 @@ namespace Discord
throw new NotImplementedException(); throw new NotImplementedException();
} }


public Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
public Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }


public Task<IUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
public Task<IUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }


public Task<IUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
public Task<IUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }


+ 3
- 3
test/Discord.Net.Tests.Unit/MockedEntities/MockedTextChannel.cs View File

@@ -176,17 +176,17 @@ namespace Discord
throw new NotImplementedException(); throw new NotImplementedException();
} }


public Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
public Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }


public Task<IUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
public Task<IUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }


public Task<IUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null)
public Task<IUserMessage> SendMessageAsync(string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageReference messageReference = null, MessageComponent component = null, ISticker[] stickers = null)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }


Loading…
Cancel
Save