Skip to content
This repository was archived by the owner on Dec 22, 2024. It is now read-only.

Commit b0be9c0

Browse files
committed
Added MISC commands
1 parent 8e79b11 commit b0be9c0

File tree

5 files changed

+337
-0
lines changed

5 files changed

+337
-0
lines changed

commands/misc/about.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
2+
3+
module.exports = {
4+
data: new SlashCommandBuilder()
5+
.setName('about')
6+
.setDescription('Get general information about the bot'),
7+
async execute(interaction) {
8+
await interaction.reply({
9+
embeds: [ new EmbedBuilder()
10+
.setColor(`6ba4b8`)
11+
.setThumbnail(interaction.client.user.avatarURL())
12+
.setDescription(`## I'm QCBot. Nice to meet you!
13+
\n- Made by <@1037338320960761998>, with lots of help from the amazing AI HUB team!
14+
\n- Did you know I'm open source? [Well there you go.](https://github.com/Antasma245/QCBot)
15+
\n- Got a model to submit? Feel free to try out my commands!`) ]
16+
});
17+
}
18+
};

commands/misc/apod.js

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const { SlashCommandBuilder } = require('discord.js');
2+
const axios = require('axios');
3+
const nasaApiKey = process.env.nasaApiKey;
4+
5+
module.exports = {
6+
data: new SlashCommandBuilder()
7+
.setName('apod')
8+
.setDescription('Get the astronomy picture of the day'),
9+
async execute(interaction) {
10+
let ephemeralReply;
11+
12+
if (interaction.inGuild()) {
13+
ephemeralReply = true;
14+
} else {
15+
ephemeralReply = false;
16+
}
17+
18+
await interaction.deferReply({ ephemeral: ephemeralReply });
19+
20+
try {
21+
const response = await axios.get(`https://api.nasa.gov/planetary/apod?thumbs=true&api_key=${nasaApiKey}`);
22+
const apod = response.data;
23+
24+
await interaction.editReply({ content: `## ${apod.title}\n${apod.explanation}\n\n**Link:** <${apod.url}>`, files: [ apod.thumbnail_url ?? apod.url ] });
25+
} catch (error) {
26+
await interaction.editReply(`An error occurred. Please try again.`);
27+
throw error;
28+
}
29+
}
30+
};

commands/misc/config.js

