Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6d6b46c
Update license to ISC and add README.md for Tiger Bot
Prarambha369 Apr 3, 2025
4943113
Update license to ISC and add README.md for Tiger Bot
Prarambha369 Apr 3, 2025
3623223
Merge remote-tracking branch 'origin/main'
Prarambha369 Apr 3, 2025
d5c72cd
Merge remote-tracking branch 'origin/main'
Prarambha369 Apr 3, 2025
87efce3
Merge remote-tracking branch 'origin/main'
Prarambha369 Apr 3, 2025
6465e3e
Add initial bot setup and command structure with various features
Prarambha369 Apr 4, 2025
850267d
Add package.json and update bot structure with new command and event …
Prarambha369 Apr 4, 2025
590936a
Fix path issues in configuration files and update dependencies in pac…
Prarambha369 Apr 4, 2025
3b1dc67
Merge remote-tracking branch 'origin/main'
Prarambha369 Apr 4, 2025
c92724a
Refactor bot initialization and enhance error handling; update depend…
Prarambha369 Apr 4, 2025
b7061b1
Update README and environment setup; integrate dotenv for configurati…
Prarambha369 Apr 4, 2025
f4624fa
Update license to ISC and add README.md for Tiger Bot
Prarambha369 Apr 3, 2025
23f6fca
Merge remote-tracking branch 'origin/main'
Prarambha369 Apr 3, 2025
eb32c16
Add initial bot setup and command structure with various features
Prarambha369 Apr 4, 2025
563a1a4
Refactor project structure by renaming Status.js and adding new confi…
Prarambha369 Apr 4, 2025
196a333
Fix path issues in configuration files and update dependencies in pac…
Prarambha369 Apr 4, 2025
455ea0d
Refactor bot initialization and enhance error handling; update depend…
Prarambha369 Apr 4, 2025
2dcee56
Update README and environment setup; integrate dotenv for configurati…
Prarambha369 Apr 4, 2025
9ab7917
Update README and environment setup; integrate dotenv for configurati…
Prarambha369 Apr 4, 2025
ad2ea3f
Update README and environment setup; integrate dotenv for configurati…
Prarambha369 Apr 4, 2025
522eec4
Add README for Tiger Bot; update dependencies in package.json and pac…
Prarambha369 Apr 4, 2025
c01a9be
Add README for Tiger Bot; update dependencies in package.json and pac…
Prarambha369 Apr 4, 2025
07bb853
Add README for Tiger Bot; update dependencies in package.json and pac…
Prarambha369 Apr 4, 2025
7638b27
Re-Add
Prarambha369 Apr 4, 2025
130fbd2
Add config.json; create commands and events directories; update packa…
Prarambha369 Apr 4, 2025
872fd22
Update LICENSE to custom terms; modify README acknowledgements
Prarambha369 Apr 4, 2025
d150e9b
Refactor command option types for consistency; remove deprecated even…
Prarambha369 Apr 4, 2025
b52a7d1
Refactor command option types for consistency; remove deprecated even…
Prarambha369 Apr 4, 2025
9b6d148
Refactor command structures to use SlashCommandBuilder; improve comma…
Prarambha369 Apr 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 5 additions & 19 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
MIT License
# Custom License

Copyright (c) 2025 NextEra Development
This project is licensed under the following terms:

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
1. **Personal Use Only**: This software is only usable for personal usages with your own hosting.
2. **Credit Requirement**: Visible credit to the original developers must be present somewhere visible at first sight.
3. **Commercial Use Prohibited**: Commercial usage is strictly prohibited. If found, the commercial use company or individual would be charged as theft.
31 changes: 31 additions & 0 deletions Owner/Status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const { Client } = require("discord.js");

module.exports = {
data: {
name: "Owner",
description: "Change the status of Tiger Bot!",
options: [{
name: "status",
description: "the new status of Tiger Bot!",
required: true,
type: 3, // Corrected type to STRING (3)
}],
},

/**
*
* @param {Client} client
* @param {*} interaction
* @returns
*/
run: async (client, interaction,args) => {
if (!client.owners.includes(interaction.user.id)) return interaction.reply({ content: `You are not a owner` });

client.user.setActivity({
name: interaction.options.getString("status", true),
type: "PLAYING"
});

interaction.reply({ content: `Status changed to : ${interaction.options.getString("status")}` });
}
}
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Tiger Bot

