diff --git a/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnection.cs b/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnection.cs index aa4bd3348..b764fedc8 100644 --- a/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnection.cs +++ b/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnection.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; namespace Discord; @@ -18,14 +19,25 @@ public class RoleConnection public string PlatformUsername { get; } /// - /// + /// Gets the object mapping keys to their string-ified values. /// - public IReadOnlyDictionary Metadata { get; } + public IReadOnlyDictionary Metadata { get; } - internal RoleConnection(string platformName, string platformUsername, IReadOnlyDictionary metadata) + internal RoleConnection(string platformName, string platformUsername, IReadOnlyDictionary metadata) { PlatformName = platformName; PlatformUsername = platformUsername; Metadata = metadata; } + + /// + /// Initializes a new with the data from this object. + /// + public RoleConnectionProperties ToRoleConnectionProperties() + => new() + { + PlatformName = PlatformName, + PlatformUsername = PlatformUsername, + Metadata = Metadata.ToDictionary() + }; } diff --git a/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionMetadataProperties.cs b/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionMetadataProperties.cs index d313fcfc6..b88e57ccc 100644 --- a/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionMetadataProperties.cs +++ b/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionMetadataProperties.cs @@ -120,5 +120,19 @@ public class RoleConnectionMetadataProperties /// Initializes a new instance of . /// public RoleConnectionMetadataProperties() { } + + /// + /// Initializes a new with the data from provided . + /// + public static RoleConnectionMetadataProperties FromRoleConnectionMetadata(RoleConnectionMetadata metadata) + => new() + { + Name = metadata.Name, + Description = metadata.Description, + Type = metadata.Type, + Key = metadata.Key, + NameLocalizations = metadata.NameLocalizations, + DescriptionLocalizations = metadata.DescriptionLocalizations + }; } diff --git a/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionProperties.cs b/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionProperties.cs new file mode 100644 index 000000000..db68fada5 --- /dev/null +++ b/src/Discord.Net.Core/Entities/ApplicationRoleConnection/RoleConnectionProperties.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; + +namespace Discord; + +/// +/// Represents the properties used to modify user's . +/// +public class RoleConnectionProperties +{ + private const int MaxPlatformNameLength = 50; + private const int MaxPlatformUsernameLength = 100; + private const int MaxMetadataRecords = 100; + + private string _platformName; + private string _platformUsername; + private Dictionary _metadata; + + /// + /// Gets or sets the vanity name of the platform a bot has connected. Max 50 characters. + /// + public string PlatformName + { + get => _platformName; + set + { + if (value is not null) + Preconditions.AtMost(value.Length, MaxPlatformNameLength, nameof(PlatformName), $"Platform name length must be less or equal to {MaxPlatformNameLength}"); + _platformName = value; + } + } + + /// + /// Gets or sets the username on the platform a bot has connected. Max 100 characters. + /// + public string PlatformUsername + { + get => _platformUsername; + set + { + if(value is not null) + Preconditions.AtMost(value.Length, MaxPlatformUsernameLength, nameof(PlatformUsername), $"Platform username length must be less or equal to {MaxPlatformUsernameLength}"); + _platformUsername = value; + } + } + + /// + /// Gets or sets object mapping keys to their string-ified values. + /// + public Dictionary Metadata + { + get => _metadata; + set + { + if (value is not null) + Preconditions.AtMost(value.Count, MaxPlatformUsernameLength, nameof(Metadata), $"Metadata records count must be less or equal to {MaxMetadataRecords}"); + _metadata = value; + } + } + + /// + /// Adds a metadata record with the provided key and value. + /// + /// The current . + public RoleConnectionProperties WithDate(string key, DateTimeOffset value) + => AddMetadataRecord(key, value.ToString("O")); + + /// + /// Adds a metadata record with the provided key and value. + /// + /// The current . + public RoleConnectionProperties WithBool(string key, bool value) + => AddMetadataRecord(key, value ? "1" : "0"); + + /// + /// Adds a metadata record with the provided key and value. + /// + /// The current . + public RoleConnectionProperties WithNumber(string key, int value) + => AddMetadataRecord(key, value.ToString()); + + /// + /// Adds a metadata record with the provided key and value. + /// + /// The current . + public RoleConnectionProperties WithNumber(string key, uint value) + => AddMetadataRecord(key, value.ToString()); + + /// + /// Adds a metadata record with the provided key and value. + /// + /// The current . + public RoleConnectionProperties WithNumber(string key, long value) + => AddMetadataRecord(key, value.ToString()); + + /// + /// Adds a metadata record with the provided key and value. + /// + /// The current . + public RoleConnectionProperties WithNumber(string key, ulong value) + => AddMetadataRecord(key, value.ToString()); + + internal RoleConnectionProperties AddMetadataRecord(string key, string value) + { + Metadata ??= new Dictionary(); + if(!Metadata.ContainsKey(key)) + Preconditions.AtMost(Metadata.Count + 1, MaxPlatformUsernameLength, nameof(Metadata), $"Metadata records count must be less or equal to {MaxMetadataRecords}"); + + _metadata[key] = value; + return this; + } + + /// + /// Initializes a new instance of . + /// + /// The name of the platform a bot has connected.s + /// Gets the username on the platform a bot has connected. + /// Object mapping keys to their values. + public RoleConnectionProperties(string platformName, string platformUsername, IDictionary metadata = null) + { + PlatformName = platformName; + PlatformUsername = platformUsername; + Metadata = metadata.ToDictionary(); + } + + /// + /// Initializes a new instance of . + /// + public RoleConnectionProperties() {} + + /// + /// Initializes a new with the data from provided . + /// + public static RoleConnectionProperties FromRoleConnection(RoleConnection roleConnection) + => new() + { + PlatformName = roleConnection.PlatformName, + PlatformUsername = roleConnection.PlatformUsername, + Metadata = roleConnection.Metadata.ToDictionary() + }; +} diff --git a/src/Discord.Net.Rest/ClientHelper.cs b/src/Discord.Net.Rest/ClientHelper.cs index b1bd0c544..61766131c 100644 --- a/src/Discord.Net.Rest/ClientHelper.cs +++ b/src/Discord.Net.Rest/ClientHelper.cs @@ -265,7 +265,7 @@ namespace Discord.Rest => client.ApiClient.RemoveRoleAsync(guildId, userId, roleId, options); #endregion - #region Role Subscription Metadata + #region Role Connection Metadata public static async Task> GetRoleConnectionMetadataRecordsAsync(BaseDiscordClient client, RequestOptions options = null) => (await client.ApiClient.GetApplicationRoleConnectionMetadataRecordsAsync(options)) @@ -308,6 +308,33 @@ namespace Discord.Rest : null)) .ToImmutableArray(); + public static async Task GetUserRoleConnectionAsync(ulong applicationId, BaseDiscordClient client, RequestOptions options = null) + { + var roleConnection = await client.ApiClient.GetUserApplicationRoleConnectionAsync(applicationId, options); + + return new RoleConnection(roleConnection.PlatformName.GetValueOrDefault(null), + roleConnection.PlatformUsername.GetValueOrDefault(null), + roleConnection.Metadata.GetValueOrDefault()); + } + + public static async Task ModifyUserRoleConnectionAsync(ulong applicationId, RoleConnectionProperties roleConnection, BaseDiscordClient client, RequestOptions options = null) + { + var updatedConnection = await client.ApiClient.ModifyUserApplicationRoleConnectionAsync(applicationId, + new API.RoleConnection + { + PlatformName = roleConnection.PlatformName, + PlatformUsername = roleConnection.PlatformUsername, + Metadata = roleConnection.Metadata + }, options); + + return new RoleConnection( + updatedConnection.PlatformName.GetValueOrDefault(null), + updatedConnection.PlatformUsername.GetValueOrDefault(null), + updatedConnection.Metadata.GetValueOrDefault()?.ToImmutableDictionary() + ); + } + + #endregion } } diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs index 4ff6668ab..56a86d46c 100644 --- a/src/Discord.Net.Rest/DiscordRestApiClient.cs +++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs @@ -2488,11 +2488,11 @@ namespace Discord.API 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) - => await SendAsync("GET", () => $"users/@me/applications/{CurrentApplicationId}/role-connection", new BucketIds(), options: options); + public async Task GetUserApplicationRoleConnectionAsync(ulong applicationId, RequestOptions options = null) + => await SendAsync("GET", () => $"users/@me/applications/{applicationId}/role-connection", new BucketIds(), options: options); - public async Task GetUserApplicationRoleConnection(RoleConnection connection, RequestOptions options = null) - => await SendJsonAsync("PUT", () => $"users/@me/applications/{CurrentApplicationId}/role-connection", connection, new BucketIds(), options: options); + public async Task ModifyUserApplicationRoleConnectionAsync(ulong applicationId, RoleConnection connection, RequestOptions options = null) + => await SendJsonAsync("PUT", () => $"users/@me/applications/{applicationId}/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 774738b57..0778e69ad 100644 --- a/src/Discord.Net.Rest/DiscordRestClient.cs +++ b/src/Discord.Net.Rest/DiscordRestClient.cs @@ -241,6 +241,12 @@ namespace Discord.Rest return ClientHelper.ModifyRoleConnectionMetadataRecordsAsync(metadata, this, options); } + public Task GetUserApplicationRoleConnectionAsync(ulong applicationId, RequestOptions options = null) + => ClientHelper.GetUserRoleConnectionAsync(applicationId, this, options); + + public Task ModifyUserApplicationRoleConnectionAsync(ulong applicationId, RoleConnectionProperties roleConnection, RequestOptions options = null) + => ClientHelper.ModifyUserRoleConnectionAsync(applicationId, roleConnection, this, options); + #endregion #region IDiscordClient