Skip to content

Commit

Permalink
[Feature] Helper list command (#92)
Browse files Browse the repository at this point in the history
* feat: add helper command

* feat: add delete helper role command

* fix: make linter happy
  • Loading branch information
hendraaagil authored Jan 13, 2024
1 parent b2a4741 commit 6715c26
Show file tree
Hide file tree
Showing 9 changed files with 718 additions and 37 deletions.
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ WEBHOOK_ID="XXXXX"
CHANNEL_LOBBY=
CHANNEL_PERKENALAN=
CHANNEL_SHOWCASE_PROJECT=
CHANNEL_SHOWCASE_WEORKSPACE=
CHANNEL_SHOWCASE_WORKSPACE=
CHANNEL_HELPER=

# Roles ID
ROLES_MAHASISWA=
Expand Down
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"printWidth": 120,
"singleQuote": true,
"tabWidth": 4,
"trailingComma": "all"
}
128 changes: 128 additions & 0 deletions commands/helper-list.command.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const { MessageEmbed } = require('discord.js');

const MAHASISWA_ID = process.env.ROLES_MAHASISWA;
const CHANNEL_HELPER_ID = process.env.CHANNEL_HELPER;

exports.command = new SlashCommandBuilder()
.setName('helper-list')
.setDescription('Helper list command')
.addRoleOption((option) => option.setName('role').setDescription('Select a role'));

exports.permissions = [
{
id: MAHASISWA_ID,
type: 'ROLE',
permission: true,
},
];

exports.execute = async (interaction) => {
await interaction.deferReply();

try {
const prisma = interaction.client.prisma;
const role = interaction.options.getRole('role');

if (!role) {
const allHelperRoles = await prisma.helper_role.findMany();
let totalMember = 0;

allHelperRoles.forEach((helperRole) => {
totalMember += interaction.guild.roles.cache.get(helperRole.role_id).members.size;
});

const allHelperEmbed = new MessageEmbed()
.setColor('#992d22')
.setDescription(`**All Helpers**`)
.addFields(
{ name: 'Total Roles', value: allHelperRoles.length.toString(), inline: true },
{ name: 'Total Members', value: totalMember.toString(), inline: true },
);

await Promise.all(
allHelperRoles.map(async (helperRole) => {
const roleName = interaction.guild.roles.cache.get(helperRole.role_id).name;
const members = interaction.guild.roles.cache
.get(helperRole.role_id)
.members.map((member) => member.user.id);
const listMembers = members.length
? members.map((member) => `- <@${member}>`).join('\n')
: '- No one here :(';

allHelperEmbed.addField(`**${roleName}**`, listMembers);
}),
);

return await interaction.editReply({ embeds: [allHelperEmbed] });
}

const helperRole = await prisma.helper_role.findUnique({ where: { role_id: role.id } });
if (!helperRole) {
return await interaction.editReply({ content: 'Role not found!' });
}

const roleMemberIds = interaction.guild.roles.cache.get(role.id).members.map((member) => member.user.id);
const members = await Promise.all(
roleMemberIds.map(async (memberId) => {
const [firstMessage, lastMessage, lastMessageCountIn30Days] = await Promise.all([
prisma.messages.findFirst({
where: { author_id: memberId, channel_id: CHANNEL_HELPER_ID },
orderBy: { timestamp: 'asc' },
}),
prisma.messages.findFirst({
where: { author_id: memberId },
orderBy: { timestamp: 'desc' },
}),
prisma.messages.count({
where: {
author_id: memberId,
timestamp: {
gte: new Date(new Date().getTime() - 30 * 24 * 60 * 60 * 1000),
},
},
}),
]);

return {
id: memberId,
joinedDate: firstMessage ? firstMessage.timestamp : null,
lastMessageDate: lastMessage ? lastMessage.timestamp : null,
lastMessageCountIn30Days,
};
}),
);

const listMembers = members.length
? members
.sort((a, b) => a.joinedDate - b.joinedDate)
.map((member) => {
const joinedDate = member.joinedDate ? new Date(member.joinedDate).toLocaleString() : 'No data';
const lastMessageDate = member.lastMessageDate
? new Date(member.lastMessageDate).toLocaleString()
: 'No message';

return `${joinedDate} - <@${member.id}> - ${lastMessageDate} - ${member.lastMessageCountIn30Days} messages`;
})
.join('\n')
: 'No one here :(';
const embed = new MessageEmbed().setColor('#992d22').setDescription(`**<@&${role.id}>**`).addFields(
{ name: 'Total Members', value: roleMemberIds.length.toString(), inline: true },
{
name: 'List Members\nDate joined - Name - Last message - Total messages in last month',
value: listMembers,
inline: false,
},
);

return await interaction.editReply({ embeds: [embed] });
} catch (error) {
console.error(error);

const embed = new MessageEmbed()
.setColor('#992d22')
.setDescription(`**Something went wrong!**`)
.addFields({ name: 'Error', value: error.message, inline: false });
return await interaction.editReply({ embeds: [embed] });
}
};
63 changes: 63 additions & 0 deletions commands/helper-role.command.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const { checkRoles } = require('../modules/utility');

const KETUA_KELAS_ID = process.env.ROLE_KETUA;

exports.command = new SlashCommandBuilder()
.setName('helper-role')
.setDescription('Add helper role command')
.addStringOption((option) =>
option
.setName('action')
.setDescription('Select an action')
.setRequired(true)
.addChoice('Add', 'add')
.addChoice('Remove', 'remove'),
)
.addRoleOption((option) => option.setName('role').setDescription('Select a role').setRequired(true));

exports.permissions = [
{
id: KETUA_KELAS_ID,
type: 'ROLE',
permission: true,
},
];

exports.execute = async (interaction) => {
if (!checkRoles(interaction)) {
return interaction.reply({ content: 'You do not have permission to use this command!', ephemeral: true });
}

const role = interaction.options.getRole('role');
if (!role.name.startsWith('Helper-')) {
return interaction.reply({ content: 'Invalid role!', ephemeral: true });
}

const action = interaction.options.getString('action');
const prisma = interaction.client.prisma;
const existingRole = await prisma.helper_role.findUnique({ where: { role_id: role.id } });

if (existingRole && action === 'add') {
return interaction.reply({ content: 'Role already exists!', ephemeral: true });
}
if (!existingRole && action === 'remove') {
return interaction.reply({ content: 'Role does not exist!', ephemeral: true });
}

if (action === 'add') {
await prisma.helper_role.create({
data: {
role_id: role.id,
added_by: interaction.user.id,
},
});

return interaction.reply({ content: 'Role added!', ephemeral: true });
}

if (action === 'remove') {
await prisma.helper_role.delete({ where: { role_id: role.id } });
return interaction.reply({ content: 'Role removed!', ephemeral: true });
}
};
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require('dotenv').config();
const { Client, Intents, Collection } = require('discord.js');

const { PrismaClient }= require('@prisma/client');
const { PrismaClient } = require('@prisma/client');
const fs = require('fs');
const TOKEN = process.env.TOKEN;
const options = {
Expand All @@ -12,7 +12,7 @@ const options = {
Intents.FLAGS.GUILD_EMOJIS_AND_STICKERS,
Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
Intents.FLAGS.GUILD_PRESENCES,
Intents.FLAGS.GUILD_WEBHOOKS
Intents.FLAGS.GUILD_WEBHOOKS,
],
allowedMentions: {
parse: ['users', 'roles'],
Expand Down
Loading

0 comments on commit 6715c26

Please sign in to comment.