Skip to content

Commit

Permalink
feat: i18n support (#7)
Browse files Browse the repository at this point in the history
* chore: add base structures

* refactor: implement player in voice command to the new structures

* refactor: migrate embed.js to Message class
other fix:
* fix eval result not code blocked
* fix whitespace when mentioning

* refactor: using custom command and remove redundant code
other changes:
* add eol rule eslint
* fix jsdoc

* fix: fix text not being decorated
and rename sendtoLogChan method

* feat: i18n support with language command

* refactor: use user.tag when getting username and discriminator

* style: add decoration to informative text

* refactor: allow seek close to the start of the song

* refactor: refactor some commands info

* refactor: autoplay takes only 5 top related videos

* refactor: refactor library

* refactor: using real emoticon

* fix: add catch block to avoid unhandled rejection

* refactor: expose bot version on bot activity

* refactor: add timestamp in logs

* docs: update README.md

* fix: forget to rename args key

* fix: remove pointer when showing playlist content
  • Loading branch information
Cudiph committed Feb 28, 2021
1 parent 6f2e748 commit 65682c0
Show file tree
Hide file tree
Showing 78 changed files with 1,360 additions and 1,539 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = {
parserOptions: {
ecmaVersion: 2019,
},
parser: "babel-eslint",
globals: {
logger: true,
},
Expand All @@ -16,6 +17,7 @@ module.exports = {
'curly': ['error', 'multi-line', 'consistent'],
"comma-spacing": ["error", { "before": false, "after": true }],
"dot-location": ["error", "property"],
"eol-last": ["error", "always"],
"indent": ["error", 2],
"max-nested-callbacks": ["error", { "max": 3 }],
"max-statements-per-line": ["error", { "max": 2 }],
Expand Down
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,36 @@
To create your bot application, you can read the official
[discord.js guide](https://discordjs.guide/preparations/setting-up-a-bot-application.html#creating-your-bot)
After getting the bot token you can copy it and put in `.env` file which will be explained in the
[running the bot](#runthebot) section
[running the bot](#running-the-bot) section

To add your bot to your server, look[here](https://discordjs.guide/preparations/adding-your-bot-to-servers.html)
To add your bot to your server, look [here](https://discordjs.guide/preparations/adding-your-bot-to-servers.html)
The invite link should look like this:
`https://discord.com/api/oauth2/authorize?client_id=762578055939620864&permissions=8&scope=bot`

## <a name="prereqs"></a> Prerequisites
You can try this bot by inviting the public bot with the link above

## Prerequisites
* [git](https://git-scm.com/downloads)
* [nodejs](https://nodejs.org/en/download/)
* [mongoDB](https://docs.mongodb.com/manual/administration/install-community/)
* [npm](https://nodejs.org/en/download/) (bundled with nodejs)
* [yarn 2](https://yarnpkg.com/getting-started/install)

## <a name="env"></a> `.env` File
## `.env` File
.env is file that stored super secret information like your bot token.
Here is the list of variable you should put in .env file :
- `TOKEN` = Token from the application in [discord developer portal](https://discord.com/developers/).
- `MONGO_URL` = Full URL of the MongoDB cluster if you're using a remote database

## <a name="runthebot"></a> Running the bot
After [prerequisites](#prereqs) are installed and your bot is already in your server,
## Running the bot
After [prerequisites](#prerequisites) are installed and your bot is already in your server,
follow the steps below to run it:
1. Clone this repo with `git clone <this repo url>`, or download the zipped file.
1. Then move to the project root directory and begin with setting up the`.env` file.
First copy the [`.env.example`](https://gitlab.com/Cudiph/monotonebot/-/blob/master/.env.example)
First copy the [`.env.example`](./.env.example)
file still in the current directory then paste and rename it to only `.env`.
Now open the file and change the value of `TOKEN` with your secret bot token,
and `MONGO_URL` with your Mongo database url.
and `MONGO_URL` with your Mongo database URI.
1. After that you can install required dependencies with `yarn install`. (Make sure you're using
yarn 2 with `yarn set version 2`)
1. Before starting the bot please check the MongoDB service if it's running and if you're running Mongo in locally
Expand Down
19 changes: 10 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,24 @@
"@discordjs/opus": "^0.4.0",
"axios": "^0.21.1",
"common-tags": "^1.8.0",
"discord-ytdl-core": "^5.0.0",
"discord-ytdl-core": "^5.0.1",
"discord.js": "^12.5.1",
"discord.js-commando": "https://github.com/discordjs/Commando.git#commit=9c2e5405fdb9a1006e6eb7554e18d0861a4c857f",
"discord.js-commando": "^0.12.2",
"dotenv": "^8.2.0",
"ffmpeg-static": "^4.2.7",
"merge-img": "^2.1.3",
"mongodb": "^3.6.3",
"mongoose": "^5.11.13",
"mongodb": "^3.6.4",
"mongoose": "^5.11.18",
"node-fetch": "^2.6.1",
"node-gtrans": "^1.5.1",
"node-gtrans": "^1.6.0",
"winston": "^3.3.3",
"yt-search": "^2.5.2",
"ytdl-core": "^4.4.5",
"ytpl": "^2.0.4"
"yt-search": "^2.7.3",
"ytdl-core": "^4.5.0",
"ytpl": "^2.0.5"
},
"devDependencies": {
"eslint": "^7.18.0",
"babel-eslint": "^10.1.0",
"eslint": "^7.20.0",
"eslint-plugin-import": "^2.22.1"
}
}
23 changes: 6 additions & 17 deletions src/Modules/administration/autorole.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { Command } = require('discord.js-commando');
const { guildSettingsSchema } = require('../../library/Database/schema.js');
const { sendtoLogChan } = require('../../library/helper/embed.js');
const Command = require('../../structures/Command.js');
const { guildSettingsSchema } = require('../../util/schema.js');


module.exports = class AutoRoleCommand extends Command {
constructor(client) {
Expand Down Expand Up @@ -37,7 +37,7 @@ module.exports = class AutoRoleCommand extends Command {
try {
guildSetting = await guildSettingsSchema.findOne({ guildId: msg.guild.id });
} catch (err) {
logger.log('error', err.stack);
logger.error(err.stack);
return msg.reply(`Can't load the data, please assign a new one if it's not already set`);
}

Expand Down Expand Up @@ -76,22 +76,11 @@ module.exports = class AutoRoleCommand extends Command {
const newGuildSettings = await guildSettingsSchema.findOneAndUpdate({ guildId: msg.guild.id }, {
autoAssignRoleId: role.id,
}, { new: true, upsert: true });
return sendtoLogChan(msg, { strMsg: `Assignment successful, new auto role is <@&${newGuildSettings.autoAssignRoleId}>` });
return msg.sendToLogChan({ strMsg: `Assignment successful, new auto role is <@&${newGuildSettings.autoAssignRoleId}>` });
} catch (err) {
logger.log('error', err.stack);
logger.error(err.stack);
return msg.reply(`Can't update new log channel.`);
}
}

async onBlock(msg, reason, data) {
super.onBlock(msg, reason, data)
.then(blockMsg => blockMsg.delete({ timeout: 10000 }))
.catch(e => e); // do nothing
}

onError(err, message, args, fromPattern, result) {
super.onError(err, message, args, fromPattern, result)
.then(msgParent => msgParent.delete({ timeout: 10000 }))
.catch(e => e); // do nothing
}
};
23 changes: 6 additions & 17 deletions src/Modules/administration/ban.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { Command } = require('discord.js-commando');
const Command = require('../../structures/Command.js');
const Discord = require('discord.js');
const { sendtoLogChan } = require('../../library/helper/embed.js');


module.exports = class BanCommand extends Command {
constructor(client) {
Expand Down Expand Up @@ -44,7 +44,7 @@ module.exports = class BanCommand extends Command {
// }

// get the banned data
const bannedName = `${member.user.username}#${member.user.discriminator} <${member.user.id}>`;
const bannedName = `${member.user.tag} <${member.user.id}>`;
const bannedImage = `${member.user.displayAvatarURL()}`;
if (member) {
try {
Expand All @@ -55,31 +55,20 @@ module.exports = class BanCommand extends Command {
.setTitle(`Banned Successfully`)
.setDescription(`**Member** : ${bannedName}\n` + `**Reason** : ${reason}\n` +
`**Time** : ${msg.createdAt.toUTCString()}`)
.setFooter(`Banned by ${msg.author.username}#${msg.author.discriminator}`,
.setFooter(`Banned by ${msg.author.tag}`,
`${msg.author.displayAvatarURL()}`);

return sendtoLogChan(msg, { embedMsg: embedMsg });
return msg.sendToLogChan({ embedMsg: embedMsg });
} catch (e) {
// due to missing permissions or role hierarchy
msg.reply(`I was unable to ban the member`);
logger.log('error', e.stack);
logger.error(e.stack);
}

} else { // Otherwise, if no user was mentioned
msg.reply("You didn't mention the user to ban!");
}
}

async onBlock(msg, reason, data) {
super.onBlock(msg, reason, data)
.then(blockMsg => blockMsg.delete({ timeout: 10000 }))
.catch(e => e); // do nothing
}

onError(err, message, args, fromPattern, result) {
super.onError(err, message, args, fromPattern, result)
.then(msgParent => msgParent.delete({ timeout: 10000 }))
.catch(e => e); // do nothing
}
};

22 changes: 6 additions & 16 deletions src/Modules/administration/guildconfig.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const { Command } = require('discord.js-commando');
const { guildSettingsSchema } = require('../../library/Database/schema.js');
const Command = require('../../structures/Command.js');
const { guildSettingsSchema } = require('../../util/schema.js');
const gtrans = require('node-gtrans');


module.exports = class GuildConfigCommand extends Command {
Expand All @@ -8,7 +9,7 @@ module.exports = class GuildConfigCommand extends Command {
name: 'guildconfig',
group: 'administration',
memberName: 'guildconfig',
aliases: ['guildsettings'],
aliases: ['guildsettings', 'gconfig', 'serverconfig'],
description: 'Show current guild configuration that stored in the database',
examples: ['guildconfig'],
guildOnly: true,
Expand Down Expand Up @@ -41,8 +42,8 @@ module.exports = class GuildConfigCommand extends Command {
inline: true,
},
{
name: 'Volume',
value: (guildSettings.volume || 0.5) * 100,
name: 'Language',
value: gtrans.validateLangId(msg.guild.language),
inline: true,
},
{
Expand Down Expand Up @@ -77,15 +78,4 @@ module.exports = class GuildConfigCommand extends Command {

}

async onBlock(msg, reason, data) {
super.onBlock(msg, reason, data)
.then(blockMsg => blockMsg.delete({ timeout: 10000 }))
.catch(e => e); // do nothing
}

onError(err, message, args, fromPattern, result) {
super.onError(err, message, args, fromPattern, result)
.then(msgParent => msgParent.delete({ timeout: 10000 }))
.catch(e => e); // do nothing
}
};
25 changes: 7 additions & 18 deletions src/Modules/administration/kick.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const Discord = require('discord.js');
const { Command } = require('discord.js-commando');
const { sendtoLogChan } = require('../../library/helper/embed.js');
const Command = require('../../structures/Command.js');


module.exports = class KickCommand extends Command {
constructor(client) {
Expand Down Expand Up @@ -31,7 +31,7 @@ module.exports = class KickCommand extends Command {
});
}

/** @param {import('discord.js-commando').CommandoMessage} message */
/** @param {import('discord.js-commando').CommandoMessage} msg */
async run(msg, { member, reason }) {
// // Manual method
// let member = await isUserId(args[0], msg);
Expand All @@ -44,7 +44,7 @@ module.exports = class KickCommand extends Command {
// } else {
// return msg.say('Invalid Id or Argument');
// }
const kickedName = `${member.user.username}#${member.user.discriminator} <${member.user.id}>`;
const kickedName = `${member.user.tag} <${member.user.id}>`;
const kickedimage = `${member.user.displayAvatarURL()}`;
try {
await member.kick(reason);
Expand All @@ -54,10 +54,10 @@ module.exports = class KickCommand extends Command {
.setTitle(`Kicked Successfully`)
.setDescription(`**Member** : ${kickedName}\n` + `**Reason** : ${reason}\n` +
`**Time** : ${msg.createdAt.toUTCString()}`)
.setFooter(`Kicked by ${msg.author.username}#${msg.author.discriminator}`,
.setFooter(`Kicked by ${msg.author.tag}`,
`${msg.author.displayAvatarURL()}`);

return sendtoLogChan(msg, { embedMsg: embedMsg });
return msg.sendToLogChan({ embedMsg: embedMsg });

} catch (e) {
// due to missing permissions or role hierarchy
Expand All @@ -66,15 +66,4 @@ module.exports = class KickCommand extends Command {

}

async onBlock(msg, reason, data) {
super.onBlock(msg, reason, data)
.then(blockMsg => blockMsg.delete({ timeout: 10000 }))
.catch(e => e); // do nothing
}

onError(err, message, args, fromPattern, result) {
super.onError(err, message, args, fromPattern, result)
.then(msgParent => msgParent.delete({ timeout: 10000 }))
.catch(e => e); // do nothing
}
};
};
15 changes: 2 additions & 13 deletions src/Modules/administration/leaveme.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { Command } = require('discord.js-commando');
const Command = require('../../structures/Command.js');

module.exports = class LeaveCommand extends Command {
constructor(client) {
Expand All @@ -16,15 +16,4 @@ module.exports = class LeaveCommand extends Command {
return msg.say("`Bye`").then(byeMsg => byeMsg.guild.leave());
}

async onBlock(msg, reason, data) {
super.onBlock(msg, reason, data)
.then(blockMsg => blockMsg.delete({ timeout: 10000 }))
.catch(e => e); // do nothing
}

onError(err, message, args, fromPattern, result) {
super.onError(err, message, args, fromPattern, result)
.then(msgParent => msgParent.delete({ timeout: 10000 }))
.catch(e => e); // do nothing
}
};
};
19 changes: 4 additions & 15 deletions src/Modules/administration/logchannel.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { stripIndents } = require('common-tags');
const { Command } = require('discord.js-commando');
const { guildSettingsSchema } = require('../../library/Database/schema.js');
const Command = require('../../structures/Command.js');
const { guildSettingsSchema } = require('../../util/schema.js');

module.exports = class LogChannelCommand extends Command {
constructor(client) {
Expand Down Expand Up @@ -41,7 +41,7 @@ module.exports = class LogChannelCommand extends Command {
try {
guildSettings = await guildSettingsSchema.findOne({ guildId: msg.guild.id });
} catch (err) {
logger.log('error', err.stack);
logger.error(err.stack);
return msg.reply(`Can't load the data, please assign a new one if it's not already set`);
}
// show current log channel if no argument
Expand Down Expand Up @@ -73,20 +73,9 @@ module.exports = class LogChannelCommand extends Command {
}, { new: true, upsert: true });
return msg.reply(`Assignment successful, new log channel is <#${newGuildSettings.logChannelId}>`);
} catch (err) {
logger.log('error', err.stack);
logger.error(err.stack);
return msg.reply(`Can't update new log channel.`);
}
}

async onBlock(msg, reason, data) {
super.onBlock(msg, reason, data)
.then(blockMsg => blockMsg.delete({ timeout: 10000 }))
.catch(e => e); // do nothing
}

onError(err, message, args, fromPattern, result) {
super.onError(err, message, args, fromPattern, result)
.then(msgParent => msgParent.delete({ timeout: 10000 }))
.catch(e => e); // do nothing
}
};
Loading

0 comments on commit 65682c0

Please sign in to comment.