Tiger Bot is an advanced multipurpose Discord bot with slash commands. Originally developed in 2022, it has been recently reviewed and updated by NextEra Development. This project holds historical significance as it was the first project of NextEra Development.

## Features

- **Multipurpose Bot**: Supports a variety of commands and functionalities.
- **Slash Commands**: Utilizes Discord's slash commands for ease of use.
- **Giveaways**: Integrated with `discord-giveaways` for managing giveaways.
- **Games**: Includes fun games like fight and rock-paper-scissors.
- **Customizable**: Easily configurable to suit different server needs.

## Installation

1. Clone the repository:
```sh
git clone https://github.com/yourusername/tiger-bot.git
cd tiger-bot
```

2. Install dependencies:
```sh
npm install
```

3. Create a `.env` file in the root directory and add your configuration:
```dotenv
TOKEN=your_discord_bot_token
MONGO_URI=your_mongodb_uri
CLIENT_ID=your_discord_client_id
OWNER_ID=your_discord_owner_id
```

4. Start the bot:
```sh
npm run dev
```

## Configuration

The bot uses environment variables for configuration. Ensure you have a `.env` file with the following variables:

- `TOKEN`: Your Discord bot token.
- `MONGO_URI`: Your MongoDB connection string.
- `CLIENT_ID`: Your Discord client ID.
- `OWNER_ID`: Your Discord owner ID.

## Contributing

We welcome contributions! Please fork the repository and create a pull request with your changes.

## License

This project is licensed under a custom license. It is only usable for personal usages with your own hosting and with visible credit to us. Commercial usage is strictly prohibited. If found, the commercial use company or individual would be charged as theft.

## Acknowledgements

- Special thanks to the original developers and the NextEra Development team for their efforts in reviewing and updating this project.
215 changes: 215 additions & 0 deletions commands/Admin/menu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
const { SlashCommandBuilder, MessageActionRow, MessageButton } = require('discord.js');
const menus = require('../../models/reactionRole');

module.exports = {
data: new SlashCommandBuilder()
.setName('menu')
.setDescription('Manage guild reaction role')
.addSubcommand(subcommand =>
subcommand
.setName('create')
.setDescription('Create a new role menu')
.addStringOption(option =>
option
.setName('name')
.setDescription('Name of the role menu')
.setRequired(true)))
.addSubcommand(subcommand =>
subcommand
.setName('delete')
.setDescription('Delete a role menu')
.addStringOption(option =>
option
.setName('name')
.setDescription('Name of the role menu')
.setRequired(true)))
.addSubcommand(subcommand =>
subcommand
.setName('start')
.setDescription('Start a new role menu')
.addStringOption(option =>
option
.setName('name')
.setDescription('Name of the role menu')
.setRequired(true))
.addChannelOption(option =>
option
.setName('channel')
.setDescription('Mention the channel')
.setRequired(true)))
.addSubcommand(subcommand =>
subcommand
.setName('add-role')
.setDescription('Add a role in a reaction role menu')
.addStringOption(option =>
option
.setName('name')
.setDescription('Name of the role menu')
.setRequired(true))
.addRoleOption(option =>
option
.setName('role')
.setDescription('Mention the role')
.setRequired(true)))
.addSubcommand(subcommand =>
subcommand
.setName('remove-role')
.setDescription('Remove a role from a reaction role menu')
.addStringOption(option =>
option
.setName('name')
.setDescription('Name of the role menu')
.setRequired(true))
.addRoleOption(option =>
option
.setName('role')
.setDescription('Mention the role')
.setRequired(true))),
permissions: ["MANAGE_GUILD", "MANAGE_ROLES"], // Corrected permission name

async execute(interaction) {
await interaction.reply({ content: `${interaction.client.user.username} is thinking...`, ephemeral: true });

const option = interaction.options.getSubcommand(true).toLowerCase();
const name = interaction.options.getString("name")?.toLowerCase()?.trim();
const menu = await menus.findOne({ name, guild: interaction.guildId });
const my_role = interaction.guild.me.roles.highest.position;
const role = interaction.options.getRole("role");
const channel = interaction.options.getChannel("channel");

switch (option) {
case "create":
await handleCreate(interaction, menu, name);
break;
case "delete":
await handleDelete(interaction, menu, name);
break;
case "start":
await handleStart(interaction, menu, channel);
break;
case "add-role":
await handleAddRole(interaction, menu, role, my_role);
break;
case "remove-role":
await handleRemoveRole(interaction, menu, role);
break;
default:
await interaction.editReply({ content: "Invalid subcommand" });
}
}
};

