blob: 00b18265834adfbc12427cd53b6d8a22bb0a33f2 [file] [log] [blame]
import { LoadingEmbed } from "./../../utils/defaultEmbeds.js";
import Discord, {
Channel,
CommandInteraction,
Message,
MessageActionRow,
MessageButton,
MessageComponentInteraction,
Role
} from "discord.js";
import type { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
import generateKeyValueList from "../../utils/generateKeyValueList.js";
import { ChannelType } from "discord-api-types/v9";
import getEmojiByName from "../../utils/getEmojiByName.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
.setName("welcome")
.setDescription(
"Messages and roles sent or given when someone joins the server"
)
.addStringOption((option) =>
option
.setName("message")
.setDescription(
"The message to send when someone joins the server"
)
.setAutocomplete(true)
)
.addRoleOption((option) =>
option
.setName("role")
.setDescription("The role given when someone joins the server")
)
.addRoleOption((option) =>
option
.setName("ping")
.setDescription("The role pinged when someone joins the server")
)
.addChannelOption((option) =>
option
.setName("channel")
.setDescription(
"The channel the welcome message should be sent to"
)
.addChannelTypes([ChannelType.GuildText, ChannelType.GuildNews])
);
const callback = async (interaction: CommandInteraction): Promise<unknown> => {
const { renderRole, renderChannel, log, NucleusColors, entry, renderUser } =
client.logger;
await interaction.reply({
embeds: LoadingEmbed,
fetchReply: true,
ephemeral: true
});
let m: Message;
if (
interaction.options.getRole("role") ||
interaction.options.getChannel("channel") ||
interaction.options.getString("message")
) {
let role: Role;
let ping: Role;
const message = interaction.options.getString("message");
try {
role = interaction.options.getRole("role") as Role;
ping = interaction.options.getRole("ping") as Role;
} catch {
return await interaction.editReply({
embeds: [
new EmojiEmbed()
.setEmoji("GUILD.ROLES.DELETE")
.setTitle("Welcome Events")
.setDescription(
"The role you provided is not a valid role"
)
.setStatus("Danger")
]
});
}
let channel: Channel;
try {
channel = interaction.options.getChannel("channel") as Channel;
} catch {
return await interaction.editReply({
embeds: [
new EmojiEmbed()
.setEmoji("GUILD.ROLES.DELETE")
.setTitle("Welcome Events")
.setDescription(
"The channel you provided is not a valid channel"
)
.setStatus("Danger")
]
});
}
role = role as Discord.Role;
ping = ping as Discord.Role;
channel = channel as Discord.TextChannel;
const options = {};
if (role) options.role = renderRole(role);
if (ping) options.ping = renderRole(ping);
if (channel) options.channel = renderChannel(channel);
if (message) options.message = "\n> " + message;
const confirmation = await new confirmationMessage(interaction)
.setEmoji("GUILD.ROLES.EDIT")
.setTitle("Welcome Events")
.setDescription(generateKeyValueList(options))
.setColor("Warning")
.setInverted(true)
.send(true);
if (confirmation.cancelled) return;
if (confirmation.success) {
try {
const toChange = {};
if (role) toChange["welcome.role"] = role.id;
if (ping) toChange["welcome.ping"] = ping.id;
if (channel) toChange["welcome.channel"] = channel.id;
if (message) toChange["welcome.message"] = message;
await client.database.guilds.write(
interaction.guild.id,
toChange
);
const list = {
memberId: entry(
interaction.user.id,
`\`${interaction.user.id}\``
),
changedBy: entry(
interaction.user.id,
renderUser(interaction.user)
)
};
if (role) list.role = entry(role.id, renderRole(role));
if (ping) list.ping = entry(ping.id, renderRole(ping));
if (channel)
list.channel = entry(channel.id, renderChannel(channel.id));
if (message) list.message = entry(message, `\`${message}\``);
const data = {
meta: {
type: "welcomeSettingsUpdated",
displayName: "Welcome Settings Changed",
calculateType: "nucleusSettingsUpdated",
color: NucleusColors.green,
emoji: "CONTROL.BLOCKTICK",
timestamp: new Date().getTime()
},
list: list,
hidden: {
guild: interaction.guild.id
}
};
log(data);
} catch (e) {
console.log(e);
return interaction.editReply({
embeds: [
new EmojiEmbed()
.setTitle("Welcome Events")
.setDescription(
"Something went wrong while updating welcome settings"
)
.setStatus("Danger")
.setEmoji("GUILD.ROLES.DELETE")
],
components: []
});
}
} else {
return interaction.editReply({
embeds: [
new EmojiEmbed()
.setTitle("Welcome Events")
.setDescription("No changes were made")
.setStatus("Success")
.setEmoji("GUILD.ROLES.CREATE")
],
components: []
});
}
}
let lastClicked = null;
while (true) {
const config = await client.database.guilds.read(interaction.guild.id);
m = (await interaction.editReply({
embeds: [
new EmojiEmbed()
.setTitle("Welcome Events")
.setDescription(
`**Message:** ${
config.welcome.message
? `\n> ${config.welcome.message}`
: "*None set*"
}\n` +
`**Role:** ${
config.welcome.role
? renderRole(
await interaction.guild.roles.fetch(
config.welcome.role
)
)
: "*None set*"
}\n` +
`**Ping:** ${
config.welcome.ping
? renderRole(
await interaction.guild.roles.fetch(
config.welcome.ping
)
)
: "*None set*"
}\n` +
`**Channel:** ${
config.welcome.channel
? config.welcome.channel == "dm"
? "DM"
: renderChannel(
await interaction.guild.channels.fetch(
config.welcome.channel
)
)
: "*None set*"
}`
)
.setStatus("Success")
.setEmoji("CHANNEL.TEXT.CREATE")
],
components: [
new MessageActionRow().addComponents([
new MessageButton()
.setLabel(
lastClicked == "clear-message"
? "Click again to confirm"
: "Clear Message"
)
.setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
.setCustomId("clear-message")
.setDisabled(!config.welcome.message)
.setStyle("DANGER"),
new MessageButton()
.setLabel(
lastClicked == "clear-role"
? "Click again to confirm"
: "Clear Role"
)
.setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
.setCustomId("clear-role")
.setDisabled(!config.welcome.role)
.setStyle("DANGER"),
new MessageButton()
.setLabel(
lastClicked == "clear-ping"
? "Click again to confirm"
: "Clear Ping"
)
.setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
.setCustomId("clear-ping")
.setDisabled(!config.welcome.ping)
.setStyle("DANGER"),
new MessageButton()
.setLabel(
lastClicked == "clear-channel"
? "Click again to confirm"
: "Clear Channel"
)
.setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
.setCustomId("clear-channel")
.setDisabled(!config.welcome.channel)
.setStyle("DANGER"),
new MessageButton()
.setLabel("Set Channel to DM")
.setCustomId("set-channel-dm")
.setDisabled(config.welcome.channel == "dm")
.setStyle("SECONDARY")
])
]
})) as Message;
let i: MessageComponentInteraction;
try {
i = await m.awaitMessageComponent({ time: 300000 });
} catch (e) {
break;
}
i.deferUpdate();
if (i.customId == "clear-message") {
if (lastClicked == "clear-message") {
await client.database.guilds.write(interaction.guild.id, {
"welcome.message": null
});
lastClicked = null;
} else {
lastClicked = "clear-message";
}
} else if (i.customId == "clear-role") {
if (lastClicked == "clear-role") {
await client.database.guilds.write(interaction.guild.id, {
"welcome.role": null
});
lastClicked = null;
} else {
lastClicked = "clear-role";
}
} else if (i.customId == "clear-ping") {
if (lastClicked == "clear-ping") {
await client.database.guilds.write(interaction.guild.id, {
"welcome.ping": null
});
lastClicked = null;
} else {
lastClicked = "clear-ping";
}
} else if (i.customId == "clear-channel") {
if (lastClicked == "clear-channel") {
await client.database.guilds.write(interaction.guild.id, {
"welcome.channel": null
});
lastClicked = null;
} else {
lastClicked = "clear-channel";
}
} else if (i.customId == "set-channel-dm") {
await client.database.guilds.write(interaction.guild.id, {
"welcome.channel": "dm"
});
lastClicked = null;
}
}
await interaction.editReply({
embeds: [m.embeds[0].setFooter({ text: "Message closed" })],
components: []
});
};
const check = (interaction: CommandInteraction) => {
const member = interaction.member as Discord.GuildMember;
if (!member.permissions.has("MANAGE_GUILD"))
throw new Error(
"You must have the *Manage Server* permission to use this command"
);
return true;
};
export { command };
export { callback };
export { check };