v0.1
This commit is contained in:
parent
a0c9bbfe9a
commit
d5e23f5033
2
default.env
Normal file
2
default.env
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
TOKEN = 0 # Your bot token
|
||||||
|
CLIENT_ID = 0 # Your bot client ID
|
1227
package-lock.json
generated
Normal file
1227
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
package.json
Normal file
18
package.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"start": "node dist/index.js",
|
||||||
|
"dev": "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"
|
||||||
|
}
|
||||||
|
}
|
21
src/config.ts
Normal file
21
src/config.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
import { Entry } from './entry.ts';
|
||||||
|
|
||||||
|
export function writeConfig(entries: Entry[]) {
|
||||||
|
const data = JSON.stringify(entries, null, 2);
|
||||||
|
fs.writeFile('./config.json', data, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function readConfig(): Entry[] {
|
||||||
|
if (!fs.existsSync('./config.json')) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const data = fs.readFileSync('./config.json', 'utf8');
|
||||||
|
return JSON.parse(data);
|
||||||
|
}
|
12
src/entry.ts
Normal file
12
src/entry.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
export class Entry {
|
||||||
|
server: string;
|
||||||
|
channel: string;
|
||||||
|
emoji: string;
|
||||||
|
count: number;
|
||||||
|
constructor(server: string, channel: string, emoji: string, count: number) {
|
||||||
|
this.server = server;
|
||||||
|
this.channel = channel;
|
||||||
|
this.emoji = emoji;
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
}
|
133
src/index.ts
Normal file
133
src/index.ts
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
import {
|
||||||
|
REST,
|
||||||
|
Routes,
|
||||||
|
Client,
|
||||||
|
Partials,
|
||||||
|
GatewayIntentBits,
|
||||||
|
Events,
|
||||||
|
} from "discord.js";
|
||||||
|
|
||||||
|
import { writeConfig, readConfig } from "./config.ts";
|
||||||
|
|
||||||
|
import 'dotenv/config'
|
||||||
|
const TOKEN = process.env.TOKEN;
|
||||||
|
const CLIENT_ID = process.env.CLIENT_ID;
|
||||||
|
if (!TOKEN) {
|
||||||
|
console.error("No token provided");
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
if (!CLIENT_ID) {
|
||||||
|
console.error("No client ID provided");
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
const rest = new REST({ version: "10" }).setToken(TOKEN);
|
||||||
|
try {
|
||||||
|
console.log("refreshing slash commands...");
|
||||||
|
await rest.put(Routes.applicationCommands(CLIENT_ID), {
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
name: "config",
|
||||||
|
description: "Replies with the channel ID",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
console.log("OK");
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = new Client({
|
||||||
|
intents: [
|
||||||
|
GatewayIntentBits.Guilds,
|
||||||
|
GatewayIntentBits.GuildMessages,
|
||||||
|
GatewayIntentBits.GuildMessageReactions,
|
||||||
|
],
|
||||||
|
partials: [Partials.Message, Partials.Channel, Partials.Reaction],
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on("ready", () => {
|
||||||
|
if (!client.user) return;
|
||||||
|
console.log(`Logged in as ${client.user.tag}!`);
|
||||||
|
});
|
||||||
|
|
||||||
|
import { Entry } from "./entry.ts";
|
||||||
|
const entries: Entry[] = readConfig();
|
||||||
|
|
||||||
|
import modal from "./modal/configure.ts";
|
||||||
|
client.on("interactionCreate", async (interaction) => {
|
||||||
|
if (!interaction.isChatInputCommand()) return;
|
||||||
|
|
||||||
|
if (interaction.commandName === "config") {
|
||||||
|
await interaction.showModal(modal);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
client.on(Events.InteractionCreate, async (interaction) => {
|
||||||
|
if (!interaction.isModalSubmit()) return;
|
||||||
|
if (interaction.customId === "config") {
|
||||||
|
const emoji = interaction.fields.getTextInputValue("emoji");
|
||||||
|
const count = parseInt(interaction.fields.getTextInputValue("count"));
|
||||||
|
const channelId = interaction.fields.getTextInputValue("channelId");
|
||||||
|
const serverId = interaction.guildId;
|
||||||
|
if (!emoji || !channelId) {
|
||||||
|
await interaction.reply({
|
||||||
|
content: "Please fill out all fields",
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (serverId === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Set entry: ${serverId} -> ${channelId} (${emoji})`);
|
||||||
|
const entry = entries.find((entry) => entry.server === serverId);
|
||||||
|
if (entry) {
|
||||||
|
entry.channel = channelId;
|
||||||
|
entry.emoji = emoji;
|
||||||
|
entry.count = count;
|
||||||
|
} else {
|
||||||
|
entries.push(new Entry(serverId, channelId, emoji, count));
|
||||||
|
}
|
||||||
|
writeConfig(entries);
|
||||||
|
|
||||||
|
await interaction.reply({
|
||||||
|
content: `Set to send messages to <#${channelId}>, watching for ${emoji}`,
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
client.on(Events.MessageReactionAdd, async (reaction, user) => {
|
||||||
|
if (reaction.partial) {
|
||||||
|
try {
|
||||||
|
await reaction.fetch();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Something went wrong when fetching the message:", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!reaction.message.guild) return;
|
||||||
|
|
||||||
|
const entry = entries.find(
|
||||||
|
(entry) => entry.server === reaction.message.guildId
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
!entry ||
|
||||||
|
reaction.emoji.name !== entry.emoji ||
|
||||||
|
reaction.count === null ||
|
||||||
|
reaction.count < entry.count
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const channel = await client.channels.fetch(entry.channel);
|
||||||
|
if (channel === null || !channel.isTextBased() || channel.isDMBased()) return;
|
||||||
|
|
||||||
|
if (reaction.count === entry.count) {
|
||||||
|
await channel.send(
|
||||||
|
`🎉 ${reaction.count} people have reacted with ${entry.emoji}! 🎉`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
client.login(TOKEN);
|
42
src/modal/configure.ts
Normal file
42
src/modal/configure.ts
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import {
|
||||||
|
ModalBuilder,
|
||||||
|
TextInputBuilder,
|
||||||
|
ActionRowBuilder,
|
||||||
|
TextInputStyle,
|
||||||
|
ModalActionRowComponentBuilder,
|
||||||
|
} from 'discord.js';
|
||||||
|
|
||||||
|
const modal = new ModalBuilder()
|
||||||
|
.setCustomId('config')
|
||||||
|
.setTitle('Configuration');
|
||||||
|
|
||||||
|
const emojiInput = new TextInputBuilder()
|
||||||
|
.setCustomId('emoji')
|
||||||
|
.setLabel('Emoji')
|
||||||
|
.setStyle(TextInputStyle.Short)
|
||||||
|
.setPlaceholder('Enter the emoji')
|
||||||
|
.setValue('⭐')
|
||||||
|
.setRequired(true);
|
||||||
|
|
||||||
|
const countInput = new TextInputBuilder()
|
||||||
|
.setCustomId('count')
|
||||||
|
.setLabel('Count')
|
||||||
|
.setStyle(TextInputStyle.Short)
|
||||||
|
.setPlaceholder('Enter the count')
|
||||||
|
.setValue('5')
|
||||||
|
.setRequired(true);
|
||||||
|
|
||||||
|
const channelIdInput = new TextInputBuilder()
|
||||||
|
.setCustomId('channelId')
|
||||||
|
.setLabel('Channel ID')
|
||||||
|
.setStyle(TextInputStyle.Short)
|
||||||
|
.setPlaceholder('Enter the channel ID')
|
||||||
|
.setRequired(true);
|
||||||
|
|
||||||
|
const first = new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents(emojiInput)
|
||||||
|
const second = new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents(countInput)
|
||||||
|
const third = new ActionRowBuilder<ModalActionRowComponentBuilder>().addComponents(channelIdInput)
|
||||||
|
|
||||||
|
modal.addComponents(first, second, third);
|
||||||
|
|
||||||
|
export default modal;
|
20
tsconfig.json
Normal file
20
tsconfig.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"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