Browse Source

rest forum channel and remove message builder for 4.x

pull/2316/head
Quin Lynch 3 years ago
parent
commit
116c7a6637
11 changed files with 452 additions and 368 deletions
  1. +118
    -3
      src/Discord.Net.Core/Entities/Channels/IForumChannel.cs
  2. +0
    -74
      src/Discord.Net.Core/Entities/Messages/Message.cs
  3. +0
    -220
      src/Discord.Net.Core/Entities/Messages/MessageBuilder.cs
  4. +33
    -0
      src/Discord.Net.Rest/API/Common/ForumThreadMessage.cs
  5. +13
    -11
      src/Discord.Net.Rest/API/Rest/CreateMultipartPostAsync.cs
  6. +2
    -21
      src/Discord.Net.Rest/API/Rest/CreatePostParams.cs
  7. +131
    -0
      src/Discord.Net.Rest/Entities/Channels/RestForumChannel.cs
  8. +1
    -0
      src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs
  9. +97
    -32
      src/Discord.Net.Rest/Entities/Channels/ThreadHelper.cs
  10. +48
    -6
      src/Discord.Net.WebSocket/Entities/Channels/SocketForumChannel.cs
  11. +9
    -1
      src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs

+ 118
- 3
src/Discord.Net.Core/Entities/Channels/IForumChannel.cs View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -39,15 +40,129 @@ namespace Discord
/// </summary>
/// <param name="title">The title of the post.</param>
/// <param name="archiveDuration">The archive duration of the post.</param>
/// <param name="message">
/// The starting message of the post. The content of the message supports full markdown.
/// <param name="slowmode">The slowmode for the posts thread.</param>
/// <param name="text">The message to be sent.</param>
/// <param name="embed">The <see cref="Discord.EmbedType.Rich"/> <see cref="Embed"/> to be sent.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <param name="allowedMentions">
/// Specifies if notifications are sent for mentioned users and roles in the message <paramref name="text"/>.
/// If <c>null</c>, all mentioned roles and users will be notified.
/// </param>
/// <param name="components">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>
/// <param name="embeds">A array of <see cref="Embed"/>s to send with this response. Max 10.</param>
/// <param name="flags">A message flag to be applied to the sent message, only <see cref="MessageFlags.SuppressEmbeds"/> is permitted.</param>
/// <returns>
/// A task that represents the asynchronous creation operation.
/// </returns>
Task<IThreadChannel> CreatePostAsync(string title, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay, int? slowmode = null,
string text = null, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None);

/// <summary>
/// Creates a new post (thread) within the forum.
/// </summary>
/// <param name="title">The title of the post.</param>
/// <param name="archiveDuration">The archive duration of the post.</param>
/// <param name="slowmode">The slowmode for the posts thread.</param>
/// <param name="filePath">The file path of the file.</param>
/// <param name="text">The message to be sent.</param>
/// <param name="embed">The <see cref="Discord.EmbedType.Rich" /> <see cref="Embed" /> to be sent.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <param name="isSpoiler">Whether the message attachment should be hidden as a spoiler.</param>
/// <param name="allowedMentions">
/// Specifies if notifications are sent for mentioned users and roles in the message <paramref name="text"/>.
/// If <c>null</c>, all mentioned roles and users will be notified.
/// </param>
/// <param name="components">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>
/// <param name="embeds">A array of <see cref="Embed"/>s to send with this response. Max 10.</param>
/// <param name="flags">A message flag to be applied to the sent message, only <see cref="MessageFlags.SuppressEmbeds"/> is permitted.</param>
/// <returns>
/// A task that represents the asynchronous creation operation.
/// </returns>
Task<IThreadChannel> CreatePostWithFileAsync(string title, string filePath, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, bool isSpoiler = false,
AllowedMentions allowedMentions = null, MessageComponent components = null,
ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None);

/// <summary>
/// Creates a new post (thread) within the forum.
/// </summary>
/// <param name="title">The title of the post.</param>
/// <param name="stream">The <see cref="Stream" /> of the file to be sent.</param>
/// <param name="filename">The name of the attachment.</param>
/// <param name="archiveDuration">The archive duration of the post.</param>
/// <param name="slowmode">The slowmode for the posts thread.</param>
/// <param name="text">The message to be sent.</param>
/// <param name="embed">The <see cref="Discord.EmbedType.Rich"/> <see cref="Embed"/> to be sent.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <param name="isSpoiler">Whether the message attachment should be hidden as a spoiler.</param>
/// <param name="allowedMentions">
/// Specifies if notifications are sent for mentioned users and roles in the message <paramref name="text"/>.
/// If <c>null</c>, all mentioned roles and users will be notified.
/// </param>
/// <param name="components">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>
/// <param name="embeds">A array of <see cref="Embed"/>s to send with this response. Max 10.</param>
/// <param name="flags">A message flag to be applied to the sent message, only <see cref="MessageFlags.SuppressEmbeds"/> is permitted.</param>
/// <returns>
/// A task that represents the asynchronous creation operation.
/// </returns>
public Task<IThreadChannel> CreatePostWithFileAsync(string title, Stream stream, string filename, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, bool isSpoiler = false,
AllowedMentions allowedMentions = null, MessageComponent components = null,
ISticker[] stickers = null, Embed[] embeds = null,MessageFlags flags = MessageFlags.None);

