Skip to content

Commit 0d3c838

Browse files
committed
fixed some bugs
1 parent b03ae71 commit 0d3c838

File tree

4 files changed

+105
-34
lines changed

4 files changed

+105
-34
lines changed

bot.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,11 @@ const commands = [
291291
.setDescription('The level at which the milestone will be reached')
292292
.setRequired(true)),
293293

294+
new SlashCommandBuilder()
295+
.setName('view-milestones')
296+
.setDescription('View the milestone levels and their associated roles')
297+
.setDefaultMemberPermissions(PermissionsBitField.Flags.ManageRoles),
298+
294299
// //
295300

296301
new SlashCommandBuilder()
@@ -530,6 +535,7 @@ client.on('interactionCreate', async interaction => {
530535
if (commandName === 'setup-levelup-channel') { console.log(`setup levelup command ran`); await configCommands.setLevelupChannel.execute(interaction, options); }
531536
// //
532537
if (commandName === 'remove-milestone') { console.log(`rm milestone command ran`); await milestoneCommands.removeMilestone.execute(interaction, options); }
538+
if (commandName === 'view-milestones') { console.log(`list milestone command ran`); await milestoneCommands.viewMilestones.execute(interaction); }
533539
// //
534540
if (commandName === 'help') { console.log(`help command ran`); await communityCommands.help.execute(interaction); }
535541

commands/admin_commands/admin_commands.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,9 @@ module.exports = {
307307
try {
308308
// Convert duration from minutes to milliseconds
309309
const durationMs = duration * 60 * 1000;
310+
311+
// if duration is greater than 40320 mintues, return with "too long"
312+
if (duration > 40320) return interaction.reply('Duration cannot exceed 40320 minutes');
310313

311314
// Apply the timeout
312315
await member.timeout(durationMs, reason);

commands/milestone_commands/milestone_commands.js

Lines changed: 88 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,60 +27,72 @@ module.exports = {
2727

2828
setupMilestone: {
2929
execute: async (interaction) => {
30-
// Check for Manage Roles permission
31-
if (!interaction.member.permissions.has(PermissionsBitField.Flags.ManageRoles)) {
32-
return interaction.reply({ content: 'You do not have permission to manage roles.', ephemeral: true });
33-
}
34-
35-
// Get input options
36-
const level = interaction.options.getInteger('level');
37-
const role = interaction.options.getRole('role');
38-
const guildId = interaction.guild.id;
39-
const members = await interaction.guild.members.fetch();
40-
41-
for (const member of members.values()) {
42-
// Fetch user data for each member
43-
let userData = await getUserData(guildId, member.id);
44-
45-
if (userData) {
46-
const userLevel = userData.level; // Retrieve the member's level from your leveling system
47-
await giveRoleToUserIfNoneArrange(member, interaction.guild.id, userLevel);
48-
}
49-
}
50-
5130
try {
31+
// Check for Manage Roles permission
32+
if (!interaction.member.permissions.has(PermissionsBitField.Flags.ManageRoles)) {
33+
return interaction.reply({ content: 'You do not have permission to manage roles.', ephemeral: true });
34+
}
35+
36+
// Get input options
37+
const level = interaction.options.getInteger('level');
38+
const role = interaction.options.getRole('role');
39+
const guildId = interaction.guild.id;
40+
console.log(`Setting up milestone for guild ${guildId}, level ${level}, role ${role.id}`);
41+
42+
// Fetch all members in the guild
43+
const members = await interaction.guild.members.fetch();
44+
for (const member of members.values()) {
45+
// Fetch user data for each member
46+
let userData = await getUserData(guildId, member.id);
47+
48+
if (userData) {
49+
const userLevel = userData.level; // Retrieve the member's level from your leveling system
50+
await giveRoleToUserIfNoneArrange(member, interaction.guild.id, userLevel);
51+
}
52+
}
53+
5254
// Check if a milestone for this level already exists in the database
53-
const existingMilestone = await MilestoneLevel.findAll({
55+
console.log('Checking if milestone already exists...');
56+
const existingMilestone = await MilestoneLevel.findOne({
5457
where: {
5558
guildId,
5659
level,
57-
reward: role.id
5860
}
5961
});
60-
61-
if (existingMilestone) { return interaction.reply({ content: `A milestone for level ${level} already exists.`, ephemeral: true }); }
62-
62+
63+
if (existingMilestone) {
64+
console.log('Milestone already exists for this level.');
65+
return interaction.reply({ content: `A milestone for level ${level} already exists.`, ephemeral: true });
66+
}
67+
6368
// Save milestone level to the database
69+
console.log('Creating new milestone...');
6470
await MilestoneLevel.create({
6571
guildId,
6672
level,
6773
reward: role.id
6874
});
69-
75+
76+
// Create and send the embed
77+
console.log('Milestone successfully created, preparing embed...');
7078
const embed = new EmbedBuilder()
7179
.setColor(0x008080)
7280
.setTitle('Milestone Set')
7381
.setDescription(`Milestone has been set!`)
7482
.addFields(
75-
{ name: 'Level', value: level },
83+
{ name: 'Level', value: level.toString() },
7684
{ name: 'Reward Role', value: `<@&${role.id}>` }
7785
)
7886
.setTimestamp();
7987

80-
return interaction.reply({ embeds: embed });
81-
} catch (error) { return interaction.reply({ content: 'An error occurred while setting the milestone. Please try again later.', ephemeral: true }); }
88+
return interaction.reply({ embeds: [embed] });
89+
} catch (error) {
90+
// Log the full error for debugging
91+
console.error('Error in setupMilestone:', error);
92+
return interaction.reply({ content: 'An error occurred while setting the milestone. Please try again later.', ephemeral: true });
93+
}
8294
}
83-
},
95+
},
8496

8597
// Remove Milestone level
8698
removeMilestone: {
@@ -117,7 +129,51 @@ module.exports = {
117129
return interaction.reply({ embeds: embed });
118130
} catch (error) { return interaction.reply({ content: 'An error occurred while removing the milestone. Please try again later.', ephemeral: true }); }
119131
}
120-
}
132+
},
121133

134+
viewMilestones: {
135+
execute: async (interaction) => {
136+
try {
137+
// Get guildId from the interaction
138+
const guildId = interaction.guild.id;
139+
140+
// Fetch all milestones for the server
141+
const milestones = await MilestoneLevel.findAll({
142+
where: {
143+
guildId: guildId
144+
},
145+
order: [['level', 'ASC']] // Order by level ascending
146+
});
147+
148+
// Check if there are any milestones set for the server
149+
if (milestones.length === 0) {
150+
return interaction.reply({ content: 'No milestone levels have been set for this server.', ephemeral: true });
151+
}
152+
153+
// Create a list of milestone levels and their corresponding roles
154+
const milestoneFields = milestones.map((milestone, index) => ({
155+
name: `Milestone ${index + 1}`,
156+
value: `**Level**: ${milestone.level}\n**Role**: <@&${milestone.reward}>`,
157+
inline: true
158+
}));
159+
160+
// Create an embed to display the milestones
161+
const milestoneEmbed = new EmbedBuilder()
162+
.setColor(0x008080) // Set your preferred color
163+
.setTitle('Server Milestone Levels')
164+
.setDescription('Here are all the milestone levels set for this server:')
165+
.addFields(milestoneFields)
166+
.setFooter({ text: `Requested by ${interaction.user.tag}` })
167+
.setTimestamp();
168+
169+
// Send the embed with milestone details
170+
return interaction.reply({ embeds: [milestoneEmbed] });
171+
} catch (error) {
172+
console.error('Failed to fetch milestone levels:', error);
173+
return interaction.reply({ content: 'An error occurred while fetching milestone levels. Please try again later.', ephemeral: true });
174+
}
175+
}
176+
}
177+
122178
// //
123179
}

models/models.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,22 @@ const MilestoneLevel = sequelize.define('MilestoneLevel', {
104104
guildId: {
105105
type: DataTypes.STRING,
106106
allowNull: false,
107-
primaryKey: true,
108107
},
109108
level: {
110109
type: DataTypes.INTEGER,
111110
allowNull: false,
112111
},
113112
reward: {
114-
type: DataTypes.STRING, // e.g., role ID, badge name
113+
type: DataTypes.STRING,
115114
allowNull: false,
116115
}
116+
}, {
117+
// Composite unique constraint
118+
uniqueKeys: {
119+
actions_unique: {
120+
fields: ['guildId', 'level']
121+
}
122+
}
117123
});
118124

119125
// Syncing the models with the database

0 commit comments

Comments
 (0)