-
-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: clyde endpoints feat: personality generation docs: mark features as experimental
- Loading branch information
Showing
9 changed files
with
452 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
|
||
using DisCatSharp.Attributes; | ||
using DisCatSharp.Entities; | ||
using DisCatSharp.Experimental.Entities; | ||
|
||
namespace DisCatSharp.Experimental; | ||
|
||
/// <summary> | ||
/// Represents experimental extension methods for DisCatSharp. | ||
/// </summary> | ||
public static class DisCatSharpExtensions | ||
{ | ||
[Experimental("This function is being tested and might change at any time."), RequiresFeature(Features.MonetizedApplication)] | ||
public static async Task<string> GetUsernameAsync(this DiscordClient client, ulong id) | ||
{ | ||
var user = await client.ApiClient.GetUserAsync(id); | ||
return user.UsernameWithDiscriminator; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the clyde profile for the given <paramref name="profileId"/>. | ||
/// </summary> | ||
/// <param name="client">The discord client.</param> | ||
/// <param name="profileId">The profile id to get.</param> | ||
[RequiresFeature(Features.Override, "This method requires the guild and/or user to have access to clyde with treatment 5.")] // TODO: Change to Features.Experiment | ||
public static async Task<ClydeProfile> GetClydeProfileAsync(this DiscordClient client, ulong profileId) | ||
{ | ||
DiscordApiClientHook hook = new(client.ApiClient); | ||
return await hook.GetClydeProfileAsync(profileId); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the clyde settings for the given <paramref name="guild"/>. | ||
/// </summary> | ||
/// <param name="guild">The guild to get clyde's settings for.</param> | ||
[RequiresFeature(Features.Override, "This method requires the guild and/or user to have access to clyde with treatment 5.")] // TODO: Change to Features.Experiment | ||
public static async Task<ClydeSettings> GetClydeSettingsAsync(this DiscordGuild guild) | ||
{ | ||
DiscordApiClientHook hook = new(guild.Discord.ApiClient); | ||
return await hook.GetClydeSettingsAsync(guild.Id); | ||
} | ||
|
||
/// <summary> | ||
/// Modifies the clyde settings for the given <paramref name="guild"/> by applying a <paramref name="profileId"/>. | ||
/// </summary> | ||
/// <param name="guild">The guild to modify clyde's settings for.</param> | ||
/// <param name="profileId">The profile id to apply.</param> | ||
[RequiresFeature(Features.Override, "This method requires the guild and/or user to have access to clyde with treatment 5.")] // TODO: Change to Features.Experiment | ||
public static async Task<ClydeSettings> ModifyClydeSettingsAsync(this DiscordGuild guild, ulong profileId) | ||
{ | ||
DiscordApiClientHook hook = new(guild.Discord.ApiClient); | ||
return await hook.ModifyClydeSettingsAsync(guild.Id, profileId); | ||
} | ||
|
||
/// <summary> | ||
/// Modifies the clyde settings for the given <paramref name="guild"/>. | ||
/// </summary> | ||
/// <param name="guild">The guild to modify clyde's settings for.</param> | ||
/// <param name="name">The new name.</param> | ||
/// <param name="personality">The new basePersonality.</param> | ||
/// <param name="avatar">The new avatar.</param> | ||
/// <param name="banner">The new banner.</param> | ||
/// <param name="themeColors">The new theme colors.</param> | ||
[RequiresFeature(Features.Override, "This method requires the guild and/or user to have access to clyde with treatment 5.")] // TODO: Change to Features.Experiment | ||
public static async Task<ClydeSettings> ModifyClydeSettingsAsync( | ||
this DiscordGuild guild, | ||
Optional<string?> name, | ||
Optional<string> personality, | ||
Optional<Stream?> avatar, | ||
Optional<Stream?> banner, | ||
Optional<List<DiscordColor>?> themeColors | ||
) | ||
{ | ||
DiscordApiClientHook hook = new(guild.Discord.ApiClient); | ||
|
||
return await hook.ModifyClydeSettingsAsync(guild.Id, name, personality, ImageTool.Base64FromStream(avatar), ImageTool.Base64FromStream(banner), themeColors.HasValue && themeColors.Value.Any() | ||
? themeColors.Value.Select(x => x.Value).ToList() | ||
: themeColors.HasValue | ||
? Optional.FromNullable<List<int>?>(null) | ||
: Optional.None); | ||
} | ||
|
||
/// <summary> | ||
/// Generates a basePersonality for clyde based on the given <paramref name="basePersonality"/>. | ||
/// </summary> | ||
/// <param name="client">The discord client.</param> | ||
/// <param name="basePersonality">The base base personality to generate a new one from.</param> | ||
[RequiresFeature(Features.Override, "This method requires the guild and/or user to have access to clyde with treatment 5.")] // TODO: Change to Features.Experiment | ||
public static async Task<string> GenerateClydePersonalityAsync(this DiscordClient client, string? basePersonality = null) | ||
{ | ||
DiscordApiClientHook hook = new(client.ApiClient); | ||
return await hook.GenerateClydePersonalityAsync(basePersonality); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,162 @@ | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Threading.Tasks; | ||
|
||
using DisCatSharp.Entities; | ||
using DisCatSharp.Experimental.Entities; | ||
using DisCatSharp.Experimental.Payloads; | ||
using DisCatSharp.Net; | ||
using DisCatSharp.Net.Serialization; | ||
|
||
using Newtonsoft.Json.Linq; | ||
|
||
namespace DisCatSharp.Experimental; | ||
|
||
internal class DiscordApiClientHook | ||
/// <summary> | ||
/// Represents a hook for the discord api client. | ||
/// </summary> | ||
internal sealed class DiscordApiClientHook | ||
{ | ||
/// <summary> | ||
/// Gets the api client. | ||
/// </summary> | ||
internal DiscordApiClient ApiClient { get; set; } | ||
|
||
public DiscordApiClientHook(DiscordApiClient apiClient) | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="DiscordApiClientHook"/> class. | ||
/// </summary> | ||
/// <param name="apiClient">The api client.</param> | ||
internal DiscordApiClientHook(DiscordApiClient apiClient) | ||
{ | ||
this.ApiClient = apiClient; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the clyde profile for the given <paramref name="profileId"/>. | ||
/// </summary> | ||
/// <param name="profileId">The profile id to get.</param> | ||
internal async Task<ClydeProfile> GetClydeProfileAsync(ulong profileId) | ||
{ | ||
var route = $"{Endpoints.CLYDE_PROFILES}/:profile_id"; | ||
var bucket = this.ApiClient.Rest.GetBucket(RestRequestMethod.GET, route, new | ||
{ | ||
profile_id = profileId | ||
}, out var path); | ||
|
||
var url = Utilities.GetApiUriFor(path, this.ApiClient.Discord.Configuration); | ||
var res = await this.ApiClient.DoRequestAsync(this.ApiClient.Discord, bucket, url, RestRequestMethod.GET, route).ConfigureAwait(false); | ||
|
||
var profile = DiscordJson.DeserializeObject<ClydeProfile>(res.Response, this.ApiClient.Discord); | ||
return profile; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the clyde settings for the given <paramref name="guildId"/>. | ||
/// </summary> | ||
/// <param name="guildId">The guild id to get clyde's settings for.</param> | ||
internal async Task<ClydeSettings> GetClydeSettingsAsync(ulong guildId) | ||
{ | ||
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.CLYDE_SETTINGS}"; | ||
var bucket = this.ApiClient.Rest.GetBucket(RestRequestMethod.GET, route, new | ||
{ | ||
guild_id = guildId | ||
}, out var path); | ||
|
||
var url = Utilities.GetApiUriFor(path, this.ApiClient.Discord.Configuration); | ||
var res = await this.ApiClient.DoRequestAsync(this.ApiClient.Discord, bucket, url, RestRequestMethod.GET, route).ConfigureAwait(false); | ||
|
||
var settings = DiscordJson.DeserializeObject<ClydeSettings>(res.Response, this.ApiClient.Discord); | ||
return settings; | ||
} | ||
|
||
/// <summary> | ||
/// Modifies the clyde settings for the given <paramref name="guildId"/> by applying a <paramref name="profileId"/>. | ||
/// </summary> | ||
/// <param name="guildId">The guild id to modify clyde's settings for.</param> | ||
/// <param name="profileId">The profile id to apply.</param> | ||
internal async Task<ClydeSettings> ModifyClydeSettingsAsync(ulong guildId, ulong profileId) | ||
{ | ||
ClydeSettingsProfileIdOnlyUpdatePayload pld = new() | ||
{ | ||
ClydeProfileId = profileId | ||
}; | ||
|
||
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.CLYDE_SETTINGS}"; | ||
var bucket = this.ApiClient.Rest.GetBucket(RestRequestMethod.PATCH, route, new | ||
{ | ||
guild_id = guildId | ||
}, out var path); | ||
|
||
var url = Utilities.GetApiUriFor(path, this.ApiClient.Discord.Configuration); | ||
var res = await this.ApiClient.DoRequestAsync(this.ApiClient.Discord, bucket, url, RestRequestMethod.PATCH, route, payload: DiscordJson.SerializeObject(pld)).ConfigureAwait(false); | ||
|
||
var obj = JObject.Parse(res.Response); | ||
var settingsString = obj.GetValue("settings")!.ToString(); | ||
var settings = DiscordJson.DeserializeObject<ClydeSettings>(settingsString, this.ApiClient.Discord); | ||
return settings; | ||
} | ||
|
||
/// <summary> | ||
/// Modifies the clyde settings for the given <paramref name="guildId"/>. | ||
/// </summary> | ||
/// <param name="guildId">The guild id to modify clyde's settings for.</param> | ||
/// <param name="name">The new name.</param> | ||
/// <param name="personality">The new basePersonality.</param> | ||
/// <param name="avatarBase64">The new avatar.</param> | ||
/// <param name="bannerBase64">The new banner.</param> | ||
/// <param name="themeColors">The new theme colors.</param> | ||
internal async Task<ClydeSettings> ModifyClydeSettingsAsync( | ||
ulong guildId, | ||
Optional<string?> name, | ||
Optional<string> personality, | ||
Optional<string?> avatarBase64, | ||
Optional<string?> bannerBase64, | ||
Optional<List<int>?> themeColors | ||
) | ||
{ | ||
ClydeSettingsProfileUpdatePayload pld = new() | ||
{ | ||
Nick = name, | ||
Personality = personality, | ||
Avatar = avatarBase64, | ||
Banner = bannerBase64, | ||
ThemeColors = themeColors | ||
}; | ||
|
||
var route = $"{Endpoints.GUILDS}/:guild_id{Endpoints.CLYDE_SETTINGS}"; | ||
var bucket = this.ApiClient.Rest.GetBucket(RestRequestMethod.PATCH, route, new | ||
{ | ||
guild_id = guildId | ||
}, out var path); | ||
|
||
var url = Utilities.GetApiUriFor(path, this.ApiClient.Discord.Configuration); | ||
var res = await this.ApiClient.DoRequestAsync(this.ApiClient.Discord, bucket, url, RestRequestMethod.PATCH, route, payload: DiscordJson.SerializeObject(pld)).ConfigureAwait(false); | ||
|
||
var obj = JObject.Parse(res.Response); | ||
var settingsString = obj.GetValue("settings")!.ToString(); | ||
var settings = DiscordJson.DeserializeObject<ClydeSettings>(settingsString, this.ApiClient.Discord); | ||
return settings; | ||
} | ||
|
||
/// <summary> | ||
/// Generates a basePersonality for clyde based on the given <paramref name="basePersonality"/>. | ||
/// </summary> | ||
/// <param name="basePersonality">The base base personality to generate a new one from.</param> | ||
internal async Task<string> GenerateClydePersonalityAsync(string? basePersonality = null) | ||
{ | ||
PersonalityGenerationPayload pld = new() | ||
{ | ||
Personality = basePersonality ?? string.Empty | ||
}; | ||
|
||
var route = $"{Endpoints.CLYDE_PROFILES}{Endpoints.GENERATE_PERSONALITY}"; | ||
var bucket = this.ApiClient.Rest.GetBucket(RestRequestMethod.POST, route, new | ||
{ }, out var path); | ||
|
||
var url = Utilities.GetApiUriFor(path, this.ApiClient.Discord.Configuration); | ||
var res = await this.ApiClient.DoRequestAsync(this.ApiClient.Discord, bucket, url, RestRequestMethod.POST, route, payload: DiscordJson.SerializeObject(pld)).ConfigureAwait(false); | ||
|
||
var generatedPersonality = DiscordJson.DeserializeObject<PersonalityGenerationPayload>(res.Response, this.ApiClient.Discord); | ||
return generatedPersonality.Personality; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Globalization; | ||
using System.Linq; | ||
|
||
using DisCatSharp.Entities; | ||
using DisCatSharp.Enums; | ||
using DisCatSharp.Net; | ||
|
||
using Newtonsoft.Json; | ||
|
||
namespace DisCatSharp.Experimental.Entities; | ||
|
||
/// <summary> | ||
/// Represents a clyde profile. | ||
/// </summary> | ||
public sealed class ClydeProfile : ObservableApiObject | ||
{ | ||
/// <summary> | ||
/// Gets clyde's profile name. | ||
/// </summary> | ||
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] | ||
public string? Name { get; internal set; } | ||
|
||
/// <summary> | ||
/// Gets clyde's profile personality. | ||
/// </summary> | ||
[JsonProperty("personality", NullValueHandling = NullValueHandling.Ignore)] | ||
public string Personality { get; internal set; } | ||
|
||
/// <summary> | ||
/// Gets clyde's profile avatar hash. | ||
/// </summary> | ||
[JsonProperty("avatar_hash", NullValueHandling = NullValueHandling.Ignore)] | ||
public string? AvatarHash { get; internal set; } | ||
|
||
/// <summary> | ||
/// Gets clyde's profile banner hash. | ||
/// </summary> | ||
[JsonProperty("banner_hash", NullValueHandling = NullValueHandling.Ignore)] | ||
public string? BannerHash { get; internal set; } | ||
|
||
/// <summary> | ||
/// Gets clyde's profile bio. | ||
/// </summary> | ||
[JsonProperty("bio", NullValueHandling = NullValueHandling.Ignore)] | ||
public string Bio { get; internal set; } | ||
|
||
/// <summary> | ||
/// Gets the user who authored this clyde profile. | ||
/// </summary> | ||
[JsonProperty("author_id", NullValueHandling = NullValueHandling.Ignore)] | ||
public ulong AuthorId { get; internal set; } | ||
|
||
/// <summary> | ||
/// Gets clyde's profile theme color ints. | ||
/// </summary> | ||
[JsonProperty("theme_colors", NullValueHandling = NullValueHandling.Ignore)] | ||
internal List<int>? ThemeColorsInternal { get; set; } | ||
|
||
/// <summary> | ||
/// Gets the clyde's profile theme colors, if set. | ||
/// </summary> | ||
[JsonIgnore] | ||
public IReadOnlyList<DiscordColor>? ThemeColors | ||
=> !(this.ThemeColorsInternal is not null && this.ThemeColorsInternal.Count != 0) ? null : this.ThemeColorsInternal.Select(x => new DiscordColor(x)).ToList(); | ||
|
||
/// <summary> | ||
/// Gets clyde's profile id. | ||
/// </summary> | ||
[JsonProperty("clyde_profile_id", NullValueHandling = NullValueHandling.Ignore)] | ||
public ulong ClydeProfileId { get; internal set; } | ||
} |
Oops, something went wrong.