/// <summary>
/// Creates a new post (thread) within the forum.
/// </summary>
/// <param name="title">The title of the post.</param>
/// <param name="attachment">The attachment containing the file and description.</param>
/// <param name="archiveDuration">The archive duration of the post.</param>
/// <param name="slowmode">The slowmode for the posts thread.</param>
/// <param name="text">The message to be sent.</param>
/// <param name="embed">The <see cref="Discord.EmbedType.Rich"/> <see cref="Embed"/> to be sent.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <param name="allowedMentions">
/// Specifies if notifications are sent for mentioned users and roles in the message <paramref name="text"/>.
/// If <c>null</c>, all mentioned roles and users will be notified.
/// </param>
/// <param name="components">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>
/// <param name="embeds">A array of <see cref="Embed"/>s to send with this response. Max 10.</param>
/// <param name="flags">A message flag to be applied to the sent message, only <see cref="MessageFlags.SuppressEmbeds"/> is permitted.</param>
/// <returns>
/// A task that represents the asynchronous creation operation.
/// </returns>
public Task<IThreadChannel> CreatePostWithFileAsync(string title, FileAttachment attachment, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None);

/// <summary>
/// Creates a new post (thread) within the forum.
/// </summary>
/// <param name="title">The title of the post.</param>
/// <param name="attachments">A collection of attachments to upload.</param>
/// <param name="archiveDuration">The archive duration of the post.</param>
/// <param name="slowmode">The slowmode for the posts thread.</param>
/// <param name="text">The message to be sent.</param>
/// <param name="embed">The <see cref="Discord.EmbedType.Rich"/> <see cref="Embed"/> to be sent.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <param name="allowedMentions">
/// Specifies if notifications are sent for mentioned users and roles in the message <paramref name="text"/>.
/// If <c>null</c>, all mentioned roles and users will be notified.
/// </param>
/// <param name="components">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>
/// <param name="embeds">A array of <see cref="Embed"/>s to send with this response. Max 10.</param>
/// <param name="flags">A message flag to be applied to the sent message, only <see cref="MessageFlags.SuppressEmbeds"/> is permitted.</param>
/// <returns>
/// A task that represents the asynchronous creation operation.
/// </returns>
Task<IThreadChannel> CreatePostAsync(string title, ThreadArchiveDuration archiveDuration, Message message, int? slowmode = null, RequestOptions options = null);
public Task<IThreadChannel> CreatePostWithFilesAsync(string title, IEnumerable<FileAttachment> attachments, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None);

/// <summary>
/// Gets a collection of active threads within this forum channel.


+ 0
- 74
src/Discord.Net.Core/Entities/Messages/Message.cs View File

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

namespace Discord
{
/// <summary>
/// Represents a message created by a <see cref="MessageBuilder"/> that can be sent to a channel.
/// </summary>
public sealed class Message
{
/// <summary>
/// Gets the content of the message.
/// </summary>
public string Content { get; }

/// <summary>
/// Gets whether or not this message should be read by a text-to-speech engine.
/// </summary>
public bool IsTTS { get; }

/// <summary>
/// Gets a collection of embeds sent along with this message.
/// </summary>
public IReadOnlyCollection<Embed> Embeds { get; }

/// <summary>
/// Gets the allowed mentions for this message.
/// </summary>
public AllowedMentions AllowedMentions { get; }

/// <summary>
/// Gets the message reference (reply to) for this message.
/// </summary>
public MessageReference MessageReference { get; }

/// <summary>
/// Gets the components of this message.
/// </summary>
public MessageComponent Components { get; }

/// <summary>
/// Gets a collection of sticker ids that will be sent with this message.
/// </summary>
public IReadOnlyCollection<ulong> StickerIds { get; }

/// <summary>
/// Gets a collection of files sent with this message.
/// </summary>
public IReadOnlyCollection<FileAttachment> Attachments { get; }

/// <summary>
/// Gets the message flags for this message.
/// </summary>
public MessageFlags Flags { get; }

internal Message(string content, bool istts, IReadOnlyCollection<Embed> embeds, AllowedMentions allowedMentions,
MessageReference messagereference, MessageComponent components, IReadOnlyCollection<ulong> stickerIds,
IReadOnlyCollection<FileAttachment> attachments, MessageFlags flags)
{
Content = content;
IsTTS = istts;
Embeds = embeds;
AllowedMentions = allowedMentions;
MessageReference = messagereference;
Components = components;
StickerIds = stickerIds;
Attachments = attachments;
Flags = flags;
}
}
}

+ 0
- 220
src/Discord.Net.Core/Entities/Messages/MessageBuilder.cs View File

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