+173
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
const { SlashCommandBuilder, ActivityType } = require('discord.js');
2+
const wait = require('node:timers/promises').setTimeout;
3+
const env = require('dotenv').config();
4+
const botAdminId = process.env.botAdminId;
5+
const submissionsChannelId = process.env.submissionsChannelId;
6+
7+
module.exports = {
8+
data: new SlashCommandBuilder()
9+
.setName('config')
10+
.setDescription('Customize the bot further')
11+
.addStringOption(option =>
12+
option.setName('status')
13+
.setDescription('Set the bot\'s status')
14+
.addChoices(
15+
{ name: 'Online', value: 'online' },
16+
{ name: 'Idle', value: 'idle' },
17+
{ name: 'Do Not Disturb', value: 'dnd' },
18+
{ name: 'Invisible', value: 'invisible' },
19+
))
20+
.addStringOption(option =>
21+
option.setName('activity-type')
22+
.setDescription('Set the bot\'s activity type')
23+
.addChoices(
24+
{ name: 'Watching', value: 'watching' },
25+
{ name: 'Listening', value: 'listening' },
26+
{ name: 'Playing', value: 'playing'},
27+
{ name: 'Competing', value: 'competing'},
28+
{ name: 'Custom', value: 'custom'},
29+
{ name: 'Reset', value: 'reset'},
30+
))
31+
.addStringOption(option =>
32+
option.setName('activity-name')
33+
.setDescription('Set the bot\'s activity name'))
34+
.addStringOption(option =>
35+
option.setName('nickname')
36+
.setDescription('Set the bot\'s nickname'))
37+
.addAttachmentOption(option =>
38+
option.setName('avatar')
39+
.setDescription('Set the bot\'s avatar'))
40+
.setDMPermission(false),
41+
async execute(interaction) {
42+
await interaction.deferReply({ ephemeral: true });
43+
44+
if (interaction.user.id != botAdminId) {
45+
return await interaction.editReply(`You do not have permission to use this command.`);
46+
}
47+
48+
const newStatus = await interaction.options.getString('status');
49+
const newActivityType = await interaction.options.getString('activity-type');
50+
const newActivityName = await interaction.options.getString('activity-name');
51+
const newNickname = await interaction.options.getString('nickname');
52+
const newAvatar = await interaction.options.getAttachment('avatar');
53+
54+
if (!newStatus && !newActivityType && !newActivityName && !newNickname && !newAvatar) {
55+
return await interaction.editReply(`Choose something to set!`);
56+
}
57+
58+
const options = [ newStatus, newActivityType, newActivityName, newNickname, newAvatar ];
59+
const plannedActions = options.filter(element => element).length;
60+
let executedActions = 0;
61+
62+
await interaction.editReply(`Waiting for all actions to be executed (${executedActions}/${plannedActions})`);
63+
await wait(2000);
64+
65+
if (newStatus) {
66+
try {
67+
await interaction.client.user.setStatus(newStatus);
68+
executedActions += 1;
69+
await interaction.editReply(`Status successfully set.\nWaiting for all actions to be executed (${executedActions}/${plannedActions})`);
70+
await wait(3000);
71+
} catch (setStatusError) {
72+
await interaction.editReply(`Unable to set status. ${setStatusError}\nWaiting for all actions to be executed (${executedActions}/${plannedActions})`);
73+
await wait(4000);
74+
}
75+
}
76+
77+
if (newActivityType) {
78+
try {
79+
if (newActivityType == 'reset') {
80+
await interaction.client.user.setPresence({});
81+
executedActions += 1;
82+
await interaction.editReply(`Activity succesfully reset.\nWaiting for all actions to be executed (${executedActions}/${plannedActions})`);
83+
await wait(3000);
84+
} else {
85+
const submissionsChannel = await interaction.guild.channels.fetch(submissionsChannelId);
86+
87+
switch (newActivityType) {
88+
case 'watching':
89+
await interaction.client.user.setActivity({
90+
name: newActivityName ?? `#${submissionsChannel.name}`,
91+
type: ActivityType.Watching,
92+
});
93+
break;
94+
case 'listening':
95+
await interaction.client.user.setActivity({
96+
name: newActivityName ?? `#${submissionsChannel.name}`,
97+
type: ActivityType.Listening,
98+
});
99+
break;
100+
case 'playing':
101+
await interaction.client.user.setActivity({
102+
name: newActivityName ?? `#${submissionsChannel.name}`,
103+
type: ActivityType.Playing,
104+
});
105+
break;
106+
case 'competing':
107+
await interaction.client.user.setActivity({
108+
name: newActivityName ?? `#${submissionsChannel.name}`,
109+
type: ActivityType.Competing,
110+
});
111+
break;
112+
case 'custom':
113+
await interaction.client.user.setActivity({
114+
name: newActivityName ?? `#${submissionsChannel.name}`,
115+
type: ActivityType.Custom,
116+
});
117+
break;
118+
}
119+
120+
if (newActivityName) {
121+
executedActions += 2;
122+
await interaction.editReply(`Activity type and name successfully set.\nWaiting for all actions to be executed (${executedActions}/${plannedActions})`);
123+
} else {
124+
executedActions += 1;
125+
await interaction.editReply(`Activity type and name successfully set and name defaulted.\nWaiting for all actions to be executed (${executedActions}/${plannedActions})`);
126+
}
127+
await wait(3000);
128+
}
129+
} catch (setActivityError) {
130+
await interaction.editReply(`Unable to set activity. ${setActivityError}\nWaiting for all actions to be executed (${executedActions}/${plannedActions})`);
131+
await wait(4000);
132+
}
133+
}
134+
135+
if (!newActivityType && newActivityName) {
136+
await interaction.editReply(`Unable to set activity name. No activity type provided.\nWaiting for all actions to be executed (${executedActions}/${plannedActions})`);
137+
await wait(4000);
138+
}
139+
140+
if (newNickname) {
141+
try {
142+
const botMember = await interaction.guild.members.fetch(interaction.client.user.id);
143+
if (newNickname == 'reset') {
144+
await botMember.setNickname(null);
145+
executedActions += 1;
146+
await interaction.editReply(`Nickname successfully reset for **${interaction.guild.name}**.\nWaiting for all actions to be executed (${executedActions}/${plannedActions})`);
147+
} else {
148+
await botMember.setNickname(newNickname);
149+
executedActions += 1;
150+
await interaction.editReply(`Nickname successfully set for **${interaction.guild.name}**.\nWaiting for all actions to be executed (${executedActions}/${plannedActions})`);
151+
}
152+
await wait(3000);
153+
} catch (setNicknameError) {
154+
await interaction.editReply(`Unable to set nickname for **${interaction.guild.name}**. ${setNicknameError}\nWaiting for all actions to be executed (${executedActions}/${plannedActions})`);
155+
await wait(4000);
156+
}
157+
}
158+
159+
if (newAvatar) {
160+
try {
161+
interaction.client.user.setAvatar(newAvatar.url);
162+
executedActions += 1;
163+
await interaction.editReply(`Avatar successfully set.\nWaiting for all actions to be executed (${executedActions}/${plannedActions})`);
164+
await wait(3000);
165+
} catch (setAvatarError) {
166+
await interaction.editReply(`Unable to set avatar. ${setAvatarError}\nWaiting for all actions to be executed (${executedActions}/${plannedActions})`);
167+
await wait(4000);
168+
}
169+
}
170+
171+
await interaction.editReply(`All actions executed (${executedActions}/${plannedActions})`);
172+
}
173+
};

