Skip to content
Merged

Sync #23

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
ffbb308
File Restructure
AkimotoRyou Jul 14, 2021
4a4f7ab
Delete
AkimotoRyou Jul 14, 2021
c0e5d97
Delete
AkimotoRyou Jul 14, 2021
e21f1f0
Delete
AkimotoRyou Jul 14, 2021
32c61dc
Delete
AkimotoRyou Jul 14, 2021
f7da194
Delete
AkimotoRyou Jul 14, 2021
e3df34c
Delete
AkimotoRyou Jul 14, 2021
31a3042
Delete
AkimotoRyou Jul 14, 2021
07a96ac
Delete
AkimotoRyou Jul 14, 2021
fa17102
Delete
AkimotoRyou Jul 14, 2021
e69a95a
Delete
AkimotoRyou Jul 14, 2021
0925e3d
Delete
AkimotoRyou Jul 14, 2021
f64ed86
Delete
AkimotoRyou Jul 14, 2021
7af4cb0
Delete
AkimotoRyou Jul 14, 2021
c99d620
Delete
AkimotoRyou Jul 14, 2021
fe16b2f
Delete
AkimotoRyou Jul 14, 2021
ceee6c8
Delete
AkimotoRyou Jul 14, 2021
fb8fc2f
Delete
AkimotoRyou Jul 14, 2021
92ce590
Delete
AkimotoRyou Jul 14, 2021
613bb84
Delete
AkimotoRyou Jul 14, 2021
7b1ac20
Delete
AkimotoRyou Jul 14, 2021
f1fff7a
Delete
AkimotoRyou Jul 14, 2021
6e31f53
Delete
AkimotoRyou Jul 14, 2021
c2b5785
Delete
AkimotoRyou Jul 14, 2021
9372c27
Delete
AkimotoRyou Jul 14, 2021
9c4d030
Delete
AkimotoRyou Jul 14, 2021
9da3911
Delete
AkimotoRyou Jul 14, 2021
d60d1c1
Delete
AkimotoRyou Jul 14, 2021
8147a81
Delete
AkimotoRyou Jul 14, 2021
1e1180b
Delete
AkimotoRyou Jul 14, 2021
7306691
Delete
AkimotoRyou Jul 14, 2021
64b79a7
Delete
AkimotoRyou Jul 14, 2021
4d91ca2
Delete
AkimotoRyou Jul 14, 2021
ad0036e
Delete
AkimotoRyou Jul 14, 2021
ddc0117
Delete
AkimotoRyou Jul 14, 2021
cf27b83
Delete
AkimotoRyou Jul 14, 2021
f77953c
Delete
AkimotoRyou Jul 14, 2021
134d6b4
Delete
AkimotoRyou Jul 14, 2021
df51a49
Delete
AkimotoRyou Jul 14, 2021
8ea4754
Delete
AkimotoRyou Jul 14, 2021
312b056
Delete
AkimotoRyou Jul 14, 2021
d2f9d55
Delete
AkimotoRyou Jul 14, 2021
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
35 changes: 10 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,40 +47,22 @@ To operate functionally the bot need the following :
* **turnoff** : Turn off the bot.
#### ~ Admin Level ~
* **bind** : Bind user thread to a channel.
* **configinfo** : Show a configuration information.
* **configuration** : Bot configuration.
* **config** : Show current bot config or info about each config.
* **guilds** : List of guilds (servers) that have this bot.
* **reset** : Reset all configuration values.
* **reset** : Reset specific or all configuration values.
* **set** : Set specific configuration value.
#### ~ Moderator Level ~
* **aclose** : Anonymously close a user thread.
* **areply** : Anonymously reply to a user thread.
* **block** : Block a user from creating new thread and replying to a thread.
* **blockinfo** : Information about a user's block.
* **blocklist** : List of blocked users.
* **block** : Block a user, show an info, or show list of blocked user(s).
* **close** : Close a user thread.
* **reply** : Reply to a user thread.
* **tag** : Send a saved response.
* **tagadd** : Add a saved response.
* **tagdelete** : Delete a saved response.
* **tagedit** : Edit a saved response.
* **taginfo** : Show a saved response information.
* **taglist** : Show all tag names.
* **threadinfo** : Show a user thread information.
* **threadlist** : Show all open threads.
* **tag** : Send, add, delete, edit, show an info or show list of saved response(s).
* **thread** : Show a user thread information or list of open thread(s).
* **unblock** : Unblock user from creating new thread.
#### ~ User level ~
* **commands** : List of all available commands according to your permission level.
* **help** : Short instruction on how to create a new thread or info on a specific command.
* **helpchs** : 显示如何使用操作这个系统的说明.
* **helpcht** : 顯示如何使用操作這個系統的說明.
* **helpde** : Anleitung zur Verwendung des Bots anzeigen.
* **helpes** : Mostrar instrucciones sobre cómo usar el bot.
* **helpfr** : Afficher les instructions sur l'utilisation du bot.
* **helpkr** : 봇 사용 방법에 대한 지시 사항 표시.
* **helppt** : Mostrar instruções sobre como usar o bot.
* **helpru** : Показать инструкцию о том, как использовать бот.
* **helptr** : Bot kullanımı hakkında talimat göster.
* **new** : Create new thread.
* **ping** : Calculate bot latency.