namespace Discord
{
/// <summary>
/// Represents a generic message builder that can build <see cref="Message"/>s.
/// </summary>
public class MessageBuilder
{
private string _content;
private List<ISticker> _stickers;
private List<EmbedBuilder> _embeds;

/// <summary>
/// Gets or sets the content of this message
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">The content is bigger than the <see cref="DiscordConfig.MaxMessageSize"/>.</exception>
public string Content
{
get => _content;
set
{
if (_content?.Length > DiscordConfig.MaxMessageSize)
throw new ArgumentOutOfRangeException(nameof(value), $"Message size must be less than or equal to {DiscordConfig.MaxMessageSize} characters");

_content = value;
}
}

/// <summary>
/// Gets or sets whether or not this message is TTS.
/// </summary>
public bool IsTTS { get; set; }

/// <summary>
/// Gets or sets the embeds of this message.
/// </summary>
public List<EmbedBuilder> Embeds
{
get
{
if (_embeds == null)
_embeds = new();
return _embeds;
}
set
{
if (value?.Count > DiscordConfig.MaxEmbedsPerMessage)
throw new ArgumentOutOfRangeException(nameof(value), $"Embed count must be less than or equal to {DiscordConfig.MaxEmbedsPerMessage}");

_embeds = value;
}
}

/// <summary>
/// Gets or sets the allowed mentions of this message.
/// </summary>
public AllowedMentions AllowedMentions { get; set; }

/// <summary>
/// Gets or sets the message reference (reply to) of this message.
/// </summary>
public MessageReference MessageReference { get; set; }

/// <summary>
/// Gets or sets the components of this message.
/// </summary>
public ComponentBuilder Components { get; set; } = new();

/// <summary>
/// Gets or sets the stickers sent with this message.
/// </summary>
public List<ISticker> Stickers
{
get => _stickers;
set
{
if (value?.Count > DiscordConfig.MaxStickersPerMessage)
throw new ArgumentOutOfRangeException(nameof(value), $"Sticker count must be less than or equal to {DiscordConfig.MaxStickersPerMessage}");

_stickers = value;
}
}

/// <summary>
/// Gets or sets the files sent with this message.
/// </summary>
public List<FileAttachment> Files { get; set; } = new();

/// <summary>
/// Gets or sets the message flags.
/// </summary>
public MessageFlags Flags { get; set; }

/// <summary>
/// Sets the <see cref="Content"/> of this message.
/// </summary>
/// <param name="content">The content of the message.</param>
/// <returns>The current builder.</returns>
public MessageBuilder WithContent(string content)
{
Content = content;
return this;
}

/// <summary>
/// Sets the <see cref="IsTTS"/> of this message.
/// </summary>
/// <param name="isTTS">whether or not this message is tts.</param>
/// <returns>The current builder.</returns>
public MessageBuilder WithTTS(bool isTTS)
{
IsTTS = isTTS;
return this;
}

public MessageBuilder WithEmbeds(params EmbedBuilder[] embeds)
{
Embeds = new(embeds);
return this;
}

public MessageBuilder AddEmbed(EmbedBuilder embed)
{
if (_embeds?.Count >= DiscordConfig.MaxEmbedsPerMessage)
throw new ArgumentOutOfRangeException(nameof(embed.Length), $"A message can only contain a maximum of {DiscordConfig.MaxEmbedsPerMessage} embeds");

_embeds ??= new();

_embeds.Add(embed);

return this;
}

public MessageBuilder WithAllowedMentions(AllowedMentions allowedMentions)
{
AllowedMentions = allowedMentions;
return this;
}

public MessageBuilder WithMessageReference(MessageReference reference)
{
MessageReference = reference;
return this;
}

public MessageBuilder WithMessageReference(IMessage message)
{
if (message != null)
MessageReference = new MessageReference(message.Id, message.Channel?.Id, ((IGuildChannel)message.Channel)?.GuildId);
return this;
}

public MessageBuilder WithComponentBuilder(ComponentBuilder builder)
{
Components = builder;
return this;
}

public MessageBuilder WithButton(ButtonBuilder button, int row = 0)
{
Components ??= new();
Components.WithButton(button, row);
return this;
}

public MessageBuilder WithButton(
string label = null,
string customId = null,
ButtonStyle style = ButtonStyle.Primary,
IEmote emote = null,
string url = null,
bool disabled = false,
int row = 0)
{
Components ??= new();
Components.WithButton(label, customId, style, emote, url, disabled, row);
return this;
}

public MessageBuilder WithSelectMenu(SelectMenuBuilder menu, int row = 0)
{
Components ??= new();
Components.WithSelectMenu(menu, row);
return this;
}

public MessageBuilder WithSelectMenu(string customId, List<SelectMenuOptionBuilder> options,
string placeholder = null, int minValues = 1, int maxValues = 1, bool disabled = false, int row = 0)
{
Components ??= new();
Components.WithSelectMenu(customId, options, placeholder, minValues, maxValues, disabled, row);
return this;
}

public Message Build()
{
var embeds = _embeds != null && _embeds.Count > 0
? _embeds.Select(x => x.Build()).ToImmutableArray()
: ImmutableArray<Embed>.Empty;

return new Message(
_content,
IsTTS,
embeds,
AllowedMentions,
MessageReference,
Components?.Build(),
_stickers != null && _stickers.Any() ? _stickers.Select(x => x.Id).ToImmutableArray() : ImmutableArray<ulong>.Empty,
Files?.ToImmutableArray() ?? ImmutableArray<FileAttachment>.Empty,
Flags
);
}
}
}

