Add blacklist and do things

This commit is contained in:
Isaac 2021-04-21 22:02:21 +01:00
parent 353cb5795e
commit a40290141b
9 changed files with 218 additions and 49 deletions

106
src/commands/blacklist.js Normal file
View File

@ -0,0 +1,106 @@
const { MessageEmbed } = require('discord.js');
const Command = require('../modules/commands/command');
module.exports = class BlacklistCommand extends Command {
constructor(client) {
const i18n = client.i18n.get(client.config.locale);
super(client, {
internal: true,
name: i18n('commands.blacklist.name'),
description: i18n('commands.blacklist.description'),
aliases: [
i18n('commands.blacklist.aliases.unblacklist'),
],
permissions: ['MANAGE_GUILD'], // staff_only: true,
process_args: false,
args: [
{
name: i18n('commands.blacklist.args.member_or_role.name'),
description: i18n('commands.blacklist.args.member_or_role.description'),
example: i18n('commands.blacklist.args.member_or_role.example'),
required: false,
}
]
});
}
async execute(message, args) {
let settings = await message.guild.settings;
const i18n = this.client.i18n.get(settings.locale);
let member = message.mentions.members.first();
if (member && (await member.isStaff() || member.hasPermission(this.permissions))) {
return await message.channel.send(
new MessageEmbed()
.setColor(settings.colour)
.setTitle(i18n('commands.blacklist.response.illegal_action.title'))
.setDescription(i18n('commands.blacklist.response.illegal_action.description', `<@${member.id}>`))
.setFooter(settings.footer, message.guild.iconURL())
);
}
let role = message.mentions.roles.first();
let id;
let input = args.trim().split(/\s/g)[0];
if (member) id = member.id;
else if (role) id = role.id;
else if (/\d{17,19}/.test(input)) id = input;
else if (settings.blacklist.length === 0) {
return await message.channel.send(
new MessageEmbed()
.setColor(settings.colour)
.setTitle(i18n('commands.blacklist.response.empty_list.title'))
.setDescription(i18n('commands.blacklist.response.empty_list.description', settings.command_prefix))
.setFooter(settings.footer, message.guild.iconURL())
);
} else {
// list blacklisted members
let blacklist = settings.blacklist.map(element => {
const is_role = message.guild.roles.cache.has(element);
if (is_role) return `» <@&${element}> (\`${element}\`)`;
else return `» <@${element}> (\`${element}\`)`;
});
return await message.channel.send(
new MessageEmbed()
.setColor(settings.colour)
.setTitle(i18n('commands.blacklist.response.list.title'))
.setDescription(blacklist.join('\n'))
.setFooter(settings.footer, message.guild.iconURL())
);
}
const is_role = role !== undefined || message.guild.roles.cache.has(id);
let member_or_role = is_role ? 'role' : 'member';
let index = settings.blacklist.findIndex(element => element === id);
let new_blacklist = [ ...settings.blacklist];
if (index === -1) {
new_blacklist.push(id);
await message.channel.send(
new MessageEmbed()
.setColor(settings.colour)
.setTitle(i18n(`commands.blacklist.response.${member_or_role}_added.title`))
.setDescription(i18n(`commands.blacklist.response.${member_or_role}_added.description`, id))
.setFooter(settings.footer, message.guild.iconURL())
);
} else {
new_blacklist.splice(index, 1);
await message.channel.send(
new MessageEmbed()
.setColor(settings.colour)
.setTitle(i18n(`commands.blacklist.response.${member_or_role}_removed.title`))
.setDescription(i18n(`commands.blacklist.response.${member_or_role}_removed.description`, id))
.setFooter(settings.footer, message.guild.iconURL())
);
}
settings.blacklist = new_blacklist;
await settings.save();
}
};

View File

