Update from Git Manager GUI
This commit is contained in:
178
commands/add.js
Normal file
178
commands/add.js
Normal file
@@ -0,0 +1,178 @@
|
||||
import {
|
||||
EmbedBuilder,
|
||||
PermissionsBitField,
|
||||
SlashCommandBuilder,
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
ButtonStyle,
|
||||
} from "discord.js";
|
||||
import fs from "fs/promises";
|
||||
import { Spiget } from "spiget";
|
||||
import {
|
||||
generateAvatarLink,
|
||||
generateAuthorURL,
|
||||
generateResourceIconURL,
|
||||
} from "../util/helpers.js";
|
||||
|
||||
const spiget = new Spiget("Viper-Network");
|
||||
export default {
|
||||
name: "add",
|
||||
description: "Richtet einen Listener ein, der Plugin-Updates in einem bestimmten Kanal postet",
|
||||
aliases: [],
|
||||
guild: ["all"],
|
||||
nsfw: false,
|
||||
user_permissions: [PermissionsBitField.Flags.Administrator],
|
||||
bot_permissions: [],
|
||||
args_required: 2,
|
||||
args_usage: "[ressourcen_id] [kanal] Beispiel: vn!add 72678 #ankündigungen",
|
||||
cooldown: 5,
|
||||
|
||||
data: new SlashCommandBuilder()
|
||||
.setName("add")
|
||||
.setDescription("Richtet einen Listener für Plugin-Updates ein")
|
||||
.addStringOption((opt) =>
|
||||
opt.setName("ressourcen_id").setDescription("Spiget Ressourcen-ID").setRequired(true)
|
||||
)
|
||||
.addChannelOption((opt) =>
|
||||
opt.setName("kanal").setDescription("Kanal für Update-Benachrichtigungen").setRequired(true)
|
||||
),
|
||||
|
||||
async execute(client, ctx, args) {
|
||||
const resourceArg = ctx.isSlash
|
||||
? ctx.interaction.options.getString("ressourcen_id")
|
||||
: args[0];
|
||||
|
||||
const channel = ctx.isSlash
|
||||
? ctx.interaction.options.getChannel("kanal")
|
||||
: ctx.mentions?.channels?.first();
|
||||
|
||||
if (!channel) {
|
||||
return ctx.reply("Dieser Kanal ist ungültig. Bitte erwähne einen Kanal auf diesem Server.");
|
||||
}
|
||||
if (!ctx.guild.channels.cache.has(channel.id)) {
|
||||
return ctx.reply("Dieser Kanal befindet sich nicht auf diesem Server!");
|
||||
}
|
||||
|
||||
let resource;
|
||||
try {
|
||||
resource = await spiget.getResource(resourceArg);
|
||||
} catch (e) {
|
||||
client.logger.error(e);
|
||||
return ctx.reply(`Ups! \`${resourceArg}\` ist keine gültige Ressourcen-ID!`);
|
||||
}
|
||||
|
||||
let author;
|
||||
try {
|
||||
author = await resource.getAuthor();
|
||||
} catch (e) {
|
||||
client.logger.error(e);
|
||||
return ctx.reply(`Ups! Der Autor für Ressource \`${resourceArg}\` konnte nicht gefunden werden.`);
|
||||
}
|
||||
|
||||
let latestVersion;
|
||||
try {
|
||||
const res = await fetch(`https://api.spigotmc.org/legacy/update.php?resource=${resourceArg}`);
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||
latestVersion = (await res.text()).trim();
|
||||
} catch (e) {
|
||||
client.logger.error(e);
|
||||
return ctx.reply("Die neueste Version konnte nicht von SpigotMC abgerufen werden. Bitte versuche es erneut.");
|
||||
}
|
||||
|
||||
const guildID = ctx.guild.id;
|
||||
const filePath = `./serverdata/${guildID}.json`;
|
||||
|
||||
// Check existing data & limits
|
||||
let saveData = { watchedResources: [] };
|
||||
try {
|
||||
const raw = await fs.readFile(filePath, "utf8");
|
||||
saveData = JSON.parse(raw);
|
||||
|
||||
const duplicate = saveData.watchedResources.find((r) => r.resourceID == resource.id);
|
||||
if (duplicate) {
|
||||
return ctx.reply(`Diese Ressource wird bereits in <#${duplicate.channelID}> beobachtet.`);
|
||||
}
|
||||
|
||||
|
||||
} catch {
|
||||
// Datei existiert noch nicht
|
||||
}
|
||||
|
||||
const authorURL = generateAuthorURL(author.name, author.id);
|
||||
const authorAvatarURL = generateAvatarLink(author.id);
|
||||
const resourceIconURL = generateResourceIconURL(resource);
|
||||
const resourceURL = `https://spigotmc.org/resources/.${resourceArg}/`;
|
||||
|
||||
// Build confirmation embed with buttons
|
||||
const confirmEmbed = new EmbedBuilder()
|
||||
.setAuthor({ name: `Autor: ${author.name}`, iconURL: authorAvatarURL, url: authorURL })
|
||||
.setColor(ctx.guild.members.me.displayHexColor)
|
||||
.setTitle(`Plugin beobachten: ${resource.name}`)
|
||||
.setDescription(`${resource.tag}\n\nSoll dieses Plugin in <#${channel.id}> beobachtet werden?`)
|
||||
.addFields([
|
||||
{ name: "Kanal", value: `<#${channel.id}>`, inline: true },
|
||||
{ name: "Version", value: latestVersion, inline: true },
|
||||
{ name: "Download", value: resourceURL, inline: false },
|
||||
])
|
||||
.setThumbnail(resourceIconURL)
|
||||
.setTimestamp();
|
||||
|
||||
const row = new ActionRowBuilder().addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId("add_confirm")
|
||||
.setLabel("✅ Bestätigen")
|
||||
.setStyle(ButtonStyle.Success),
|
||||
new ButtonBuilder()
|
||||
.setCustomId("add_cancel")
|
||||
.setLabel("❌ Abbrechen")
|
||||
.setStyle(ButtonStyle.Danger)
|
||||
);
|
||||
|
||||
const confirmMsg = await ctx.reply({ embeds: [confirmEmbed], components: [row], fetchReply: true });
|
||||
|
||||
// Wait for button click (30 seconds)
|
||||
let btnInteraction;
|
||||
try {
|
||||
btnInteraction = await confirmMsg.awaitMessageComponent({
|
||||
filter: (i) => i.user.id === ctx.author.id,
|
||||
time: 30_000,
|
||||
});
|
||||
} catch {
|
||||
// Timeout
|
||||
const timeoutEmbed = EmbedBuilder.from(confirmEmbed)
|
||||
.setColor("#808080")
|
||||
.setDescription("⏱️ Zeit abgelaufen – Befehl wurde abgebrochen.");
|
||||
return confirmMsg.edit({ embeds: [timeoutEmbed], components: [] });
|
||||
}
|
||||
|
||||
if (btnInteraction.customId === "add_cancel") {
|
||||
const cancelEmbed = EmbedBuilder.from(confirmEmbed)
|
||||
.setColor("#FF0000")
|
||||
.setDescription("❌ Abgebrochen.");
|
||||
return btnInteraction.update({ embeds: [cancelEmbed], components: [] });
|
||||
}
|
||||
|
||||
// Confirmed – save data
|
||||
saveData.watchedResources.push({
|
||||
resourceID: resource.id,
|
||||
resourceName: resource.name,
|
||||
channelID: channel.id,
|
||||
lastCheckedVersion: latestVersion,
|
||||
});
|
||||
|
||||
try {
|
||||
await fs.mkdir("./serverdata", { recursive: true });
|
||||
await fs.writeFile(filePath, JSON.stringify(saveData, null, 2));
|
||||
} catch (e) {
|
||||
client.logger.error(e);
|
||||
return btnInteraction.update({ content: "Beim Speichern der Beobachtungsdaten ist ein Fehler aufgetreten.", components: [] });
|
||||
}
|
||||
|
||||
const successEmbed = EmbedBuilder.from(confirmEmbed)
|
||||
.setTitle(`✅ Wird jetzt beobachtet: ${resource.name}`)
|
||||
.setDescription(resource.tag)
|
||||
.setColor("#00FF00");
|
||||
|
||||
return btnInteraction.update({ embeds: [successEmbed], components: [] });
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user