+ 33
- 0
src/Discord.Net.Rest/API/Common/ForumThreadMessage.cs View File

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

namespace Discord.API
{
internal class ForumThreadMessage
{
[JsonProperty("content")]
public Optional<string> Content { get; set; }

[JsonProperty("nonce")]
public Optional<string> Nonce { get; set; }

[JsonProperty("embeds")]
public Optional<Embed[]> Embeds { get; set; }

[JsonProperty("allowed_mentions")]
public Optional<AllowedMentions> AllowedMentions { get; set; }

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

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

[JsonProperty("flags")]
public Optional<MessageFlags> Flags { get; set; }
}
}

+ 13
- 11
src/Discord.Net.Rest/API/Rest/CreateMultipartPostAsync.cs View File

@@ -22,7 +22,6 @@ namespace Discord.API.Rest


public Optional<string> Content { get; set; }
public Optional<bool> IsTTS { get; set; }
public Optional<Embed[]> Embeds { get; set; }
public Optional<AllowedMentions> AllowedMentions { get; set; }
public Optional<ActionRowComponent[]> MessageComponent { get; set; }
@@ -39,26 +38,27 @@ namespace Discord.API.Rest
var d = new Dictionary<string, object>();

var payload = new Dictionary<string, object>();
var message = new Dictionary<string, object>();

payload["title"] = Title;
payload["name"] = Title;
payload["auto_archive_duration"] = ArchiveDuration;

if (Slowmode.IsSpecified)
payload["rate_limit_per_user"] = Slowmode.Value;

// message
if (Content.IsSpecified)
payload["content"] = Content.Value;
if (IsTTS.IsSpecified)
payload["tts"] = IsTTS.Value;
message["content"] = Content.Value;
if (Embeds.IsSpecified)
payload["embeds"] = Embeds.Value;
message["embeds"] = Embeds.Value;
if (AllowedMentions.IsSpecified)
payload["allowed_mentions"] = AllowedMentions.Value;
message["allowed_mentions"] = AllowedMentions.Value;
if (MessageComponent.IsSpecified)
payload["components"] = MessageComponent.Value;
message["components"] = MessageComponent.Value;
if (Stickers.IsSpecified)
payload["sticker_ids"] = Stickers.Value;
message["sticker_ids"] = Stickers.Value;
if (Flags.IsSpecified)
payload["flags"] = Flags.Value;
message["flags"] = Flags.Value;

List<object> attachments = new();

@@ -79,7 +79,9 @@ namespace Discord.API.Rest
});
}

payload["attachments"] = attachments;
message["attachments"] = attachments;

payload["message"] = message;

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


+ 2
- 21
src/Discord.Net.Rest/API/Rest/CreatePostParams.cs View File

@@ -19,26 +19,7 @@ namespace Discord.API.Rest
[JsonProperty("rate_limit_per_user")]
public Optional<int?> Slowmode { get; set; }

// message
[JsonProperty("content")]
public string Content { get; set; }

[JsonProperty("tts")]
public Optional<bool> IsTTS { get; set; }

[JsonProperty("embeds")]
public Optional<Embed[]> Embeds { get; set; }

[JsonProperty("allowed_mentions")]
public Optional<AllowedMentions> AllowedMentions { get; set; }

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

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

[JsonProperty("flags")]
public Optional<MessageFlags> Flags { get; set; }
[JsonProperty("message")]
public ForumThreadMessage Message { get; set; }
}
}

+ 131
- 0
src/Discord.Net.Rest/Entities/Channels/RestForumChannel.cs View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Model = Discord.API.Channel;

