From ed25b54048787ffd8735b01b0f452fc5ff0a93e1 Mon Sep 17 00:00:00 2001 From: Jordian <82140054+Jordian0@users.noreply.github.com> Date: Tue, 29 Oct 2024 06:39:49 +0530 Subject: [PATCH] added contests command to see upcoming leetcode contests (#61) --- interactions/commands/contests.js | 125 ++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 interactions/commands/contests.js diff --git a/interactions/commands/contests.js b/interactions/commands/contests.js new file mode 100644 index 0000000..337170e --- /dev/null +++ b/interactions/commands/contests.js @@ -0,0 +1,125 @@ +import { SlashCommandBuilder, EmbedBuilder } from "discord.js"; +import { createRequire } from 'module'; +const require = createRequire(import.meta.url); +const https = require('https'); + +function formatTimeLeft(contestTime) { + const now = new Date(); + const contestDate = new Date(contestTime); + const timeDiff = contestDate - now; + + if (timeDiff < 0) return "Contest has started"; + + const days = Math.floor(timeDiff / (1000 * 60 * 60 * 24)); + const hours = Math.floor((timeDiff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + const minutes = Math.floor((timeDiff % (1000 * 60 * 60)) / (1000 * 60)); + + let timeString = ""; + if (days > 0) timeString += `${days}d `; + if (hours > 0) timeString += `${hours}h `; + if (minutes > 0) timeString += `${minutes}m`; + + return timeString.trim() || "Less than a minute"; +} + +// Helper function to make an HTTPS GET request +function fetchData(url) { + return new Promise((resolve, reject) => { + https.get(url, (response) => { + let data = ''; + + // A chunk of data has been received + response.on('data', (chunk) => { + data += chunk; + }); + + response.on('end', () => { + // console.log("Raw response data:", data); + + try { + // Check if the content type is JSON or text + const contentType = response.headers['content-type']; + if (contentType && contentType.includes('application/json')) { + // If it's JSON, parse it directly + const parsedData = JSON.parse(data); + resolve(parsedData); + } else if (contentType && contentType.includes('text/plain')) { + // If it's plain text, attempt to parse as JSON-like string + const parsedData = JSON.parse(data); + resolve(parsedData); + } else { + console.error("Unexpected content type:", contentType); + reject(new Error('Response is not JSON or text')); + } + } catch (error) { + console.error('Error parsing data:', error); + reject(new Error('Error parsing data')); + } + }); + }).on('error', (error) => { + reject(error); + }); + }); +} + + +export default { + data: new SlashCommandBuilder() + .setName('contests') + .setDescription('Shows upcoming LeetCode contests'), + run: async (interaction) => { + await interaction.deferReply(); + + try { + const url = 'https://contest-hive.vercel.app/api/leetcode'; // Your HTTP URL + const response = await fetchData(url); + const contests = response.data; + + if (!contests || contests.length === 0) { + return interaction.editReply('No upcoming contests found.'); + } + + const embed = new EmbedBuilder() + .setTitle('Upcoming LeetCode Contests') + .setColor(0xD1006C) + .setDescription('Here are the upcoming LeetCode contests:') + .setTimestamp(); + + contests.forEach((contest, index) => { + // Skip if contest has ended + if (new Date(contest.startTime) < new Date()) return; + + // Clean up the URL by removing 'undefined' + let cleanedUrl = contest.url ? contest.url.replace('undefined', '') : ''; + + // Format contest duration to hours and minutes + const duration = contest.duration / 60; + const hours = Math.floor(duration / 60); + const minutes = duration % 60; + const durationStr = `${hours}h ${minutes}m`; + + embed.addFields({ + name: `${index + 1}. ${contest.title}`, + value: ` + **Starts In:** ${formatTimeLeft(contest.startTime)} + **Duration:** ${durationStr} + **Date:** + **Link:** [Contest Link](https://leetcode.com/contest/${cleanedUrl}) + + `, + inline: false + }); + }); + + embed.setFooter({ + text: 'Pro Tip: Don\'t forget to register for the contests!' + }); + + return interaction.editReply({ embeds: [embed] }); + + } catch (error) { + console.error('Error fetching contests:', error); + return interaction.editReply('Sorry, there was an error fetching the contest information. Please try again later.'); + } + } +};