diff --git a/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionMetadata.cs b/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionMetadata.cs
index c13264d97..26ac3065d 100644
--- a/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionMetadata.cs
+++ b/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionMetadata.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Collections.Immutable;
@@ -5,26 +6,58 @@ namespace Discord;
public class RoleConnectionMetadata
{
+ ///
+ /// Gets the of metadata value.
+ ///
public RoleConnectionMetadataType Type { get; }
+ ///
+ /// Gets the dictionary key for the metadata field.
+ ///
public string Key { get; }
- public string Name{ get; }
-
- public Optional> NameLocalizations { get; }
+ ///
+ /// Gets the name of the metadata field.
+ ///
+ public string Name { get; }
+ ///
+ /// Gets the description of the metadata field.
+ ///
public string Description { get; }
- public Optional> DescriptionLocalizations { get; }
+ ///
+ /// Gets translations of the name. if not set.
+ ///
+ public IReadOnlyDictionary NameLocalizations { get; }
+
+ ///
+ /// Gets translations of the description. if not set.
+ ///
+ public IReadOnlyDictionary DescriptionLocalizations { get; }
internal RoleConnectionMetadata(RoleConnectionMetadataType type, string key, string name, string description,
- Dictionary nameLocalizations = null, Dictionary descriptionLocalizations = null)
+ IDictionary nameLocalizations = null, IDictionary descriptionLocalizations = null)
{
Type = type;
Key = key;
Name = name;
Description = description;
- NameLocalizations = nameLocalizations.ToImmutableDictionary();
- DescriptionLocalizations = descriptionLocalizations.ToImmutableDictionary();
+ NameLocalizations = nameLocalizations?.ToImmutableDictionary();
+ DescriptionLocalizations = descriptionLocalizations?.ToImmutableDictionary();
}
+
+ ///
+ /// Initializes a new with the data from this object.
+ ///
+ public RoleConnectionMetadataProperties ToRoleConnectionMetadataProperties()
+ => new()
+ {
+ Name = Name,
+ Description = Description,
+ Type = Type,
+ Key = Key,
+ NameLocalizations = NameLocalizations,
+ DescriptionLocalizations = DescriptionLocalizations
+ };
}
diff --git a/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionMetadataProperties.cs b/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionMetadataProperties.cs
new file mode 100644
index 000000000..9c4fb87b6
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionMetadataProperties.cs
@@ -0,0 +1,121 @@
+using System.Collections.Generic;
+using System;
+using System.Collections.Immutable;
+
+namespace Discord;
+
+public class RoleConnectionMetadataProperties
+{
+ private const int MaxKeyLength = 50;
+ private const int MaxNameLength = 100;
+ private const int MaxDescriptionLength = 200;
+
+ private string _key;
+ private string _name;
+ private string _description;
+
+ private IReadOnlyDictionary _nameLocalizations;
+ private IReadOnlyDictionary _descriptionLocalizations;
+
+ ///
+ /// Gets or sets the of metadata value.
+ ///
+ public RoleConnectionMetadataType Type { get; set; }
+
+ ///
+ /// Gets or sets the dictionary key for the metadata field.
+ ///
+ public string Key
+ {
+ get => _key;
+ set
+ {
+ Preconditions.AtMost(value.Length, MaxKeyLength, nameof(Key), $"Key length must be less than or equal to {MaxKeyLength}");
+ _key = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the name of the metadata field.
+ ///
+ public string Name
+ {
+ get => _name;
+ set
+ {
+ Preconditions.AtMost(value.Length, MaxNameLength, nameof(Name), $"Name length must be less than or equal to {MaxNameLength}");
+ _name = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the description of the metadata field.
+ ///
+ public string Description
+ {
+ get => _description;
+ set
+ {
+ Preconditions.AtMost(value.Length, MaxDescriptionLength, nameof(Description), $"Description length must be less than or equal to {MaxDescriptionLength}");
+ _description = value;
+ }
+ }
+
+ ///
+ /// Gets or sets translations of the name. if not set.
+ ///
+ public IReadOnlyDictionary NameLocalizations
+ {
+ get => _nameLocalizations;
+ set
+ {
+ if (value is not null)
+ foreach (var localization in value)
+ if (localization.Value.Length > MaxNameLength)
+ throw new ArgumentException($"Name localization length must be less than or equal to {MaxNameLength}. Locale '{localization}'");
+ _nameLocalizations = value;
+ }
+ }
+
+ ///
+ /// Gets or sets translations of the description. if not set.
+ ///
+ public IReadOnlyDictionary DescriptionLocalizations
+ {
+ get => _descriptionLocalizations;
+ set
+ {
+ if (value is not null)
+ foreach (var localization in value)
+ if (localization.Value.Length > MaxDescriptionLength)
+ throw new ArgumentException($"Description localization length must be less than or equal to {MaxDescriptionLength}. Locale '{localization}'");
+ _descriptionLocalizations = value;
+ }
+ }
+
+ ///
+ /// Initializes a new instance of .
+ ///
+ /// The type of the metadata value.
+ /// The dictionary key for the metadata field. Max 50 characters.
+ /// The name of the metadata visible in user profile. Max 100 characters.
+ /// The description of the metadata visible in user profile. Max 200 characters.
+ /// Translations for the name.
+ /// Translations for the description.
+ public RoleConnectionMetadataProperties(RoleConnectionMetadataType type, string key, string name, string description,
+ IDictionary nameLocalizations = null, IDictionary descriptionLocalizations = null)
+ {
+ Type = type;
+ Key = key;
+ Name = name;
+ Description = description;
+ NameLocalizations = nameLocalizations?.ToImmutableDictionary();
+ DescriptionLocalizations = descriptionLocalizations?.ToImmutableDictionary();
+ }
+
+ ///
+ /// Initializes a new instance of .
+ ///
+ public RoleConnectionMetadataProperties() { }
+}
+
diff --git a/src/Discord.Net.Rest/API/Common/RoleConnectionMetadata.cs b/src/Discord.Net.Rest/API/Common/RoleConnectionMetadata.cs
index 472c14e62..9ce36a05d 100644
--- a/src/Discord.Net.Rest/API/Common/RoleConnectionMetadata.cs
+++ b/src/Discord.Net.Rest/API/Common/RoleConnectionMetadata.cs
@@ -18,8 +18,8 @@ public class RoleConnectionMetadata
public string Description { get; set; }
[JsonProperty("name_localizations")]
- public Optional>> NameLocalizations { get; set; }
+ public Optional> NameLocalizations { get; set; }
[JsonProperty("description_localizations")]
- public Optional>> DescriptionLocalizations { get; set; }
+ public Optional> DescriptionLocalizations { get; set; }
}
diff --git a/src/Discord.Net.Rest/ClientHelper.cs b/src/Discord.Net.Rest/ClientHelper.cs
index 0c8f8c42f..b1bd0c544 100644
--- a/src/Discord.Net.Rest/ClientHelper.cs
+++ b/src/Discord.Net.Rest/ClientHelper.cs
@@ -264,5 +264,50 @@ namespace Discord.Rest
public static Task RemoveRoleAsync(BaseDiscordClient client, ulong guildId, ulong userId, ulong roleId, RequestOptions options = null)
=> client.ApiClient.RemoveRoleAsync(guildId, userId, roleId, options);
#endregion
+
+ #region Role Subscription Metadata
+
+ public static async Task> GetRoleConnectionMetadataRecordsAsync(BaseDiscordClient client, RequestOptions options = null)
+ => (await client.ApiClient.GetApplicationRoleConnectionMetadataRecordsAsync(options))
+ .Select(model
+ => new RoleConnectionMetadata(
+ model.Type,
+ model.Key,
+ model.Name,
+ model.Description,
+ model.NameLocalizations.IsSpecified
+ ? model.NameLocalizations.Value?.ToImmutableDictionary()
+ : null,
+ model.DescriptionLocalizations.IsSpecified
+ ? model.DescriptionLocalizations.Value?.ToImmutableDictionary()
+ : null))
+ .ToImmutableArray();
+
+ public static async Task> ModifyRoleConnectionMetadataRecordsAsync(ICollection metadata, BaseDiscordClient client, RequestOptions options = null)
+ => (await client.ApiClient.UpdateApplicationRoleConnectionMetadataRecordsAsync(metadata
+ .Select(x => new API.RoleConnectionMetadata
+ {
+ Name = x.Name,
+ Description = x.Description,
+ Key = x.Key,
+ Type = x.Type,
+ NameLocalizations = x.NameLocalizations?.ToDictionary(),
+ DescriptionLocalizations = x.DescriptionLocalizations?.ToDictionary()
+ }).ToArray()))
+ .Select(model
+ => new RoleConnectionMetadata(
+ model.Type,
+ model.Key,
+ model.Name,
+ model.Description,
+ model.NameLocalizations.IsSpecified
+ ? model.NameLocalizations.Value?.ToImmutableDictionary()
+ : null,
+ model.DescriptionLocalizations.IsSpecified
+ ? model.DescriptionLocalizations.Value?.ToImmutableDictionary()
+ : null))
+ .ToImmutableArray();
+
+ #endregion
}
}
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index 12656be88..4ff6668ab 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -4,7 +4,9 @@ using Discord.Net;
using Discord.Net.Converters;
using Discord.Net.Queue;
using Discord.Net.Rest;
+
using Newtonsoft.Json;
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -2480,25 +2482,17 @@ namespace Discord.API
#region Application Role Connections Metadata
- public async Task> GetApplicationRoleConnectionMetadataRecordsAsync(RequestOptions options = null)
- {
- return await SendAsync>("GET", $"/applications/{CurrentApplicationId}/role-connections/metadata", options: options).ConfigureAwait(false);
- }
+ public async Task GetApplicationRoleConnectionMetadataRecordsAsync(RequestOptions options = null)
+ => await SendAsync("GET", () => $"applications/{CurrentApplicationId}/role-connections/metadata", new BucketIds(), options: options).ConfigureAwait(false);
- public async Task> UpdateApplicationRoleConnectionMetadataRecordsAsync(IEnumerable roleConnections, RequestOptions options = null)
- {
- return await SendJsonAsync>("PUT", $"/applications/{CurrentApplicationId}/role-connections/metadata", roleConnections, options: options).ConfigureAwait(false);
- }
+ public async Task UpdateApplicationRoleConnectionMetadataRecordsAsync(RoleConnectionMetadata[] roleConnections, RequestOptions options = null)
+ => await SendJsonAsync ("PUT", () => $"applications/{CurrentApplicationId}/role-connections/metadata", roleConnections, new BucketIds(), options: options).ConfigureAwait(false);
public async Task GetUserApplicationRoleConnection(RequestOptions options = null)
- {
- return await SendAsync("GET", $"/users/@me/applications/{CurrentApplicationId}/role-connection", options: options);
- }
+ => await SendAsync("GET", () => $"users/@me/applications/{CurrentApplicationId}/role-connection", new BucketIds(), options: options);
public async Task GetUserApplicationRoleConnection(RoleConnection connection, RequestOptions options = null)
- {
- return await SendJsonAsync("PUT", $"/users/@me/applications/{CurrentApplicationId}/role-connection", connection, options: options);
- }
+ => await SendJsonAsync("PUT", () => $"users/@me/applications/{CurrentApplicationId}/role-connection", connection, new BucketIds(), options: options);
#endregion
}
diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs
index ddd38c5be..774738b57 100644
--- a/src/Discord.Net.Rest/DiscordRestClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestClient.cs
@@ -231,7 +231,17 @@ namespace Discord.Rest
=> MessageHelper.RemoveAllReactionsAsync(channelId, messageId, this, options);
public Task RemoveAllReactionsForEmoteAsync(ulong channelId, ulong messageId, IEmote emote, RequestOptions options = null)
=> MessageHelper.RemoveAllReactionsForEmoteAsync(channelId, messageId, emote, this, options);
-#endregion
+
+ public Task> GetRoleConnectionMetadataRecordsAsync(RequestOptions options = null)
+ => ClientHelper.GetRoleConnectionMetadataRecordsAsync(this, options);
+
+ public Task> ModifyRoleConnectionMetadataRecordsAsync(ICollection metadata, RequestOptions options = null)
+ {
+ Preconditions.AtMost(metadata.Count, 5, nameof(metadata), "An application can have a maximum of 5 metadata records.");
+ return ClientHelper.ModifyRoleConnectionMetadataRecordsAsync(metadata, this, options);
+ }
+
+ #endregion
#region IDiscordClient
///