Expand All @@ -90,5 +72,8 @@ I made Discord server to test the bot, feel free to join at https://discord.gg/b

## Change Log

1. Migrate Database system from sqlite to replDB.
2. Due to replDB limitation, queue feature are removed and several other changes are made.
1. Events separated from index file make it easier for me to maintain or add stuff.
2. Permission check are now sentralized in commandHandler.js instead of in individual command file.
3. Config value are now checked before executing the command and will notify if it's invalid.
4. Several commands are now merged, use `<prefix>help <command name>` for more info.
5. More bot action logged in console for easier debugging.
109 changes: 60 additions & 49 deletions commands/aclose.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,69 @@
module.exports = {
name: 'aclose',
aliases: false,
level: 'Moderator',
name: "aclose",
aliases: ["ac"],
level: "Moderator",
guildOnly: true,
args: true,
usage: '[reason]-[note]',
description: 'Anonymously close a user thread.',
reqConfig: ["mainServerID", "threadServerID", "logChannelID"], // Configs needed to run this command.
usage: ["<reason>-[note]"],
description: "Anonymously close a user thread.",
note: false,
async execute(param, message, args) {
const config = param.config;
async execute(param, message, args, replyChannel) {
console.log(`~~ ${this.name.toUpperCase()} ~~`);

const client = param.client;
const getEmbed = param.getEmbed;
const aclose = param.aclose;

const noPermEmbed = getEmbed.execute(param, config.warning_color, "Missing Permission", "You don't have permission to run this command.");
const noServerEmbed = getEmbed.execute(param, config.warning_color, "Configuration Needed", "`mainServerID` and/or `threadServerID` value is empty.");
const noChannelEmbed = getEmbed.execute(param, config.error_color, "Configuration Needed", "`categoryID` and/or `logChannelID` value is empty.");
const noAdminEmbed = getEmbed.execute(param, config.warning_color, "Configuration Needed", "`adminRoleID` and/or `modRoleID` value is empty.");
const notChannelEmbed = getEmbed.execute(param, config.error_color, "Invalid Channel", `This isn't thread channel.`);

if (config.mainServerID == "empty" && config.threadServerID == "empty" && message.member.hasPermission("ADMINISTRATOR")) {
// mainServerID and threadServerID empty and user has ADMINISTRATOR permission
return message.channel.send(noServerEmbed);
} else if(message.guild.id == config.threadServerID) {
// inside thread server
if (config.adminRoleID == "empty" || config.modRoleID == "empty") {
// adminRoleID or modRoleID empty
return message.channel.send(noAdminEmbed);
} else if(config.categoryID == "empty" || config.logChannelID == "empty") {
// categoryID or logChannelID empty
return message.channel.send(noChannelEmbed);
} else if (message.channel.parentID != config.categoryID || message.channel.id == config.logChannelID || message.channel.id == config.botChannelID) {
// adminRoleID, modRoleID, categoryID and logChannelID not empty
// the channel isn't under modmail category or it's a log channel or it's bot channel -_-
return message.channel.send(notChannelEmbed);
} else if(message.author.id == config.botOwnerID) {
// the channel is under modmail category, it's not a log channel, and it's not bot channel
return aclose.execute(param, message, args);
} else if (message.member.hasPermission("ADMINISTRATOR") || await param.roleCheck.execute(message, config.adminRoleID)) {
// user has ADMINISTRATOR permission or has admin role
return aclose.execute(param, message, args);
} else if (await param.roleCheck.execute(message, config.modRoleID)) {
// user has moderator role
return aclose.execute(param, message, args);
} else if (config.botChannelID != "empty" && message.channel.id != config.botChannelID) {
// user didn't have ADMINISTRATOR permission, admin role, moderator role, and not in bot channel
return;
} else {
// user didn't have ADMINISTRATOR permission, admin role, nor moderator role
return message.channel.send(noPermEmbed);
const config = param.config;
const db = param.db;
const threadPrefix = param.dbPrefix.thread;
const updateActivity = param.updateActivity;

const mainServerID = config.mainServerID;
const mainServer = await client.guilds.fetch(mainServerID);
const threadServerID = config.threadServerID;
const threadServer = await client.guilds.fetch(threadServerID);
const logChannelID = config.logChannelID;
const logChannel = await threadServer.channels.fetch(logChannelID);
const author = message.author;
const channel = message.channel;

const userID = channel.name.split("-").pop();
const isThread = await db.get(threadPrefix + userID);
const addSpace = args.join(" ");
const deleteSeparator = addSpace.split(/-+/);
const reason = deleteSeparator.shift();
const note = deleteSeparator.shift() || "empty";

const noThreadEmbed = getEmbed.execute(param, "", config.error_color, "Not Found", "Couldn't find any thread asociated with this channel.");

if (!isThread) {
console.log("> Thread not found.");
return replyChannel.send(noThreadEmbed);
}
else {
const temp = isThread.split("-");
temp.shift();
const threadTitle = temp.join("-");
const user = await client.users.fetch(userID);
const logDescription = `${threadTitle}\n**Reason** : ${reason}\n**Note** : ${note}`;
const userDescription = `${threadTitle}\n**Reason** : ${reason}`;

let logEmbed;
const userDMEmbed = getEmbed.execute(param, "[Anonymous]", config.warning_color, "Thread Closed", userDescription, "", mainServer);

if (user) {
logEmbed = getEmbed.execute(param, author, config.warning_color, "Thread Closed Anonymously", logDescription, "", user);
await user.send(userDMEmbed);
await logChannel.send(logEmbed);
}
else {
logEmbed = getEmbed.execute(param, author, config.warning_color, "Thread Closed Anonymously", logDescription, "", `Can't find user | ${userID}`);
await logChannel.send(logEmbed);
}

} else {
// outside main server and thread server
return message.channel.send(noPermEmbed);
db.delete(threadPrefix + userID).then(() => console.log("> Thread closed anonymously."));
await updateActivity.execute(param);
return channel.delete().then(() => console.log("> Channel deleted."));
}
}
},
};
133 changes: 80 additions & 53 deletions commands/areply.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,88 @@
module.exports = {
name: 'areply',
aliases: false,
level: 'Moderator',
name: "areply",
aliases: ["ar"],
level: "Moderator",
guildOnly: true,
// in case only attachment no message
args: false,
usage: '[reply message]',
description: 'Anonymously reply to a user thread.',
args: false, // in case there's only attachment with no message
reqConfig: ["mainServerID"], // Configs needed to run this command.
usage: ["[reply message]"],
description: "Anonymously reply to a user thread.",
note: false,
async execute(param, message, args) {
const config = param.config;
async execute(param, message, args, replyChannel) {
console.log(`~~ ${this.name.toUpperCase()} ~~`);

const MessageAttachment = param.MessageAttachment;
const client = param.client;
const getEmbed = param.getEmbed;
const areply = param.areply;

const noPermEmbed = getEmbed.execute(param, config.warning_color, "Missing Permission", "You don't have permission to run this command.");
const noServerEmbed = getEmbed.execute(param, config.warning_color, "Configuration Needed", "`mainServerID` and/or `threadServerID` value is empty.");
const noChannelEmbed = getEmbed.execute(param, config.error_color, "Configuration Needed", "`categoryID` and/or `logChannelID` value is empty.");
const noAdminEmbed = getEmbed.execute(param, config.warning_color, "Configuration Needed", "`adminRoleID` and/or `modRoleID` value is empty.");
const notChannelEmbed = getEmbed.execute(param, config.error_color, "Invalid Channel", `This isn't thread channel.`);
const noArgsEmbed = param.getEmbed.execute(param, config.warning_color, "Missing Arguments", `You didn't provide any arguments nor attachments.`);

if (config.mainServerID == "empty" && config.threadServerID == "empty" && message.member.hasPermission("ADMINISTRATOR")) {
// mainServerID and threadServerID empty and user has ADMINISTRATOR permission
return message.channel.send(noServerEmbed);
} else if(message.guild.id == config.threadServerID) {
// inside thread server
if (config.adminRoleID == "empty" || config.modRoleID == "empty") {
// adminRoleID or modRoleID empty
return message.channel.send(noAdminEmbed);
} else if(config.categoryID == "empty" || config.logChannelID == "empty") {
// categoryID or logChannelID empty
return message.channel.send(noChannelEmbed);
} else if (message.channel.parentID != config.categoryID || message.channel.id == config.logChannelID || message.channel.id == config.botChannelID) {
// adminRoleID, modRoleID, categoryID and logChannelID not empty
// the channel isn't under modmail category or it's a log channel or it's bot channel -_-
return message.channel.send(notChannelEmbed);
} else if(!args.length && message.attachments.size == 0) {
// the channel is under modmail category, it's not a log channel, and it's not bot channel
return message.channel.send(noArgsEmbed);
} else if(message.author.id == config.botOwnerID) {
return areply.execute(param, message, args);
} else if (message.member.hasPermission("ADMINISTRATOR") || await param.roleCheck.execute(message, config.adminRoleID)) {
// user has ADMINISTRATOR permission or has admin role
return areply.execute(param, message, args);
} else if (await param.roleCheck.execute(message, config.modRoleID)) {
// user has moderator role
return areply.execute(param, message, args);
} else if (config.botChannelID != "empty" && message.channel.id != config.botChannelID) {
// user didn't have ADMINISTRATOR permission nor has admin role
return;
} else {
return message.channel.send(noPermEmbed);
const config = param.config;
const db = param.db;
const threadPrefix = param.dbPrefix.thread;
const isMember = param.isMember;
const isBlocked = param.isBlocked;

const mainServerID = config.mainServerID;
const mainServer = await client.guilds.fetch(mainServerID);
const author = message.author;

const userID = message.channel.name.split("-").pop();
const isThread = await db.get(threadPrefix + userID);
const checkIsBlocked = await isBlocked.execute(param, author.id);

const blockedEmbed = getEmbed.execute(param, "", config.error_color, "Blocked", "User blocked.");
const noDMEmbed = getEmbed.execute(param, "", config.error_color, "Not Sent", "User disabled Direct Message.");
const noUserEmbed = getEmbed.execute(param, "", config.error_color, "Not Found", "Couldn't find user in my collection.");
const noThreadEmbed = getEmbed.execute(param, "", config.error_color, "Not Found", "Couldn't find any thread asociated with this channel.");

if (!isThread) {
console.log("> Thread not found.");
return replyChannel.send(noThreadEmbed);
}
else {
const checkIsMember = await isMember.execute(param, userID);
const notMemberEmbed = getEmbed.execute(param, "", config.error_color, "Not a Member", `User aren't inside [**${mainServer.name}**] guild.`);

if (!checkIsMember) {
console.log("> The user isn't a main server member.");
return replyChannel.send(notMemberEmbed);
}
else if (checkIsBlocked) {
console.log("> The user is blocked.");
return replyChannel.send(blockedEmbed);
}
else {
const member = await mainServer.members.fetch(userID);

} else {
// outside main server and thread server
return message.channel.send(noPermEmbed);
if (!member) {
console.log("> Can't fetch user data.");
return replyChannel.send(noUserEmbed);
}
else {
const user = member.user;
const description = args.join(" ");
const userDMEmbed = getEmbed.execute(param, "[Anonymous]", config.sent_color, "Message Received", description, "", mainServer);
const threadChannelEmbed = getEmbed.execute(param, author, config.sent_color, "Message Sent Anonymously", description, "", user);

try{
await user.send(userDMEmbed);
}
catch (error) {
if(error.message == "Cannot send messages to this user") {
console.log("> Recipient's DM are disabled.");
return replyChannel.send(noDMEmbed);
}
}
await replyChannel.send(threadChannelEmbed);
if (message.attachments.size > 0) {
await message.attachments.forEach(async atch => {
const attachment = new MessageAttachment(atch.url);
await user.send(attachment);
await replyChannel.send(attachment);
});
}
return message.delete().then(() => console.log("> Message deleted."));
}

}
}
}
},
};
Loading