all repos — stealth-developers @ 960f8f74d3c05db34f143b02ffb9180777ed6380

src/interactions/buttons/tickets/message.ts (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
import {
	ActionRowBuilder,
	ButtonBuilder,
	ButtonStyle,
	type ChatInputCommandInteraction,
	type Client,
	ContainerBuilder,
	type GuildMember,
	LabelBuilder,
	ModalBuilder,
	type ModalSubmitInteraction,
	SlashCommandBuilder,
	TextDisplayBuilder,
	TextInputBuilder,
	TextInputStyle,
} from "discord.js";

import { makeComponentId } from "@/utils/components";
import { formatMessage } from "@/utils/formatting";
import { loggers } from "@/utils/logging";
import { hasManagerPermissions } from "@/utils/permissions";
import { getGuild } from "@/utils/queries";

const logger = loggers.interactions.child({ name: "messageCommand" });

const commandData = new SlashCommandBuilder()
	.setName("ticket-message")
	.setDescription("Send the ticket message in the designated channel")
	.addChannelOption((c) =>
		c
			.setName("channel")
			.setDescription("The channel to send the ticket message in")
			.setRequired(true),
	);

const MODAL_ID = makeComponentId(commandData, "message");
const INPUT_ID = "message_content";

async function execute(
	_client: Client,
	interaction: ChatInputCommandInteraction,
) {
	if (!interaction.guild || !interaction.member) {
		await interaction.reply({
			content: "❌ This command can only be used in a server.",
			flags: ["Ephemeral"],
		});
		return;
	}

	const hasPerms = await hasManagerPermissions(
		interaction.member as GuildMember,
	);
	if (!hasPerms) {
		await interaction.reply({
			content: "❌ You don't have permission to use this command.",
			flags: ["Ephemeral"],
		});
		return;
	}

	const targetChannel = interaction.options.getChannel("channel", true);

	// construct & show the modal
	const textInput = new LabelBuilder()
		.setLabel("Message Content")
		.setTextInputComponent(
			new TextInputBuilder()
				.setCustomId(INPUT_ID)
				.setStyle(TextInputStyle.Paragraph)
				.setRequired(true),
		);

	await interaction.showModal(
		new ModalBuilder()
			.setCustomId(`${MODAL_ID}:${targetChannel.id}`)
			.setTitle("Ticket Message")
			.setLabelComponents(textInput),
	);
}

async function modalExecute(
	_client: Client,
	interaction: ModalSubmitInteraction,
) {
	if (!interaction.guild || !interaction.member) return;

	const channelId = interaction.customId.split(":")[2];

	const { data: guildData } = await getGuild(interaction.guild.id);
	const channel = interaction.guild.channels.cache.get(channelId);
	if (!channel) {
		await interaction.reply({
			content: "❌ The channel specified is invalid.",
			flags: ["Ephemeral"],
		});
		return;
	}

	if (!channel.isSendable()) {
		await interaction.reply({
			content: "❌ I'm not able to send messages in the specified channel.",
			flags: ["Ephemeral"],
		});
		return;
	}

	const message = interaction.fields.getTextInputValue(INPUT_ID);
	const formatted = formatMessage(message, interaction);

	const controls = new ActionRowBuilder<ButtonBuilder>().addComponents(
		new ButtonBuilder()
			.setCustomId("ticket:create")
			.setLabel("Open a Ticket")
			.setEmoji("📩")
			.setStyle(ButtonStyle.Success),
	);

	const container = new ContainerBuilder()
		.addTextDisplayComponents(new TextDisplayBuilder().setContent(formatted))
		.addActionRowComponents(controls);

	const sent = await channel
		.send({ components: [container], flags: ["IsComponentsV2"] })
		.catch((err) => {
			logger.error({ err, channelId }, "Failed to send ticket message");
			return null;
		});

	if (!sent) {
		await interaction.reply({
			content: "❌ Failed to send the message in the specified channel.",
			flags: ["Ephemeral"],
		});
		return;
	}

	await interaction.reply({
		content: `✅ Message sent successfully! ${sent.url}`,
		flags: ["Ephemeral"],
		allowedMentions: {
			users: [],
		},
	});
}

export default {
	data: commandData,
	execute,
	modalExecute,
};