Commit-Overflow-Counting/commands/commit-count.js

204 lines
No EOL
8.4 KiB
JavaScript

/*
* Commit Overflow Counting - Slash Command Definition File
* commit-count.js - Gets an initial commit count for Commit Overflow
*/
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
const { convertSnowflakeToDate, convertDateToSnowflake } = require('../utils/convert.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('commit-count')
.setDescription('Counts Commits')
// .addStringOption(option =>
// option.setName('emoji')
// .setDescription('Optionally choose an emoji for verified messages'))
// .addMentionableOption(option =>
// option.setName('role')
// .setDescription('Choose a role for those that can react to verify'))
.addStringOption(option =>
option.setName('start')
.setDescription('Optionally specify a start date (MM/DD/YYYY preferred)'))
.addStringOption(option =>
option.setName('end')
.setDescription('Optionally specify a end date (MM/DD/YYYY preferred)')),
async execute(interaction) {
if (interaction.inGuild() && interaction.channel.isThread()) {
const threadStarterMessage = await interaction.channel.fetchStarterMessage();
const emojiCheck = interaction.options.getString('emoji') ?? 'gh_green_square';
const roleCheck = interaction.options.getString('role') ?? '1232803664150659133';
const startDate = new Date(interaction.options.getString('start-date') ?? threadStarterMessage.createdTimestamp);
const endDate = new Date(interaction.options.getString('end-date') ?? interaction.createdTimestamp);
await interaction.deferReply();
// Fetch Messages
const sum_messages = [];
let first_id = convertDateToSnowflake(startDate);
const messageMap = new Map();
let continueFetching = true;
while (continueFetching) {
const options = { limit: 100 };
options.after = first_id;
try {
const messages = await interaction.channel.messages.fetch(options);
sum_messages.push(...messages.values());
for (const [snowflake, message] of messages) {
if (message.author.id === threadStarterMessage.member.id) {
const messageDate = convertSnowflakeToDate(snowflake);
let monthName = '';
// Assuming only Dec, Jan for now, can be expanded later
if (messageDate.getMonth() === 11) {
monthName = 'Dec.';
}
else if (messageDate.getMonth() === 0) {
monthName = 'Jan.';
}
const mapKey = monthName + ' ' + messageDate.getDate().toString();
if (messageMap.has(mapKey)) {
const mapValue = messageMap.get(mapKey);
mapValue.push(snowflake);
messageMap.set(mapKey, mapValue);
}
else {
const mapValue = [snowflake];
messageMap.set(mapKey, mapValue);
}
}
}
first_id = messages.first().id;
if (messages.size < 100) {
continueFetching = false;
}
}
catch (error) {
console.error('Error fetching messages: ', error);
continueFetching = false;
}
}
// Start Commit Checking
let validString = '';
let invalidString = '';
const validDays = [];
for (const [date] of messageMap) {
let dateVerified = false;
let verifyReason = '';
const messageList = messageMap.get(date);
for (const messageId of messageList) {
if (dateVerified != true) {
await interaction.channel.messages.fetch(messageId)
.then(async message => {
if (/http.:\/\/.*\/(commit|compare)\/.*/g.test(message.content)) {
dateVerified = true;
verifyReason = 'Commit URL';
}
else if (message.attachments.size > 0) {
dateVerified = true;
verifyReason = 'Attachment';
}
else if (message.reactions.cache.size > 0) {
for (const reaction of message.reactions.cache.values()) {
const emojiName = reaction._emoji.name;
const reactionUsers = await reaction.users.fetch();
if (emojiName === emojiCheck) {
for (const [userId] of reactionUsers) {
const member = await interaction.guild.members.fetch(userId);
if (member.roles.cache.has(roleCheck)) {
dateVerified = true;
verifyReason = 'Reaction';
break;
}
}
}
}
}
})
.catch(console.error);
}
}
if (dateVerified) {
validString += `${date}: ${verifyReason}\n`;
validDays.push(date);
}
}
const resultsEmbed = {
title: 'Commits',
fields: [
{
name: 'Valid Commits',
value: validString,
},
],
};
const allDays = [];
let currentDate = startDate;
while (currentDate <= endDate) {
allDays.push(new Date(currentDate));
currentDate = currentDate.setDate(currentDate.getDate + 1);
}
for (const day of allDays) {
let monthName = '';
// Assuming only Dec, Jan for ease at the moment. Can be changed later
if (day.getMonth() == 11) {
monthName = 'Dec.';
}
else if (day.getMonth() == 0) {
monthName = 'Jan.';
}
const formattedDay = monthName + ' ' + day.getDate().toString();
if (!validDays.includes(formattedDay)) {
invalidString += `${formattedDay}\n`;
}
}
if (invalidString != '') {
resultsEmbed.fields.push(
{
name: 'Missed Days',
value: invalidString,
},
);
resultsEmbed.footer =
{
text: `Organizers: Please check the above dates and react with ${emojiCheck} on any missed commits!`,
};
}
resultsEmbed.fields.push(
{
name: 'Total Commit Count',
value: validDays.length,
},
);
await interaction.editReply({ embeds: [resultsEmbed], ephemeral: false });
}
else {
const notInThread = new EmbedBuilder()
.setColor(interaction.member.displayHexColor)
.setTitle('Not in a Thread')
.setDescription('You must run this command in a Thread!');
await interaction.reply({ embeds: [notInThread], ephemeral: true });
}
},
};