@ -7,6 +7,10 @@ module.exports = ({ config }, sequelize) => {
primaryKey: true, primaryKey: true,
allowNull: false, allowNull: false,
}, },
blacklist: {
type: DataTypes.JSON,
defaultValue: [],
},
colour: { colour: {
type: DataTypes.STRING, type: DataTypes.STRING,
defaultValue: config.defaults.colour defaultValue: config.defaults.colour

View File

@ -23,6 +23,10 @@ module.exports = (client, sequelize) => {
type: DataTypes.CHAR(18), type: DataTypes.CHAR(18),
allowNull: false, allowNull: false,
}, },
first_response: {
type: DataTypes.DATE,
allowNull: true,
},
guild: { guild: {
type: DataTypes.CHAR(18), type: DataTypes.CHAR(18),
allowNull: false, allowNull: false,

View File

@ -6,6 +6,27 @@ module.exports = {
let settings = await message.guild.settings; let settings = await message.guild.settings;
if (!settings) settings = await message.guild.createSettings(); if (!settings) settings = await message.guild.createSettings();
let is_blacklisted = false;
if (settings.blacklist.includes(message.author.id)) {
is_blacklisted = true;
client.log.info(`Ignoring blacklisted member ${message.author.tag}`);
} else {
settings.blacklist.forEach(element => {
if (message.guild.roles.cache.has(element) && message.member.roles.cache.has(element)) {
is_blacklisted = true;
client.log.info(`Ignoring member ${message.author.tag} with blacklisted role`);
}
});
}
if (is_blacklisted) {
try {
return message.react('❌');
} catch (error) {
return client.log.debug('Failed to react to a message');
}
}
if (settings.log_messages && !message.system) client.tickets.archives.addMessage(message); // add the message to the archives (if it is in a ticket channel) if (settings.log_messages && !message.system) client.tickets.archives.addMessage(message); // add the message to the archives (if it is in a ticket channel)
client.commands.handle(message); // pass the message to the command handler client.commands.handle(message); // pass the message to the command handler

View File

@ -1,5 +1,22 @@
module.exports = { module.exports = {
event: 'messageReactionAdd', event: 'messageReactionAdd',
execute: (client, r, u) => { execute: async (client, r, u) => {
const guild = r.message;
if (!guild) return;
let settings = await guild.settings;
if (!settings) settings = await guild.createSettings();
if (settings.blacklist.includes(u.id)) {
return client.log.info(`Ignoring blacklisted member ${u.tag}`);
} else {
let member = await guild.members.fetch(u.id);
settings.blacklist.forEach(element => {
if (guild.roles.cache.has(element) && member.roles.cache.has(element)) {
return client.log.info(`Ignoring member ${u.tag} with blacklisted role`);
}
});
}
} }
}; };

View File

@ -18,37 +18,41 @@
"unblacklist": "unblacklist" "unblacklist": "unblacklist"
}, },
"args": { "args": {
"member": { "member_or_role": {
"name": "member", "name": "memberOrRole",
"description": "A member mention or ID", "description": "A member mention, a role mention, or the ID of a member or role",
"example": "@naughty" "example": "@naughty-member"
} }
}, },
"description": "Blacklist/unblacklist a member from interacting with the bot", "description": "Blacklist/unblacklist a member from interacting with the bot",
"name": "blacklist", "name": "blacklist",
"response": { "response": {
"added": { "empty_list": {
"title": "✅ Added member to blacklist", "title": "📃 Blacklisted members and roles",
"description": "%s has been added to the blacklist. They will no longer be able to interact with the bot." "description": "There are no members or roles blacklisted. Type `%sblacklist <memberOrRole>` to add a member or role to the blacklist."
},
"already_in_list": {
"title": "❌ Can't add member to blacklist",
"description": "%s is already blacklisted, so can not be added to the blacklist."
},
"list": {
"title": "📃 Blacklisted members"
},
"not_in_list": {
"title": "❌ Can't remove member from blacklist",
"description": "%s is not blacklisted, so can not be unblacklisted."
}, },
"illegal_action": { "illegal_action": {
"title": "❌ You can't blacklist this member", "title": "❌ You can't blacklist this member",
"description": "%s is a staff member and cannot be blacklisted." "description": "%s is a staff member and cannot be blacklisted."
}, },
"removed": { "list": {
"title": "📃 Blacklisted members and roles"
},
"member_added": {
"title": "✅ Added member to blacklist",
"description": "<@%s> has been added to the blacklist. They will no longer be able to interact with the bot."
},
"member_removed": {
"title": "✅ Removed member from blacklist", "title": "✅ Removed member from blacklist",
"description": "%s has been removed from the blacklist. They can now use the bot again." "description": "<@%s> has been removed from the blacklist. They can now use the bot again."
},
"role_added": {
"title": "✅ Added role to blacklist",
"description": "<@&%s> has been added to the blacklist. Members with this role will no longer be able to interact with the bot."
},
"role_removed": {
"title": "✅ Removed role from blacklist",
"description": "<@&%s> has been removed from the blacklist. Members with this role can now use the bot again."
} }
} }
}, },

