fix: improve error handling
This commit is contained in:
parent
09ccb03626
commit
b273fd3a3e
1227
package-lock.json
generated
1227
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
15
package.json
15
package.json
|
@ -1,15 +0,0 @@
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"start": "tsx src/index.ts"
|
|
||||||
},
|
|
||||||
"type": "module",
|
|
||||||
"dependencies": {
|
|
||||||
"discord.js": "^14.16.1",
|
|
||||||
"dotenv": "^16.4.5"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "^22.5.4",
|
|
||||||
"tsx": "^4.19.0",
|
|
||||||
"typescript": "^5.5.4"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,6 +16,11 @@ export function readConfig(): Entry[] {
|
||||||
if (!fs.existsSync('./config.json')) {
|
if (!fs.existsSync('./config.json')) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
const data = fs.readFileSync('./config.json', 'utf8');
|
const data = fs.readFileSync('./config.json', 'utf8');
|
||||||
return JSON.parse(data);
|
return JSON.parse(data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to read or parse config.json:', error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
122
src/index.ts
122
src/index.ts
|
@ -1,9 +1,8 @@
|
||||||
import "dotenv/config";
|
const TOKEN = Deno.env.get("TOKEN");
|
||||||
const TOKEN = process.env.TOKEN;
|
const CLIENT_ID = Deno.env.get("CLIENT_ID");
|
||||||
const CLIENT_ID = process.env.CLIENT_ID;
|
|
||||||
if (!TOKEN || !CLIENT_ID) {
|
if (!TOKEN || !CLIENT_ID) {
|
||||||
console.error(`No ${TOKEN ? "CLIENT_ID" : "TOKEN"} provided`);
|
console.error(`No ${TOKEN ? "CLIENT_ID" : "TOKEN"} provided`);
|
||||||
process.exit();
|
Deno.exit(1);
|
||||||
}
|
}
|
||||||
import commands from "./commands.ts";
|
import commands from "./commands.ts";
|
||||||
|
|
||||||
|
@ -42,7 +41,7 @@ const client = new Client({
|
||||||
client.on("ready", () => {
|
client.on("ready", () => {
|
||||||
if (!client.user) {
|
if (!client.user) {
|
||||||
console.error("Failed to login");
|
console.error("Failed to login");
|
||||||
process.exit();
|
Deno.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Logged in as ${client.user.tag}!`);
|
console.log(`Logged in as ${client.user.tag}!`);
|
||||||
|
@ -79,11 +78,15 @@ client.on("interactionCreate", async (interaction) => {
|
||||||
writeConfig(entries);
|
writeConfig(entries);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} finally {
|
await interaction.followUp({
|
||||||
|
content: "Failed to set output channel. Please try again.",
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
await interaction.followUp({
|
await interaction.followUp({
|
||||||
content: `Set output to <#${channel.id}>`,
|
content: `Set output to <#${channel.id}>`,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
} else if (subcommand === "channels") {
|
} else if (subcommand === "channels") {
|
||||||
const channel = interaction.options.getChannel("channel", true);
|
const channel = interaction.options.getChannel("channel", true);
|
||||||
const mode = interaction.options.getString("add_remove", true);
|
const mode = interaction.options.getString("add_remove", true);
|
||||||
|
@ -101,11 +104,15 @@ client.on("interactionCreate", async (interaction) => {
|
||||||
writeConfig(entries);
|
writeConfig(entries);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} finally {
|
await interaction.followUp({
|
||||||
|
content: "Failed to configure channel list. Please try again.",
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
await interaction.followUp({
|
await interaction.followUp({
|
||||||
content: `Set to watch for reactions in <#${channel.id}>`,
|
content: `Set to watch for reactions in <#${channel.id}>`,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
} else if (subcommand === "channels_type") {
|
} else if (subcommand === "channels_type") {
|
||||||
const channel_type = interaction.options.getString(
|
const channel_type = interaction.options.getString(
|
||||||
"channels_type",
|
"channels_type",
|
||||||
|
@ -121,16 +128,23 @@ client.on("interactionCreate", async (interaction) => {
|
||||||
entry = new Entry(interaction.guildId!);
|
entry = new Entry(interaction.guildId!);
|
||||||
entries.push(entry);
|
entries.push(entry);
|
||||||
}
|
}
|
||||||
|
if (channel_type !== "include" && channel_type !== "exclude") {
|
||||||
|
throw new Error(`Invalid channel type: ${channel_type}`);
|
||||||
|
}
|
||||||
entry.channel_type = channel_type as Type;
|
entry.channel_type = channel_type as Type;
|
||||||
writeConfig(entries);
|
writeConfig(entries);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} finally {
|
await interaction.followUp({
|
||||||
|
content: "Failed to set channel list type. Please try again.",
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
await interaction.followUp({
|
await interaction.followUp({
|
||||||
content: `channel list type set to ${channel_type}`,
|
content: `channel list type set to ${channel_type}`,
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
} else if (subcommand === "emojis") {
|
} else if (subcommand === "emojis") {
|
||||||
const emoji = interaction.options.getString("emoji", true);
|
const emoji = interaction.options.getString("emoji", true);
|
||||||
const mode = interaction.options.getString("add_remove", true);
|
const mode = interaction.options.getString("add_remove", true);
|
||||||
|
@ -148,12 +162,16 @@ client.on("interactionCreate", async (interaction) => {
|
||||||
await writeConfig(entries);
|
await writeConfig(entries);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} finally {
|
await interaction.followUp({
|
||||||
|
content: "Failed to configure emoji list. Please try again.",
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
await interaction.followUp({
|
await interaction.followUp({
|
||||||
content: `Set to watch for ${emoji}`,
|
content: `Set to watch for ${emoji}`,
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
} else if (subcommand === "emojis_type") {
|
} else if (subcommand === "emojis_type") {
|
||||||
const emoji_type = interaction.options.getString("emojis_type", true);
|
const emoji_type = interaction.options.getString("emojis_type", true);
|
||||||
try {
|
try {
|
||||||
|
@ -165,16 +183,23 @@ client.on("interactionCreate", async (interaction) => {
|
||||||
entry = new Entry(interaction.guildId!);
|
entry = new Entry(interaction.guildId!);
|
||||||
entries.push(entry);
|
entries.push(entry);
|
||||||
}
|
}
|
||||||
|
if (emoji_type !== "include" && emoji_type !== "exclude") {
|
||||||
|
throw new Error(`Invalid emoji type: ${emoji_type}`);
|
||||||
|
}
|
||||||
entry.emoji_type = emoji_type as Type;
|
entry.emoji_type = emoji_type as Type;
|
||||||
writeConfig(entries);
|
writeConfig(entries);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} finally {
|
await interaction.followUp({
|
||||||
|
content: "Failed to set emoji list type. Please try again.",
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
await interaction.followUp({
|
await interaction.followUp({
|
||||||
content: `emoji list type set to ${emoji_type}`,
|
content: `emoji list type set to ${emoji_type}`,
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
} else if (subcommand === "score") {
|
} else if (subcommand === "score") {
|
||||||
const score = interaction.options.getInteger("score", true);
|
const score = interaction.options.getInteger("score", true);
|
||||||
try {
|
try {
|
||||||
|
@ -190,7 +215,12 @@ client.on("interactionCreate", async (interaction) => {
|
||||||
await writeConfig(entries);
|
await writeConfig(entries);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
} finally {
|
await interaction.followUp({
|
||||||
|
content: "Failed to set score threshold. Please try again.",
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
await interaction.followUp({
|
await interaction.followUp({
|
||||||
content: `The score needed to trigger is now ${score}`,
|
content: `The score needed to trigger is now ${score}`,
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
|
@ -198,19 +228,23 @@ client.on("interactionCreate", async (interaction) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
import awardEmbed from "./award_message.ts";
|
import awardEmbed from "./award_message.ts";
|
||||||
client.on(Events.MessageReactionAdd, async (reaction, user) => {
|
async function handleReactionFetch(reaction: any) {
|
||||||
if (reaction.partial) {
|
if (reaction.partial) {
|
||||||
try {
|
try {
|
||||||
await reaction.fetch();
|
await reaction.fetch();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Something went wrong when fetching the message:", error);
|
console.error("Something went wrong when fetching the message:", error);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
client.on(Events.MessageReactionAdd, async (reaction, user) => {
|
||||||
|
if (!(await handleReactionFetch(reaction))) return;
|
||||||
if (!reaction.message.guild) return;
|
if (!reaction.message.guild) return;
|
||||||
|
|
||||||
const entry = entries.find(
|
const entry = entries.find(
|
||||||
|
@ -235,10 +269,22 @@ client.on(Events.MessageReactionAdd, async (reaction, user) => {
|
||||||
const channel = reaction.message.guild.channels.cache.get(
|
const channel = reaction.message.guild.channels.cache.get(
|
||||||
entry.output_channel
|
entry.output_channel
|
||||||
) as TextChannel;
|
) as TextChannel;
|
||||||
|
|
||||||
|
if (!channel) {
|
||||||
|
console.error(`Output channel ${entry.output_channel} not found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!channel.isTextBased()) {
|
||||||
|
console.error(`Channel ${entry.output_channel} is not a text channel`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
channel.messages.fetch({ limit: 10 }).then((messages) => {
|
channel.messages.fetch({ limit: 10 }).then((messages) => {
|
||||||
messages.find((message) => {
|
messages.find((message) => {
|
||||||
if (message.embeds[0]?.fields[0].value.includes(reaction.message.id)) {
|
if (message.embeds[0]?.fields[0].value.includes(reaction.message.id)) {
|
||||||
message.delete();
|
message.delete().catch((error) => {
|
||||||
|
console.error("Failed to delete old message:", error);
|
||||||
|
});
|
||||||
console.log("old message deleted.");
|
console.log("old message deleted.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -246,21 +292,18 @@ client.on(Events.MessageReactionAdd, async (reaction, user) => {
|
||||||
});
|
});
|
||||||
channel.send({
|
channel.send({
|
||||||
embeds: [awardEmbed(reaction, totalScore)],
|
embeds: [awardEmbed(reaction, totalScore)],
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error("Failed to send award message:", error);
|
||||||
});
|
});
|
||||||
console.log("message sent.");
|
console.log("message sent.");
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error("Failed to fetch messages:", error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on(Events.MessageReactionRemove, async (reaction, user) => {
|
client.on(Events.MessageReactionRemove, async (reaction, user) => {
|
||||||
if (reaction.partial) {
|
if (!(await handleReactionFetch(reaction))) return;
|
||||||
try {
|
|
||||||
await reaction.fetch();
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Something went wrong when fetching the message:", error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!reaction.message.guild) return;
|
if (!reaction.message.guild) return;
|
||||||
|
|
||||||
const entry = entries.find(
|
const entry = entries.find(
|
||||||
|
@ -284,14 +327,28 @@ client.on(Events.MessageReactionRemove, async (reaction, user) => {
|
||||||
const channel = reaction.message.guild.channels.cache.get(
|
const channel = reaction.message.guild.channels.cache.get(
|
||||||
entry.output_channel
|
entry.output_channel
|
||||||
) as TextChannel;
|
) as TextChannel;
|
||||||
|
|
||||||
|
if (!channel) {
|
||||||
|
console.error(`Output channel ${entry.output_channel} not found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!channel.isTextBased()) {
|
||||||
|
console.error(`Channel ${entry.output_channel} is not a text channel`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
channel.messages.fetch({ limit: 10 }).then((messages) => {
|
channel.messages.fetch({ limit: 10 }).then((messages) => {
|
||||||
messages.find((message) => {
|
messages.find((message) => {
|
||||||
if (message.embeds[0]?.fields[0].value.includes(reaction.message.id)) {
|
if (message.embeds[0]?.fields[0].value.includes(reaction.message.id)) {
|
||||||
message.delete();
|
message.delete().catch((error) => {
|
||||||
|
console.error("Failed to delete old message:", error);
|
||||||
|
});
|
||||||
console.log("old message deleted.");
|
console.log("old message deleted.");
|
||||||
if (totalScore >= entry.score) {
|
if (totalScore >= entry.score) {
|
||||||
channel.send({
|
channel.send({
|
||||||
embeds: [awardEmbed(reaction, totalScore)],
|
embeds: [awardEmbed(reaction, totalScore)],
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error("Failed to send award message:", error);
|
||||||
});
|
});
|
||||||
console.log("message sent.");
|
console.log("message sent.");
|
||||||
}
|
}
|
||||||
|
@ -299,10 +356,15 @@ client.on(Events.MessageReactionRemove, async (reaction, user) => {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
}).catch((error) => {
|
||||||
|
console.error("Failed to fetch messages:", error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
client.login(TOKEN);
|
client.login(TOKEN).catch((error) => {
|
||||||
|
console.error("Failed to login to Discord:", error);
|
||||||
|
Deno.exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
async function getMessageScore(
|
async function getMessageScore(
|
||||||
entry: Entry,
|
entry: Entry,
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ES2022",
|
|
||||||
"lib": [
|
|
||||||
"ES2023"
|
|
||||||
],
|
|
||||||
"module": "node16",
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"strict": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"allowImportingTsExtensions": true,
|
|
||||||
"noEmit": true,
|
|
||||||
|
|
||||||
"outDir": "./dist",
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"src/**/*.ts"
|
|
||||||
]
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user