···11+MIT License
22+33+Copyright (c) 2024 isabelroses
44+55+Permission is hereby granted, free of charge, to any person obtaining a copy
66+of this software and associated documentation files (the "Software"), to deal
77+in the Software without restriction, including without limitation the rights
88+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99+copies of the Software, and to permit persons to whom the Software is
1010+furnished to do so, subject to the following conditions:
1111+1212+The above copyright notice and this permission notice shall be included in all
1313+copies or substantial portions of the Software.
1414+1515+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1616+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1717+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121+SOFTWARE.
+32
README.md
···11+# Blahaj
22+33+<h1 align="center">
44+ <img src="assets/BigBlobhajHug.svg" width="128" height="128" /><br />
55+ Blåhaj
66+</h1>
77+88+Blahaj is a simple discord bot that is designed to do anything that you want it to do. It is written in JavaScript and uses the discord.js library.
99+1010+## Installation
1111+1212+To install blahaj, you need to have node.js installed. You can download it from [here](https://nodejs.org/en/download/). Once you have node.js installed, you can install blahaj by running the following command:
1313+1414+Then navigate to the file and run the following command:
1515+```bash
1616+npm install
1717+```
1818+This will install all the dependencies that blahaj needs to run.
1919+2020+## Usage
2121+2222+To run blahaj
2323+```bash
2424+node src/index.js
2525+```
2626+2727+2828+## Thanks
2929+3030+Thanks to [discord.js](https://discord.js.org/#/) for making this bot possible.
3131+3232+Thanks to this [reddit post](https://www.reddit.com/r/BLAHAJ/comments/s91n8d/some_blahaj_emojis/) for the emojis.
···11+const { SlashCommandBuilder, PermissionsBitField } = require('discord.js');
22+33+module.exports = {
44+ data: new SlashCommandBuilder()
55+ .setName('ban')
66+ .setDescription('Bans a user')
77+ .setDefaultMemberPermissions(PermissionsBitField.Flags.BanMembers)
88+ .addUserOption(option => option.setName('target').setDescription('The user to ban').setRequired(true))
99+ .addStringOption(option => option.setName('reason').setDescription('The reason for the ban').setRequired(false)),
1010+ async execute(interaction) {
1111+ const user = interaction.options.getUser('target');
1212+ const member = await interaction.guild.members.fetch(user.id).catch(console.error);
1313+ let reason = interaction.options.getString('reason');
1414+ if (!reason) reason = 'No reason provided';
1515+1616+ if (!interaction.member.permissions.has(PermissionsBitField.Flags.BanMembers)) return await interaction.reply({ content: 'You do not have permission to ban this user', ephemeral: true })
1717+ if (!member.kickable) return await interaction.reply({ content: 'This user cannot be banned', ephemeral: true })
1818+ if (!member) return await interaction.reply({ content: `User ${user.tag} is not in this server`, ephemeral: true })
1919+ if (interaction.member.id === user.id) return await interaction.reply({ content: 'You cannot ban yourself', ephemeral: true })
2020+ if (member.permissions.has(PermissionsBitField.Flags.Administrator)) return await interaction.reply({ content: 'You cannot ban this user', ephemeral: true })
2121+2222+ user.send(`You have been banned from ${interaction.guild.name} for ${reason}`).catch(console.log("Dm's are disabled for this user"));
2323+ await member.ban({
2424+ deleteMessageSeconds: 60 * 60 * 24 * 7,
2525+ reason: reason,
2626+ }).catch(console.error);
2727+ await interaction.reply({
2828+ content: `Banned ${user.tag} for ${reason}`,
2929+ ephemeral: true
3030+ })
3131+ }
3232+};
+29
src/commands/moderation/kick.js
···11+const { SlashCommandBuilder, PermissionsBitField } = require('discord.js');
22+33+module.exports = {
44+ data: new SlashCommandBuilder()
55+ .setName('kick')
66+ .setDescription('Kicks a user')
77+ .setDefaultMemberPermissions(PermissionsBitField.Flags.KickMembers)
88+ .addUserOption(option => option.setName('target').setDescription('The user to kick').setRequired(true))
99+ .addStringOption(option => option.setName('reason').setDescription('The reason for the kick').setRequired(false)),
1010+ async execute(interaction) {
1111+ const user = interaction.options.getUser('target');
1212+ const member = await interaction.guild.members.fetch(user.id).catch(console.error);
1313+ let reason = interaction.options.getString('reason');
1414+ if (!reason) reason = 'No reason provided';
1515+1616+ if (!interaction.member.permissions.has(PermissionsBitField.Flags.KickMembers)) return await interaction.reply({ content: 'You do not have permission to kick this user', ephemeral: true })
1717+ if (!member.kickable) return await interaction.reply({ content: 'This user cannot be kicked', ephemeral: true })
1818+ if (!member) return await interaction.reply({ content: `User ${user.tag} is not in this server`, ephemeral: true })
1919+ if (interaction.member.id === user.id) return await interaction.reply({ content: 'You cannot kick yourself', ephemeral: true })
2020+ if (member.permissions.has(PermissionsBitField.Flags.Administrator)) return await interaction.reply({ content: 'You cannot kick this user', ephemeral: true })
2121+2222+ user.send(`You have been kicked from ${interaction.guild.name} for ${reason}`).catch(console.error);
2323+ await member.kick(`You have been kicked from ${interaction.guild.name} for ${reason}`).catch(console.log("Dm's are disabled for this user"));
2424+ await interaction.reply({
2525+ content: `Kicked ${user.tag} for ${reason}`,
2626+ ephemeral: true
2727+ })
2828+ }
2929+};
+27
src/commands/moderation/purge.js
···11+const { SlashCommandBuilder } = require('@discordjs/builders');
22+const { PermissionsBitField } = require('discord.js');
33+44+module.exports = {
55+ data: new SlashCommandBuilder()
66+ .setName('purge')
77+ .setDescription('Deletes messages.')
88+ .setDefaultMemberPermissions(PermissionsBitField.Flags.ManageMessages)
99+ .addIntegerOption(option =>
1010+ option.setName('amount')
1111+ .setMinValue(1)
1212+ .setMaxValue(100)
1313+ .setDescription('The amount of messages to delete.')
1414+ .setRequired(true)),
1515+ async execute(interaction) {
1616+ if (!interaction.member.permissions.has(PermissionsBitField.Flags.ManageMessages)) return await interaction.reply({ content: 'You do not have permission to purge messages', ephemeral: true })
1717+1818+ let amount = interaction.options.getInteger('amount');
1919+2020+ await interaction.channel.bulkDelete(amount).catch(err => {
2121+ console.error(err);
2222+ interaction.reply({ content: 'There was an error trying to purge messages in this channel!', ephemeral: true });
2323+ });
2424+2525+ await interaction.reply({ content: `Successfully deleted ${amount} messages.`, ephemeral: true });
2626+ }
2727+};
+41
src/commands/moderation/timeout.js
···11+const { SlashCommandBuilder, PermissionsBitField } = require('discord.js');
22+33+module.exports = {
44+ data: new SlashCommandBuilder()
55+ .setName('timeout')
66+ .setDescription('Times out a user')
77+ .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers)
88+ .addUserOption(option => option.setName('target').setDescription('The user to time out').setRequired(true))
99+ .addStringOption(option => option.setName('time').setDescription('The duration to time the user out').setRequired(true).addChoices(
1010+ { name: '60 seconds', value: '60' },
1111+ { name: '5 minutes', value: '300' },
1212+ { name: '10 minutes', value: '600' },
1313+ { name: '30 minutes', value: '1800' },
1414+ { name: '1 hour', value: '3600' },
1515+ { name: '12 hours', value: '43200' },
1616+ { name: '1 day', value: '86400' },
1717+ { name: '1 week', value: '604800' },
1818+ { name: '1 month', value: '2629743' }
1919+ ))
2020+ .addStringOption(option => option.setName('reason').setDescription('The reason for the timeout').setRequired(false)),
2121+ async execute(interaction) {
2222+ const user = interaction.options.getUser('target');
2323+ const member = await interaction.guild.members.fetch(user.id).catch(console.error);
2424+ let reason = interaction.options.getString('reason');
2525+ let time = interaction.options.getString('time');
2626+ if (!time) time = '60';
2727+ if (!reason) reason = 'No reason provided';
2828+2929+ if (!interaction.member.permissions.has(PermissionsBitField.Flags.ModerateMembers)) return await interaction.reply({ content: 'You do not have permission to timeout this user', ephemeral: true })
3030+ if (!member.kickable) return await interaction.reply({ content: 'This user cannot be timed out', ephemeral: true })
3131+ if (!member) return await interaction.reply({ content: `User ${user.tag} is not in this server`, ephemeral: true })
3232+ if (interaction.member.id === user.id) return await interaction.reply({ content: 'You cannot timeout yourself', ephemeral: true })
3333+ if (member.permissions.has(PermissionsBitField.Flags.Administrator)) return await interaction.reply({ content: 'You cannot timeout this user', ephemeral: true })
3434+3535+ await member.timeout(time * 1000, reason).catch(console.error);
3636+ await interaction.reply({
3737+ content: `Timed out ${user.tag} for ${time} seconds for ${reason}`,
3838+ ephemeral: true
3939+ })
4040+ }
4141+};
+28
src/commands/moderation/unban.js
···11+const { SlashCommandBuilder, PermissionsBitField } = require('discord.js');
22+33+module.exports = {
44+ data: new SlashCommandBuilder()
55+ .setName('unban')
66+ .setDescription('Unbans a user')
77+ .setDefaultMemberPermissions(PermissionsBitField.Flags.BanMembers)
88+ .addUserOption(option => option.setName('target').setDescription('The user to unban').setRequired(true)),
99+ async execute(interaction, client) {
1010+ const userid = interaction.options.getUser('target');
1111+1212+ if (!interaction.member.permissions.has(PermissionsBitField.Flags.BanMembers)) return await interaction.reply({ content: 'You do not have permission to unbanned this user', ephemeral: true })
1313+ if (!member.kickable) return await interaction.reply({ content: 'This user cannot be unbanned out', ephemeral: true })
1414+ if (!member) return await interaction.reply({ content: `User ${user.tag} is not in this server`, ephemeral: true })
1515+ if (interaction.member.id === userid) return await interaction.reply({ content: 'You cannot unbanned yourself', ephemeral: true })
1616+ if (member.permissions.has(PermissionsBitField.Flags.Administrator)) return await interaction.reply({ content: 'You cannot unbanned this user', ephemeral: true })
1717+1818+ await interactions.guild.ban.fetch().then(async bans => {
1919+ if (bans.size == 0) return await interaction.reply({ content: 'There are no banned users in this server', ephemeral: true });
2020+ let bUser = bans.find(b => b.user.id == userid);
2121+ if (!bUser) return await interaction.reply({ content: 'This user is not banned', ephemeral: true });
2222+2323+ await interaction.guild.bans.remove(userid).catch(err => {
2424+ return interaction.reply({ content: 'There was an error unbanning this user', ephemeral: true });
2525+ });
2626+ });
2727+ }
2828+};
+25
src/commands/moderation/untimeout.js
···11+const { SlashCommandBuilder, PermissionsBitField } = require('discord.js');
22+33+module.exports = {
44+ data: new SlashCommandBuilder()
55+ .setName('untimeout')
66+ .setDescription('Untimes out a user')
77+ .setDefaultMemberPermissions(PermissionsBitField.Flags.ModerateMembers)
88+ .addUserOption(option => option.setName('target').setDescription('The user to untimeout').setRequired(true)),
99+ async execute(interaction) {
1010+ const user = interaction.options.getUser('target');
1111+ const member = await interaction.guild.members.fetch(user.id).catch(console.error);
1212+1313+ if (!interaction.member.permissions.has(PermissionsBitField.Flags.ModerateMembers)) return await interaction.reply({ content: 'You do not have permission to untimeout this user', ephemeral: true })
1414+ if (!member.isTimeout) return await interaction.reply({ content: `User ${user.tag} is not timed out`, ephemeral: true })
1515+ if (!member) return await interaction.reply({ content: `User ${user.tag} is not in this server`, ephemeral: true })
1616+ if (interaction.member.id === user.id) return await interaction.reply({ content: 'You cannot untimeout yourself', ephemeral: true })
1717+ if (member.permissions.has(PermissionsBitField.Flags.Administrator)) return await interaction.reply({ content: 'You cannot untimeout this user', ephemeral: true })
1818+1919+ await member.timeout(null).catch(console.error);
2020+ await interaction.reply({
2121+ content: `Untimed out ${user.tag}`,
2222+ ephemeral: true
2323+ })
2424+ }
2525+};