View File

@ -53,9 +53,7 @@ module.exports = class CommandManager {
throw new Error(`A non-internal command with the name "${cmd.name}" already exists`); throw new Error(`A non-internal command with the name "${cmd.name}" already exists`);
this.commands.set(cmd.name, cmd); this.commands.set(cmd.name, cmd);
this.client.log.commands(`Loaded "${cmd.name}" command`);
let internal = cmd.internal ? 'internal ' : '';
this.client.log.commands(`Loaded ${internal}"${cmd.name}" command`);
} }
/** /**
@ -110,19 +108,7 @@ module.exports = class CommandManager {
); );
} }
if (cmd.staff_only) { if (cmd.staff_only && await message.member.isStaff() === false) {
let staff_roles = new Set();
let guild_categories = await this.client.db.models.Category.findAll({
where: {
guild: message.guild.id
}
});
guild_categories.forEach(cat => {
cat.roles.forEach(r => staff_roles.add(r));
}); // add all of the staff role IDs to the Set
staff_roles = staff_roles.filter(r => message.member.roles.cache.has(r)); // filter out any roles that the member does not have
const not_staff = staff_roles.length === 0;
if (not_staff) {
return await message.channel.send( return await message.channel.send(
new MessageEmbed() new MessageEmbed()
.setColor(settings.error_colour) .setColor(settings.error_colour)
@ -130,7 +116,6 @@ module.exports = class CommandManager {
.setDescription(i18n('staff_only.description')) .setDescription(i18n('staff_only.description'))
); );
} }
}
try { try {
this.client.log.commands(`Executing "${cmd.name}" command (invoked by ${message.author.tag})`); this.client.log.commands(`Executing "${cmd.name}" command (invoked by ${message.author.tag})`);

View File

@ -0,0 +1,26 @@
const { Structures } = require('discord.js');
Structures.extend('GuildMember', GuildMember => {
return class extends GuildMember {
constructor(client, data, guild) {
super(client, data, guild);
}
async isStaff() {
let guild_categories = await this.client.db.models.Category.findAll({
where: {
guild: this.guild.id
}
});
guild_categories.forEach(cat => {
cat.roles.forEach(r => {
if (this.roles.cache.has(r)) return true;
});
});
return false;
}
};
});

View File

@ -2,6 +2,7 @@ const fetch = require('node-fetch');
const boxen = require('boxen'); const boxen = require('boxen');
const link = require('terminal-link'); const link = require('terminal-link');
const semver = require('semver'); const semver = require('semver');
const { format } = require('leekslazylogger-fastify');
let { version: current } = require('../package.json'); let { version: current } = require('../package.json');
@ -17,13 +18,14 @@ module.exports = async client => {
if (semver.lt(current, latest)) { if (semver.lt(current, latest)) {
client.log.notice(client.log.f(`There is an update available for Discord Tickets (${current} -> ${update.tag_name})`)); client.log.notice(client.log.f(`There is an update available for Discord Tickets (${current} -> ${update.tag_name})`));
let notice = []; let lines = [
notice.push(`&6You are currently using &c${current}&6, the latest is &a${update.tag_name}&6.`); `&6You are currently using &c${current}&6, the latest is &a${update.tag_name}&6.`,
notice.push(`&6Download "&f${update.name}&6" from`); `&6Download "&f${update.name}&6" from`,
notice.push(link('&6the GitHub releases page', 'https://github.com/discord-tickets/bot/releases/')); link('&6the GitHub releases page', 'https://github.com/discord-tickets/bot/releases/')
];
console.log( console.log(
boxen(client.log.f(notice.join('\n')), { boxen(format(lines.join('\n')), {
padding: 1, padding: 1,
margin: 1, margin: 1,
align: 'center', align: 'center',