ban reaction
This commit is contained in:
parent
b51e508357
commit
0529a9d4d7
13 changed files with 305 additions and 79 deletions
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "knightrider",
|
||||
"version": "4.8.434",
|
||||
"version": "4.9.000",
|
||||
"description": "a bot for a private discord server",
|
||||
"main": "./dist/index.js",
|
||||
"scripts": {
|
||||
|
|
53
src/bot/commands/banreaction.ts
Normal file
53
src/bot/commands/banreaction.ts
Normal file
|
@ -0,0 +1,53 @@
|
|||
import { Client, ChatInputCommandInteraction, PermissionFlagsBits, SlashCommandBuilder } from "discord.js";
|
||||
|
||||
|
||||
import YALAS from 'mcstatusbot-logger';
|
||||
|
||||
import * as AddBanReaction from './banreaction/add';
|
||||
import * as RemoveBanReaction from './banreaction/remove';
|
||||
import { GuildInstance } from "../../database/schemas/Guild";
|
||||
import { UserInstance } from "../../database/schemas/User";
|
||||
|
||||
const data = {
|
||||
allowSuspendedUserAccess: false,
|
||||
command: new SlashCommandBuilder()
|
||||
.setName('banreaction')
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
|
||||
.setDescription("setup reaction to ban members from your server")
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('add')
|
||||
.setDescription("Add a ban reaction to your channel")
|
||||
.addChannelOption(option =>
|
||||
option.setName('channel')
|
||||
.setDescription('The channel in which you want to add a reaction')
|
||||
.setRequired(true)
|
||||
)
|
||||
|
||||
)
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('remove')
|
||||
.setDescription("remove a ban reaction")
|
||||
.addChannelOption(option =>
|
||||
option.setName('channel')
|
||||
.setDescription('The channel in which you want to remove a reaction')
|
||||
.setRequired(true)
|
||||
)
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export { data };
|
||||
|
||||
|
||||
export async function chatInputCommand(client: Client, interaction: ChatInputCommandInteraction, guild: GuildInstance, user: UserInstance) {
|
||||
switch (interaction.options.getSubcommand()) {
|
||||
case 'add':
|
||||
AddBanReaction.chatInputCommand(client, interaction, guild, user)
|
||||
break;
|
||||
case 'remove':
|
||||
RemoveBanReaction.chatInputCommand(client, interaction, guild, user)
|
||||
break;
|
||||
}
|
||||
}
|
116
src/bot/commands/banreaction/add.ts
Normal file
116
src/bot/commands/banreaction/add.ts
Normal file
|
@ -0,0 +1,116 @@
|
|||
import { Client, ChatInputCommandInteraction, GuildChannelResolvable, PermissionsBitField, ChannelType, EmbedBuilder } from "discord.js";
|
||||
|
||||
import { schemas } from "../../../database";
|
||||
|
||||
import YALAS from 'mcstatusbot-logger';
|
||||
|
||||
import { GuildInstance } from "../../../database/schemas/Guild";
|
||||
import { UserInstance } from "../../../database/schemas/User";
|
||||
|
||||
|
||||
export async function chatInputCommand(client: Client, interaction: ChatInputCommandInteraction, guild: GuildInstance, user: UserInstance) {
|
||||
if (!interaction.guild) return interaction.reply("must be done in discord server");
|
||||
|
||||
const botMember = interaction.guild.members.me;
|
||||
if (!botMember) {
|
||||
YALAS.error("reactionrole add: bot in guild null");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//get and validate channel
|
||||
const channel = interaction.options.getChannel('channel');
|
||||
if (channel == undefined) {
|
||||
return interaction.reply({
|
||||
embeds: [{
|
||||
title: "Channel Not Found",
|
||||
description: "The selected channel could not be found please try again."
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
if (channel.type !== ChannelType.GuildText) {
|
||||
return interaction.reply({
|
||||
embeds: [{
|
||||
title: "That Will Not Work",
|
||||
description: "The selected channel is not a text channel please select a text channel."
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
const botPermSM = botMember.permissionsIn((channel as GuildChannelResolvable)).toArray();
|
||||
if (botPermSM && !botPermSM.includes('SendMessages')) {
|
||||
return interaction.reply({
|
||||
embeds: [{
|
||||
title: "Missing permission",
|
||||
description: "you need to give me the send message permission in the selected channel."
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//check bot has manage roles perm
|
||||
const botPermMR = botMember.permissions.has(PermissionsBitField.Flags.BanMembers);
|
||||
if (!botPermMR) {
|
||||
return interaction.reply({
|
||||
embeds: [{
|
||||
title: "Missing permission",
|
||||
description: "you need to give me the Ban Members permission in this server."
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
await interaction.deferReply();
|
||||
//check emoji does net exist for reaction in channel
|
||||
try {
|
||||
const BanReaction = await schemas['BanReaction'].findOne({
|
||||
where: {
|
||||
guild: guild.id,
|
||||
channel: channel.id
|
||||
}
|
||||
});
|
||||
|
||||
if (BanReaction !== null) {
|
||||
return interaction.editReply({
|
||||
embeds: [{
|
||||
title: "Ban Reaction Exists",
|
||||
description: "This is already setup in selected channel."
|
||||
}]
|
||||
});
|
||||
}
|
||||
} catch (err: any) {
|
||||
YALAS.error(err)
|
||||
YALAS.error(err.stack || err);
|
||||
return interaction.editReply("error when checking for existing ban reaction in database.");
|
||||
}
|
||||
|
||||
try {
|
||||
await schemas['BanReaction'].create({
|
||||
guild: guild.id,
|
||||
channel: channel.id
|
||||
});
|
||||
} catch (err: any) {
|
||||
YALAS.error(err.stack || err);
|
||||
return interaction.editReply("error when saving ban reaction to database.");
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const textChannel = interaction.guild?.channels.cache.get(channel.id);
|
||||
if (textChannel === undefined || textChannel.type !== 0) return;
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setDescription("React with a ❌")
|
||||
.setFooter({ text: 'to get banned this is no joke' });
|
||||
|
||||
|
||||
const BanReactionMsg = await textChannel.send({ embeds: [embed] });
|
||||
await BanReactionMsg.react('❌');
|
||||
return interaction.editReply("ban reaction added to channel <#" + textChannel.id + ">.");
|
||||
} catch (err: any) {
|
||||
YALAS.error(err.stack || err);
|
||||
return interaction.editReply("error when making ban reaction embed.");
|
||||
}
|
||||
|
||||
}
|
67
src/bot/commands/banreaction/remove.ts
Normal file
67
src/bot/commands/banreaction/remove.ts
Normal file
|
@ -0,0 +1,67 @@
|
|||
import { GuildInstance } from "../../../database/schemas/Guild";
|
||||
import { UserInstance } from "../../../database/schemas/User";
|
||||
|
||||
import { Client, ChatInputCommandInteraction, Role, GuildChannelResolvable, TextChannel, ChannelType } from "discord.js";
|
||||
|
||||
import parseEmoji from "../../functions/parseEmoji";
|
||||
import { schemas } from "../../../database";
|
||||
|
||||
import YALAS from 'mcstatusbot-logger';
|
||||
|
||||
import SendReactionRoleEmbed from "../../functions/SendReactionRoleEmbed";
|
||||
|
||||
|
||||
|
||||
export async function chatInputCommand(client: Client, interaction: ChatInputCommandInteraction, guild: GuildInstance, user: UserInstance) {
|
||||
if (!interaction.guild) return interaction.reply("must be done in discord server");
|
||||
|
||||
//get and validate channel
|
||||
const channel = interaction.options.getChannel('channel');
|
||||
if (channel == undefined) {
|
||||
return interaction.reply({
|
||||
embeds: [{
|
||||
title: "Channel Not Found",
|
||||
description: "The selected channel could not be found please try again."
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
if (channel.type !== ChannelType.GuildText) {
|
||||
return interaction.reply({
|
||||
embeds: [{
|
||||
title: "That Will Not Work",
|
||||
description: "The selected channel is not a text channel please select a text channel."
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
await interaction.deferReply();
|
||||
try {
|
||||
const BanReaction = await schemas['BanReaction'].findOne({
|
||||
where: {
|
||||
guild: guild.id,
|
||||
channel: channel.id,
|
||||
},
|
||||
raw: true
|
||||
});
|
||||
|
||||
if (BanReaction == null) {
|
||||
return interaction.editReply({
|
||||
embeds: [{
|
||||
title: "Ban Role Doesn't Exists",
|
||||
description: "This ban reaction could not be found in the selected channel."
|
||||
}]
|
||||
});
|
||||
}
|
||||
await schemas['BanReaction'].destroy({ where: { id: BanReaction.id } });
|
||||
return interaction.editReply("ban reaction deleted.");
|
||||
} catch (err: any) {
|
||||
YALAS.error(err)
|
||||
YALAS.error(err.stack || err);
|
||||
return interaction.editReply("error when getting and deleting reaction role in database.");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { Client, ChatInputCommandInteraction, Role, GuildChannelResolvable, PermissionsBitField } from "discord.js";
|
||||
import { Client, ChatInputCommandInteraction, Role, GuildChannelResolvable, PermissionsBitField, ChannelType } from "discord.js";
|
||||
|
||||
import parseEmoji from "../../functions/parseEmoji";
|
||||
import { schemas } from "../../../database";
|
||||
|
@ -31,7 +31,7 @@ export async function chatInputCommand(client: Client, interaction: ChatInputCom
|
|||
});
|
||||
}
|
||||
|
||||
if (channel.type !== 0) {
|
||||
if (channel.type !== ChannelType.GuildText) {
|
||||
return interaction.reply({
|
||||
embeds: [{
|
||||
title: "That Will Not Work",
|
||||
|
@ -75,6 +75,15 @@ export async function chatInputCommand(client: Client, interaction: ChatInputCom
|
|||
});
|
||||
}
|
||||
|
||||
if (cleanEmoji == '❌') {
|
||||
return interaction.reply({
|
||||
embeds: [{
|
||||
title: "Invalid Emoji",
|
||||
description: "The selected emoji is used for the ban reaction to avoid confusion you can not use it."
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//get and validate role
|
||||
const role = interaction.options.getMentionable('role');
|
||||
|
@ -146,6 +155,7 @@ export async function chatInputCommand(client: Client, interaction: ChatInputCom
|
|||
const textChannel = interaction.guild?.channels.cache.get(channel.id);
|
||||
if (textChannel === undefined || textChannel.type !== 0) return;
|
||||
const embed = await SendReactionRoleEmbed(textChannel, guild.id, channel.id);
|
||||
|
||||
|
||||
return interaction.editReply({
|
||||
embeds: [{
|
||||
|
|
41
src/bot/functions/BanReactionHandler.ts
Normal file
41
src/bot/functions/BanReactionHandler.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { Client, MessageReaction, PartialMessageReaction, User, PartialUser, Guild, Role, GuildMember } from "discord.js";
|
||||
import { schemas } from "../../database";
|
||||
|
||||
import * as YALAS from 'mcstatusbot-logger';
|
||||
export default async function ReactionRoleAddHandler(reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser) {
|
||||
|
||||
const emoji: string | null = reaction.emoji.id ?? reaction.emoji.name;
|
||||
const guild: Guild | null = reaction.message.guild;
|
||||
const channelId: string = reaction.message.channelId;
|
||||
|
||||
|
||||
if (guild === null || emoji === null) {
|
||||
YALAS.error("failed to find guild");
|
||||
return false;
|
||||
}
|
||||
if (emoji!=='❌') return false;
|
||||
|
||||
|
||||
//TODO: implement redis cache or better table lookup
|
||||
const banReaction = await schemas['BanReaction'].findOne({
|
||||
where: {
|
||||
guild: guild.id,
|
||||
channel: channelId
|
||||
},
|
||||
raw: true
|
||||
});
|
||||
if (banReaction===null) return false;
|
||||
|
||||
|
||||
try {
|
||||
const member: GuildMember | null = guild.members.cache.get(user.id) || (await guild.members.fetch(user.id).catch(() => null));
|
||||
if (!member) return YALAS.error("Ban Reaction Handler: Member not found in the guild '" + guild.id + "'");
|
||||
|
||||
await member.ban({reason: "ban reaction"});
|
||||
return true;
|
||||
} catch (error){
|
||||
YALAS.error("Ban Reaction Handler: Error banning user '" + user.id + "' for guild '" + guild.id + "'");
|
||||
YALAS.error(error);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
import { Client, MessageReaction, PartialMessageReaction, User, PartialUser, Guild, Role, GuildMember } from "discord.js";
|
||||
import { schemas } from "../../database";
|
||||
|
||||
import * as YALAS from 'mcstatusbot-logger';
|
||||
export default async function ReactionRoleAddHandler(reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser) {
|
||||
|
||||
const emoji: string | null = reaction.emoji.id ?? reaction.emoji.name;
|
||||
const guild: Guild | null = reaction.message.guild;
|
||||
const channelId: string = reaction.message.channelId;
|
||||
|
||||
if (guild === null || emoji === null) return YALAS.error("failed to find guild");
|
||||
|
||||
|
||||
async function getRole(roleId: string) {
|
||||
if (!guild) return null;
|
||||
let role: Role | null | undefined = guild.roles.cache.get(roleId);
|
||||
if (role) return role
|
||||
try {
|
||||
role = await guild.roles.fetch(roleId);
|
||||
} catch (error) {
|
||||
YALAS.error('Error fetching role:');
|
||||
YALAS.error(error);
|
||||
return null;
|
||||
}
|
||||
if (role) return role
|
||||
return null;
|
||||
}
|
||||
|
||||
const reactionRoles = await schemas['ReactionRole'].findAll({
|
||||
where: {
|
||||
guild: guild.id,
|
||||
channel: channelId,
|
||||
reaction: emoji,
|
||||
},
|
||||
raw: true
|
||||
});
|
||||
|
||||
for (const rRole of reactionRoles) {
|
||||
let role = await getRole(rRole.role);
|
||||
if (role == null) return YALAS.error("failed to find role '" + rRole.role + "' in guild '" + guild.id + "' ")
|
||||
|
||||
// Fetch role if not cached
|
||||
|
||||
|
||||
// Get the member from the user
|
||||
const member: GuildMember | null = guild.members.cache.get(user.id) || (await guild.members.fetch(user.id).catch(() => null));
|
||||
if (!member) return YALAS.error("Member not found in the guild '" + guild.id + "'");
|
||||
|
||||
|
||||
// Add the role to the member
|
||||
try {
|
||||
await member.roles.add(role);
|
||||
if (process.env.DEBUG === 'true') YALAS.info(`Added role "${role.name}" to user "${user.tag}".`);
|
||||
} catch (error) {
|
||||
YALAS.error("Error adding role '" + role.id + "' to user '" + user.id + "' for guild '" + guild.id + "'");
|
||||
YALAS.error(error);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
//TODO: move to redis cache?
|
||||
export default class PrefixCache {
|
||||
private cache = new Map<string, string>();
|
||||
|
||||
|
|
|
@ -44,14 +44,14 @@ export default async function ReactionRoleAddHandler(reaction: MessageReaction |
|
|||
let role = await getRole(rRole.role);
|
||||
if (role == null) return YALAS.error("failed to find role '" + rRole.role + "' in guild '" + guild.id + "' ")
|
||||
|
||||
//TODO: mod channel logs ad role error etc
|
||||
//TODO: implement audit log
|
||||
// Add the role to the member
|
||||
try {
|
||||
await member.roles.add(role);
|
||||
if (process.env.DEBUG === 'true') YALAS.info(`Added role "${role.name}" to user "${user.tag}".`);
|
||||
} catch (error) {
|
||||
|
||||
//TODO: implement ignore reaction reomve when using this
|
||||
//TODO: implement ignoring this reaction remove to avoid errors with msg reaction remove handler
|
||||
//reaction.users.remove(user.id);
|
||||
|
||||
const errUsrMsg = await (channel as TextChannel).send(`Sorry <@!${user.id}>, that did not work please try again later or ask a moderator.`);
|
||||
|
|
|
@ -9,6 +9,7 @@ export default async function ReactionRoleRemoveHandler(reaction: MessageReactio
|
|||
const channel = reaction.message.channel;
|
||||
|
||||
if (guild === null || emoji === null) return YALAS.error("failed to find guild");
|
||||
if (emoji=='❌') return;
|
||||
|
||||
|
||||
async function getRole(roleId: string) {
|
||||
|
@ -46,13 +47,14 @@ export default async function ReactionRoleRemoveHandler(reaction: MessageReactio
|
|||
|
||||
if (rRole.dataValues.reactionRemove === false) continue;
|
||||
|
||||
//TODO: implement audit log
|
||||
// Add the role to the member
|
||||
try {
|
||||
await member.roles.remove(role);
|
||||
if (process.env.DEBUG === 'true') YALAS.info(`Added role "${role.name}" to user "${user.tag}".`);
|
||||
} catch (error) {
|
||||
reaction.users.remove(user.id);
|
||||
|
||||
|
||||
const errUsrMsg = await (channel as TextChannel).send(`Sorry <@!${user.id}>, that did not work please try again later or ask a moderator.`);
|
||||
|
||||
setTimeout(() => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Client, MessageReaction, PartialMessageReaction, User, PartialUser } from "discord.js";
|
||||
import ReactionRoleAddHandler from "../functions/ReactionRoleAddHandler";
|
||||
import BanReactionHandler from "../functions/BanReactionHandler";
|
||||
|
||||
import * as YALAS from 'mcstatusbot-logger';
|
||||
export default async function MessageReactionAdd(client: Client, reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser) {
|
||||
|
@ -13,7 +14,7 @@ export default async function MessageReactionAdd(client: Client, reaction: Messa
|
|||
}
|
||||
}
|
||||
if (!reaction.message.guild) return;
|
||||
|
||||
|
||||
|
||||
if (user.partial) {
|
||||
try {
|
||||
|
@ -23,12 +24,12 @@ export default async function MessageReactionAdd(client: Client, reaction: Messa
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (user.id===client.user?.id) return;
|
||||
if (user.id === client.user?.id) return;
|
||||
|
||||
const memberBanned = await BanReactionHandler(reaction, user);
|
||||
//non need to try and run reactions roles if member banned
|
||||
if (memberBanned === true) return;
|
||||
|
||||
await ReactionRoleAddHandler(reaction, user);
|
||||
|
||||
//TODO: ban role hndler
|
||||
//TODO: kick role handler
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ const sequelize = new Sequelize(process.env.DB_URI, {
|
|||
});
|
||||
|
||||
const schemas = {
|
||||
BanRole: BanReaction(sequelize),
|
||||
BanReaction: BanReaction(sequelize),
|
||||
Guild: Guild(sequelize),
|
||||
KickRole: KickReaction(sequelize),
|
||||
MessageMacro: MessageMacro(sequelize),
|
||||
|
@ -34,7 +34,6 @@ const schemas = {
|
|||
|
||||
|
||||
export async function connect() {
|
||||
|
||||
YALAS.info("attempting to connect to db");
|
||||
try {
|
||||
await sequelize.authenticate();
|
||||
|
|
|
@ -4,7 +4,6 @@ export interface BanReactionAttributes {
|
|||
id: number;
|
||||
guild: string;
|
||||
channel: string;
|
||||
reaction: string;
|
||||
}
|
||||
|
||||
export interface BanReactionCreationAttributes extends Optional<BanReactionAttributes, 'id'> { }
|
||||
|
@ -28,11 +27,7 @@ export default function BanRole(sequelize: Sequelize) {
|
|||
channel: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
reaction: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
// Sync the model with the database
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue