diff --git a/DisCatSharp/Net/Abstractions/ClientProperties.cs b/DisCatSharp/Net/Abstractions/ClientProperties.cs
index ada7dc8b7..79cec3f2b 100644
--- a/DisCatSharp/Net/Abstractions/ClientProperties.cs
+++ b/DisCatSharp/Net/Abstractions/ClientProperties.cs
@@ -1,113 +1,109 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Reflection;
using System.Runtime.InteropServices;
+using DisCatSharp.Entities;
+
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
///
/// Represents data for identify payload's client properties.
///
-internal sealed class ClientProperties
+internal sealed class ClientProperties : ObservableApiObject
{
- ///
- /// Gets or sets the discord client.
- ///
- [JsonIgnore]
- public BaseDiscordClient Discord { get; set; }
-
///
/// Gets the client's operating system.
///
[JsonProperty("os")]
public string OperatingSystem
{
get
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return "windows";
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
return "linux";
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
return "osx";
var plat = RuntimeInformation.OSDescription.ToLowerInvariant();
if (plat.Contains("freebsd"))
return "freebsd";
else if (plat.Contains("openbsd"))
return "openbsd";
else if (plat.Contains("netbsd"))
return "netbsd";
else if (plat.Contains("dragonfly"))
return "dragonflybsd";
else if (plat.Contains("miros bsd") || plat.Contains("mirbsd"))
return "miros bsd";
else if (plat.Contains("desktopbsd"))
return "desktopbsd";
else return plat.Contains("darwin") ? "osx" : plat.Contains("unix") ? "unix" : "toaster (unknown)";
}
}
///
/// Gets the client's browser.
///
[JsonProperty("browser")]
public string Browser
{
get
{
if (this.Discord.Configuration.MobileStatus)
return "Discord Android";
else
{
var a = typeof(DiscordClient).GetTypeInfo().Assembly;
var an = a.GetName();
return $"DisCatSharp {an.Version.ToString(4)}";
}
}
}
///
/// Gets the client's device.
///
[JsonProperty("device")]
public string Device
=> this.Browser;
///
/// Gets the client's referrer.
///
[JsonProperty("referrer")]
public string Referrer
=> "";
///
/// Gets the client's referring domain.
///
[JsonProperty("referring_domain")]
public string ReferringDomain
=> "";
}
diff --git a/DisCatSharp/Net/Abstractions/FollowedChannelAddPayload.cs b/DisCatSharp/Net/Abstractions/FollowedChannelAddPayload.cs
index 08a21090c..e05c1a9c3 100644
--- a/DisCatSharp/Net/Abstractions/FollowedChannelAddPayload.cs
+++ b/DisCatSharp/Net/Abstractions/FollowedChannelAddPayload.cs
@@ -1,37 +1,39 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
+using DisCatSharp.Entities;
+
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
///
/// Represents a followed channel add payload.
///
-internal sealed class FollowedChannelAddPayload
+internal sealed class FollowedChannelAddPayload : ObservableApiObject
{
///
/// Gets or sets the webhook channel id.
///
[JsonProperty("webhook_channel_id")]
public ulong WebhookChannelId { get; set; }
}
diff --git a/DisCatSharp/Net/Abstractions/Rest/RestApplicationCommandPayloads.cs b/DisCatSharp/Net/Abstractions/Rest/RestApplicationCommandPayloads.cs
index 61aba03ca..e2c9a1307 100644
--- a/DisCatSharp/Net/Abstractions/Rest/RestApplicationCommandPayloads.cs
+++ b/DisCatSharp/Net/Abstractions/Rest/RestApplicationCommandPayloads.cs
@@ -1,282 +1,282 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Collections.Generic;
using DisCatSharp.Entities;
using DisCatSharp.Enums;
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
///
/// Represents a application command create payload.
///
-internal class RestApplicationCommandCreatePayload
+internal class RestApplicationCommandCreatePayload : ObservableApiObject
{
///
/// Gets the type.
///
[JsonProperty("type")]
public ApplicationCommandType Type { get; set; }
///
/// Gets the name.
///
[JsonProperty("name")]
public string Name { get; set; }
///
/// Gets the name localizations.
///
[JsonProperty("name_localizations", NullValueHandling = NullValueHandling.Ignore)]
public Optional> NameLocalizations { get; set; }
///
/// Gets the description.
///
[JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
public string Description { get; set; }
///
/// Gets the description localizations.
///
[JsonProperty("description_localizations", NullValueHandling = NullValueHandling.Ignore)]
public Optional> DescriptionLocalizations { get; set; }
///
/// Gets the options.
///
[JsonProperty("options", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable Options { get; set; }
///
/// Whether the command is allowed for everyone.
///
[JsonProperty("default_permission", NullValueHandling = NullValueHandling.Include)]
public bool? DefaultPermission { get; set; } = null;
///
/// The command needed permissions.
///
[JsonProperty("default_member_permissions", NullValueHandling = NullValueHandling.Include)]
public Permissions? DefaultMemberPermission { get; set; }
///
/// Whether the command is allowed for dms.
///
[JsonProperty("dm_permission", NullValueHandling = NullValueHandling.Include)]
public bool? DmPermission { get; set; }
///
/// Whether the command is marked as NSFW.
///
[JsonProperty("nsfw", NullValueHandling = NullValueHandling.Ignore)]
public bool Nsfw { get; set; }
}
///
/// Represents a application command edit payload.
///
-internal class RestApplicationCommandEditPayload
+internal class RestApplicationCommandEditPayload : ObservableApiObject
{
///
/// Gets the name.
///
[JsonProperty("name")]
public Optional Name { get; set; }
///
/// Gets the name localizations.
///
[JsonProperty("name_localizations")]
public Optional> NameLocalizations { get; set; }
///
/// Gets the description.
///
[JsonProperty("description")]
public Optional Description { get; set; }
///
/// Gets the description localizations.
///
[JsonProperty("description_localizations")]
public Optional> DescriptionLocalizations { get; set; }
///
/// Gets the options.
///
[JsonProperty("options", NullValueHandling = NullValueHandling.Ignore)]
public Optional> Options { get; set; }
///
/// The command needed permissions.
///
[JsonProperty("default_member_permissions", NullValueHandling = NullValueHandling.Include)]
public Optional DefaultMemberPermission { get; set; }
///
/// Whether the command is allowed for dms.
///
[JsonProperty("dm_permission", NullValueHandling = NullValueHandling.Include)]
public Optional DmPermission { get; set; }
///
/// Whether the command is marked as NSFW.
///
[JsonProperty("nsfw", NullValueHandling = NullValueHandling.Ignore)]
public Optional Nsfw { get; set; }
}
///
/// Represents a interaction response payload.
///
-internal class RestInteractionResponsePayload
+internal class RestInteractionResponsePayload : ObservableApiObject
{
///
/// Gets the type.
///
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
public InteractionResponseType Type { get; set; }
///
/// Gets the data.
///
[JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)]
public DiscordInteractionApplicationCommandCallbackData Data { get; set; }
///
/// Gets the attachments.
///
[JsonProperty("attachments", NullValueHandling = NullValueHandling.Ignore)]
public List Attachments { get; set; }
}
///
/// Represents a interaction response payload.
///
-internal class RestInteractionModalResponsePayload
+internal class RestInteractionModalResponsePayload : ObservableApiObject
{
///
/// Gets the type.
///
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
public InteractionResponseType Type { get; set; }
///
/// Gets the data.
///
[JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)]
public DiscordInteractionApplicationCommandModalCallbackData Data { get; set; }
}
///
/// Represents a followup message create payload.
///
-internal class RestFollowupMessageCreatePayload
+internal class RestFollowupMessageCreatePayload : ObservableApiObject
{
///
/// Gets the content.
///
[JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
public string Content { get; set; }
///
/// Get whether the message is tts.
///
[JsonProperty("tts", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsTts { get; set; }
///
/// Gets the embeds.
///
[JsonProperty("embeds", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable Embeds { get; set; }
///
/// Gets the mentions.
///
[JsonProperty("allowed_mentions", NullValueHandling = NullValueHandling.Ignore)]
public DiscordMentions Mentions { get; set; }
///
/// Gets the flags.
///
[JsonProperty("flags", NullValueHandling = NullValueHandling.Ignore)]
public MessageFlags? Flags { get; set; }
///
/// Gets the components.
///
[JsonProperty("components", NullValueHandling = NullValueHandling.Ignore)]
public IReadOnlyCollection Components { get; set; }
///
/// Gets attachments.
///
[JsonProperty("attachments", NullValueHandling = NullValueHandling.Ignore)]
public List Attachments { get; set; }
}
///
/// Represents a role connection metadata payload.
///
-internal class RestApplicationRoleConnectionMetadataPayload
+internal class RestApplicationRoleConnectionMetadataPayload : ObservableApiObject
{
///
/// Gets the metadata type.
///
[JsonProperty("type")]
public ApplicationRoleConnectionMetadataType Type { get; set; }
///
/// Gets the metadata key.
///
[JsonProperty("key")]
public string Key { get; set; }
///
/// Gets the metadata name.
///
[JsonProperty("name")]
public string Name { get; set; }
///
/// Gets the metadata description.
///
[JsonProperty("description")]
public string Description { get; set; }
///
/// Gets the metadata name translations.
///
[JsonProperty("name_localizations", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary NameLocalizations { get; set; }
///
/// Gets the metadata description localizations.
///
[JsonProperty("description_localizations", NullValueHandling = NullValueHandling.Ignore)]
public Dictionary DescriptionLocalizations { get; set; }
}
diff --git a/DisCatSharp/Net/Abstractions/Rest/RestApplicationPayloads.cs b/DisCatSharp/Net/Abstractions/Rest/RestApplicationPayloads.cs
index 7b11f3bfb..0c4dec13c 100644
--- a/DisCatSharp/Net/Abstractions/Rest/RestApplicationPayloads.cs
+++ b/DisCatSharp/Net/Abstractions/Rest/RestApplicationPayloads.cs
@@ -1,62 +1,62 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Collections.Generic;
using DisCatSharp.Entities;
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
-internal sealed class RestApplicationModifyPayload
+internal sealed class RestApplicationModifyPayload : ObservableApiObject
{
///
/// Gets or sets the description.
///
[JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
public Optional Description { get; set; }
///
/// Gets or sets the interactions endpoint url.
///
[JsonProperty("interactions_endpoint_url", NullValueHandling = NullValueHandling.Ignore)]
public Optional InteractionsEndpointUrl { get; set; }
///
/// Gets or sets the role connections verification url.
///
[JsonProperty("role_connections_verification_url", NullValueHandling = NullValueHandling.Ignore)]
public Optional RoleConnectionsVerificationUrl { get; set; }
///
/// Gets or sets the tags.
///
[JsonProperty("tags", NullValueHandling = NullValueHandling.Ignore)]
public Optional?> Tags { get; set; }
///
/// Gets or sets the icon base64.
///
[JsonProperty("icon")]
public Optional IconBase64 { get; set; }
}
diff --git a/DisCatSharp/Net/Abstractions/Rest/RestAutomodRuleModifyPayload.cs b/DisCatSharp/Net/Abstractions/Rest/RestAutomodRuleModifyPayload.cs
index fb30ac97d..7903adf07 100644
--- a/DisCatSharp/Net/Abstractions/Rest/RestAutomodRuleModifyPayload.cs
+++ b/DisCatSharp/Net/Abstractions/Rest/RestAutomodRuleModifyPayload.cs
@@ -1,57 +1,57 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Collections.Generic;
using DisCatSharp.Entities;
using DisCatSharp.Enums;
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
-internal class RestAutomodRuleModifyPayload
+internal class RestAutomodRuleModifyPayload : ObservableApiObject
{
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public Optional Name { get; set; }
[JsonProperty("event_type", NullValueHandling = NullValueHandling.Ignore)]
public Optional EventType { get; set; }
[JsonProperty("trigger_type", NullValueHandling = NullValueHandling.Ignore)]
public Optional TriggerType { get; set; }
[JsonProperty("trigger_metadata", NullValueHandling = NullValueHandling.Ignore)]
public Optional TriggerMetadata { get; set; }
[JsonProperty("actions", NullValueHandling = NullValueHandling.Ignore)]
public Optional> Actions { get; set; }
[JsonProperty("enabled", NullValueHandling = NullValueHandling.Ignore)]
public Optional Enabled { get; set; }
[JsonProperty("exempt_roles", NullValueHandling = NullValueHandling.Ignore)]
public Optional> ExemptRoles { get; set; }
[JsonProperty("exempt_channels", NullValueHandling = NullValueHandling.Ignore)]
public Optional> ExemptChannels { get; set; }
}
diff --git a/DisCatSharp/Net/Abstractions/Rest/RestChannelPayloads.cs b/DisCatSharp/Net/Abstractions/Rest/RestChannelPayloads.cs
index 874b98162..1d3dc6e78 100644
--- a/DisCatSharp/Net/Abstractions/Rest/RestChannelPayloads.cs
+++ b/DisCatSharp/Net/Abstractions/Rest/RestChannelPayloads.cs
@@ -1,582 +1,582 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Collections.Generic;
using DisCatSharp.Entities;
using DisCatSharp.Enums;
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
///
/// Represents a channel create payload.
///
-internal sealed class RestChannelCreatePayload
+internal sealed class RestChannelCreatePayload : ObservableApiObject
{
///
/// Gets or sets the name.
///
[JsonProperty("name")]
public string Name { get; set; }
///
/// Gets or sets the type.
///
[JsonProperty("type")]
public ChannelType Type { get; set; }
///
/// Gets or sets the parent.
///
[JsonProperty("parent_id", NullValueHandling = NullValueHandling.Ignore)]
public ulong? Parent { get; set; }
///
/// Gets or sets the topic.
///
[JsonProperty("topic")]
public Optional Topic { get; set; }
///
/// Gets or sets the template.
///
[JsonProperty("template")]
public Optional Template { get; set; }
///
/// Gets or sets the bitrate.
///
[JsonProperty("bitrate", NullValueHandling = NullValueHandling.Ignore)]
public int? Bitrate { get; set; }
///
/// Gets or sets the user limit.
///
[JsonProperty("user_limit", NullValueHandling = NullValueHandling.Ignore)]
public int? UserLimit { get; set; }
///
/// Gets or sets the permission overwrites.
///
[JsonProperty("permission_overwrites", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable PermissionOverwrites { get; set; }
///
/// Gets or sets a value indicating whether nsfw.
///
[JsonProperty("nsfw", NullValueHandling = NullValueHandling.Ignore)]
public bool? Nsfw { get; set; }
///
/// Gets or sets the per user rate limit.
///
[JsonProperty("rate_limit_per_user")]
public Optional PerUserRateLimit { get; set; }
[JsonProperty("default_thread_rate_limit_per_user", NullValueHandling = NullValueHandling.Ignore)]
public Optional PostCreateUserRateLimit { get; internal set; }
///
/// Gets or sets the quality mode.
///
[JsonProperty("video_quality_mode", NullValueHandling = NullValueHandling.Ignore)]
public VideoQualityMode? QualityMode { get; set; }
///
/// Gets or sets the default auto archive duration.
///
[JsonProperty("default_auto_archive_duration", NullValueHandling = NullValueHandling.Ignore)]
public Optional DefaultAutoArchiveDuration { get; set; }
///
/// Gets the default reaction emoji for forum posts.
///
[JsonProperty("default_reaction_emoji", NullValueHandling = NullValueHandling.Ignore)]
public Optional DefaultReactionEmoji { get; internal set; }
///
/// Gets the default forum post sort order
///
[JsonProperty("default_sort_order", NullValueHandling = NullValueHandling.Ignore)]
public Optional DefaultSortOrder { get; internal set; }
///
/// Gets or sets the channel flags.
///
[JsonProperty("flags", NullValueHandling = NullValueHandling.Include)]
public Optional Flags { internal get; set; }
}
///
/// Represents a channel modify payload.
///
-internal sealed class RestChannelModifyPayload
+internal sealed class RestChannelModifyPayload : ObservableApiObject
{
///
/// Gets or sets the name.
///
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; set; }
///
/// Gets or sets the type.
///
[JsonProperty("type")]
public Optional Type { get; set; }
///
/// Gets or sets the position.
///
[JsonProperty("position", NullValueHandling = NullValueHandling.Ignore)]
public int? Position { get; set; }
///
/// Gets or sets the topic.
///
[JsonProperty("topic")]
public Optional Topic { get; set; }
///
/// Gets or sets the template.
///
[JsonProperty("template")]
public Optional Template { get; set; }
///
/// Gets or sets a value indicating whether nsfw.
///
[JsonProperty("nsfw", NullValueHandling = NullValueHandling.Ignore)]
public bool? Nsfw { get; set; }
///
/// Gets or sets the parent.
///
[JsonProperty("parent_id")]
public Optional Parent { get; set; }
///
/// Gets or sets the bitrate.
///
[JsonProperty("bitrate", NullValueHandling = NullValueHandling.Ignore)]
public int? Bitrate { get; set; }
///
/// Gets or sets the user limit.
///
[JsonProperty("user_limit", NullValueHandling = NullValueHandling.Ignore)]
public Optional UserLimit { get; set; }
///
/// Gets or sets the per user rate limit.
///
[JsonProperty("rate_limit_per_user")]
public Optional PerUserRateLimit { get; set; }
[JsonProperty("default_thread_rate_limit_per_user", NullValueHandling = NullValueHandling.Ignore)]
public Optional PostCreateUserRateLimit { get; internal set; }
///
/// Gets or sets the rtc region.
///
[JsonProperty("rtc_region")]
public Optional RtcRegion { get; set; }
///
/// Gets or sets the quality mode.
///
[JsonProperty("video_quality_mode", NullValueHandling = NullValueHandling.Ignore)]
public VideoQualityMode? QualityMode { get; set; }
///
/// Gets or sets the default auto archive duration.
///
[JsonProperty("default_auto_archive_duration", NullValueHandling = NullValueHandling.Ignore)]
public Optional DefaultAutoArchiveDuration { get; set; }
///
/// Gets or sets the permission overwrites.
///
[JsonProperty("permission_overwrites", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable PermissionOverwrites { get; set; }
///
/// Gets the default reaction emoji for forum posts.
///
[JsonProperty("default_reaction_emoji", NullValueHandling = NullValueHandling.Ignore)]
public Optional DefaultReactionEmoji { get; internal set; }
///
/// Gets the default forum post sort order
///
[JsonProperty("default_sort_order", NullValueHandling = NullValueHandling.Ignore)]
public Optional DefaultSortOrder { get; internal set; }
///
/// Gets or sets the channel flags.
///
[JsonProperty("flags", NullValueHandling = NullValueHandling.Include)]
public Optional Flags { internal get; set; }
///
/// Gets or sets the available tags.
///
[JsonProperty("available_tags", NullValueHandling = NullValueHandling.Ignore)]
#pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
public Optional?> AvailableTags { internal get; set; }
#pragma warning restore CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
}
///
/// Represents a channel message edit payload.
///
-internal class RestChannelMessageEditPayload
+internal class RestChannelMessageEditPayload : ObservableApiObject
{
///
/// Gets or sets the content.
///
[JsonProperty("content", NullValueHandling = NullValueHandling.Include)]
public string Content { get; set; }
///
/// Gets or sets a value indicating whether has content.
///
[JsonIgnore]
public bool HasContent { get; set; }
///
/// Gets or sets the embeds.
///
[JsonProperty("embeds", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable Embeds { get; set; }
///
/// Gets or sets the mentions.
///
[JsonProperty("allowed_mentions", NullValueHandling = NullValueHandling.Ignore)]
public DiscordMentions Mentions { get; set; }
///
/// Gets or sets the attachments.
///
[JsonProperty("attachments", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable Attachments { get; set; }
///
/// Gets or sets the flags.
///
[JsonProperty("flags", NullValueHandling = NullValueHandling.Ignore)]
public MessageFlags? Flags { get; set; }
///
/// Gets or sets the components.
///
[JsonProperty("components", NullValueHandling = NullValueHandling.Ignore)]
public IReadOnlyCollection Components { get; set; }
///
/// Gets or sets a value indicating whether has embed.
///
[JsonIgnore]
public bool HasEmbed { get; set; }
///
/// Should serialize the content.
///
public bool ShouldSerializeContent()
=> this.HasContent;
///
/// Should serialize the embed.
///
public bool ShouldSerializeEmbed()
=> this.HasEmbed;
}
///
/// Represents a channel message create payload.
///
internal sealed class RestChannelMessageCreatePayload : RestChannelMessageEditPayload
{
///
/// Gets or sets a value indicating whether t t is s.
///
[JsonProperty("tts", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsTts { get; set; }
///
/// Gets or sets the stickers ids.
///
[JsonProperty("sticker_ids", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable StickersIds { get; set; }
///
/// Gets or sets the message reference.
///
[JsonProperty("message_reference", NullValueHandling = NullValueHandling.Ignore)]
public InternalDiscordMessageReference? MessageReference { get; set; }
}
///
/// Represents a channel message create multipart payload.
///
-internal sealed class RestChannelMessageCreateMultipartPayload
+internal sealed class RestChannelMessageCreateMultipartPayload : ObservableApiObject
{
///
/// Gets or sets the content.
///
[JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
public string Content { get; set; }
///
/// Gets or sets a value indicating whether t t is s.
///
[JsonProperty("tts", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsTts { get; set; }
///
/// Gets or sets the embeds.
///
[JsonProperty("embeds", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable Embeds { get; set; }
///
/// Gets or sets the mentions.
///
[JsonProperty("allowed_mentions", NullValueHandling = NullValueHandling.Ignore)]
public DiscordMentions Mentions { get; set; }
///
/// Gets or sets the message reference.
///
[JsonProperty("message_reference", NullValueHandling = NullValueHandling.Ignore)]
public InternalDiscordMessageReference? MessageReference { get; set; }
}
///
/// Represents a channel message bulk delete payload.
///
-internal sealed class RestChannelMessageBulkDeletePayload
+internal sealed class RestChannelMessageBulkDeletePayload : ObservableApiObject
{
///
/// Gets or sets the messages.
///
[JsonProperty("messages", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable Messages { get; set; }
}
///
/// Represents a channel invite create payload.
///
-internal sealed class RestChannelInviteCreatePayload
+internal sealed class RestChannelInviteCreatePayload : ObservableApiObject
{
///
/// Gets or sets the max age.
///
[JsonProperty("max_age", NullValueHandling = NullValueHandling.Ignore)]
public int MaxAge { get; set; }
///
/// Gets or sets the max uses.
///
[JsonProperty("max_uses", NullValueHandling = NullValueHandling.Ignore)]
public int MaxUses { get; set; }
///
/// Gets or sets the target type.
///
[JsonProperty("target_type", NullValueHandling = NullValueHandling.Ignore)]
public TargetType? TargetType { get; set; }
///
/// Gets or sets the target application.
///
[JsonProperty("target_application_id", NullValueHandling = NullValueHandling.Ignore)]
public ulong? TargetApplicationId { get; set; }
///
/// Gets or sets the target user id.
///
[JsonProperty("target_user_id", NullValueHandling = NullValueHandling.Ignore)]
public ulong? TargetUserId { get; set; }
///
/// Gets or sets a value indicating whether temporary.
///
[JsonProperty("temporary", NullValueHandling = NullValueHandling.Ignore)]
public bool Temporary { get; set; }
///
/// Gets or sets a value indicating whether unique.
///
[JsonProperty("unique", NullValueHandling = NullValueHandling.Ignore)]
public bool Unique { get; set; }
}
///
/// Represents a channel permission edit payload.
///
-internal sealed class RestChannelPermissionEditPayload
+internal sealed class RestChannelPermissionEditPayload : ObservableApiObject
{
///
/// Gets or sets the allow.
///
[JsonProperty("allow", NullValueHandling = NullValueHandling.Ignore)]
public Permissions Allow { get; set; }
///
/// Gets or sets the deny.
///
[JsonProperty("deny", NullValueHandling = NullValueHandling.Ignore)]
public Permissions Deny { get; set; }
///
/// Gets or sets the type.
///
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
public string Type { get; set; }
}
///
/// Represents a channel group dm recipient add payload.
///
internal sealed class RestChannelGroupDmRecipientAddPayload : IOAuth2Payload
{
///
/// Gets or sets the access token.
///
[JsonProperty("access_token")]
public string AccessToken { get; set; }
///
/// Gets or sets the nickname.
///
[JsonProperty("nick", NullValueHandling = NullValueHandling.Ignore)]
public string Nickname { get; set; }
}
///
/// The acknowledge payload.
///
-internal sealed class AcknowledgePayload
+internal sealed class AcknowledgePayload : ObservableApiObject
{
///
/// Gets or sets the token.
///
[JsonProperty("token", NullValueHandling = NullValueHandling.Include)]
public string Token { get; set; }
}
///
/// Represents a thread channel create payload.
///
-internal sealed class RestThreadChannelCreatePayload
+internal sealed class RestThreadChannelCreatePayload : ObservableApiObject
{
///
/// Gets or sets the name.
///
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)]
public RestChannelMessageCreatePayload Message { get; set; }
///
/// Gets or sets the auto archive duration.
///
[JsonProperty("auto_archive_duration", NullValueHandling = NullValueHandling.Ignore)]
public Optional AutoArchiveDuration { get; set; }
///
/// Gets or sets the rate limit per user.
///
[JsonProperty("rate_limit_per_user")]
public int? PerUserRateLimit { get; set; }
///
/// Gets or sets the thread type.
///
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
public ChannelType? Type { get; set; }
///
/// Gets or sets the applied tags.
///
[JsonProperty("applied_tags", NullValueHandling = NullValueHandling.Ignore)]
public Optional> AppliedTags { internal get; set; }
}
///
/// Represents a thread channel modify payload.
///
-internal sealed class RestThreadChannelModifyPayload
+internal sealed class RestThreadChannelModifyPayload : ObservableApiObject
{
///
/// Gets or sets the name.
///
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; set; }
///
/// Gets or sets the archived.
///
[JsonProperty("archived", NullValueHandling = NullValueHandling.Ignore)]
public Optional Archived { get; set; }
///
/// Gets or sets the auto archive duration.
///
[JsonProperty("auto_archive_duration", NullValueHandling = NullValueHandling.Ignore)]
public Optional AutoArchiveDuration { get; set; }
///
/// Gets or sets the locked.
///
[JsonProperty("locked", NullValueHandling = NullValueHandling.Ignore)]
public Optional Locked { get; set; }
///
/// Gets or sets the per user rate limit.
///
[JsonProperty("rate_limit_per_user", NullValueHandling = NullValueHandling.Ignore)]
public Optional PerUserRateLimit { get; set; }
///
/// Gets or sets the thread's invitable state.
///
[JsonProperty("invitable", NullValueHandling = NullValueHandling.Ignore)]
public Optional Invitable { internal get; set; }
///
/// Gets or sets the applied tags.
///
[JsonProperty("applied_tags", NullValueHandling = NullValueHandling.Ignore)]
public Optional> AppliedTags { internal get; set; }
///
/// Gets or sets the channel flags.
///
[JsonProperty("flags", NullValueHandling = NullValueHandling.Include)]
public Optional Flags { internal get; set; }
}
diff --git a/DisCatSharp/Net/Abstractions/Rest/RestForumPostTagPayloads.cs b/DisCatSharp/Net/Abstractions/Rest/RestForumPostTagPayloads.cs
index 98812ad34..4662aeda7 100644
--- a/DisCatSharp/Net/Abstractions/Rest/RestForumPostTagPayloads.cs
+++ b/DisCatSharp/Net/Abstractions/Rest/RestForumPostTagPayloads.cs
@@ -1,57 +1,57 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using DisCatSharp.Entities;
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
///
/// Represents the forum tag payload.
///
-public class RestForumPostTagPayloads
+public class RestForumPostTagPayloads : ObservableApiObject
{
///
/// Sets the tags's new name.
///
[JsonProperty("name")]
public string Name { internal get; set; }
///
/// Sets the tags's new emoji.
///
[JsonProperty("emoji_id", NullValueHandling = NullValueHandling.Include)]
public Optional Emoji { internal get; set; }
///
/// Sets whether the tag should be mod only.
///
[JsonProperty("moderated", NullValueHandling = NullValueHandling.Ignore)]
public bool Moderated { internal get; set; }
///
/// Gets the unicode emoji of the forum post tag.
///
[JsonProperty("emoji_name", NullValueHandling = NullValueHandling.Include)]
public Optional UnicodeEmojiString { internal get; set; }
}
diff --git a/DisCatSharp/Net/Abstractions/Rest/RestGuildScheduledEventPayloads.cs b/DisCatSharp/Net/Abstractions/Rest/RestGuildScheduledEventPayloads.cs
index 7d823a863..bc8e9e739 100644
--- a/DisCatSharp/Net/Abstractions/Rest/RestGuildScheduledEventPayloads.cs
+++ b/DisCatSharp/Net/Abstractions/Rest/RestGuildScheduledEventPayloads.cs
@@ -1,150 +1,150 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System;
using DisCatSharp.Entities;
using DisCatSharp.Enums;
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
///
/// The rest guild scheduled event create payload.
///
-internal class RestGuildScheduledEventCreatePayload
+internal class RestGuildScheduledEventCreatePayload : ObservableApiObject
{
///
/// Gets or sets the channel id.
///
[JsonProperty("channel_id", NullValueHandling = NullValueHandling.Ignore)]
public ulong? ChannelId { get; set; }
///
/// Gets or sets the entity metadata.
///
[JsonProperty("entity_metadata", NullValueHandling = NullValueHandling.Ignore)]
public DiscordScheduledEventEntityMetadata EntityMetadata { get; set; }
///
/// Gets or sets the name.
///
[JsonProperty("name")]
public string Name { get; set; }
///
/// Gets or sets the description.
///
[JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
public string Description { get; set; }
///
/// Gets or sets the privacy level of the scheduled event.
///
[JsonProperty("privacy_level")]
public ScheduledEventPrivacyLevel PrivacyLevel { get; set; }
///
/// Gets or sets the time to schedule the scheduled event.
///
[JsonProperty("scheduled_start_time")]
public DateTimeOffset ScheduledStartTime { get; internal set; }
///
/// Gets or sets the time when the scheduled event is scheduled to end.
///
[JsonProperty("scheduled_end_time", NullValueHandling = NullValueHandling.Ignore)]
public DateTimeOffset? ScheduledEndTime { get; internal set; }
///
/// Gets or sets the entity type of the scheduled event.
///
[JsonProperty("entity_type")]
public ScheduledEventEntityType EntityType { get; set; }
///
/// Gets or sets the image as base64.
///
[JsonProperty("image", NullValueHandling = NullValueHandling.Include)]
public Optional CoverBase64 { get; set; }
}
///
/// The rest guild scheduled event modify payload.
///
-internal class RestGuildScheduledEventModifyPayload
+internal class RestGuildScheduledEventModifyPayload : ObservableApiObject
{
///
/// Gets or sets the channel id.
///
[JsonProperty("channel_id")]
public Optional ChannelId { get; set; }
///
/// Gets or sets the entity metadata.
///
[JsonProperty("entity_metadata")]
public Optional EntityMetadata { get; set; }
///
/// Gets or sets the name.
///
[JsonProperty("name")]
public Optional Name { get; set; }
///
/// Gets or sets the description.
///
[JsonProperty("description")]
public Optional Description { get; set; }
///
/// Gets or sets the time to schedule the scheduled event.
///
[JsonProperty("scheduled_start_time")]
public Optional ScheduledStartTime { get; internal set; }
///
/// Gets or sets the time when the scheduled event is scheduled to end.
///
[JsonProperty("scheduled_end_time")]
public Optional ScheduledEndTime { get; internal set; }
///
/// Gets or sets the entity type of the scheduled event.
///
[JsonProperty("entity_type")]
public Optional EntityType { get; set; }
///
/// Gets or sets the cover image as base64.
///
[JsonProperty("image")]
public Optional CoverBase64 { get; set; }
///
/// Gets or sets the status of the scheduled event.
///
[JsonProperty("status")]
public Optional Status { get; set; }
}
diff --git a/DisCatSharp/Net/Abstractions/Rest/RestStageInstancePayloads.cs b/DisCatSharp/Net/Abstractions/Rest/RestStageInstancePayloads.cs
index c22b5329e..1cb161189 100644
--- a/DisCatSharp/Net/Abstractions/Rest/RestStageInstancePayloads.cs
+++ b/DisCatSharp/Net/Abstractions/Rest/RestStageInstancePayloads.cs
@@ -1,69 +1,69 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using DisCatSharp.Entities;
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
///
/// Represents a stage instance create payload.
///
-internal sealed class RestStageInstanceCreatePayload
+internal sealed class RestStageInstanceCreatePayload : ObservableApiObject
{
///
/// Gets or sets the channel id.
///
[JsonProperty("channel_id", NullValueHandling = NullValueHandling.Ignore)]
public ulong ChannelId { get; set; }
///
/// Gets or sets the topic.
///
[JsonProperty("topic", NullValueHandling = NullValueHandling.Ignore)]
public string Topic { get; set; }
///
/// Gets or sets the associated scheduled event id.
///
[JsonProperty("guild_scheduled_event_id", NullValueHandling = NullValueHandling.Ignore)]
public ulong? ScheduledEventId { get; set; }
///
/// Whether everyone should be notified about the start.
///
[JsonProperty("send_start_notification", NullValueHandling = NullValueHandling.Ignore)]
public bool SendStartNotification { get; set; }
}
///
/// Represents a stage instance modify payload.
///
-internal sealed class RestStageInstanceModifyPayload
+internal sealed class RestStageInstanceModifyPayload : ObservableApiObject
{
///
/// Gets or sets the topic.
///
[JsonProperty("topic", NullValueHandling = NullValueHandling.Ignore)]
public Optional Topic { get; set; }
}
diff --git a/DisCatSharp/Net/Abstractions/Rest/RestStickerPayloads.cs b/DisCatSharp/Net/Abstractions/Rest/RestStickerPayloads.cs
index 32d942b3a..d850d2b2e 100644
--- a/DisCatSharp/Net/Abstractions/Rest/RestStickerPayloads.cs
+++ b/DisCatSharp/Net/Abstractions/Rest/RestStickerPayloads.cs
@@ -1,51 +1,51 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using DisCatSharp.Entities;
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
///
/// Represents a sticker modify payload.
///
-internal class RestStickerModifyPayload
+internal class RestStickerModifyPayload : ObservableApiObject
{
///
/// Gets or sets the name.
///
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public Optional Name { get; set; }
///
/// Gets or sets the description.
///
[JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
public Optional Description { get; set; }
///
/// Gets or sets the tags.
///
[JsonProperty("tags", NullValueHandling = NullValueHandling.Ignore)]
public Optional Tags { get; set; }
}
diff --git a/DisCatSharp/Net/Abstractions/Rest/RestUserPayloads.cs b/DisCatSharp/Net/Abstractions/Rest/RestUserPayloads.cs
index 672b24603..b81f05647 100644
--- a/DisCatSharp/Net/Abstractions/Rest/RestUserPayloads.cs
+++ b/DisCatSharp/Net/Abstractions/Rest/RestUserPayloads.cs
@@ -1,155 +1,156 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Collections.Generic;
+using DisCatSharp.Entities;
using DisCatSharp.Enums;
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
///
/// Represents a user dm create payload.
///
-internal sealed class RestUserDmCreatePayload
+internal sealed class RestUserDmCreatePayload : ObservableApiObject
{
///
/// Gets or sets the recipient.
///
[JsonProperty("recipient_id")]
public ulong Recipient { get; set; }
}
///
/// Represents a user group dm create payload.
///
-internal sealed class RestUserGroupDmCreatePayload
+internal sealed class RestUserGroupDmCreatePayload : ObservableApiObject
{
///
/// Gets or sets the access tokens.
///
[JsonProperty("access_tokens")]
public IEnumerable AccessTokens { get; set; }
///
/// Gets or sets the nicknames.
///
[JsonProperty("nicks")]
public IDictionary Nicknames { get; set; }
}
///
/// Represents a user update current payload.
///
-internal sealed class RestUserUpdateCurrentPayload
+internal sealed class RestUserUpdateCurrentPayload : ObservableApiObject
{
///
/// Gets or sets the username.
///
[JsonProperty("username", NullValueHandling = NullValueHandling.Ignore)]
public string Username { get; set; }
///
/// Gets or sets the avatar base64.
///
[JsonProperty("avatar", NullValueHandling = NullValueHandling.Include)]
public string AvatarBase64 { get; set; }
///
/// Gets or sets a value indicating whether avatar set.
///
[JsonIgnore]
public bool AvatarSet { get; set; }
///
/// Gets whether the avatar should be serialized.
///
public bool ShouldSerializeAvatarBase64()
=> this.AvatarSet;
}
///
/// Represents a user guild.
///
-internal sealed class RestUserGuild
+internal sealed class RestUserGuild : ObservableApiObject
{
///
/// Gets the id.
///
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
public ulong Id { get; set; }
///
/// Gets the name.
///
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; set; }
///
/// Gets the icon hash.
///
[JsonProperty("icon", NullValueHandling = NullValueHandling.Ignore)]
public string IconHash { get; set; }
///
/// Gets a value indicating whether is owner.
///
[JsonProperty("owner", NullValueHandling = NullValueHandling.Ignore)]
public bool IsOwner { get; set; }
///
/// Gets the permissions.
///
[JsonProperty("permissions", NullValueHandling = NullValueHandling.Ignore)]
public Permissions Permissions { get; set; }
///
/// Gets the guild features.
///
[JsonProperty("features", NullValueHandling = NullValueHandling.Ignore)]
public List Features { get; set; }
}
///
/// Represents a user guild list payload.
///
-internal sealed class RestUserGuildListPayload
+internal sealed class RestUserGuildListPayload : ObservableApiObject
{
///
/// Gets or sets the limit.
///
[JsonProperty("limit", NullValueHandling = NullValueHandling.Ignore)]
public int Limit { get; set; }
///
/// Gets or sets the before.
///
[JsonProperty("before", NullValueHandling = NullValueHandling.Ignore)]
public ulong? Before { get; set; }
///
/// Gets or sets the after.
///
[JsonProperty("after", NullValueHandling = NullValueHandling.Ignore)]
public ulong? After { get; set; }
}
diff --git a/DisCatSharp/Net/Abstractions/Rest/RestWebhookPayloads.cs b/DisCatSharp/Net/Abstractions/Rest/RestWebhookPayloads.cs
index 343ce4077..d81422699 100644
--- a/DisCatSharp/Net/Abstractions/Rest/RestWebhookPayloads.cs
+++ b/DisCatSharp/Net/Abstractions/Rest/RestWebhookPayloads.cs
@@ -1,168 +1,168 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Collections.Generic;
using DisCatSharp.Entities;
using DisCatSharp.Enums;
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
///
/// Represents a webhook payload.
///
-internal sealed class RestWebhookPayload
+internal sealed class RestWebhookPayload : ObservableApiObject
{
///
/// Gets or sets the name.
///
[JsonProperty("name")]
public string Name { get; set; }
///
/// Gets or sets the avatar base64.
///
[JsonProperty("avatar", NullValueHandling = NullValueHandling.Include)]
public string AvatarBase64 { get; set; }
///
/// Gets or sets the channel id.
///
[JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
///
/// Gets whether an avatar is set.
///
[JsonProperty]
public bool AvatarSet { get; set; }
///
/// Gets whether the avatar should be serialized.
///
public bool ShouldSerializeAvatarBase64()
=> this.AvatarSet;
}
///
/// Represents a webhook execute payload.
///
-internal sealed class RestWebhookExecutePayload
+internal sealed class RestWebhookExecutePayload : ObservableApiObject
{
///
/// Gets or sets the content.
///
[JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
public string Content { get; set; }
///
/// Gets or sets the username.
///
[JsonProperty("username", NullValueHandling = NullValueHandling.Ignore)]
public string Username { get; set; }
///
/// Gets or sets the avatar url.
///
[JsonProperty("avatar_url", NullValueHandling = NullValueHandling.Ignore)]
public string AvatarUrl { get; set; }
///
/// Whether this message is tts.
///
[JsonProperty("tts", NullValueHandling = NullValueHandling.Ignore)]
public bool? IsTts { get; set; }
///
/// Gets or sets the embeds.
///
[JsonProperty("embeds", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable Embeds { get; set; }
///
/// Gets or sets the mentions.
///
[JsonProperty("allowed_mentions", NullValueHandling = NullValueHandling.Ignore)]
public DiscordMentions Mentions { get; set; }
///
/// Gets or sets the components.
///
[JsonProperty("components", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable Components { get; set; }
///
/// Gets or sets the attachments.
///
[JsonProperty("attachments", NullValueHandling = NullValueHandling.Ignore)]
public List Attachments { get; set; }
///
/// Gets or sets the thread name.
///
[JsonProperty("thread_name", NullValueHandling = NullValueHandling.Ignore)]
public string ThreadName { get; set; }
[JsonProperty("flags", NullValueHandling = NullValueHandling.Ignore)]
public MessageFlags Flags { get; set; }
}
///
/// Represents a webhook message edit payload.
///
-internal sealed class RestWebhookMessageEditPayload
+internal sealed class RestWebhookMessageEditPayload : ObservableApiObject
{
///
/// Gets or sets the content.
///
[JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)]
public Optional Content { get; set; }
///
/// Gets or sets the embeds.
///
[JsonProperty("embeds", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable Embeds { get; set; }
///
/// Gets or sets the mentions.
///
[JsonProperty("allowed_mentions", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable Mentions { get; set; }
///
/// Gets or sets the attachments.
///
[JsonProperty("attachments", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable Attachments { get; set; }
///
/// Gets or sets the components.
///
[JsonProperty("components", NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable Components { get; set; }
[JsonProperty("flags", NullValueHandling = NullValueHandling.Ignore)]
public MessageFlags? Flags { get; set; }
}
diff --git a/DisCatSharp/Net/Abstractions/StatusUpdate.cs b/DisCatSharp/Net/Abstractions/StatusUpdate.cs
index 1201b98cd..8402e6d89 100644
--- a/DisCatSharp/Net/Abstractions/StatusUpdate.cs
+++ b/DisCatSharp/Net/Abstractions/StatusUpdate.cs
@@ -1,74 +1,75 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using DisCatSharp.Entities;
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
///
/// Represents data for websocket status update payload.
///
-internal sealed class StatusUpdate
+internal sealed class StatusUpdate : ObservableApiObject
{
///
/// Gets or sets the unix millisecond timestamp of when the user went idle.
///
[JsonProperty("since", NullValueHandling = NullValueHandling.Include)]
public long? IdleSince { get; set; }
///
/// Gets or sets whether the user is AFK.
///
[JsonProperty("afk")]
public bool IsAfk { get; set; }
///
/// Gets or sets the status of the user.
///
[JsonIgnore]
public UserStatus Status { get; set; } = UserStatus.Online;
///
/// Gets the status string of the user.
///
[JsonProperty("status")]
internal string StatusString =>
this.Status switch
{
UserStatus.Online => "online",
UserStatus.Idle => "idle",
UserStatus.DoNotDisturb => "dnd",
UserStatus.Invisible or UserStatus.Offline => "invisible",
UserStatus.Streaming => "streaming",
_ => "online",
};
///
/// Gets or sets the game the user is playing.
///
[JsonProperty("game", NullValueHandling = NullValueHandling.Ignore)]
public TransportActivity Activity { get; set; }
+ [JsonIgnore]
internal DiscordActivity ActivityInternal;
}
diff --git a/DisCatSharp/Net/Abstractions/VoiceStateUpdate.cs b/DisCatSharp/Net/Abstractions/VoiceStateUpdate.cs
index ee9fab636..154fcb5b5 100644
--- a/DisCatSharp/Net/Abstractions/VoiceStateUpdate.cs
+++ b/DisCatSharp/Net/Abstractions/VoiceStateUpdate.cs
@@ -1,55 +1,57 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
+using DisCatSharp.Entities;
+
using Newtonsoft.Json;
namespace DisCatSharp.Net.Abstractions;
///
/// Represents data for websocket voice state update payload.
///
-internal sealed class VoiceStateUpdate
+internal sealed class VoiceStateUpdate : ObservableApiObject
{
///
/// Gets or sets the guild for which the user is updating their voice state.
///
[JsonProperty("guild_id")]
public ulong GuildId { get; set; }
///
/// Gets or sets the channel user wants to connect to. Null if disconnecting.
///
[JsonProperty("channel_id")]
public ulong? ChannelId { get; set; }
///
/// Gets or sets whether the client is muted.
///
[JsonProperty("self_mute")]
public bool Mute { get; set; }
///
/// Gets or sets whether the client is deafened.
///
[JsonProperty("self_deaf")]
public bool Deafen { get; set; }
}
diff --git a/DisCatSharp/Net/Models/ApplicationCommandEditModel.cs b/DisCatSharp/Net/Models/ApplicationCommandEditModel.cs
index 6e876785f..fbf93177c 100644
--- a/DisCatSharp/Net/Models/ApplicationCommandEditModel.cs
+++ b/DisCatSharp/Net/Models/ApplicationCommandEditModel.cs
@@ -1,97 +1,97 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System;
using System.Collections.Generic;
using DisCatSharp.Entities;
using DisCatSharp.Enums;
namespace DisCatSharp.Net.Models;
///
/// Represents a application command edit model.
///
-public class ApplicationCommandEditModel
+public class ApplicationCommandEditModel : ObservableApiObject
{
///
/// Sets the command's new name.
///
public Optional Name
{
internal get => this._name;
set
{
if (value.Value.Length > 32)
throw new ArgumentException("Application command name cannot exceed 32 characters.", nameof(value));
this._name = value;
}
}
private Optional _name;
///
/// Sets the command's new description
///
public Optional Description
{
internal get => this._description;
set
{
if (value.Value.Length > 100)
throw new ArgumentException("Application command description cannot exceed 100 characters.", nameof(value));
this._description = value;
}
}
private Optional _description;
///
/// Sets the command's name localizations.
///
public Optional NameLocalizations { internal get; set; }
///
/// Sets the command's description localizations.
///
public Optional DescriptionLocalizations { internal get; set; }
///
/// Sets the command's new options.
///
#pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
public Optional?> Options { internal get; set; }
#pragma warning restore CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
///
/// Sets the command's needed permissions.
///
public Optional DefaultMemberPermissions { internal get; set; }
///
/// Sets whether the command can be used in direct messages.
///
public Optional DmPermission { internal get; set; }
///
/// Sets whether the command is marked as NSFW.
///
public Optional IsNsfw { internal get; set; }
}
diff --git a/DisCatSharp/Net/Rest/DiscordApiClient.cs b/DisCatSharp/Net/Rest/DiscordApiClient.cs
index a8d202da0..a297c7764 100644
--- a/DisCatSharp/Net/Rest/DiscordApiClient.cs
+++ b/DisCatSharp/Net/Rest/DiscordApiClient.cs
@@ -1,5772 +1,5762 @@
// This file is part of the DisCatSharp project, based off DSharpPlus.
//
// Copyright (c) 2021-2023 AITSYS
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using DisCatSharp.Entities;
using DisCatSharp.Enums;
using DisCatSharp.Net.Abstractions;
using DisCatSharp.Net.Serialization;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace DisCatSharp.Net;
///
/// Represents a discord api client.
///
public sealed class DiscordApiClient
{
///
/// The audit log reason header name.
///
private const string REASON_HEADER_NAME = "X-Audit-Log-Reason";
///
/// Gets the discord client.
///
internal BaseDiscordClient Discord { get; }
///
/// Gets the rest client.
///
internal RestClient Rest { get; }
///
/// Initializes a new instance of the class.
///
/// The client.
internal DiscordApiClient(BaseDiscordClient client)
{
this.Discord = client;
this.Rest = new RestClient(client);
}
///
/// Initializes a new instance of the class.
///
/// The proxy.
/// The timeout.
/// If true, use relative rate limit.
/// The logger.
internal DiscordApiClient(IWebProxy proxy, TimeSpan timeout, bool useRelativeRateLimit, ILogger logger) // This is for meta-clients, such as the webhook client
{
this.Rest = new RestClient(proxy, timeout, useRelativeRateLimit, logger);
}
///
/// Builds the query string.
///
/// The values.
/// Whether this query will be transmitted via POST.
private static string BuildQueryString(IDictionary values, bool post = false)
{
if (values == null || values.Count == 0)
return string.Empty;
var valsCollection = values.Select(xkvp =>
$"{WebUtility.UrlEncode(xkvp.Key)}={WebUtility.UrlEncode(xkvp.Value)}");
var vals = string.Join("&", valsCollection);
return !post ? $"?{vals}" : vals;
}
///
/// Prepares the message.
///
/// The msg_raw.
/// A DiscordMessage.
private DiscordMessage PrepareMessage(JToken msgRaw)
{
var author = msgRaw["author"].ToObject();
var ret = msgRaw.ToDiscordObject();
ret.Discord = this.Discord;
this.PopulateMessage(author, ret);
var referencedMsg = msgRaw["referenced_message"];
if (ret.MessageType == MessageType.Reply && !string.IsNullOrWhiteSpace(referencedMsg?.ToString()))
{
author = referencedMsg["author"].ToObject();
ret.ReferencedMessage.Discord = this.Discord;
this.PopulateMessage(author, ret.ReferencedMessage);
}
if (ret.Channel != null)
return ret;
var channel = !ret.GuildId.HasValue
? new DiscordDmChannel
{
Id = ret.ChannelId,
Discord = this.Discord,
Type = ChannelType.Private
}
: new DiscordChannel
{
Id = ret.ChannelId,
GuildId = ret.GuildId,
Discord = this.Discord
};
ret.Channel = channel;
return ret;
}
///
/// Populates the message.
///
/// The author.
/// The message.
private void PopulateMessage(TransportUser author, DiscordMessage ret)
{
var guild = ret.Channel?.Guild;
//If this is a webhook, it shouldn't be in the user cache.
if (author.IsBot && int.Parse(author.Discriminator) == 0)
{
ret.Author = new DiscordUser(author) { Discord = this.Discord };
}
else
{
if (!this.Discord.UserCache.TryGetValue(author.Id, out var usr))
{
this.Discord.UserCache[author.Id] = usr = new DiscordUser(author) { Discord = this.Discord };
}
if (guild != null)
{
if (!guild.Members.TryGetValue(author.Id, out var mbr))
mbr = new DiscordMember(usr) { Discord = this.Discord, GuildId = guild.Id };
ret.Author = mbr;
}
else
{
ret.Author = usr;
}
}
ret.PopulateMentions();
ret.ReactionsInternal ??= new List();
foreach (var xr in ret.ReactionsInternal)
xr.Emoji.Discord = this.Discord;
}
///
/// Executes a rest request.
///
/// The client.
/// The bucket.
/// The url.
/// The method.
/// The route.
/// The headers.
/// The payload.
/// The ratelimit wait override.
internal Task DoRequestAsync(BaseDiscordClient client, RateLimitBucket bucket, Uri url, RestRequestMethod method, string route, IReadOnlyDictionary headers = null, string payload = null, double? ratelimitWaitOverride = null)
{
var req = new RestRequest(client, bucket, url, method, route, headers, payload, ratelimitWaitOverride);
if (this.Discord != null)
this.Rest.ExecuteRequestAsync(req).LogTaskFault(this.Discord.Logger, LogLevel.Error, LoggerEvents.RestError, $"Error while executing request. Url: {url.AbsoluteUri}");
else
_ = this.Rest.ExecuteRequestAsync(req);
return req.WaitForCompletionAsync();
}
///
/// Executes a multipart rest request for stickers.
///
/// The client.
/// The bucket.
/// The url.
/// The method.
/// The route.
/// The headers.
/// The file.
/// The sticker name.
/// The sticker tag.
/// The sticker description.
/// The ratelimit wait override.
private Task DoStickerMultipartAsync(BaseDiscordClient client, RateLimitBucket bucket, Uri url, RestRequestMethod method, string route, IReadOnlyDictionary headers = null,
DiscordMessageFile file = null, string name = "", string tags = "", string description = "", double? ratelimitWaitOverride = null)
{
var req = new MultipartStickerWebRequest(client, bucket, url, method, route, headers, file, name, tags, description, ratelimitWaitOverride);
if (this.Discord != null)
this.Rest.ExecuteRequestAsync(req).LogTaskFault(this.Discord.Logger, LogLevel.Error, LoggerEvents.RestError, "Error while executing request");
else
_ = this.Rest.ExecuteRequestAsync(req);
return req.WaitForCompletionAsync();
}
///
/// Executes a multipart request.
///
/// The client.
/// The bucket.
/// The url.
/// The method.
/// The route.
/// The headers.
/// The values.
/// The files.
/// The ratelimit wait override.
private Task DoMultipartAsync(BaseDiscordClient client, RateLimitBucket bucket, Uri url, RestRequestMethod method, string route, IReadOnlyDictionary headers = null, IReadOnlyDictionary values = null,
IReadOnlyCollection files = null, double? ratelimitWaitOverride = null)
{
var req = new MultipartWebRequest(client, bucket, url, method, route, headers, values, files, ratelimitWaitOverride);
if (this.Discord != null)
this.Rest.ExecuteRequestAsync(req).LogTaskFault(this.Discord.Logger, LogLevel.Error, LoggerEvents.RestError, "Error while executing request");
else
_ = this.Rest.ExecuteRequestAsync(req);
return req.WaitForCompletionAsync();
}
// begin todo
#region Guild
+ ///
+ /// Gets the guild async.
+ ///
+ /// The guild id.
+ /// If true, with_counts.
+ internal async Task GetGuildAsync(ulong guildId, bool? withCounts)
+ {
+ var urlParams = new Dictionary();
+ if (withCounts.HasValue)
+ urlParams["with_counts"] = withCounts?.ToString();
+
+ var route = $"{Endpoints.GUILDS}/:guild_id";
+ var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new { guild_id = guildId }, out var path);
+
+ var url = Utilities.GetApiUriFor(path, urlParams.Any() ? BuildQueryString(urlParams) : "", this.Discord.Configuration);
+ var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.GET, route, urlParams).ConfigureAwait(false);
+
+ var json = JObject.Parse(res.Response);
+ var rawMembers = (JArray)json["members"];
+ var guildRest = DiscordJson.DeserializeObject(res.Response, this.Discord);
+ foreach (var r in guildRest.RolesInternal.Values)
+ r.GuildId = guildRest.Id;
+
+ if (this.Discord is DiscordClient dc)
+ {
+ await dc.OnGuildUpdateEventAsync(guildRest, rawMembers).ConfigureAwait(false);
+ return dc.GuildsInternal[guildRest.Id];
+ }
+ else
+ {
+ guildRest.Discord = this.Discord;
+ return guildRest;
+ }
+ }
+
///
/// Searches the members async.
///
/// The guild_id.
/// The name.
/// The limit.
internal async Task> SearchMembersAsync(ulong guildId, string name, int? limit)
{
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.MEMBERS}{Endpoints.SEARCH}";
var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new {guild_id = guildId }, out var path);
var querydict = new Dictionary
{
["query"] = name,
["limit"] = limit.ToString()
};
var url = Utilities.GetApiUriFor(path, BuildQueryString(querydict), this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.GET, route).ConfigureAwait(false);
var json = JArray.Parse(res.Response);
var tms = json.ToObject>();
var mbrs = new List();
foreach (var xtm in tms)
{
var usr = new DiscordUser(xtm.User) { Discord = this.Discord };
this.Discord.UserCache.AddOrUpdate(xtm.User.Id, usr, (id, old) =>
{
old.Username = usr.Username;
old.Discord = usr.Discord;
old.AvatarHash = usr.AvatarHash;
old.GlobalName = usr.GlobalName;
return old;
});
mbrs.Add(new DiscordMember(xtm) { Discord = this.Discord, GuildId = guildId });
}
return mbrs;
}
///
/// Gets the guild ban async.
///
/// The guild_id.
/// The user_id.
internal async Task GetGuildBanAsync(ulong guildId, ulong userId)
{
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.BANS}/:user_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new {guild_id = guildId, user_id = userId}, out var path);
var uri = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, uri, RestRequestMethod.GET, route).ConfigureAwait(false);
var json = JObject.Parse(res.Response);
var ban = json.ToObject();
return ban;
}
///
/// Creates the guild async.
///
/// The name.
/// The region_id.
/// The iconb64.
/// The verification_level.
/// The default_message_notifications.
/// The system_channel_flags.
internal async Task CreateGuildAsync(string name, string regionId, Optional iconb64, VerificationLevel? verificationLevel,
DefaultMessageNotifications? defaultMessageNotifications, SystemChannelFlags? systemChannelFlags)
{
var pld = new RestGuildCreatePayload
{
Name = name,
RegionId = regionId,
DefaultMessageNotifications = defaultMessageNotifications,
VerificationLevel = verificationLevel,
IconBase64 = iconb64,
SystemChannelFlags = systemChannelFlags
};
var route = $"{Endpoints.GUILDS}";
var bucket = this.Rest.GetBucket(RestRequestMethod.POST, route, new { }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.POST, route, payload: DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
var json = JObject.Parse(res.Response);
var rawMembers = (JArray)json["members"];
var guild = json.ToDiscordObject();
if (this.Discord is DiscordClient dc)
await dc.OnGuildCreateEventAsync(guild, rawMembers, null).ConfigureAwait(false);
return guild;
}
///
/// Creates the guild from template async.
///
/// The template_code.
/// The name.
/// The iconb64.
internal async Task CreateGuildFromTemplateAsync(string templateCode, string name, Optional iconb64)
{
var pld = new RestGuildCreateFromTemplatePayload
{
Name = name,
IconBase64 = iconb64
};
var route = $"{Endpoints.GUILDS}{Endpoints.TEMPLATES}/:template_code";
var bucket = this.Rest.GetBucket(RestRequestMethod.POST, route, new {template_code = templateCode }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.POST, route, payload: DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
var json = JObject.Parse(res.Response);
var rawMembers = (JArray)json["members"];
var guild = json.ToDiscordObject();
if (this.Discord is DiscordClient dc)
await dc.OnGuildCreateEventAsync(guild, rawMembers, null).ConfigureAwait(false);
return guild;
}
///
/// Deletes the guild async.
///
/// The guild_id.
internal async Task DeleteGuildAsync(ulong guildId)
{
var route = $"{Endpoints.GUILDS}/:guild_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.DELETE, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.DELETE, route).ConfigureAwait(false);
if (this.Discord is DiscordClient dc)
{
var gld = dc.GuildsInternal[guildId];
await dc.OnGuildDeleteEventAsync(gld).ConfigureAwait(false);
}
}
///
/// Modifies the guild.
///
/// The guild id.
/// The name.
/// The verification level.
/// The default message notifications.
/// The mfa level.
/// The explicit content filter.
/// The afk channel id.
/// The afk timeout.
/// The iconb64.
/// The owner id.
/// The splashb64.
/// The system channel id.
/// The system channel flags.
/// The public updates channel id.
/// The rules channel id.
/// The description.
/// The banner base64.
/// The discovery base64.
/// The home header base64.
/// The preferred locale.
/// Whether the premium progress bar should be enabled.
/// The reason.
internal async Task ModifyGuildAsync(ulong guildId, Optional name, Optional verificationLevel,
Optional defaultMessageNotifications, Optional mfaLevel,
Optional explicitContentFilter, Optional afkChannelId,
Optional afkTimeout, Optional iconb64, Optional ownerId, Optional splashb64,
Optional systemChannelId, Optional systemChannelFlags,
Optional publicUpdatesChannelId, Optional rulesChannelId, Optional description,
Optional bannerb64, Optional discoverySplashb64, Optional homeHeaderb64, Optional preferredLocale, Optional premiumProgressBarEnabled, string reason)
{
var pld = new RestGuildModifyPayload
{
Name = name,
VerificationLevel = verificationLevel,
DefaultMessageNotifications = defaultMessageNotifications,
MfaLevel = mfaLevel,
ExplicitContentFilter = explicitContentFilter,
AfkChannelId = afkChannelId,
AfkTimeout = afkTimeout,
IconBase64 = iconb64,
SplashBase64 = splashb64,
BannerBase64 = bannerb64,
DiscoverySplashBase64 = discoverySplashb64,
OwnerId = ownerId,
SystemChannelId = systemChannelId,
SystemChannelFlags = systemChannelFlags,
RulesChannelId = rulesChannelId,
PublicUpdatesChannelId = publicUpdatesChannelId,
PreferredLocale = preferredLocale,
Description = description,
PremiumProgressBarEnabled = premiumProgressBarEnabled,
HomeHeaderBase64 = homeHeaderb64
};
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new { guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, headers, DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
var json = JObject.Parse(res.Response);
var rawMembers = (JArray)json["members"];
var guild = json.ToDiscordObject();
foreach (var r in guild.RolesInternal.Values)
r.GuildId = guild.Id;
if (this.Discord is DiscordClient dc)
await dc.OnGuildUpdateEventAsync(guild, rawMembers).ConfigureAwait(false);
return guild;
}
///
/// Modifies the guild community settings.
///
/// The guild id.
/// The guild features.
/// The rules channel id.
/// The public updates channel id.
/// The preferred locale.
/// The description.
/// The default message notifications.
/// The explicit content filter.
/// The verification level.
/// The reason.
internal async Task ModifyGuildCommunitySettingsAsync(ulong guildId, List features, Optional rulesChannelId, Optional publicUpdatesChannelId, string preferredLocale, string description, DefaultMessageNotifications defaultMessageNotifications, ExplicitContentFilter explicitContentFilter, VerificationLevel verificationLevel, string reason)
{
var pld = new RestGuildCommunityModifyPayload
{
VerificationLevel = verificationLevel,
DefaultMessageNotifications = defaultMessageNotifications,
ExplicitContentFilter = explicitContentFilter,
RulesChannelId = rulesChannelId,
PublicUpdatesChannelId = publicUpdatesChannelId,
PreferredLocale = preferredLocale,
Description = Optional.FromNullable(description),
Features = features
};
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new { guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, headers, DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
var json = JObject.Parse(res.Response);
var rawMembers = (JArray)json["members"];
var guild = json.ToDiscordObject();
foreach (var r in guild.RolesInternal.Values)
r.GuildId = guild.Id;
if (this.Discord is DiscordClient dc)
await dc.OnGuildUpdateEventAsync(guild, rawMembers).ConfigureAwait(false);
return guild;
}
///
/// Modifies the guild safety settings.
///
/// The guild id.
/// The guild features.
/// The safety alerts channel id.
/// The reason.
internal async Task ModifyGuildSafetyAlertsSettingsAsync(ulong guildId, List features, Optional safetyAlertsChannelId, string reason)
{
var pld = new RestGuildSafetyModifyPayload
{
SafetyAlertsChannelId = safetyAlertsChannelId,
Features = features
};
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new { guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, headers, DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
var json = JObject.Parse(res.Response);
var rawMembers = (JArray)json["members"];
var guild = json.ToDiscordObject();
foreach (var r in guild.RolesInternal.Values)
r.GuildId = guild.Id;
if (this.Discord is DiscordClient dc)
await dc.OnGuildUpdateEventAsync(guild, rawMembers).ConfigureAwait(false);
return guild;
}
///
/// Modifies the guild features.
///
/// The guild id.
/// The guild features.
/// The reason.
///
internal async Task ModifyGuildFeaturesAsync(ulong guildId, List features, string reason)
{
var pld = new RestGuildFeatureModifyPayload
{
Features = features
};
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new { guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, headers, DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
var json = JObject.Parse(res.Response);
var rawMembers = (JArray)json["members"];
var guild = json.ToDiscordObject();
foreach (var r in guild.RolesInternal.Values)
r.GuildId = guild.Id;
if (this.Discord is DiscordClient dc)
await dc.OnGuildUpdateEventAsync(guild, rawMembers).ConfigureAwait(false);
return guild;
}
///
/// Enables the guilds mfa requirement.
///
/// The guild id.
/// The reason.
internal async Task EnableGuildMfaAsync(ulong guildId, string reason)
{
var pld = new RestGuildMfaLevelModifyPayload
{
Level = MfaLevel.Enabled
};
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.MFA}";
var bucket = this.Rest.GetBucket(RestRequestMethod.POST, route, new { guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.POST, route, headers, DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
}
///
/// Disables the guilds mfa requirement.
///
/// The guild id.
/// The reason.
internal async Task DisableGuildMfaAsync(ulong guildId, string reason)
{
var pld = new RestGuildMfaLevelModifyPayload
{
Level = MfaLevel.Disabled
};
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.MFA}";
var bucket = this.Rest.GetBucket(RestRequestMethod.POST, route, new { guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.POST, route, headers, DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
}
///
/// Implements https://discord.com/developers/docs/resources/guild#get-guild-bans.
///
internal async Task> GetGuildBansAsync(ulong guildId, int? limit, ulong? before, ulong? after)
{
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.BANS}";
var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new {guild_id = guildId }, out var path);
var urlParams = new Dictionary();
if (limit != null)
urlParams["limit"] = limit.Value.ToString(CultureInfo.InvariantCulture);
if (before != null)
urlParams["before"] = before.Value.ToString(CultureInfo.InvariantCulture);
if (after != null)
urlParams["after"] = after.Value.ToString(CultureInfo.InvariantCulture);
var url = Utilities.GetApiUriFor(path, BuildQueryString(urlParams), this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.GET, route).ConfigureAwait(false);
var bansRaw = JsonConvert.DeserializeObject>(res.Response).Select(xb =>
{
if (!this.Discord.TryGetCachedUserInternal(xb.RawUser.Id, out var usr))
{
usr = new DiscordUser(xb.RawUser) { Discord = this.Discord };
usr = this.Discord.UserCache.AddOrUpdate(usr.Id, usr, (id, old) =>
{
old.Username = usr.Username;
old.Discriminator = usr.Discriminator;
old.AvatarHash = usr.AvatarHash;
old.GlobalName = usr.GlobalName;
return old;
});
}
xb.User = usr;
return xb;
});
var bans = new ReadOnlyCollection(new List(bansRaw));
return bans;
}
///
/// Creates the guild ban async.
///
/// The guild_id.
/// The user_id.
/// The delete_message_days.
/// The reason.
internal Task CreateGuildBanAsync(ulong guildId, ulong userId, int deleteMessageDays, string reason)
{
if (deleteMessageDays < 0 || deleteMessageDays > 7)
throw new ArgumentException("Delete message days must be a number between 0 and 7.", nameof(deleteMessageDays));
var urlParams = new Dictionary
{
["delete_message_days"] = deleteMessageDays.ToString(CultureInfo.InvariantCulture)
};
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.BANS}/:user_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.PUT, route, new {guild_id = guildId, user_id = userId }, out var path);
var url = Utilities.GetApiUriFor(path, BuildQueryString(urlParams), this.Discord.Configuration);
return this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PUT, route, headers);
}
///
/// Removes the guild ban async.
///
/// The guild_id.
/// The user_id.
/// The reason.
internal Task RemoveGuildBanAsync(ulong guildId, ulong userId, string reason)
{
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.BANS}/:user_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.DELETE, route, new {guild_id = guildId, user_id = userId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
return this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.DELETE, route, headers);
}
///
/// Leaves the guild async.
///
/// The guild_id.
internal Task LeaveGuildAsync(ulong guildId)
{
var route = $"{Endpoints.USERS}{Endpoints.ME}{Endpoints.GUILDS}/:guild_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.DELETE, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
return this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.DELETE, route);
}
///
/// Adds the guild member async.
///
/// The guild_id.
/// The user_id.
/// The access_token.
/// The nick.
/// The roles.
/// If true, muted.
/// If true, deafened.
internal async Task AddGuildMemberAsync(ulong guildId, ulong userId, string accessToken, string nick, IEnumerable roles, bool muted, bool deafened)
{
var pld = new RestGuildMemberAddPayload
{
AccessToken = accessToken,
Nickname = nick ?? "",
Roles = roles ?? new List(),
Deaf = deafened,
Mute = muted
};
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.MEMBERS}/:user_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.PUT, route, new {guild_id = guildId, user_id = userId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PUT, route, payload: DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
var tm = DiscordJson.DeserializeObject(res.Response, this.Discord);
tm.Discord = this.Discord;
tm.GuildId = guildId;
return tm;
}
///
/// Lists the guild members async.
///
/// The guild_id.
/// The limit.
/// The after.
internal async Task> ListGuildMembersAsync(ulong guildId, int? limit, ulong? after)
{
var urlParams = new Dictionary();
if (limit != null && limit > 0)
urlParams["limit"] = limit.Value.ToString(CultureInfo.InvariantCulture);
if (after != null)
urlParams["after"] = after.Value.ToString(CultureInfo.InvariantCulture);
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.MEMBERS}";
var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, urlParams.Any() ? BuildQueryString(urlParams) : "", this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.GET, route).ConfigureAwait(false);
var membersRaw = JsonConvert.DeserializeObject>(res.Response);
return new ReadOnlyCollection(membersRaw);
}
///
/// Adds the guild member role async.
///
/// The guild_id.
/// The user_id.
/// The role_id.
/// The reason.
internal Task AddGuildMemberRoleAsync(ulong guildId, ulong userId, ulong roleId, string reason)
{
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.MEMBERS}/:user_id{Endpoints.ROLES}/:role_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.PUT, route, new {guild_id = guildId, user_id = userId, role_id = roleId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
return this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PUT, route, headers);
}
///
/// Removes the guild member role async.
///
/// The guild_id.
/// The user_id.
/// The role_id.
/// The reason.
internal Task RemoveGuildMemberRoleAsync(ulong guildId, ulong userId, ulong roleId, string reason)
{
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.MEMBERS}/:user_id{Endpoints.ROLES}/:role_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.DELETE, route, new {guild_id = guildId, user_id = userId, role_id = roleId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
return this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.DELETE, route, headers);
}
///
/// Modifies the guild channel position async.
///
/// The guild_id.
/// The pld.
/// The reason.
internal Task ModifyGuildChannelPositionAsync(ulong guildId, IEnumerable pld, string reason)
{
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.CHANNELS}";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
return this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, headers, DiscordJson.SerializeObject(pld));
}
///
/// Modifies the guild channel parent async.
///
/// The guild_id.
/// The pld.
/// The reason.
internal Task ModifyGuildChannelParentAsync(ulong guildId, IEnumerable pld, string reason)
{
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.CHANNELS}";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
return this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, headers, DiscordJson.SerializeObject(pld));
}
///
/// Detaches the guild channel parent async.
///
/// The guild_id.
/// The pld.
/// The reason.
internal Task DetachGuildChannelParentAsync(ulong guildId, IEnumerable pld, string reason)
{
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.CHANNELS}";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
return this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, headers, DiscordJson.SerializeObject(pld));
}
///
/// Modifies the guild role position async.
///
/// The guild_id.
/// The pld.
/// The reason.
internal Task ModifyGuildRolePositionAsync(ulong guildId, IEnumerable pld, string reason)
{
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.ROLES}";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
return this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, headers, DiscordJson.SerializeObject(pld));
}
///
/// Gets the audit logs async.
///
/// The guild_id.
/// The limit.
/// The after.
/// The before.
/// The responsible.
/// The action_type.
internal async Task GetAuditLogsAsync(ulong guildId, int limit, ulong? after, ulong? before, ulong? responsible, int? actionType)
{
var urlParams = new Dictionary
{
["limit"] = limit.ToString(CultureInfo.InvariantCulture)
};
if (after != null)
urlParams["after"] = after?.ToString(CultureInfo.InvariantCulture);
if (before != null)
urlParams["before"] = before?.ToString(CultureInfo.InvariantCulture);
if (responsible != null)
urlParams["user_id"] = responsible?.ToString(CultureInfo.InvariantCulture);
if (actionType != null)
urlParams["action_type"] = actionType?.ToString(CultureInfo.InvariantCulture);
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.AUDIT_LOGS}";
var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, urlParams.Any() ? BuildQueryString(urlParams) : "", this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.GET, route).ConfigureAwait(false);
var auditLogDataRaw = DiscordJson.DeserializeObject(res.Response, this.Discord);
return auditLogDataRaw;
}
///
/// Gets the guild vanity url async.
///
/// The guild_id.
internal async Task GetGuildVanityUrlAsync(ulong guildId)
{
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.VANITY_URL}";
var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.GET, route).ConfigureAwait(false);
var invite = DiscordJson.DeserializeObject(res.Response, this.Discord);
return invite;
}
///
/// Gets the guild widget async.
///
/// The guild_id.
internal async Task GetGuildWidgetAsync(ulong guildId)
{
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.WIDGET_JSON}";
var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.GET, route).ConfigureAwait(false);
var json = JObject.Parse(res.Response);
var rawChannels = (JArray)json["channels"];
var ret = json.ToDiscordObject();
ret.Discord = this.Discord;
ret.Guild = this.Discord.Guilds.ContainsKey(guildId) ? this.Discord.Guilds[guildId] : null;
ret.Channels = ret.Guild == null
? rawChannels.Select(r => new DiscordChannel
{
Id = (ulong)r["id"],
Name = r["name"].ToString(),
Position = (int)r["position"]
}).ToList()
: rawChannels.Select(r =>
{
var c = ret.Guild.GetChannel((ulong)r["id"]);
c.Position = (int)r["position"];
return c;
}).ToList();
return ret;
}
///
/// Gets the guild widget settings async.
///
/// The guild_id.
internal async Task GetGuildWidgetSettingsAsync(ulong guildId)
{
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.WIDGET}";
var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.GET, route).ConfigureAwait(false);
var ret = DiscordJson.DeserializeObject(res.Response, this.Discord);
ret.Guild = this.Discord.Guilds[guildId];
return ret;
}
///
/// Modifies the guild widget settings async.
///
/// The guild_id.
/// If true, is enabled.
/// The channel id.
/// The reason.
internal async Task ModifyGuildWidgetSettingsAsync(ulong guildId, bool? isEnabled, ulong? channelId, string reason)
{
var pld = new RestGuildWidgetSettingsPayload
{
Enabled = isEnabled,
ChannelId = channelId
};
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.WIDGET}";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, headers, DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
var ret = DiscordJson.DeserializeObject(res.Response, this.Discord);
ret.Guild = this.Discord.Guilds[guildId];
return ret;
}
///
/// Gets the guild templates async.
///
/// The guild_id.
internal async Task> GetGuildTemplatesAsync(ulong guildId)
{
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.TEMPLATES}";
var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.GET, route).ConfigureAwait(false);
var templatesRaw = JsonConvert.DeserializeObject>(res.Response);
return new ReadOnlyCollection(new List(templatesRaw));
}
///
/// Creates the guild template async.
///
/// The guild_id.
/// The name.
/// The description.
internal async Task CreateGuildTemplateAsync(ulong guildId, string name, string description)
{
var pld = new RestGuildTemplateCreateOrModifyPayload
{
Name = name,
Description = description
};
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.TEMPLATES}";
var bucket = this.Rest.GetBucket(RestRequestMethod.POST, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.POST, route, payload: DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
var ret = DiscordJson.DeserializeObject(res.Response, this.Discord);
return ret;
}
///
/// Syncs the guild template async.
///
/// The guild_id.
/// The template_code.
internal async Task SyncGuildTemplateAsync(ulong guildId, string templateCode)
{
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.TEMPLATES}/:template_code";
var bucket = this.Rest.GetBucket(RestRequestMethod.PUT, route, new {guild_id = guildId, template_code = templateCode }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PUT, route).ConfigureAwait(false);
var templateRaw = DiscordJson.DeserializeObject(res.Response, this.Discord);
return templateRaw;
}
///
/// Modifies the guild template async.
///
/// The guild_id.
/// The template_code.
/// The name.
/// The description.
internal async Task ModifyGuildTemplateAsync(ulong guildId, string templateCode, string name, string description)
{
var pld = new RestGuildTemplateCreateOrModifyPayload
{
Name = name,
Description = description
};
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.TEMPLATES}/:template_code";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new {guild_id = guildId, template_code = templateCode }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, payload: DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
var templateRaw = DiscordJson.DeserializeObject(res.Response, this.Discord);
return templateRaw;
}
///
/// Deletes the guild template async.
///
/// The guild_id.
/// The template_code.
internal async Task DeleteGuildTemplateAsync(ulong guildId, string templateCode)
{
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.TEMPLATES}/:template_code";
var bucket = this.Rest.GetBucket(RestRequestMethod.DELETE, route, new {guild_id = guildId, template_code = templateCode }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.DELETE, route).ConfigureAwait(false);
var templateRaw = DiscordJson.DeserializeObject(res.Response, this.Discord);
return templateRaw;
}
///
/// Gets the guild membership screening form async.
///
/// The guild_id.
internal async Task GetGuildMembershipScreeningFormAsync(ulong guildId)
{
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.MEMBER_VERIFICATION}";
var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.GET, route).ConfigureAwait(false);
var screeningRaw = DiscordJson.DeserializeObject(res.Response, this.Discord);
return screeningRaw;
}
///
/// Modifies the guild membership screening form async.
///
/// The guild_id.
/// The enabled.
/// The fields.
/// The description.
internal async Task ModifyGuildMembershipScreeningFormAsync(ulong guildId, Optional enabled, Optional fields, Optional description)
{
var pld = new RestGuildMembershipScreeningFormModifyPayload
{
Enabled = enabled,
Description = description,
Fields = fields
};
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.MEMBER_VERIFICATION}";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, payload: DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
var screeningRaw = DiscordJson.DeserializeObject(res.Response, this.Discord);
return screeningRaw;
}
///
/// Gets the guild welcome screen async.
///
/// The guild_id.
internal async Task GetGuildWelcomeScreenAsync(ulong guildId)
{
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.WELCOME_SCREEN}";
var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.GET, route);
var ret = DiscordJson.DeserializeObject(res.Response, this.Discord);
return ret;
}
///
/// Modifies the guild welcome screen async.
///
/// The guild_id.
/// The enabled.
/// The welcome channels.
/// The description.
internal async Task ModifyGuildWelcomeScreenAsync(ulong guildId, Optional enabled, Optional> welcomeChannels, Optional description)
{
var pld = new RestGuildWelcomeScreenModifyPayload
{
Enabled = enabled,
WelcomeChannels = welcomeChannels,
Description = description
};
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.WELCOME_SCREEN}";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, payload: DiscordJson.SerializeObject(pld));
var ret = DiscordJson.DeserializeObject(res.Response, this.Discord);
return ret;
}
///
/// Updates the current user voice state async.
///
/// The guild_id.
/// The channel id.
/// If true, suppress.
/// The request to speak timestamp.
internal async Task UpdateCurrentUserVoiceStateAsync(ulong guildId, ulong channelId, bool? suppress, DateTimeOffset? requestToSpeakTimestamp)
{
var pld = new RestGuildUpdateCurrentUserVoiceStatePayload
{
ChannelId = channelId,
Suppress = suppress,
RequestToSpeakTimestamp = requestToSpeakTimestamp
};
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.VOICE_STATES}/@me";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, payload: DiscordJson.SerializeObject(pld));
}
///
/// Updates the user voice state async.
///
/// The guild_id.
/// The user_id.
/// The channel id.
/// If true, suppress.
internal async Task UpdateUserVoiceStateAsync(ulong guildId, ulong userId, ulong channelId, bool? suppress)
{
var pld = new RestGuildUpdateUserVoiceStatePayload
{
ChannelId = channelId,
Suppress = suppress
};
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.VOICE_STATES}/:user_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new {guild_id = guildId, user_id = userId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, payload: DiscordJson.SerializeObject(pld));
}
///
/// Gets all auto mod rules for a guild.
///
/// The guild id.
/// A collection of all auto mod rules in the guild.
internal async Task> GetAutomodRulesAsync(ulong guildId)
{
var route = $"{Endpoints.GUILDS}/:guild_id/auto-moderation/rules";
var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new { guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.GET, route);
var ret = JsonConvert.DeserializeObject>(res.Response);
foreach (var r in ret)
r.Discord = this.Discord;
return ret.AsReadOnly();
}
///
/// Gets a specific auto mod rule in the guild.
///
/// The guild id for the rule.
/// The rule id.
/// The rule if one is found.
internal async Task GetAutomodRuleAsync(ulong guildId, ulong ruleId)
{
var route = $"{Endpoints.GUILDS}/:guild_id/auto-moderation/rules/:rule_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.GET, route, new { guild_id = guildId, rule_id = ruleId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.GET, route);
var ret = DiscordJson.DeserializeObject(res.Response, this.Discord);
ret.Discord = this.Discord;
return ret;
}
///
/// Creates an auto mod rule.
///
/// The guild id of the rule.
/// The name of the rule.
/// The event type of the rule.
/// The trigger type.
/// The actions of the rule.
/// The metadata of the rule.
/// Whether this rule is enabled.
/// The exempt roles of the rule.
/// The exempt channels of the rule.
/// The reason for this addition.
/// The new auto mod rule.
internal async Task CreateAutomodRuleAsync(ulong guildId, string name, AutomodEventType eventType, AutomodTriggerType triggerType, IEnumerable actions,
AutomodTriggerMetadata triggerMetadata = null, bool enabled = false, IEnumerable exemptRoles = null, IEnumerable exemptChannels = null, string reason = null)
{
var route = $"{Endpoints.GUILDS}/:guild_id/auto-moderation/rules";
var bucket = this.Rest.GetBucket(RestRequestMethod.POST, route, new { guild_id = guildId }, out var path);
RestAutomodRuleModifyPayload pld = new()
{
Name = name,
EventType = eventType,
TriggerType = triggerType,
Actions = actions.ToArray(),
Enabled = enabled,
TriggerMetadata = triggerMetadata ?? null
};
if (exemptChannels != null)
pld.ExemptChannels = exemptChannels.ToArray();
if (exemptRoles != null)
pld.ExemptRoles = exemptRoles.ToArray();
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.POST, route, headers, payload: DiscordJson.SerializeObject(pld)).ConfigureAwait(false);
var ret = DiscordJson.DeserializeObject(res.Response, this.Discord);
ret.Discord = this.Discord;
if (this.Discord is DiscordClient dc)
{
await dc.OnAutomodRuleCreated(ret).ConfigureAwait(false);
}
return ret;
}
///
/// Modifies an auto mod role
///
/// The guild id.
/// The rule id.
/// The new name of the rule.
/// The new event type of the rule.
/// The new metadata of the rule.
/// The new actions of the rule.
/// Whether this rule is enabled.
/// The new exempt roles of the rule.
/// The new exempt channels of the rule.
/// The reason for this modification.
/// The updated automod rule
internal async Task ModifyAutomodRuleAsync(ulong guildId, ulong ruleId, Optional name, Optional eventType, Optional metadata, Optional> actions,
Optional enabled, Optional> exemptRoles, Optional> exemptChannels, string reason = null)
{
var pld = new RestAutomodRuleModifyPayload
{
Name = name,
EventType = eventType,
TriggerMetadata = metadata,
Enabled = enabled
};
if (actions.HasValue)
pld.Actions = actions.Value?.ToArray();
if (exemptChannels.HasValue)
pld.ExemptChannels = exemptChannels.Value?.ToArray();
if (exemptRoles.HasValue)
pld.ExemptRoles = exemptRoles.Value?.ToArray();
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var route = $"{Endpoints.GUILDS}/:guild_id/auto-moderation/rules/:rule_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.PATCH, route, new { guild_id = guildId, rule_id = ruleId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.PATCH, route, headers, payload: DiscordJson.SerializeObject(pld));
var ret = DiscordJson.DeserializeObject(res.Response, this.Discord);
ret.Discord = this.Discord;
if (this.Discord is DiscordClient dc)
{
await dc.OnAutomodRuleUpdated(ret).ConfigureAwait(false);
}
return ret;
}
///
/// Deletes an auto mod rule.
///
/// The guild id of the rule.
/// The rule id.
/// The reason for this deletion.
/// The deleted auto mod rule.
internal async Task DeleteAutomodRuleAsync(ulong guildId, ulong ruleId, string reason = null)
{
var route = $"{Endpoints.GUILDS}/:guild_id/auto-moderation/rules/:rule_id";
var bucket = this.Rest.GetBucket(RestRequestMethod.DELETE, route, new { guild_id = guildId, rule_id = ruleId }, out var path);
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers.Add(REASON_HEADER_NAME, reason);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.DELETE, route, headers).ConfigureAwait(false);
var ret = DiscordJson.DeserializeObject(res.Response, this.Discord);
ret.Discord = this.Discord;
if (this.Discord is DiscordClient dc)
{
await dc.OnAutomodRuleDeleted(ret).ConfigureAwait(false);
}
return ret;
}
#endregion
+ // End todo
#region Guild Scheduled Events
///
/// Creates a scheduled event.
///
internal async Task CreateGuildScheduledEventAsync(ulong guildId, ulong? channelId, DiscordScheduledEventEntityMetadata metadata, string name, DateTimeOffset scheduledStartTime, DateTimeOffset? scheduledEndTime, string description, ScheduledEventEntityType type, Optional coverb64, string reason = null)
{
var pld = new RestGuildScheduledEventCreatePayload
{
ChannelId = channelId,
EntityMetadata = metadata,
Name = name,
ScheduledStartTime = scheduledStartTime,
ScheduledEndTime = scheduledEndTime,
Description = description,
EntityType = type,
CoverBase64 = coverb64
};
var headers = Utilities.GetBaseHeaders();
if (!string.IsNullOrWhiteSpace(reason))
headers[REASON_HEADER_NAME] = reason;
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.SCHEDULED_EVENTS}";
var bucket = this.Rest.GetBucket(RestRequestMethod.POST, route, new {guild_id = guildId }, out var path);
var url = Utilities.GetApiUriFor(path, this.Discord.Configuration);
var res = await this.DoRequestAsync(this.Discord, bucket, url, RestRequestMethod.POST, route, headers, DiscordJson.SerializeObject(pld));
var scheduledEvent = DiscordJson.DeserializeObject(res.Response, this.Discord);
var guild = this.Discord.Guilds[guildId];
scheduledEvent.Discord = this.Discord;
if (scheduledEvent.Creator != null)
scheduledEvent.Creator.Discord = this.Discord;
if (this.Discord is DiscordClient dc)
await dc.OnGuildScheduledEventCreateEventAsync(scheduledEvent, guild);
return scheduledEvent;
}
///
/// Modifies a scheduled event.
///
internal async Task ModifyGuildScheduledEventAsync(ulong guildId, ulong scheduledEventId, Optional channelId, Optional metadata, Optional name, Optional scheduledStartTime, Optional scheduledEndTime, Optional description, Optional type, Optional status, Optional