namespace Discord.Rest
{
/// <summary>
/// Represents a REST-based forum channel in a guild.
/// </summary>
public class RestForumChannel : RestGuildChannel, IForumChannel
{
/// <inheritdoc/>
public bool IsNsfw { get; private set; }

/// <inheritdoc/>
public string Topic { get; private set; }

/// <inheritdoc/>
public ThreadArchiveDuration DefaultAutoArchiveDuration { get; private set; }

/// <inheritdoc/>
public IReadOnlyCollection<ForumTag> Tags { get; private set; }

/// <inheritdoc/>
public string Mention => MentionUtils.MentionChannel(Id);

internal RestForumChannel(BaseDiscordClient client, IGuild guild, ulong id)
: base(client, guild, id)
{

}

internal new static RestStageChannel Create(BaseDiscordClient discord, IGuild guild, Model model)
{
var entity = new RestStageChannel(discord, guild, model.Id);
entity.Update(model);
return entity;
}

internal override void Update(Model model)
{
base.Update(model);
IsNsfw = model.Nsfw.GetValueOrDefault(false);
Topic = model.Topic.GetValueOrDefault();
DefaultAutoArchiveDuration = model.AutoArchiveDuration.GetValueOrDefault(ThreadArchiveDuration.OneDay);

Tags = model.ForumTags.GetValueOrDefault(Array.Empty<API.ForumTags>()).Select(
x => new ForumTag(x.Id, x.Name, x.EmojiId.GetValueOrDefault(null), x.EmojiName.GetValueOrDefault())
).ToImmutableArray();
}

/// <inheritdoc cref="IForumChannel.CreatePostAsync(string, ThreadArchiveDuration, int?, string, Embed, RequestOptions, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
public Task<RestThreadChannel> CreatePostAsync(string title, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay, int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
=> ThreadHelper.CreatePostAsync(this, Discord, title, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags);

/// <inheritdoc cref="IForumChannel.CreatePostWithFileAsync(string, string, ThreadArchiveDuration, int?, string, Embed, RequestOptions, bool, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
public async Task<RestThreadChannel> CreatePostWithFileAsync(string title, string filePath, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, bool isSpoiler = false,
AllowedMentions allowedMentions = null, MessageComponent components = null,
ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
{
using var file = new FileAttachment(filePath, isSpoiler: isSpoiler);
return await ThreadHelper.CreatePostAsync(this, Discord, title, new FileAttachment[] { file }, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
}

/// <inheritdoc cref="IForumChannel.CreatePostWithFileAsync(string, Stream, string, ThreadArchiveDuration, int?, string, Embed, RequestOptions, bool, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
public async Task<RestThreadChannel> CreatePostWithFileAsync(string title, Stream stream, string filename, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, bool isSpoiler = false,
AllowedMentions allowedMentions = null, MessageComponent components = null,
ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
{
using var file = new FileAttachment(stream, filename, isSpoiler: isSpoiler);
return await ThreadHelper.CreatePostAsync(this, Discord, title, new FileAttachment[] { file }, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
}

/// <inheritdoc cref="IForumChannel.CreatePostWithFileAsync(string, FileAttachment, ThreadArchiveDuration, int?, string, Embed, RequestOptions, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
public Task<RestThreadChannel> CreatePostWithFileAsync(string title, FileAttachment attachment, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
=> ThreadHelper.CreatePostAsync(this, Discord, title, new FileAttachment[] { attachment }, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags);

/// <inheritdoc cref="IForumChannel.CreatePostWithFilesAsync(string, IEnumerable{FileAttachment}, ThreadArchiveDuration, int?, string, Embed, RequestOptions, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
public Task<RestThreadChannel> CreatePostWithFilesAsync(string title, IEnumerable<FileAttachment> attachments, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
=> ThreadHelper.CreatePostAsync(this, Discord, title, attachments, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags);

/// <inheritdoc cref="IForumChannel.GetActiveThreadsAsync(RequestOptions)"/>
public Task<IReadOnlyCollection<RestThreadChannel>> GetActiveThreadsAsync(RequestOptions options = null)
=> ThreadHelper.GetActiveThreadsAsync(Guild, Discord, options);

/// <inheritdoc cref="IForumChannel.GetJoinedPrivateArchivedThreadsAsync(int?, DateTimeOffset?, RequestOptions)"/>
public Task<IReadOnlyCollection<RestThreadChannel>> GetJoinedPrivateArchivedThreadsAsync(int? limit = null, DateTimeOffset? before = null, RequestOptions options = null)
=> ThreadHelper.GetJoinedPrivateArchivedThreadsAsync(this, Discord, limit, before, options);

/// <inheritdoc cref="IForumChannel.GetPrivateArchivedThreadsAsync(int?, DateTimeOffset?, RequestOptions)"/>
public Task<IReadOnlyCollection<RestThreadChannel>> GetPrivateArchivedThreadsAsync(int? limit = null, DateTimeOffset? before = null, RequestOptions options = null)
=> ThreadHelper.GetPrivateArchivedThreadsAsync(this, Discord, limit, before, options);

/// <inheritdoc cref="IForumChannel.GetPublicArchivedThreadsAsync(int?, DateTimeOffset?, RequestOptions)"/>
public Task<IReadOnlyCollection<RestThreadChannel>> GetPublicArchivedThreadsAsync(int? limit = null, DateTimeOffset? before = null, RequestOptions options = null)
=> ThreadHelper.GetPublicArchivedThreadsAsync(this, Discord, limit, before, options);

#region IForumChannel
async Task<IReadOnlyCollection<IThreadChannel>> IForumChannel.GetActiveThreadsAsync(RequestOptions options)
=> await GetActiveThreadsAsync(options).ConfigureAwait(false);
async Task<IReadOnlyCollection<IThreadChannel>> IForumChannel.GetPublicArchivedThreadsAsync(int? limit, DateTimeOffset? before, RequestOptions options)
=> await GetPublicArchivedThreadsAsync(limit, before, options).ConfigureAwait(false);
async Task<IReadOnlyCollection<IThreadChannel>> IForumChannel.GetPrivateArchivedThreadsAsync(int? limit, DateTimeOffset? before, RequestOptions options)
=> await GetPrivateArchivedThreadsAsync(limit, before, options).ConfigureAwait(false);
async Task<IReadOnlyCollection<IThreadChannel>> IForumChannel.GetJoinedPrivateArchivedThreadsAsync(int? limit, DateTimeOffset? before, RequestOptions options)
=> await GetJoinedPrivateArchivedThreadsAsync(limit, before, options).ConfigureAwait(false);
async Task<IThreadChannel> IForumChannel.CreatePostAsync(string title, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
=> await CreatePostAsync(title, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
async Task<IThreadChannel> IForumChannel.CreatePostWithFileAsync(string title, string filePath, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
=> await CreatePostWithFileAsync(title, filePath, archiveDuration, slowmode, text, embed, options, isSpoiler, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
async Task<IThreadChannel> IForumChannel.CreatePostWithFileAsync(string title, Stream stream, string filename, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
=> await CreatePostWithFileAsync(title, stream, filename, archiveDuration, slowmode, text, embed, options, isSpoiler, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
async Task<IThreadChannel> IForumChannel.CreatePostWithFileAsync(string title, FileAttachment attachment, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
=> await CreatePostWithFileAsync(title, attachment, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
async Task<IThreadChannel> IForumChannel.CreatePostWithFilesAsync(string title, IEnumerable<FileAttachment> attachments, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
=> await CreatePostWithFilesAsync(title, attachments, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags);

#endregion
}
}

+ 1
- 0
src/Discord.Net.Rest/Entities/Channels/RestGuildChannel.cs View File

@@ -39,6 +39,7 @@ namespace Discord.Rest
ChannelType.Text => RestTextChannel.Create(discord, guild, model),
ChannelType.Voice => RestVoiceChannel.Create(discord, guild, model),
ChannelType.Stage => RestStageChannel.Create(discord, guild, model),
ChannelType.Forum => RestForumChannel.Create(discord, guild, model),
ChannelType.Category => RestCategoryChannel.Create(discord, guild, model),
ChannelType.PublicThread or ChannelType.PrivateThread or ChannelType.NewsThread => RestThreadChannel.Create(discord, guild, model),
_ => new RestGuildChannel(discord, guild, model.Id),


+ 97
- 32
src/Discord.Net.Rest/Entities/Channels/ThreadHelper.cs View File

@@ -103,47 +103,112 @@ namespace Discord.Rest
return RestThreadUser.Create(client, channel.Guild, model, channel);
}

public static async Task<RestThreadChannel> CreatePostAsync(IForumChannel channel, BaseDiscordClient client, string title, ThreadArchiveDuration archiveDuration, Message message, int? slowmode = null, RequestOptions options = null)
public static async Task<RestThreadChannel> CreatePostAsync(IForumChannel channel, BaseDiscordClient client, string title, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay, int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
{
Model model;
embeds ??= Array.Empty<Embed>();
if (embed != null)
embeds = new[] { embed }.Concat(embeds).ToArray();

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(embeds.Length, 10, nameof(embeds), "A max of 10 embeds are allowed.");

if (message.Attachments?.Any() ?? false)
// check that user flag and user Id list are exclusive, same with role flag and role Id list
if (allowedMentions != null && allowedMentions.AllowedTypes.HasValue)
{
var args = new CreateMultipartPostAsync(message.Attachments.ToArray())
if (allowedMentions.AllowedTypes.Value.HasFlag(AllowedMentionTypes.Users) &&
allowedMentions.UserIds != null && allowedMentions.UserIds.Count > 0)
{
AllowedMentions = message.AllowedMentions.ToModel(),
ArchiveDuration = archiveDuration,
Content = message.Content,
Embeds = message.Embeds.Any() ? message.Embeds.Select(x => x.ToModel()).ToArray() : Optional<API.Embed[]>.Unspecified,
Flags = message.Flags,
IsTTS = message.IsTTS,
MessageComponent = message.Components?.Components?.Any() ?? false ? message.Components.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional<API.ActionRowComponent[]>.Unspecified,
Slowmode = slowmode,
Stickers = message.StickerIds?.Any() ?? false ? message.StickerIds.ToArray() : Optional<ulong[]>.Unspecified,
Title = title
};

model = await client.ApiClient.CreatePostAsync(channel.Id, args, options).ConfigureAwait(false);
throw new ArgumentException("The Users flag is mutually exclusive with the list of User Ids.", nameof(allowedMentions));
}

if (allowedMentions.AllowedTypes.Value.HasFlag(AllowedMentionTypes.Roles) &&
allowedMentions.RoleIds != null && allowedMentions.RoleIds.Count > 0)
{
throw new ArgumentException("The Roles flag is mutually exclusive with the list of Role Ids.", nameof(allowedMentions));
}
}
else

if (stickers != null)
{
var args = new CreatePostParams()
Preconditions.AtMost(stickers.Length, 3, nameof(stickers), "A max of 3 stickers are allowed.");
}


if (flags is not MessageFlags.None and not MessageFlags.SuppressEmbeds)
throw new ArgumentException("The only valid MessageFlags are SuppressEmbeds and none.", nameof(flags));

var args = new CreatePostParams()
{
Title = title,
ArchiveDuration = archiveDuration,
Slowmode = slowmode,
Message = new()
{
AllowedMentions = message.AllowedMentions.ToModel(),
ArchiveDuration = archiveDuration,
Content = message.Content,
Embeds = message.Embeds.Any() ? message.Embeds.Select(x => x.ToModel()).ToArray() : Optional<API.Embed[]>.Unspecified,
Flags = message.Flags,
IsTTS = message.IsTTS,
Components = message.Components?.Components?.Any() ?? false ? message.Components.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional<API.ActionRowComponent[]>.Unspecified,
Slowmode = slowmode,
Stickers = message.StickerIds?.Any() ?? false ? message.StickerIds.ToArray() : Optional<ulong[]>.Unspecified,
Title = title
};

model = await client.ApiClient.CreatePostAsync(channel.Id, args, options);
AllowedMentions = allowedMentions.ToModel(),
Content = text,
Embeds = embeds.Any() ? embeds.Select(x => x.ToModel()).ToArray() : Optional<API.Embed[]>.Unspecified,
Flags = flags,
Components = components?.Components?.Any() ?? false ? components.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.CreatePostAsync(channel.Id, args, options).ConfigureAwait(false);

return RestThreadChannel.Create(client, channel.Guild, model);
}

public static async Task<RestThreadChannel> CreatePostAsync(IForumChannel channel, BaseDiscordClient client, string title, IEnumerable<FileAttachment> attachments, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
{
embeds ??= Array.Empty<Embed>();
if (embed != null)
embeds = new[] { embed }.Concat(embeds).ToArray();

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(embeds.Length, 10, nameof(embeds), "A max of 10 embeds are allowed.");

// check that user flag and user Id list are exclusive, same with role flag and role Id list
if (allowedMentions != null && allowedMentions.AllowedTypes.HasValue)
{
if (allowedMentions.AllowedTypes.Value.HasFlag(AllowedMentionTypes.Users) &&
allowedMentions.UserIds != null && allowedMentions.UserIds.Count > 0)
{
throw new ArgumentException("The Users flag is mutually exclusive with the list of User Ids.", nameof(allowedMentions));
}

if (allowedMentions.AllowedTypes.Value.HasFlag(AllowedMentionTypes.Roles) &&
allowedMentions.RoleIds != null && allowedMentions.RoleIds.Count > 0)
{
throw new ArgumentException("The Roles flag is mutually exclusive with the list of Role Ids.", nameof(allowedMentions));
}
}

if (stickers != null)
{
Preconditions.AtMost(stickers.Length, 3, nameof(stickers), "A max of 3 stickers are allowed.");
}


if (flags is not MessageFlags.None and not MessageFlags.SuppressEmbeds)
throw new ArgumentException("The only valid MessageFlags are SuppressEmbeds and none.", nameof(flags));

var args = new CreateMultipartPostAsync(attachments.ToArray())
{
AllowedMentions = allowedMentions.ToModel(),
ArchiveDuration = archiveDuration,
Content = text,
Embeds = embeds.Any() ? embeds.Select(x => x.ToModel()).ToArray() : Optional<API.Embed[]>.Unspecified,
Flags = flags,
MessageComponent = components?.Components?.Any() ?? false ? components.Components.Select(x => new API.ActionRowComponent(x)).ToArray() : Optional<API.ActionRowComponent[]>.Unspecified,
Slowmode = slowmode,
Stickers = stickers?.Any() ?? false ? stickers.Select(x => x.Id).ToArray() : Optional<ulong[]>.Unspecified,
Title = title
};

var model = await client.ApiClient.CreatePostAsync(channel.Id, args, options);

return RestThreadChannel.Create(client, channel.Guild, model);
}
}


+ 48
- 6
src/Discord.Net.WebSocket/Entities/Channels/SocketForumChannel.cs View File

@@ -2,6 +2,7 @@ using Discord.Rest;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -45,14 +46,46 @@ namespace Discord.WebSocket
Topic = model.Topic.GetValueOrDefault();
DefaultAutoArchiveDuration = model.AutoArchiveDuration.GetValueOrDefault(ThreadArchiveDuration.OneDay);

Tags = model.ForumTags.GetValueOrDefault(new API.ForumTags[0]).Select(
Tags = model.ForumTags.GetValueOrDefault(Array.Empty<API.ForumTags>()).Select(
x => new ForumTag(x.Id, x.Name, x.EmojiId.GetValueOrDefault(null), x.EmojiName.GetValueOrDefault())
).ToImmutableArray();
}

/// <inheritdoc cref="IForumChannel.CreatePostAsync(string, ThreadArchiveDuration, Message, int?, RequestOptions)"/>
public Task<RestThreadChannel> CreatePostAsync(string title, ThreadArchiveDuration archiveDuration, Message message, int? slowmode = null, RequestOptions options = null)
=> ThreadHelper.CreatePostAsync(this, Discord, title, archiveDuration, message, slowmode, options);
/// <inheritdoc cref="IForumChannel.CreatePostAsync(string, ThreadArchiveDuration, int?, string, Embed, RequestOptions, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
public Task<RestThreadChannel> CreatePostAsync(string title, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay, int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null, MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
=> ThreadHelper.CreatePostAsync(this, Discord, title, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags);

/// <inheritdoc cref="IForumChannel.CreatePostWithFileAsync(string, string, ThreadArchiveDuration, int?, string, Embed, RequestOptions, bool, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
public async Task<RestThreadChannel> CreatePostWithFileAsync(string title, string filePath, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, bool isSpoiler = false,
AllowedMentions allowedMentions = null, MessageComponent components = null,
ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
{
using var file = new FileAttachment(filePath, isSpoiler: isSpoiler);
return await ThreadHelper.CreatePostAsync(this, Discord, title, new FileAttachment[] { file }, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
}

/// <inheritdoc cref="IForumChannel.CreatePostWithFileAsync(string, Stream, string, ThreadArchiveDuration, int?, string, Embed, RequestOptions, bool, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
public async Task<RestThreadChannel> CreatePostWithFileAsync(string title, Stream stream, string filename, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, bool isSpoiler = false,
AllowedMentions allowedMentions = null, MessageComponent components = null,
ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
{
using var file = new FileAttachment(stream, filename, isSpoiler: isSpoiler);
return await ThreadHelper.CreatePostAsync(this, Discord, title, new FileAttachment[] { file }, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
}

/// <inheritdoc cref="IForumChannel.CreatePostWithFileAsync(string, FileAttachment, ThreadArchiveDuration, int?, string, Embed, RequestOptions, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
public Task<RestThreadChannel> CreatePostWithFileAsync(string title, FileAttachment attachment, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
=> ThreadHelper.CreatePostAsync(this, Discord, title, new FileAttachment[] { attachment }, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags);

/// <inheritdoc cref="IForumChannel.CreatePostWithFilesAsync(string, IEnumerable{FileAttachment}, ThreadArchiveDuration, int?, string, Embed, RequestOptions, AllowedMentions, MessageComponent, ISticker[], Embed[], MessageFlags)"/>
public Task<RestThreadChannel> CreatePostWithFilesAsync(string title, IEnumerable<FileAttachment> attachments, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay,
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, AllowedMentions allowedMentions = null,
MessageComponent components = null, ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None)
=> ThreadHelper.CreatePostAsync(this, Discord, title, attachments, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags);

/// <inheritdoc cref="IForumChannel.GetActiveThreadsAsync(RequestOptions)"/>
public Task<IReadOnlyCollection<RestThreadChannel>> GetActiveThreadsAsync(RequestOptions options = null)
@@ -71,8 +104,6 @@ namespace Discord.WebSocket
=> ThreadHelper.GetPublicArchivedThreadsAsync(this, Discord, limit, before, options);

#region IForumChannel
async Task<IThreadChannel> IForumChannel.CreatePostAsync(string title, ThreadArchiveDuration archiveDuration, Message message, int? slowmode, RequestOptions options)
=> await CreatePostAsync(title, archiveDuration, message, slowmode, options).ConfigureAwait(false);
async Task<IReadOnlyCollection<IThreadChannel>> IForumChannel.GetActiveThreadsAsync(RequestOptions options)
=> await GetActiveThreadsAsync(options).ConfigureAwait(false);
async Task<IReadOnlyCollection<IThreadChannel>> IForumChannel.GetPublicArchivedThreadsAsync(int? limit, DateTimeOffset? before, RequestOptions options)
@@ -81,6 +112,17 @@ namespace Discord.WebSocket
=> await GetPrivateArchivedThreadsAsync(limit, before, options).ConfigureAwait(false);
async Task<IReadOnlyCollection<IThreadChannel>> IForumChannel.GetJoinedPrivateArchivedThreadsAsync(int? limit, DateTimeOffset? before, RequestOptions options)
=> await GetJoinedPrivateArchivedThreadsAsync(limit, before, options).ConfigureAwait(false);
async Task<IThreadChannel> IForumChannel.CreatePostAsync(string title, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
=> await CreatePostAsync(title, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
async Task<IThreadChannel> IForumChannel.CreatePostWithFileAsync(string title, string filePath, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
=> await CreatePostWithFileAsync(title, filePath, archiveDuration, slowmode, text, embed, options, isSpoiler, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
async Task<IThreadChannel> IForumChannel.CreatePostWithFileAsync(string title, Stream stream, string filename, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, bool isSpoiler, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
=> await CreatePostWithFileAsync(title, stream, filename, archiveDuration, slowmode, text, embed, options, isSpoiler, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
async Task<IThreadChannel> IForumChannel.CreatePostWithFileAsync(string title, FileAttachment attachment, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
=> await CreatePostWithFileAsync(title, attachment, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags).ConfigureAwait(false);
async Task<IThreadChannel> IForumChannel.CreatePostWithFilesAsync(string title, IEnumerable<FileAttachment> attachments, ThreadArchiveDuration archiveDuration, int? slowmode, string text, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageComponent components, ISticker[] stickers, Embed[] embeds, MessageFlags flags)
=> await CreatePostWithFilesAsync(title, attachments, archiveDuration, slowmode, text, embed, options, allowedMentions, components, stickers, embeds, flags);

#endregion
}
}

+ 9
- 1
src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs View File

@@ -705,7 +705,15 @@ namespace Discord.WebSocket
/// </returns>
public SocketThreadChannel GetThreadChannel(ulong id)
=> GetChannel(id) as SocketThreadChannel;

/// <summary>
/// Gets a forum channel in this guild.
/// </summary>
/// <param name="id">The snowflake identifier for the forum channel.</param>
/// <returns>
/// A forum channel associated with the specified <paramref name="id" />; <see langword="null"/> if none is found.
/// </returns>
public SocketForumChannel GetForumChannel(ulong id)
=> GetChannel(id) as SocketForumChannel;
/// <summary>
/// Gets a voice channel in this guild.
/// </summary>


Loading…
Cancel
Save