async function handleCreate(interaction, menu, name) {
if (menu) {
return interaction.editReply({ content: `A Reaction Role menu already exists with that name. Please use a different name.` });
}

await menus.create({ guild: interaction.guildId, name, roles: [], message: "0" }); // Initialize roles as an empty array
interaction.editReply({ content: `Role menu created with name: \`${name}\`.` });
}

async function handleDelete(interaction, menu, name) {
if (!menu) {
return interaction.editReply({ content: `No Reaction Role menu exists with that name. Please provide a valid menu name.` });
}

await menus.findOneAndDelete({ guild: interaction.guildId, name });
interaction.editReply({ content: `Role menu deleted with name: \`${name}\`.` });
}

async function handleStart(interaction, menu, channel) {
if (channel.type !== "GUILD_TEXT" && channel.type !== "GUILD_NEWS") {
return interaction.editReply({ content: "Invalid channel was provided" });
}
if (!menu?.roles?.length) {
return interaction.editReply({ content: "This menu has 0 roles." });
}

const { content, rows } = createMenuContentAndButtons(interaction, menu);

const msg = await channel.send({ content, components: rows });

await menus.findOneAndUpdate({ name: menu.name, guild: interaction.guildId }, { message: msg.id });

interaction.editReply({ content: "Menu started successfully" });
}

function createMenuContentAndButtons(interaction, menu) {
let content = `Reaction Menu : **${menu.name}**\n\nReact to get yourself a role\n\n`,
rows = [new MessageActionRow()], index;

menu.roles.forEach((v, i) => {
content += `> ${interaction.guild.emojis.cache.get(v.emoji)?.toString() || v.emoji} : \`${interaction.guild.roles.cache.get(v.role).name}\`\n\n`;

index = parseInt(i / 5);
const button = new MessageButton({
customId: `reaction_role_${i}`,
style: "SECONDARY",
emoji: v.emoji,
});

rows[index] ? rows[index].addComponents(button) : rows[index] = new MessageActionRow().addComponents(button);
});

return { content, rows };
}

async function handleAddRole(interaction, menu, role, my_role) {
if (!menu) {
return interaction.editReply({ content: `Reaction Role menu does not exist with that name. Please provide a valid menu name.` });
}

if (role.position >= my_role) {
return interaction.editReply({ content: `The provided role is above my highest role. Please adjust the role hierarchy and try again.` });
}

const msg = await interaction.channel.send({ content: `React with the emoji you want for this role` });

const reactions = await msg.awaitReactions({
errors: ["time"],
filter: (r, u) => u.id === interaction.user.id,
max: 1,
time: 300000
}).catch(e => { });

const emoji = reactions.first()?.emoji;

if (!emoji) {
return interaction.editReply({ content: "You took too much time to respond" });
}

if (isRoleOrEmojiInMenu(menu, role, emoji)) {
return interaction.editReply({ content: `Reaction Role menu already has either the provided role or the emoji` });
}

menu.roles.push({ role: role.id, emoji: emoji.id || emoji.name });

await menus.findOneAndUpdate({ name, guild: interaction.guildId }, { roles: menu.roles });

interaction.editReply({ content: `Added role \`${role.name}\` with emoji: ${emoji.toString()} for menu: \`${menu.name}\`` });
await msg.delete();
}

async function handleRemoveRole(interaction, menu, role) {
if (!menu) {
return interaction.editReply({ content: `Reaction Role menu does not exist with that name. Please provide a valid menu name.` });
}

if (!isRoleInMenu(menu, role)) {
return interaction.editReply({ content: `Reaction Role menu does not have this role as part of it` });
}

menu.roles = menu.roles.filter((v) => v.role !== role.id);

await menus.findOneAndUpdate({ name, guild: interaction.guildId }, { roles: menu.roles });

interaction.editReply({ content: `Removed role \`${role.name}\` from menu: \`${menu.name}\`` });
}

function isRoleOrEmojiInMenu(menu, role, emoji) {
return menu.roles.some(v => v.role === role.id) || menu.roles.some(v => v.emoji === emoji.id || v.emoji === emoji.name);
}

function isRoleInMenu(menu, role) {
return menu.roles.some(v => v.role === role.id);
}
Loading