├── .github
├── FUNDING.yml
├── workflows
│ ├── stale.yml
│ └── codeql-analysis.yml
└── stale.yml
├── events
├── disconnect.js
├── reconnecting.js
├── guildMemberRemove.js
├── guildMemberAdd.js
├── interactionCreate.js
├── ready.js
└── messageCreate.js
├── model
├── card.js
└── xp.js
├── commandhandler file exemple.txt
├── botconfig.json copy.exemple
├── slash
└── commands
│ └── ping.js
├── commands
├── music
│ ├── volume.js
│ ├── join.js
│ ├── pause.js
│ ├── resume.js
│ ├── leave.js
│ ├── skip.js
│ ├── queue.js
│ └── play.js
├── info
│ ├── invit.js
│ ├── game.js
│ ├── wink.js
│ ├── uptime.js
│ ├── ping.js
│ ├── serverinfo.js
│ ├── reddit.js
│ ├── whois.js
│ ├── botInfo.js
│ ├── addcard.js
│ ├── help.js
│ ├── lbtop10.js
│ ├── wow.js
│ └── rank.js
├── moderation
│ ├── say.js
│ ├── clear.js
│ ├── mute.js
│ ├── kick.js
│ └── ban.js
└── dev
│ └── eval.js
├── handler
└── command.js
├── deploy-commands.js
├── .circleci
└── config.yml
├── function.js
├── package.json
├── .gitignore
├── .eslintrc.json
├── LICENSE
├── CHANGELOGS.md
├── CODE_OF_CONDUCT.md
├── index.js
├── README.md
└── Cards.js
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | patreon: Asthriona
4 | ko_fi: Asthriona
5 |
--------------------------------------------------------------------------------
/events/disconnect.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "disconnect",
3 | once: false,
4 | execute() {
5 | console.log("Bot has been disconnected from discord...");
6 | },
7 | };
--------------------------------------------------------------------------------
/events/reconnecting.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "reconnecting",
3 | once: false,
4 | execute() {
5 | console.log("The bot is reconnecting to discord...");
6 | },
7 | };
--------------------------------------------------------------------------------
/model/card.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const cardsSchema = new mongoose.Schema({
4 | did: String,
5 | link: String,
6 | });
7 | module.exports = mongoose.model("Cards", cardsSchema);
--------------------------------------------------------------------------------
/commandhandler file exemple.txt:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: " ",
3 | category: "info",
4 | description: " ",
5 | run: async (bot, message, args) => {
6 | message.channel.send(`POG`)
7 | }
8 | }
--------------------------------------------------------------------------------
/botconfig.json copy.exemple:
--------------------------------------------------------------------------------
1 | {
2 | "token": "Bot tokken",
3 | "prefix": "a!",
4 | "dbLink": "mongodb://yukiko:127.0.0.1",
5 | "lavaHost": "localhost",
6 | "lavaPort": "2333",
7 | "lavaPasswd": "youshallnotpass"
8 | }
9 |
--------------------------------------------------------------------------------
/slash/commands/ping.js:
--------------------------------------------------------------------------------
1 | const { SlashCommandBuilder } = require("discord.js");
2 |
3 | module.exports = {
4 | data: new SlashCommandBuilder()
5 | .setName("ping")
6 | .setDescription("Pong!"),
7 | async execute(interaction) {
8 | interaction.reply("Pong!");
9 | },
10 | };
--------------------------------------------------------------------------------
/commands/music/volume.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "volume",
3 | category: "music",
4 | description: "change the volume of the video.",
5 | run: async (bot, message, args) => {
6 | // Just so my linter shut up. I'll make the command later.
7 | console.log(bot, message, args);
8 | },
9 | };
--------------------------------------------------------------------------------
/model/xp.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const userSchema = new mongoose.Schema({
4 | did: String,
5 | username: String,
6 | serverID: String,
7 | xp: Number,
8 | level: Number,
9 | message: Number,
10 | warns: Number,
11 | avatarURL: String,
12 | });
13 | module.exports = mongoose.model("Users", userSchema);
--------------------------------------------------------------------------------
/commands/info/invit.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "invite",
3 | category: "info",
4 | description: "Create an invitation to this server",
5 | run: async (bot, message) => {
6 | message.channel.createInvite()
7 | .then(invite => message.channel.send(`Here is your invitation! => \n ${invite}`))
8 | .catch(console.error);
9 | },
10 | };
--------------------------------------------------------------------------------
/events/guildMemberRemove.js:
--------------------------------------------------------------------------------
1 | const { farewell } = require("../Cards");
2 | module.exports = {
3 | name: "guildMemberRemove",
4 | once: false,
5 | async execute(member) {
6 | const farewellChannel = member.guild.channels.find(channel => channel.name === "welcome");
7 | if (!farewellChannel) return;
8 | return await farewell(member, farewellChannel);
9 | },
10 | };
--------------------------------------------------------------------------------
/commands/music/join.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "join",
3 | category: "music",
4 | description: "Let the bot join your VC waiting for music.",
5 | run: async (bot, message) => {
6 | const player = bot.manager.create({
7 | guild: message.guild.id,
8 | voiceChannel: message.member.voice.channel.id,
9 | textChannel: message.channel.id,
10 | });
11 | player.connect();
12 | message.reply("Here I am :D");
13 | },
14 | };
--------------------------------------------------------------------------------
/commands/info/game.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "game",
3 | category: "info",
4 | description: "change what bot is actually playing.",
5 | aliases: ["setgame"],
6 | run: async (bot, message, args) => {
7 | if(message.member.permissions.has("BAN_MEMBERS")) {
8 | bot.user.setPresence({ activities: [{ name: args.join(" ") }] });
9 | }
10 | else{
11 | return message.reply("Oy! You can't tell me what to do! ");
12 | }
13 |
14 | },
15 | };
--------------------------------------------------------------------------------
/events/guildMemberAdd.js:
--------------------------------------------------------------------------------
1 | // remember to make a command for the welcome channel as this bot is not set to run with a website.
2 | const { WelcomeCad } = require("../Cards");
3 | module.exports = {
4 | name: "guildMemberAdd",
5 | once: false,
6 | async execute(member) {
7 | const welcomeChannel = member.guild.channels.find(channel => channel.name === "welcome");
8 | if (!welcomeChannel) return;
9 | return await WelcomeCad(member, welcomeChannel);
10 | },
11 | };
--------------------------------------------------------------------------------
/commands/music/pause.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "pause",
3 | category: "music",
4 | description: "Pause the current video.",
5 | run: async (bot, message) => {
6 | const player = bot.manager.get(message.guild.id);
7 | if(!player) return message.reply("Im not playing at the moment, please use the `play` command.");
8 | if(player.playing != false || player.pause != false) return message.reply("Player is already paused.");
9 | player.pause(true);
10 | message.reply("Music has been paused!");
11 | },
12 | };
--------------------------------------------------------------------------------
/commands/music/resume.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "resume",
3 | category: "music",
4 | description: "Resume the current video.",
5 | run: async (bot, message) => {
6 | const player = bot.manager.get(message.guild.id);
7 | if(!player) return message.reply("Im not playing at the moment, please use the `play` command.");
8 | if(player.playing != true || player.pause != true) return message.reply("Player is not paused.");
9 | player.pause(false);
10 | message.reply("Music has been resumed!");
11 | },
12 | };
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | name: Mark stale issues and pull requests
2 |
3 | on:
4 | schedule:
5 | - cron: "30 1 * * *"
6 |
7 | jobs:
8 | stale:
9 |
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - uses: actions/stale@v1
14 | with:
15 | repo-token: ${{ secrets.GITHUB_TOKEN }}
16 | stale-issue-message: 'Stale issue message'
17 | stale-pr-message: 'Stale pull request message'
18 | stale-issue-label: 'no-issue-activity'
19 | stale-pr-label: 'no-pr-activity'
20 |
--------------------------------------------------------------------------------
/commands/info/wink.js:
--------------------------------------------------------------------------------
1 | const axios = require("axios");
2 | const { MessageEmbed } = require("discord.js");
3 | module.exports = {
4 | name: "wink",
5 | category: "info",
6 | description: "send a Winky face!",
7 | run: async (bot, message) => {
8 | const { body } = await axios
9 | .get("https://some-random-api.ml/animu/wink");
10 | const winkembed = new MessageEmbed()
11 | .setColor("#800080")
12 | .setTitle("winky Face! ;)")
13 | .setImage(body.link);
14 |
15 | message.channel.send({ embeds: [winkembed] });
16 | },
17 | };
--------------------------------------------------------------------------------
/commands/music/leave.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "stop",
3 | category: "music",
4 | description: "stop playing music and leave the channel.",
5 | run: async (bot, message) => {
6 | const player = bot.manager.get(message.guild.id);
7 | if(!player) return message.reply("There is no active player at the moment.");
8 | if (!player.playing) {
9 | player.destroy();
10 | message.channel.send("👉🚪 Leaving the channel.");
11 | }
12 | else {
13 | player.destroy();
14 | message.channel.send("🎵 Player has been destroyed. 👉🚪 Leaving the channel.");
15 | }
16 | },
17 | };
--------------------------------------------------------------------------------
/events/interactionCreate.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "interactionCreate",
3 | once: false,
4 | async execute(interaction, bot) {
5 | console.log(interaction);
6 | // check if command.
7 | if(!interaction.isChatInputCommand()) return;
8 | // check if command is run in DMs.
9 | if(interaction.commandGuildId === null || interaction.channel.type === "DM") return;
10 |
11 | // Build Data for command.
12 | const cmd = interaction.commandName;
13 | const Slashes = bot.slash.get(cmd);
14 | if(!Slashes) return;
15 | // Executhe command.
16 | Slashes.execute(interaction, bot);
17 | },
18 | };
19 |
--------------------------------------------------------------------------------
/commands/info/uptime.js:
--------------------------------------------------------------------------------
1 | // Geez. I had no idea how time works.
2 | // Message to Future Asthriona. use Day.js or moment for that pls.
3 | module.exports = {
4 | name: "uptime",
5 | category: "info",
6 | description: "Show bot's uptime",
7 | run: async (bot, message) => {
8 | let totalSeconds = (bot.uptime / 1000);
9 | const days = Math.floor(totalSeconds / 86400);
10 | const hours = Math.floor(totalSeconds / 3600);
11 | totalSeconds %= 3600;
12 | const minutes = Math.floor(totalSeconds / 60);
13 | const seconds = Math.floor(totalSeconds / 60);
14 | const uptime = `${days} days, ${hours} hours, ${minutes} minutes and ${seconds} seconds`;
15 | message.channel.send(uptime);
16 | },
17 | };
--------------------------------------------------------------------------------
/commands/music/skip.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "skip",
3 | category: "music",
4 | description: "Skip the current video.",
5 | run: async (bot, message) => {
6 | const player = bot.manager.get(message.guild.id);
7 | if(!player || player.playing == false) return message.reply("Nothing is playing at the moment");
8 | if(player.trackRepeat == true) {
9 | player.setTrackRepeat(false);
10 | await player.stop();
11 | message.channel.send(`${player.queue.current.title} has been skiped, repeat is disabled. \`${this.client.prefix}repeat\` to re-enable `);
12 | }
13 | else{
14 | player.stop();
15 | message.channel.send(`${player.queue.current.title} has been skiped.`);
16 | }
17 | },
18 | };
--------------------------------------------------------------------------------
/events/ready.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "ready",
3 | once: false,
4 | execute(bot) {
5 | console.log("Setting bot presence...");
6 | const statues = ["Persona 4 Golden", "Twitter: @YukikoApp", "W/ @Asthriona's Feelings", "w/ Rise", "in my castle", "Bummer! an error happened!"];
7 | setInterval(function() {
8 | const status = statues[Math.floor(Math.random() * statues.length)];
9 | bot.user.setStatus("dnd");
10 | bot.user.setPresence({ game: { name: status, type: "PLAYING" },
11 | });
12 | }, 600000);
13 | console.log("waiting for ready event...");
14 | console.log(`\x1b[32m${bot.user.username}\x1b[0m is now started and running.`);
15 | console.log("Init Player manager...");
16 | bot.manager.init(bot.user.id);
17 | },
18 | };
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | daysUntilStale: 7
3 | # Number of days of inactivity before a stale issue is closed
4 | daysUntilClose: 5
5 | # Issues with these labels will never be considered stale
6 | exemptLabels:
7 | - pinned
8 | - security
9 | # Label to use when marking an issue as stale
10 | staleLabel: wontfix
11 | # Comment to post when marking an issue as stale. Set to `false` to disable
12 | markComment: >
13 | This issue has been automatically marked as stale because it has not had
14 | recent activity. It will be closed if no further activity occurs. Thank you
15 | for your contributions.
16 | # Comment to post when closing a stale issue. Set to `false` to disable
17 | closeComment: true
18 |
--------------------------------------------------------------------------------
/handler/command.js:
--------------------------------------------------------------------------------
1 | const { readdirSync } = require("fs");
2 |
3 | const ascii = require("ascii-table");
4 |
5 | const table = new ascii("Commands");
6 | table.setHeading("Command", "Load status");
7 |
8 | module.exports = (bot) => {
9 | readdirSync("./commands/").forEach(dir => {
10 | const commands = readdirSync(`./commands/${dir}/`).filter(file => file.endsWith(".js"));
11 | for (const file of commands) {
12 | const pull = require(`../commands/${dir}/${file}`);
13 |
14 | if (pull.name) {
15 | bot.Commands.set(pull.name, pull);
16 | table.addRow(file, "✔️ Ok!");
17 | }
18 | else {
19 | table.addRow(file, "❌ -> missing a help.name, or help.name is not a string.");
20 | continue;
21 | }
22 |
23 | // If there's an aliases key, read the aliases.
24 | if (pull.aliases && Array.isArray(pull.aliases)) pull.aliases.forEach(alias => bot.Aliases.set(alias, pull.name));
25 | }
26 | });
27 | // Log the table
28 | console.log(table.toString());
29 | };
--------------------------------------------------------------------------------
/commands/info/ping.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-useless-escape */
2 | module.exports = {
3 | name: "ping",
4 | category: "info",
5 | description: "return bot latency and API ping.",
6 | run: async (bot, message) => {
7 | const spells = [
8 | "Agi", "Maragi", "Agilao", "Maragion",
9 | "Agidyne", "Maragidyne",
10 | ];
11 | const shadows = [
12 | "Lying Hablerie", "Calm Pesce", "Trance Twins", "Black Raven",
13 | "Magic Hand", "Secret Bambino", "Positive King", "Brinze Dice",
14 | "Burning Beetle", "Phantom Mage", "Heat Balance", "Laughing Table",
15 | "Avenger knight",
16 | ];
17 | const randomSpell = spells[Math.floor(Math.random() * spells.length)];
18 | const randomShadow = shadows[Math.floor(Math.random() * shadows.length)];
19 | const msg = await message.reply(`\* Yukiko cast ${randomSpell} against ${randomShadow} \*`);
20 | msg.edit(`**Pong!** \n Gateway latency: ${Math.floor(msg.createdAt - message.createdAt)}ms. \n API latency: ${Math.round(bot.ws.ping)}ms.`);
21 | },
22 | };
--------------------------------------------------------------------------------
/deploy-commands.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs");
2 | const path = require("path");
3 | const { REST, Routes } = require("discord.js");
4 | const { clientId, guildId, token } = require("./botconfig.json");
5 |
6 | const commands = [];
7 | const commandPath = path.join(__dirname, "slash/commands");
8 | const commandFiles = fs.readdirSync(commandPath).filter(file => file.endsWith(".js"));
9 | for(const file of commandFiles) {
10 | const filePath = path.join(commandPath, file);
11 | const command = require(filePath);
12 | commands.push(command.data.toJSON());
13 | }
14 |
15 | const rest = new REST({ version: "9" }).setToken(token);
16 | (async () => {
17 | try{
18 | console.log("Updating commands...");
19 | await rest.put(
20 | Routes.applicationGuildCommands(clientId, guildId),
21 | { body: commands },
22 | );
23 | console.log("Commands updated!");
24 | }
25 | catch(err) {
26 | console.error("an error happened while trying to refresh commands the commands:");
27 | console.error(err);
28 | }
29 | })();
--------------------------------------------------------------------------------
/commands/moderation/say.js:
--------------------------------------------------------------------------------
1 | const Discord = require("discord.js");
2 | module.exports = {
3 | name: "say",
4 | category: "Moderation",
5 | description: "Let the bot speak for you",
6 | run: async (bot, message, args) => {
7 | if(!message.member.permissions.has("BAN_MEMBERS")) return message.reply("Oy! dont tell me what to say!");
8 | if(message.deletable) message.delete();
9 | if(args.length < 1) {return message.reply("Nothing to say? Please TALK TO ME! 😢");}
10 |
11 | const roleColor = message.guild.me.displayHexColor === "#000" ? "#fff" : message.guild.me.displayHexColor ;
12 | if(args[0].toLowerCase() === "embed") {
13 | const embed = new Discord.MessageEmbed()
14 | .setColor(roleColor)
15 | .setAuthor({ name: message.author.username, iconURL: message.author.displayAvatarURL()})
16 | .setDescription(args.slice(1).join(" "))
17 | .setTimestamp()
18 | .setFooter({ name: `Powered by: ${bot.user.username}`, iconURL: bot.user.displayAvatarURL()});
19 | message.channel.send({ embeds:[embed] });
20 | }
21 | else{
22 | message.channel.send(args.join(" "));
23 | }
24 | },
25 | };
--------------------------------------------------------------------------------
/commands/info/serverinfo.js:
--------------------------------------------------------------------------------
1 | const { MessageEmbed } = require("discord.js");
2 | const moment = require("moment");
3 | module.exports = {
4 | name: "server",
5 | aliases: ["server-info", "serverinfo"],
6 | category: "info",
7 | description: "Return server infos.",
8 | run: async (bot, message) => {
9 | const guildOwner = bot.users.cache.get(message.guild.ownerId);
10 | const serverembed = new MessageEmbed()
11 | .setDescription("Server Information")
12 | .setColor("#800080")
13 | .setThumbnail(message.guild.iconURL())
14 | .addField("Server name", `${message.guild.name}`)
15 | .addField("Created at", `${moment(message.guild.createdAt).format("MMMM Do YYYY, h:mm:ss a")} (${moment(message.guild.createdAt).fromNow()})`)
16 | .addField("Joined at: ", `${moment(message.member.joinedAt).format("MMMM Do YYYY, h:mm:ss a")} (${moment(message.member.joinedAt).fromNow()})`)
17 | .addField("Owner: ", `${guildOwner}`)
18 | .addField("Total members: ", `${message.guild.memberCount}`)
19 | .setFooter(bot.user.username, bot.user.displayAvatarURL())
20 | .setTimestamp();
21 | return message.channel.send({ embeds: [serverembed] });
22 | },
23 | };
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | # JavaScript Node CircleCI 2.0 configuration file
2 | #
3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details
4 | #
5 | version: 2
6 | jobs:
7 | build:
8 | docker:
9 | # specify the version you desire here
10 | - image: circleci/node:7.10
11 |
12 | # Specify service dependencies here if necessary
13 | # CircleCI maintains a library of pre-built images
14 | # documented at https://circleci.com/docs/2.0/circleci-images/
15 | # - image: circleci/mongo:3.4.4
16 |
17 | working_directory: ~/repo
18 |
19 | steps:
20 | - checkout
21 |
22 | # Download and cache dependencies
23 | - restore_cache:
24 | keys:
25 | - v1-dependencies-{{ checksum "package.json" }}
26 | # fallback to using the latest cache if no exact match is found
27 | - v1-dependencies-
28 |
29 | - run: npm install
30 | - run: mv botconfig.json.exemple botconfig.json
31 |
32 | - save_cache:
33 | paths:
34 | - node_modules
35 | key: v1-dependencies-{{ checksum "package.json" }}
36 |
37 | # run tests!
38 | - run: npm start
39 |
--------------------------------------------------------------------------------
/commands/moderation/clear.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "clear",
3 | category: "Moderation",
4 | aliases: ["delete", "suppr", "remove"],
5 | description: "delete a lot of message :O",
6 | usage: "!clear [1 - 100]",
7 | run: async (bot, message, args) => {
8 | if(message.deletable) {
9 | message.delete();
10 | }
11 | if (!message.member.permissions.has("MANAGE_MESSAGES")) {
12 | return message.reply("you dont have the permissions to delete those message!");
13 | }
14 | if (isNaN(args[0]) || parseInt(args[0]) <= 0) {
15 | return message.reply("Oh my... Is this even a number?! Please use a number between 0 and 100 in numeric value.");
16 | }
17 | if(!message.guild.me.permissions.has("MANAGE_MESSAGES")) {
18 | return message.reply("I dont have the permissions to do that. Please add 'MANAGE_MESSAGES' to my permissions.");
19 | }
20 | let deleteAmount;
21 | if(parseInt(args[0]) > 100) {
22 | deleteAmount = 100;
23 | }
24 | else{
25 | deleteAmount = parseInt(args[0]);
26 | }
27 | message.channel.bulkDelete(deleteAmount, true)
28 | .then(deleted => message.channel.send(`I deleted ${deleted.size} messages.`)).then(m => m.delete({ timeout: 20000 }))
29 | .catch(err => message.reply("Yikes! An error sucessfully happened! " + err));
30 | },
31 | };
32 |
--------------------------------------------------------------------------------
/function.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | getMember: function(message, toFind = "") {
3 | toFind = toFind.toLowerCase();
4 | let target = message.guild.members.cache.get(toFind);
5 | if (!target && message.mentions.members) {target = message.mentions.members.first();}
6 | if (!target && toFind) {
7 | target = message.guild.members.find(member => {
8 | return member.displayName.toLowerCase().includes(toFind) ||
9 | member.user.tag.toLowerCase().includes(toFind);
10 | });
11 | }
12 | if (!target) {target = message.member;}
13 |
14 | return target;
15 | },
16 | formatDate: function(date) {
17 | return new Intl.DateTimeFormat("en-US").format(date);
18 | },
19 | promptMessage: async function(message, author, time, validReactions) {
20 | time *= 1000;
21 | for(const reaction of validReactions) await message.react(reaction);
22 | const filter = (reaction, user) => validReactions.includes(reaction.emoji.name) && user.id === author.id;
23 | return message
24 | .awaitReactions(filter, { max: 1, time: time })
25 | .then(collected => collected.first() && collected.first().emoji.name);
26 | },
27 | // for later use.
28 | loadSlashCommands() {
29 | return;
30 | },
31 | loadEvents() {
32 | return;
33 | },
34 | loadCommands() {
35 | return;
36 | },
37 | };
--------------------------------------------------------------------------------
/commands/info/reddit.js:
--------------------------------------------------------------------------------
1 | const axios = require("axios");
2 | const { MessageEmbed } = require("discord.js");
3 |
4 | module.exports = {
5 | name: "reddit",
6 | category: "info",
7 | description: "Send an image from a sub reddit!",
8 | usage: "$reddit [sub-reddit]",
9 | run: async (bot, message, args) => {
10 | const { body } = await axios
11 | .get(`https://www.reddit.com/r/${args}.json?sort=top&t=week`)
12 | .query({ limit: 800 });
13 |
14 | const allowed = message.channel.nsfw ? body.data.children : body.data.children.filter(post => !post.data.over_18);
15 | if(!allowed.length) return message.reply("We are running out of dank meme. 😂😂😂");
16 | const randomNumber = Math.floor(Math.random() * allowed.length);
17 | const embed = new MessageEmbed()
18 | .setColor("PURPLE")
19 | .setTitle(allowed[randomNumber].data.title)
20 | .setDescription(allowed[randomNumber].data.author)
21 | .setImage(allowed[randomNumber].data.url)
22 | .addField("Information: ", "Up vote:" + allowed[randomNumber].data.ups + " / Comment: " + allowed[randomNumber].data.num_comments)
23 | .setURL("https://reddit.com" + allowed[randomNumber].data.permalink)
24 | .setTimestamp()
25 | .setFooter(bot.user.username, bot.user.displayAvatarURL());
26 | return message.channel.send({ embeds: [embed] });
27 | },
28 | };
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yukiko-opensource",
3 | "version": "2.0.0",
4 | "description": "As Yukiko 2.0 (Closed sources) grow I don't have much time to work and update this version. if you need a great bot to help with your Discord guilds please use [Yukiko.app](https://Yukiko.app)",
5 | "main": "index.js",
6 | "dependencies": {
7 | "ascii-table": "0.0.9",
8 | "axios": "^0.21.4",
9 | "beautify": "0.0.8",
10 | "canvas": "^2.10.1",
11 | "common-tags": "^1.8.2",
12 | "discord.js": "^14.6.0",
13 | "erela.js": "^2.4.0",
14 | "fast-sort": "^3.2.0",
15 | "moment": "^2.29.4",
16 | "mongoose": "^5.13.15",
17 | "ms": "^2.1.3",
18 | "snyk": "^1.1033.0"
19 | },
20 | "scripts": {
21 | "test": "echo \"Error: no test specified\" && exit 1",
22 | "dev": "nodemon start"
23 | },
24 | "keywords": [
25 | "Discord",
26 | "bot",
27 | "Asthri",
28 | "Asthriona",
29 | "NodeJS",
30 | "NPM"
31 | ],
32 | "repository": {
33 | "type": "git",
34 | "url": "git+https://github.com/Asthriona/Yukiko.git"
35 | },
36 | "author": "",
37 | "license": "ISC",
38 | "bugs": {
39 | "url": "https://github.com/Asthriona/Yukiko/issues"
40 | },
41 | "homepage": "https://github.com/Asthriona/Yukiko#readme",
42 | "devDependencies": {
43 | "eslint": "^8.25.0"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/commands/dev/eval.js:
--------------------------------------------------------------------------------
1 | const { MessageEmbed } = require("discord.js");
2 | const beautify = require("beautify");
3 | const Config = require("../../botconfig.json");
4 | module.exports = {
5 | name: "eval",
6 | category: "dev",
7 | description: "Run some code directly in discord! (developper only!)",
8 | run: async (bot, message, args) => {
9 | if(!Config.owners.includes(message.author.id)) return message.reply("You are not a developper! you can't run code just like that!");
10 | if(!args[0]) return message.channel.send("Please gimme some good code!");
11 |
12 | try {
13 | if(args.join(" ").toLowerCase().includes("token")) {
14 | return message.channel.send("No, I'm not gonna give you my token! Nice try tho!");
15 | }
16 | const toEval = args.join(" ");
17 | const evaluated = eval(toEval);
18 |
19 | const embed = new MessageEmbed()
20 | .setColor("PURPLE")
21 | .setTimestamp()
22 | .setFooter(bot.user.username, bot.user.displayAvatarURL())
23 | .setTitle("Elva")
24 | .addField("To Evaluate:", `\`\`\`js\n${beautify(args.join(" "), { format: "js" })}\n\`\`\``)
25 | .addField("Evaluated:", evaluated)
26 | .addField("Type of:", typeof (evaluated));
27 |
28 | message.channel.send({ embeds: [embed] });
29 | }
30 | catch (e) {
31 | message.channel.send("ERROR! \n ```" + e + "```");
32 | }
33 | },
34 | };
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
63 | botconfig.json
64 | .env
65 | ./node_modules
66 |
67 | package-lock.json
68 |
69 | test.js
70 | IbeatYou.js
71 | createinvite.js
72 | commands/dev/fetch.js
73 | commands/dev/create.js
74 | package-lock.json
75 |
--------------------------------------------------------------------------------
/commands/music/queue.js:
--------------------------------------------------------------------------------
1 | const { MessageEmbed } = require("discord.js");
2 | const ms = require("ms");
3 |
4 | module.exports = {
5 | name: "queue",
6 | category: "music",
7 | description: "Show the queue",
8 | run: async (bot, message) => {
9 | const player = bot.manager.get(message.guild.id);
10 | if(!player) return message.reply("Noting playing at the moment.");
11 | try {
12 | if(!player.playing) return message.reply("Nothing is playing at the moment.");
13 | let total = 0;
14 | player.queue.forEach(queue => {
15 | total = total + queue.duration;
16 | });
17 | const queueEmbed = new MessageEmbed()()
18 | .setAuthor({name: "Playlist " + ms(total, { long: true }), iconURL: message.author.displayAvatarURL() })
19 | .setTitle(`Now Playing: ${player.queue.current.title} requested by: ${player.queue.current.requester.username}`)
20 | .setFooter({ text: `${bot.user.username} - Yukiko Dev Team`, iconURL: bot.user.displayAvatarURL() });
21 | queueEmbed.addField("Last Song:", player.queue.previous ? `${player.queue.previous.title} | ${player.queue.previous.requester.username}` : "No previously played songs.");
22 | for (let i = 0; i < player.queue.length; i += 10) {queueEmbed.splitFields(player.queue.map(track => `${++i}) 『${track.title}』 | Requested by <@${track.requester.id}>`).join(("\n")));}
23 | message.channel.send(queueEmbed);
24 | }
25 | catch (error) {
26 | console.log(error);
27 | message.channel.send(`Oops! an error happened...\n\`\`\`${error.message}\`\`\``);
28 | }
29 | },
30 | };
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "eslint:recommended",
3 | "env": {
4 | "node": true,
5 | "es6": true
6 | },
7 | "parserOptions": {
8 | "ecmaVersion": 2019
9 | },
10 | "rules": {
11 | "brace-style": ["warn", "stroustrup", { "allowSingleLine": true }],
12 | "comma-dangle": ["warn", "always-multiline"],
13 | "comma-spacing": "warn",
14 | "comma-style": "warn",
15 | "curly": ["warn", "multi-line", "consistent"],
16 | "dot-location": ["warn", "property"],
17 | "handle-callback-err": "off",
18 | "indent": ["warn", "tab"],
19 | "max-nested-callbacks": ["warn", { "max": 4 }],
20 | "max-statements-per-line": ["warn", { "max": 2 }],
21 | "no-console": "off",
22 | "no-empty-function": "warn",
23 | "no-floating-decimal": "warn",
24 | "no-inline-comments": "warn",
25 | "no-inner-declarations": "off",
26 | "no-lonely-if": "warn",
27 | "no-multi-spaces": "warn",
28 | "no-multiple-empty-lines": ["warn", { "max": 2, "maxEOF": 1, "maxBOF": 0 }],
29 | "no-shadow": ["warn", { "allow": ["err", "resolve", "reject"] }],
30 | "no-trailing-spaces": ["warn"],
31 | "no-var": "warn",
32 | "object-curly-spacing": ["warn", "always"],
33 | "prefer-const": "warn",
34 | "quotes": ["warn", "double"],
35 | "semi": ["warn", "always"],
36 | "space-before-blocks": "warn",
37 | "space-before-function-paren": ["warn", {
38 | "anonymous": "never",
39 | "named": "never",
40 | "asyncArrow": "always"
41 | }],
42 | "space-in-parens": "warn",
43 | "space-infix-ops": "warn",
44 | "space-unary-ops": "warn",
45 | "spaced-comment": "warn",
46 | "yoda": "warn"
47 | }
48 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2020, Asthriona
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/commands/info/whois.js:
--------------------------------------------------------------------------------
1 | const { MessageEmbed } = require("discord.js");
2 | const { stripIndents } = require("common-tags");
3 | const { getMember, formatDate } = require("../../function");
4 |
5 | module.exports = {
6 | name: "whois",
7 | aliases: ["who", "user", "info", "tamer"],
8 | description: "Returns user information",
9 | category: "info",
10 | usage: "[username | id | mention]",
11 | run: (bot, message, args) => {
12 | const member = getMember(message, args.join(" "));
13 |
14 | // Member variables
15 | const joined = formatDate(member.joinedAt);
16 | const roles = member.roles.cache
17 | .filter(r => r.id !== message.guild.id)
18 | .map(r => r).join(", ") || "none";
19 |
20 | // User variables
21 | const created = formatDate(member.user.createdAt);
22 |
23 | const embed = new MessageEmbed()
24 | .setAuthor({ name: message.author.username, iconURL: message.author.displayAvatarURL() })
25 | .setThumbnail(member.user.displayAvatarURL({ dynamic: true }))
26 | .setColor(member.displayHexColor === "#000000" ? "#ffffff" : member.displayHexColor)
27 | .setFooter({ text: bot.user.username, iconURL: bot.user.displayAvatarURL() })
28 |
29 | .addField("Member information:", stripIndents`**=> Display name:** ${member.displayName}
30 | **=> Joined at:** ${joined}
31 | **=> Roles:** ${roles}`, true)
32 |
33 | .addField("User information:", stripIndents`**=> ID:** ${member.user.id}
34 | **=> Username:** ${member.user.username}
35 | **=> Tag:** ${member.user.tag}
36 | **=> Created at:** ${created}`, true)
37 |
38 | .setTimestamp();
39 | message.channel.send({ embeds: [embed] });
40 | },
41 | };
--------------------------------------------------------------------------------
/commands/info/botInfo.js:
--------------------------------------------------------------------------------
1 | const { MessageEmbed } = require("discord.js");
2 | const pjson = require("../../package.json");
3 | module.exports = {
4 | name: "botinfo",
5 | category: "info",
6 | description: "show you information about this bot.",
7 | run: async (bot, message) => {
8 | const botembed = new MessageEmbed()
9 | .setThumbnail(bot.user.displayAvatarURL)
10 | .setTitle("About this bot:")
11 | .setAuthor({ name: bot.user.username, iconURL: bot.user.displayAvatarURL() })
12 | .setDescription("this bot can make your cat explode, Mount the DOGO, burn your egg and clean your house. (but not your room. we tested all of this.(RIP my cat...))")
13 | .setColor("#800080")
14 | .addField("Bot name:", bot.user.username, true)
15 | .addField("Version:", `${pjson.version} ${pjson.codeName}`, true)
16 | .addField("Developped by:", "[Asthriona](https://Asthriona.com) / [RiseDev](https://twitter.com/_RiseDev)", true)
17 | .addField("Developpers Website", "[Yukiko Dev Team](https://team.yukiko.app/), [Asthriona](https://Asthriona.com), [RiseDev](https://twitter.com/_RiseDev)", true)
18 | // Please DO NOT un-credit us. feel free to un-comment the line below to credit yourself :)
19 | // .addField("Edited by", "[Your Name](https://YourWebsiteOrLink.com)")
20 | .addField("Created on", bot.user.createdAt, true)
21 | .addField("On the server since:", bot.user.joinedAt, true)
22 | .addField("Git:", "https://github.com/Asthriona/Yukiko", true)
23 | .addField("Site: ", "http://yukiko.nishikino.me/", true)
24 | .addField("Guilds Using this bot: ", bot.guilds.size, true)
25 | .setTimestamp()
26 | .setFooter({ text: bot.user.username, iconURL: bot.user.displayAvatarURL() });
27 | return message.reply({ embeds: [botembed] });
28 | },
29 | };
--------------------------------------------------------------------------------
/commands/info/addcard.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 | const botConfig = require("../../botconfig.json");
3 | mongoose.connect(botConfig.dbLink, {
4 | useNewUrlParser: true,
5 | useUnifiedTopology: true,
6 | });
7 |
8 | const Cards = require("../../model/card.js");
9 | module.exports = {
10 | name: "card",
11 | aliases: ["cards", "rankcards", "changeCards", "newcards"],
12 | category: "info",
13 | description: "give you the possibility to change your card background!",
14 | usage: " | ",
15 | run: async (bot, message, args) => {
16 | if(args[0] === "info") {
17 | message.reply("You can send a custom image to use as a rank card.\n Your image must be in **934x282**. if it's not it will be stretched to this resolution. \n you must send a link to an image in ***.jpg*** or ***.png***. Any other link will be refused.");
18 | }
19 | console.log(args[0]);
20 | if(!args[0]) return message.reply("Please send a link to your image!");
21 | if(!args[0].startsWith("http" || "https")) return message.reply("please send a valid link.");
22 | // fix this.
23 | // aaah. I cant remember the issue. well test and fix this future me please.
24 | if(!args[0].endsWith(".png") || !args[0].endsWith(".jpg")) return message.reply("please send a link to an image in jpg or png.");
25 | Cards.findOne({
26 | did: message.author.id,
27 | }, (err, cards)=>{
28 | if(err) console.log(err);
29 | if (!cards) {
30 | const newCards = new Cards({
31 | did: message.author.id,
32 | link: args[0],
33 | });
34 | newCards.save().catch(error => console.log(error));
35 | message.reply("Your card has been saved!");
36 | }
37 | else {
38 | cards.link = args[0];
39 | cards.save().catch(error => console.log(error));
40 | message.reply("Your card has been saved!");
41 | }
42 | });
43 | },
44 |
45 | };
--------------------------------------------------------------------------------
/commands/info/help.js:
--------------------------------------------------------------------------------
1 | const { MessageEmbed } = require("discord.js");
2 | const { stripIndents } = require("common-tags");
3 | // var { botConfig } = require("../../botconfig.json")
4 | module.exports = {
5 | name: "help",
6 | category: "info",
7 | description: "Return all the commands for this bot.",
8 | usage: "[command | alias]",
9 | run: async (bot, message, args) => {
10 | if(args[0]) {
11 | return getCMD(bot, message, args[0]);
12 | }
13 | else {
14 | return getAll(bot, message);
15 | }
16 | },
17 | };
18 | // var prefix = botConfig.prefix;
19 |
20 | function getAll(bot, message) {
21 | const embed = new MessageEmbed()
22 | .setColor("RANDOM");
23 | const commands = (category) => {
24 | return bot.Commands
25 | .filter(cmd => cmd.category === category)
26 | .map(cmd => `\`${cmd.name}\``)
27 | .join(", ");
28 | };
29 | const info = bot.Categories
30 | .map(cat => stripIndents`**${cat[0].toUpperCase() + cat.slice(1)}** \n ${commands(cat)}`)
31 | .reduce((string, category) => string + "\n" + category);
32 | embed.setDescription(info);
33 | return message.reply({ embeds: [embed] });
34 | }
35 | function getCMD(bot, message, input) {
36 | const embed = new MessageEmbed();
37 | const cmd = bot.Commands.get(input.toLowerCase()) || bot.commands.get(bot.alias.get(input.toLowerCase()));
38 | let info = `No information for the commands ***${input.toLowerCase}`;
39 | embed.setColor("RED")
40 | .setDescription(info);
41 | if(!cmd) {
42 | return message.reply({ embeds: [embed] });
43 | }
44 | if(cmd.name) info = `**command name** ${cmd.name}`;
45 | if(cmd.alias) info += `\n**Alialses** ${cmd.aliases.map(a => `\`${a}\``).join(", ")}`;
46 | if(cmd.description) info += `\n**Description**: ${cmd.description}`;
47 | if(cmd.usage) {
48 | info += `\n**Usage**: ${cmd.usage}`;
49 | embed.setFooter("Syntax: <> = Is required, [] = is optional")
50 | .setColor("PURPLE")
51 | .setDescription(info);
52 | }
53 | return message.reply({ embeds: [embed] });
54 | }
--------------------------------------------------------------------------------
/CHANGELOGS.md:
--------------------------------------------------------------------------------
1 | # Change Logs
2 | Cette page me sert a noter l'avancement du bot au file des mise a jours, j'y note tout les Add, les bug fix (réparation de bug), les supressions, et modification.
3 |
4 | # 1.0
5 | ## ***It's alive!***
6 | + Add ban
7 | + Add kick
8 | + Add Mute
9 | + Add warn
10 | + Add report
11 | + Add ping
12 | + Add Présence personalisé
13 | + Add help (WIP)
14 | + Add help-commands (WIP)
15 | + Add help-game (WIP)
16 | + Add uptime
17 | + Add Clear (1 - 100)
18 |
19 | # 1.0.1
20 | ## ***[OwO]?***
21 | + Fix: permission warn/unwarn
22 | + Fix: Erreur Ban sans raison
23 | + Fix: Erreur Kick sans raison
24 | + Fix: Permission command Watch, Play, stream
25 | + Edit: changed the link of a!help commands
26 | + Edit: Traduction francaise a!server-info
27 | + Edit: Traduction francaise a!info
28 | + Update: Change logs
29 | + Deleted: Weebness de Ash.
30 |
31 | # 1.1.0
32 | ## ***[UwU Music? OwO]***
33 | + add: Music module [BETA] used with a!play a!skip a!stop
34 | + Edit: a!play has been changed to /game
35 | + Update: Change logs
36 | + deleted: Weebness de Ash.
37 | ## 1.1.1
38 | + Add: Queue system
39 | ## 1.1.2
40 | + Add: Better youtube support
41 | ## 1.1.3
42 | + Add: System play/pause
43 | + Add: volume commands
44 | + Add: Send music title when playing
45 | + Add: Now Playing command
46 | ## 1.1.4
47 | + Add: a!play now support playlists
48 | + Add: a!play now support youtube search
49 | + Add: Server Info
50 | + Add: User info
51 | + Update: Change logs
52 | + Deleted: Weebness de Ash.
53 | ## 2.0.0 [i'm Back to rules them all!]
54 | + Bot completely rewrited.
55 | + deleted: Mute commands [Temp]
56 | + Add: better commands handler
57 | + Add: a!animeFM is now playing [AnimeFM](https://Animefm.co) Main station
58 | + Update: Dynamic help commands
59 | + Update: a!help can now take argument like a command name to get more information on the commands.
60 |
61 |
62 | ### Bug
63 | + Warn reason can't contain only one word (fix in progress)
64 | + Uptime command is using his own time system.
65 |
66 |
67 | ## Road-Map
68 | + Custom rank cards
--------------------------------------------------------------------------------
/commands/info/lbtop10.js:
--------------------------------------------------------------------------------
1 | const { MessageEmbed } = require("discord.js");
2 | const mongoose = require("mongoose");
3 | const botConfig = require("../../botconfig.json");
4 |
5 | mongoose.connect(botConfig.dbLink, {
6 | useNewUrlParser: true,
7 | useUnifiedTopology: true,
8 | });
9 | const Users = require("../../model/xp.js");
10 |
11 | module.exports = {
12 | name: "top",
13 | category: "info",
14 | description: "Show the top 10 leaderboard!",
15 | run: async (bot, message) => {
16 | Users.find({
17 | serverID: message.guild.id,
18 | }).sort([
19 | ["xp", "descending"],
20 | ]).exec((err, res) => {
21 | if(err) console.log(err);
22 | const embed = new MessageEmbed()
23 | .setTitle("Yukiko's Leaderboard!")
24 | .setThumbnail(message.guild.iconURL())
25 | .setDescription("Here is our top10!")
26 | .setFooter(`Powered by ${bot.user.username}`, bot.user.displayAvatarURL());
27 | if(res.length === 0) {
28 | // if no result
29 | embed.setColor("red");
30 | embed.addField("No Data :c");
31 | }
32 | else if(res.length < 10) {
33 | // if less than 10
34 | embed.setColor("#351B96");
35 | let i;
36 | for(i = 0; i < res.length; i++) {
37 | const member = message.guild.members.cache.get(res[i].did) || "User is gone :/";
38 | if(member === "User is gone :/") {
39 | embed.addField(`${i + 1}. ${member}`, `**Level**: ${res[i].level} || **XP**: ${res[i].xp}`);
40 |
41 | }
42 | else{
43 | embed.addField(`${i + 1}. ${member.user.username}`, `**Level**: ${res[i].level} || **XP**: ${res[i].xp}`);
44 | }
45 | }
46 | }
47 | else{
48 | // if more than 10
49 | embed.setColor("#351B96");
50 | let i;
51 | for(i = 0; i < 10; i++) {
52 | const member = message.guild.members.get(res[i].did) || "User is gone :/";
53 | if(member === "User is gone :/") {
54 | embed.addField(`${i + 1}. ${member}`, `**Level**: ${res[i].level} || **XP**: ${res[i].xp}`);
55 |
56 | }
57 | else{
58 | embed.addField(`${i + 1}. ${member.user.username}`, `**Level**: ${res[i].level} || **XP**: ${res[i].xp}`, true);
59 | }
60 | }
61 | }
62 | message.reply({ embeds: [embed] });
63 | });
64 |
65 | },
66 | };
--------------------------------------------------------------------------------
/events/messageCreate.js:
--------------------------------------------------------------------------------
1 | // Holy fuck. Lots of work to do here.
2 | const Config = require("../botconfig.json");
3 | const Users = require("../model/xp.js");
4 | const Cards = require("../model/card.js");
5 | const { lvlupimg } = require("../Cards.js");
6 | module.exports = {
7 | name: "messageCreate",
8 | once: false,
9 | async execute(message, bot) {
10 | // ignore types of messages or without prefix.
11 | if (message.channel.type === "dm") return;
12 | if(message.author.bot) return;
13 | // DA NEW XP SYSTEM 2.0
14 | const xpAdd = Math.ceil(Math.random() * 15);
15 | const messageAdd = +1;
16 |
17 |
18 | Users.findOne({
19 | did: message.author.id,
20 | serverID: message.guild.id,
21 | }, (err, users) => {
22 | if (err) console.log(err);
23 | if (!users) {
24 | const newUsers = new Users({
25 | did: message.author.id,
26 | username: message.author.username,
27 | serverID: message.guild.id,
28 | xp: xpAdd,
29 | level: 0,
30 | message: messageAdd,
31 | warns: 0,
32 | avatarURL: message.author.displayAvatarURL(),
33 | });
34 |
35 | newUsers.save().catch(error => console.log(error));
36 | }
37 | else {
38 | users.xp = users.xp + xpAdd;
39 | users.message = users.message + messageAdd;
40 | users.username = message.author.username;
41 | users.avatarURL = message.author.displayAvatarURL();
42 |
43 | const nxtlvl = 300 * Math.pow(2, users.level);
44 | if (users.xp >= nxtlvl) {
45 | users.level = users.level + 1;
46 |
47 | // lvl up image
48 | const sendimg = async function sendimg() {
49 | await lvlupimg(message, users);
50 |
51 | };
52 | sendimg();
53 | }
54 | users.save().catch(error => console.log(error));
55 | }
56 | });
57 |
58 | // Add default cards to new users
59 | Cards.findOne({
60 | did: message.author.id,
61 | }, (err, cards) => {
62 | if (err) console.log(err);
63 | if (!cards) {
64 | const newCards = new Cards({
65 | did: message.author.id,
66 | link: "https://cdn.yukiko.app/Cards/DefaultYukikocard.jpg",
67 | });
68 | newCards.save().catch(error => console.log(error));
69 | }
70 | });
71 |
72 | // Setup Prefix and args
73 | const prefix = Config.prefix;
74 | const messageArray = message.content.split(" ");
75 | const args = messageArray.slice(1);
76 | const cmd = messageArray[0];
77 |
78 | if(!prefix) return;
79 | // Commands Handler
80 | const commandfile = bot.Commands.get(messageArray[0].slice(prefix.length));
81 | if (commandfile) commandfile.run(bot, message, args, cmd);
82 | },
83 | };
--------------------------------------------------------------------------------
/commands/info/wow.js:
--------------------------------------------------------------------------------
1 | // Well... I got this commands working on another bot (private commission) but I think i never finished it here.
2 | // Naw worries, its on my todo list :)
3 | const { MessageEmbed } = require("discord.js");
4 | const axios = require("axios");
5 | const botConfig = require("../../botconfig.json");
6 |
7 | module.exports = {
8 | name: "wow",
9 | category: "info",
10 | description: "Return your World of warcraft character!",
11 | usage: "",
12 | run: async (bot, message, args) => {
13 | const char = args[0];
14 | const realm = args[1];
15 | let region = args[2];
16 | if(!region) region = "eu";
17 | console.log(args[0] + " " + args[1]);
18 | axios.get("https://" + region + ".api.blizzard.com/wow/character/" + realm + "/" + char + "?locale=en_US&access_token=" + botConfig.wowAT).then(function(res) {
19 |
20 | if(message.author.id === "186195458182479874") {
21 | if(res.data.faction === 0) {
22 | const wowembed = new MessageEmbed()()
23 | .setTitle("Infos for: " + args)
24 | .addField("Name:", res.data.name, true)
25 | .addField("Realm", res.data.realm, true)
26 | .addField("Battlegroup", res.data.battlegroup, true)
27 | .addField("Class:", res.data.class, true)
28 | .addField("Race", res.data.race, true)
29 | .addField("Gender", res.data.gender, true)
30 | .addField("level", res.data.level, true)
31 | .addField("Achievement Points", res.data.achievementPoints, true)
32 | .addField("Calc Class", res.data.calcClass, true)
33 | .addField("faction", "Alliance", true)
34 | .addField("Total Honorable Kills", res.data.totalHonorableKills, true)
35 | .addField("ID", res.data.id, true);
36 | message.channel.send({ embeds: [wowembed] });
37 | }
38 | else{
39 | const wowembed = new MessageEmbed()()
40 | .setTitle("Infos for: " + args)
41 | .addField("Name:", res.data.name, true)
42 | .addField("Realm", res.data.realm, true)
43 | .addField("Battlegroup", res.data.battlegroup, true)
44 | .addField("Class:", res.data.class, true)
45 | .addField("Race", res.data.race, true)
46 | .addField("Gender", res.data.gender, true)
47 | .addField("level", res.data.level, true)
48 | .addField("Achievement Points", res.data.achievementPoints, true)
49 | .addField("Calc Class", res.data.calcClass, true)
50 | .addField("faction", "Horde", true)
51 | .addField("Total Honorable Kills", res.data.totalHonorableKills, true)
52 | .addField("ID", res.data.id, true);
53 | message.channel.send({ embeds: [wowembed] });
54 | }
55 | }
56 | }).catch(err => message.channel.send("WAW! an error sucessfully happened! ```" + err + "```"));
57 | },
58 | };
--------------------------------------------------------------------------------
/commands/music/play.js:
--------------------------------------------------------------------------------
1 | const ms = require("ms");
2 |
3 | module.exports = {
4 | name: "play",
5 | category: "music",
6 | description: "Play music from youtube",
7 | run: async (bot, message, args) => {
8 | const { channel } = message.member.voice;
9 | if (!channel) return message.reply("You must be in a voice channel.");
10 | let player = bot.manager.get(message.guild.id);
11 | if(!player) {
12 | player = bot.manager.create({
13 | guild: message.guild.id,
14 | voiceChannel: message.member.voice.channel.id,
15 | textChannel: message.channel.id,
16 | });
17 | player.connect();
18 | }
19 | try {
20 | bot.manager.search(args.join(" "), message.author).then(async res =>{
21 | switch (res.loadType) {
22 | case "TRACK_LOADED":
23 | player.queue.add(res.tracks[0]);
24 | message.channel.send(`${res.tracks[0].title} has been added to the queue.`);
25 | if(player.playing == true) {
26 | return;
27 | }
28 | else{
29 | player.play();
30 | }
31 | break;
32 | case "SEARCH_RESULT":
33 | // Music search not working anymore for whatever reason.
34 | // if someone wanna fix it, go ahead and PR :)
35 | player.queue.add(res.tracks[0]);
36 | message.reply(`${res.tracks[0].title} has been added to the queue.`);
37 | if (player.playing == true) {
38 | return;
39 | }
40 | else {
41 | player.play();
42 | }
43 | break;
44 | // let index = 1;
45 | // const tracks = res.tracks.slice(0, 5);
46 | // const embed = new MessageEmbed()
47 | // .setAuthor("Song Selection", bot.user.displayAvatarURL())
48 | // .setDescription(tracks.map(video => `**${index++} - ** ${video.title}`))
49 | // .setFooter("Your response time close within 30 seconds.");
50 |
51 | // await message.channel.send(embed);
52 | // const collector = message.channel.createMessageCollector(m =>{
53 | // return m.author.id === message.author.id && new RegExp("^([1-5|cancel])$", "i").test(m.content);
54 | // }, { time: 30000, max: 1 });
55 | // collector.on("collect", m =>{
56 | // const track = tracks[Number(m.content) - 1];
57 | // player.queue.add(track);
58 | // if(player.playing) {
59 | // return;
60 | // }
61 | // else{
62 | // player.play();
63 | // }
64 | // });
65 | // break;
66 | case "PLAYLIST_LOADED":
67 | res.tracks.forEach(track => player.queue.add(track));
68 | message.reply(`Enqueuing \`${res.tracks.length}\` tracks from the playlist \`${res.playlist.name}\` total time: \`${ms(res.playlist.duration, { long: true })}\``);
69 | if(player.playing) {
70 | return;
71 | }
72 | else{
73 | player.play();
74 | }
75 | break;
76 | }
77 | });
78 | }
79 | catch (error) {
80 | message.channel.send("Oops! an error happened...");
81 | console.log(error);
82 | }
83 | },
84 | };
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ "dev" ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ "dev" ]
20 | schedule:
21 | - cron: '26 19 * * 6'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
38 |
39 | steps:
40 | - name: Checkout repository
41 | uses: actions/checkout@v3
42 |
43 | # Initializes the CodeQL tools for scanning.
44 | - name: Initialize CodeQL
45 | uses: github/codeql-action/init@v2
46 | with:
47 | languages: ${{ matrix.language }}
48 | # If you wish to specify custom queries, you can do so here or in a config file.
49 | # By default, queries listed here will override any specified in a config file.
50 | # Prefix the list here with "+" to use these queries and those in the config file.
51 |
52 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
53 | # queries: security-extended,security-and-quality
54 |
55 |
56 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
57 | # If this step fails, then you should remove it and run the build manually (see below)
58 | - name: Autobuild
59 | uses: github/codeql-action/autobuild@v2
60 |
61 | # ℹ️ Command-line programs to run using the OS shell.
62 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
63 |
64 | # If the Autobuild fails above, remove it and uncomment the following three lines.
65 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
66 |
67 | # - run: |
68 | # echo "Run, Build Application using script"
69 | # ./location_of_script_within_repo/buildscript.sh
70 |
71 | - name: Perform CodeQL Analysis
72 | uses: github/codeql-action/analyze@v2
73 |
--------------------------------------------------------------------------------
/commands/moderation/mute.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unreachable */
2 | const { MessageEmbed } = require("discord.js");
3 | const ms = require("ms");
4 |
5 | module.exports = {
6 | name: "mute",
7 | category: "Moderation",
8 | description: "Create a new role!",
9 | usage: "!mute <@mention>