-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.ts
More file actions
156 lines (148 loc) · 4.71 KB
/
index.ts
File metadata and controls
156 lines (148 loc) · 4.71 KB
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
152
153
154
155
156
import {
GuildQueueEvent,
Player,
QueueRepeatMode,
useMainPlayer,
} from "discord-player";
import { SoundcloudExtractor } from "discord-player-soundcloud";
import { SpotifyExtractor } from "discord-player-spotify";
import {
ChatInputCommandInteraction,
Client,
Collection,
Events,
GatewayIntentBits,
MessageFlags,
REST,
Routes,
type Interaction,
} from "discord.js";
import { readdirSync } from "fs";
import path from "path";
import type { BotModule } from "./types";
// Register modules
const commands = new Collection<string, BotModule["commands"][string]>();
const foldersPath = path.join(__dirname, "modules");
const modulePaths = readdirSync(foldersPath);
for (const file of modulePaths) {
const modulePath = path.join(foldersPath, file);
const modulePaths = file.endsWith(".ts")
? [modulePath]
: readdirSync(modulePath)
.filter((file) => file.endsWith(".ts"))
.map((f) => path.join(file, f));
for (const modulePath of modulePaths) {
const module = require(modulePath).default as BotModule;
// Set a new item in the Collection with the key as the command name and the value as the exported module
if (
"commands" in module &&
typeof module.commands === "object" &&
!Array.isArray(module.commands)
) {
for (const [key, command] of Object.entries(module.commands)) {
if ("data" in command && "execute" in command) {
command.data.setName(key);
commands.set(command.data.name, command);
} else {
console.log(
`[WARNING] Command ${key} at ${modulePath} is missing a required "data" or "execute" property.`,
);
}
}
} else {
console.log(
`[WARNING] The module at ${modulePath} is missing a required "commands" property.`,
);
}
}
}
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildVoiceStates,
],
});
const rest = new REST().setToken(process.env.TOKEN!);
client.on(Events.ClientReady, async (readyClient) => {
console.log(`Logged in as ${readyClient.user.tag}!`);
try {
console.log(
`Started refreshing ${commands.size} application (/) commands.`,
);
// The put method is used to fully refresh all commands with the current set
const data = (await rest.put(
Routes.applicationCommands(process.env.CLIENT_ID!),
{
body: commands
.values()
.map((x) => x.data.toJSON())
.toArray(),
},
)) as any[];
console.log(
`Successfully refreshed ${data.length} application (/) commands.`,
);
} catch (error) {
// And of course, make sure you catch and log any errors!
console.error(error);
}
});
client.on(Events.Error, console.error);
client.on(Events.GuildMemberAdd, async (member) => {
if (member.guild.id === "810082644623622204" && !member.user.bot) {
await member.roles.add([
"810082644636860451",
"810082644623622212",
"810082644623622205",
]);
}
});
const player = new Player(client);
await player.extractors.loadMulti([SoundcloudExtractor, SpotifyExtractor], {});
player.events.on(GuildQueueEvent.PlayerError, async (queue, error) => {
await queue.metadata.channel?.send(`Error: ${error.message}`);
});
player.events.on(GuildQueueEvent.PlayerStart, async (queue, track) => {
await queue.metadata.channel?.send(`Now playing **${track.cleanTitle}**!`);
});
player.events.on(GuildQueueEvent.PlayerFinish, async (queue, track) => {
if (queue.repeatMode === QueueRepeatMode.OFF && queue.isEmpty())
await queue.metadata.channel?.send(
`Queue is empty, leaving the voice channel.`,
);
});
client.on(Events.InteractionCreate, async (interaction) => {
if (
!((interaction: Interaction): interaction is ChatInputCommandInteraction =>
interaction.isChatInputCommand())(interaction)
)
return;
const command = commands.get(interaction.commandName);
if (!command) {
console.error(`No command matching ${interaction.commandName} was found.`);
return;
}
try {
await interaction.deferReply();
if (interaction.guild)
await useMainPlayer().context.provide({ guild: interaction.guild }, () =>
command.execute(interaction),
);
else command.execute(interaction);
} catch (error) {
console.error(error);
if (interaction.replied || interaction.deferred) {
await interaction.followUp({
content: "There was an error while executing this command!",
flags: MessageFlags.Ephemeral,
});
} else {
await interaction.reply({
content: "There was an error while executing this command!",
flags: MessageFlags.Ephemeral,
});
}
}
});
client.login(process.env.TOKEN);