commands/misc/ping.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
2+
3+
module.exports = {
4+
data: new SlashCommandBuilder()
5+
.setName('ping')
6+
.setDescription('Check the bot\'s ping'),
7+
async execute(interaction) {
8+
const sentMessage = await interaction.reply({
9+
embeds: [ new EmbedBuilder()
10+
.setColor(`6ba4b8`)
11+
.setTitle(`Pinging... 📨`) ],
12+
fetchReply: true
13+
});
14+
15+
await interaction.editReply({
16+
embeds: [ new EmbedBuilder()
17+
.setColor(`6ba4b8`)
18+
.setTitle(`Pong! 📬`)
19+
.setDescription(`Websocket heartbeat: ${interaction.client.ws.ping}ms\nRoundtrip latency: ${sentMessage.createdTimestamp - interaction.createdTimestamp}ms`) ]
20+
});
21+
}
22+
};

commands/misc/say.js

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
const { SlashCommandBuilder } = require('discord.js');
2+
const wait = require('node:timers/promises').setTimeout;
3+
const env = require('dotenv').config();
4+
const botAdminId = process.env.botAdminId;
5+
6+
module.exports = {
7+
data: new SlashCommandBuilder()
8+
.setName('say')
9+
.setDescription('Make the bot say something')
10+
.addStringOption(option =>
11+
option.setName('text')
12+
.setDescription('Enter text')
13+
.setRequired(true))
14+
.addStringOption(option =>
15+
option.setName('target-id')
16+
.setDescription('A target message ID to reply'))
17+
.addBooleanOption(option =>
18+
option.setName('ping-reply')
19+
.setDescription('Whether to ping the target author'))
20+
.addBooleanOption(option =>
21+
option.setName('add-reaction')
22+
.setDescription('Whether to react to the target'))
23+
.addBooleanOption(option =>
24+
option.setName('edit')
25+
.setDescription('Whether to edit the target'))
26+
.setDMPermission(false),
27+
async execute(interaction) {
28+
await interaction.deferReply({ ephemeral: true });
29+
30+
if (interaction.user.id != botAdminId) {
31+
return await interaction.editReply(`You do not have permission to use this command.`);
32+
}
33+
34+
const text = await interaction.options.getString('text');
35+
const targetMessageId = await interaction.options.getString('target-id');
36+
const pingOnReply = await interaction.options.getBoolean('ping-reply') ?? true;
37+
const addReaction = await interaction.options.getBoolean('add-reaction') ?? false;
38+
const editMessage = await interaction.options.getBoolean('edit') ?? false;
39+
40+
function lenghtOfMatches(text, regexPattern) {
41+
const matches = text.match(regexPattern);
42+
let totalMatchesLength = 0;
43+
44+
if (matches) {
45+
const matchesString = matches.join('');
46+
totalMatchesLength = matchesString.length;
47+
}
48+
49+
return totalMatchesLength;
50+
}
51+
52+
const emojiPattern = /<:[^<>]+:[^<>]+>/g;
53+
const totalEmojiLength = lenghtOfMatches(text, emojiPattern);
54+
55+
const linkPattern = /\bhttps:\/\/\S+/g;
56+
const totalLinkLength = lenghtOfMatches(text, linkPattern);
57+
58+
const typingTime = (text.length * 150) - (totalEmojiLength * 150) - (totalLinkLength * 150);
59+
60+
try {
61+
if (!targetMessageId) {
62+
await interaction.channel.sendTyping();
63+
await wait(typingTime);
64+
65+
await interaction.channel.send(text);
66+
67+
await interaction.editReply(`Message sent!`);
68+
} else if (!addReaction && !editMessage) {
69+
const targetMessage = await interaction.channel.messages.fetch(targetMessageId);
70+
71+
await interaction.channel.sendTyping();
72+
await wait(typingTime);
73+
74+
await targetMessage.reply({ content: text, allowedMentions: { repliedUser: pingOnReply } });
75+
76+
await interaction.editReply(`Message sent!`);
77+
} else if (addReaction) {
78+
const targetMessage = await interaction.channel.messages.fetch(targetMessageId);
79+
80+
await targetMessage.react(text);
81+
82+
await interaction.editReply(`Reaction added!`);
83+
} else {
84+
const targetMessage = await interaction.channel.messages.fetch(targetMessageId);
85+
86+
await targetMessage.edit(text);
87+
88+
await interaction.editReply(`Message edited!`);
89+
}
90+
} catch (error) {
91+
await interaction.editReply(`Failed to execute! ${error}`);
92+
}
93+
}
94+
};

0 commit comments

Comments
 (0)