Refactor tag editing command to improve option handling and embed structure

- Simplified the retrieval of command options for editing tags, enhancing readability and maintainability.
- Updated embed handling to use an object structure instead of null, ensuring consistency in the updateTag function.
- Improved overall clarity by using descriptive variable names for command options.
This commit is contained in:
smueller
2026-07-22 13:09:06 +02:00
parent 8ec9b94879
commit 1ceb8c3574
3 changed files with 31 additions and 23 deletions

View File

@@ -1,4 +1,4 @@
import { PermissionFlagsBits } from 'discord.js'; import { ChannelType, PermissionFlagsBits } from 'discord.js';
import { import {
SelfRoleBehaviorSchema, SelfRoleBehaviorSchema,
SelfRoleModeSchema, SelfRoleModeSchema,
@@ -71,8 +71,7 @@ const selfrolesCommand: SlashCommand = {
); );
const mode = SelfRoleModeSchema.parse(interaction.options.getString('mode', true)); const mode = SelfRoleModeSchema.parse(interaction.options.getString('mode', true));
const channel = interaction.options.getChannel('channel', true); const channel = interaction.options.getChannel('channel', true);
if (channel.type !== ChannelType.GuildText && channel.type !== ChannelType.GuildAnnouncement) {
if (!channel.isTextBased() || channel.isDMBased()) {
await interaction.reply({ await interaction.reply({
content: t(locale, 'selfroles.error.invalid_channel'), content: t(locale, 'selfroles.error.invalid_channel'),
ephemeral: true ephemeral: true

View File

@@ -99,28 +99,32 @@ const tagCommand: SlashCommand = {
} }
if (sub === 'edit') { if (sub === 'edit') {
const contentValue = interaction.options.getString('content');
const triggerValue = interaction.options.getString('trigger_word');
const rolesValue = interaction.options.getString('allowed_roles');
const channelsValue = interaction.options.getString('allowed_channels');
const embedTitle = interaction.options.getString('embed_title');
const embedDescription = interaction.options.getString('embed_description');
const embedColor = interaction.options.getInteger('embed_color');
const embedProvided =
embedTitle !== null || embedDescription !== null || embedColor !== null;
const tag = await updateTag(context, interaction.guildId!, interaction.options.getString('name', true), { const tag = await updateTag(context, interaction.guildId!, interaction.options.getString('name', true), {
newName: interaction.options.getString('new_name') ?? undefined, newName: interaction.options.getString('new_name') ?? undefined,
responseType: interaction.options.getString('response_type') responseType: interaction.options.getString('response_type')
? TagResponseTypeSchema.parse(interaction.options.getString('response_type')) ? TagResponseTypeSchema.parse(interaction.options.getString('response_type'))
: undefined, : undefined,
content: interaction.options.has('content') content: contentValue !== null ? contentValue : undefined,
? interaction.options.getString('content') embed: embedProvided
? {
title: embedTitle ?? undefined,
description: embedDescription ?? undefined,
color: embedColor ?? undefined
}
: undefined, : undefined,
embed: interaction.options.has('embed_title') || triggerWord: triggerValue !== null ? triggerValue : undefined,
interaction.options.has('embed_description') || allowedRoleIds: rolesValue !== null ? parseIdList(rolesValue) : undefined,
interaction.options.has('embed_color') allowedChannelIds: channelsValue !== null ? parseIdList(channelsValue) : undefined
? buildEmbedPayload(interaction) ?? null
: undefined,
triggerWord: interaction.options.has('trigger_word')
? interaction.options.getString('trigger_word')
: undefined,
allowedRoleIds: interaction.options.has('allowed_roles')
? parseIdList(interaction.options.getString('allowed_roles'))
: undefined,
allowedChannelIds: interaction.options.has('allowed_channels')
? parseIdList(interaction.options.getString('allowed_channels'))
: undefined
}); });
await interaction.reply({ await interaction.reply({

View File

@@ -1,4 +1,4 @@
import { EmbedBuilder, type Guild, type GuildMember, type InteractionReplyOptions } from 'discord.js'; import { EmbedBuilder, type Guild, type GuildMember } from 'discord.js';
import { import {
applyTagPlaceholders, applyTagPlaceholders,
TagResponseTypeSchema, TagResponseTypeSchema,
@@ -64,12 +64,17 @@ export function parseTagEmbed(raw: unknown) {
return parsed.success ? parsed.data : null; return parsed.success ? parsed.data : null;
} }
export type TagReplyPayload = {
content?: string;
embeds?: EmbedBuilder[];
};
export function buildTagReply( export function buildTagReply(
tag: Tag, tag: Tag,
member: GuildMember | null, member: GuildMember | null,
guild: Guild, guild: Guild,
args: string args: string
): InteractionReplyOptions { ): TagReplyPayload {
const vars = buildTagPlaceholderVars(member, guild, args); const vars = buildTagPlaceholderVars(member, guild, args);
const responseType = TagResponseTypeSchema.parse(tag.responseType); const responseType = TagResponseTypeSchema.parse(tag.responseType);
@@ -208,7 +213,7 @@ export async function updateTag(
name: newName ?? existing.name, name: newName ?? existing.name,
responseType, responseType,
content, content,
embed: embed ?? null, embed: embed ?? undefined,
triggerWord: triggerWord:
updates.triggerWord !== undefined ? updates.triggerWord?.trim() || null : existing.triggerWord, updates.triggerWord !== undefined ? updates.triggerWord?.trim() || null : existing.triggerWord,
allowedRoleIds: updates.allowedRoleIds ?? existing.allowedRoleIds, allowedRoleIds: updates.allowedRoleIds ?? existing.allowedRoleIds,
@@ -240,7 +245,7 @@ export async function executeTag(
guild: Guild, guild: Guild,
channelId: string, channelId: string,
args: string args: string
): Promise<MessageReplyOptions> { ): Promise<TagReplyPayload> {
const tag = await getTagByName(context, guildId, name); const tag = await getTagByName(context, guildId, name);
if (!tag) { if (!tag) {
throw new TagError('not_found'); throw new TagError('not_found');