feat(bot): allow querying legacy embeds with -se flag

This commit is contained in:
Iris System 2025-08-25 14:26:29 +12:00
parent 1b2d069f28
commit 35e5fa4800
4 changed files with 119 additions and 0 deletions

View file

@ -520,6 +520,12 @@ public class Groups
public async Task ShowGroupCard(Context ctx, PKGroup target)
{
var system = await GetGroupSystem(ctx, target);
if (ctx.MatchFlag("show-embed", "se"))
{
await ctx.Reply(text: EmbedService.LEGACY_EMBED_WARNING, embed: await _embeds.CreateGroupEmbed(ctx, system, target));
return;
}
await ctx.Reply(components: await _embeds.CreateGroupMessageComponents(ctx, system, target));
}

View file

@ -122,6 +122,14 @@ public class Member
public async Task ViewMember(Context ctx, PKMember target)
{
var system = await ctx.Repository.GetSystem(target.System);
if (ctx.MatchFlag("show-embed", "se"))
{
await ctx.Reply(
text: EmbedService.LEGACY_EMBED_WARNING,
embed: await _embeds.CreateMemberEmbed(system, target, ctx.Guild, ctx.Config, ctx.LookupContextFor(system.Id), ctx.Zone));
return;
}
await ctx.Reply(
components: await _embeds.CreateMemberMessageComponents(system, target, ctx.Guild, ctx.Config, ctx.LookupContextFor(system.Id), ctx.Zone));
}

View file

@ -17,6 +17,11 @@ public class System
public async Task Query(Context ctx, PKSystem system)
{
if (system == null) throw Errors.NoSystemError(ctx.DefaultPrefix);
if (ctx.MatchFlag("show-embed", "se"))
{
await ctx.Reply(text: EmbedService.LEGACY_EMBED_WARNING, embed: await _embeds.CreateSystemEmbed(ctx, system, ctx.LookupContextFor(system.Id)));
return;
}
await ctx.Reply(components: await _embeds.CreateSystemMessageComponents(ctx, system, ctx.LookupContextFor(system.Id)));
}

View file

@ -15,6 +15,8 @@ namespace PluralKit.Bot;
public class EmbedService
{
public const string LEGACY_EMBED_WARNING = "\u26A0\uFE0F The \"legacy\" embeds for system/member/group cards are deprecated, and will be removed in future.";
private readonly IDiscordCache _cache;
private readonly IDatabase _db;
private readonly ModelRepository _repo;
@ -186,6 +188,104 @@ public class EmbedService
];
}
public async Task<Embed> CreateSystemEmbed(Context cctx, PKSystem system, LookupContext ctx)
{
// Fetch/render info for all accounts simultaneously
var accounts = await _repo.GetSystemAccounts(system.Id);
var users = (await GetUsers(accounts)).Select(x => x.User?.NameAndMention() ?? $"(deleted account {x.Id})");
var countctx = LookupContext.ByNonOwner;
if (cctx.MatchFlag("a", "all"))
{
if (system.Id == cctx.System.Id)
countctx = LookupContext.ByOwner;
else
throw Errors.LookupNotAllowed;
}
var memberCount = await _repo.GetSystemMemberCount(system.Id, countctx == LookupContext.ByOwner ? null : PrivacyLevel.Public);
var eb = new EmbedBuilder()
.Title(system.NameFor(ctx))
.Footer(new Embed.EmbedFooter(
$"System ID: {system.DisplayHid(cctx.Config)} | Created on {system.Created.FormatZoned(cctx.Zone)}"))
.Color(system.Color?.ToDiscordColor())
.Url($"https://dash.pluralkit.me/profile/s/{system.Hid}");
var avatar = system.AvatarFor(ctx);
if (avatar != null)
eb.Thumbnail(new Embed.EmbedThumbnail(avatar));
if (system.BannerPrivacy.CanAccess(ctx))
eb.Image(new Embed.EmbedImage(system.BannerImage));
var latestSwitch = await _repo.GetLatestSwitch(system.Id);
if (latestSwitch != null && system.FrontPrivacy.CanAccess(ctx))
{
var switchMembers =
await _db.Execute(conn => _repo.GetSwitchMembers(conn, latestSwitch.Id)).ToListAsync();
if (switchMembers.Count > 0)
{
var memberStr = string.Join(", ", switchMembers.Select(m => m.NameFor(ctx)));
if (memberStr.Length > 200)
memberStr = $"[too many to show, see `{cctx.DefaultPrefix}system {system.DisplayHid(cctx.Config)} fronters`]";
eb.Field(new Embed.Field("Fronter".ToQuantity(switchMembers.Count, ShowQuantityAs.None), memberStr));
}
}
if (system.Tag != null)
eb.Field(new Embed.Field("Tag", system.Tag.EscapeMarkdown(), true));
if (cctx.Guild != null)
{
var guildSettings = await _repo.GetSystemGuild(cctx.Guild.Id, system.Id);
if (guildSettings.Tag != null && guildSettings.TagEnabled)
eb.Field(new Embed.Field($"Tag (in server '{cctx.Guild.Name}')", guildSettings.Tag
.EscapeMarkdown(), true));
if (!guildSettings.TagEnabled)
eb.Field(new Embed.Field($"Tag (in server '{cctx.Guild.Name}')",
"*(tag is disabled in this server)*"));
if (guildSettings.DisplayName != null)
eb.Title(guildSettings.DisplayName);
var guildAvatar = guildSettings.AvatarUrl.TryGetCleanCdnUrl();
if (guildAvatar != null)
{
eb.Thumbnail(new Embed.EmbedThumbnail(guildAvatar));
var sysDesc = "*(this system has a server-specific avatar set";
if (avatar != null)
sysDesc += $"; [click here]({system.AvatarUrl.TryGetCleanCdnUrl()}) to see their global avatar)*";
else
sysDesc += ")*";
eb.Description(sysDesc);
}
}
if (system.PronounPrivacy.CanAccess(ctx) && system.Pronouns != null)
eb.Field(new Embed.Field("Pronouns", system.Pronouns, true));
if (!system.Color.EmptyOrNull()) eb.Field(new Embed.Field("Color", $"#{system.Color}", true));
eb.Field(new Embed.Field("Linked accounts", string.Join("\n", users).Truncate(1000), true));
if (system.MemberListPrivacy.CanAccess(ctx))
{
if (memberCount > 0)
eb.Field(new Embed.Field($"Members ({memberCount})",
$"(see `{cctx.DefaultPrefix}system {system.DisplayHid(cctx.Config)} list` or `{cctx.DefaultPrefix}system {system.DisplayHid(cctx.Config)} list full`)", true));
else
eb.Field(new Embed.Field($"Members ({memberCount})", $"Add one with `{cctx.DefaultPrefix}member new`!", true));
}
if (system.DescriptionFor(ctx) is { } desc)
eb.Field(new Embed.Field("Description", desc.NormalizeLineEndSpacing().Truncate(1024)));
return eb.Build();
}
public Embed CreateLoggedMessageEmbed(Message triggerMessage, Message proxiedMessage, string systemHid,
PKMember member, string channelName, string oldContent = null)
{