easyantispam
Advanced tools
Comparing version 1.1.2 to 2.0.0
{ | ||
"name": "easyantispam", | ||
"version": "1.1.2", | ||
"description": "Easy Anti Spam package used for Discord Bots to prevent invites link from other servers", | ||
"version": "2.0.0", | ||
"description": "Easy Anti Spam package used for Discord Bots to prevent invites link from other servers and flooded/duplicated messages.", | ||
"main": "src/index.js", | ||
@@ -17,2 +17,3 @@ "types": "typings/index.d.ts", | ||
"filter", | ||
"anti-flood", | ||
"anti-spam", | ||
@@ -19,0 +20,0 @@ "discord.js", |
@@ -11,4 +11,9 @@ # Easy Anti Spam | ||
The principal function for this package is handle all URLs sended by users on a server and delete it if you want. | ||
This package have 2 principal functions: | ||
- Handle URLs spammed. | ||
- Handle flood messages and repeated messages. | ||
# Summary | ||
- [Support](#support) | ||
@@ -45,3 +50,3 @@ - [Installation](#installation) | ||
Easy = new EasyAntiSpam.Config({ type: 2, antiStaff: false, warningMessage: `Message to advice` }); // Config variables | ||
Easy = new EasyAntiSpam.Config({ urls: true, canKick: true, canBan: true, warnRow: 3 }); // And more config variables... | ||
@@ -72,3 +77,3 @@ client.once('ready', () => console.log('Bot is online!')); | ||
Properties marked with `?` are optional. | ||
Properties marked with `?` are optional. All options are predefined | ||
@@ -79,6 +84,23 @@ ### EasyAntiSpamOptions | ||
{ | ||
type: 1 // 1: Only Discord Invites, 2: All URLS | ||
dm?: true/false, // If you want to send a DM with his/her message. False by default. | ||
antiStaff?: true/false, // If you want to delete staff urls or not. False by default. | ||
warningMessage?: "Here is your warning message" // You have different options found in warningMessageOptions section. | ||
urls?: false, // Delete or not all URLS | ||
discordInvites?: false, // Delete or not Discord Invites | ||
allowUrlImages?: true, // Delete or not Images provided by URL | ||
dm?: false, // If true, send your message with URL to private message | ||
messageLink?: "Hey {author}, you are not allowed to send spam.", // Message sent when a user send an URL | ||
messageFlood?: "Hey {author}, stop doing spam.", // Message sent when a user is warned for flood | ||
messageKicked?: "{author} has been kicked.", // Message sent when a user is kicked | ||
messageBanned?: "{author} has been banned.", // Message sent when a user is banned | ||
allowBots?: true, // Allow bots | ||
allowedPerms?: [], // List of permissions allowed to do spam | ||
warnRow?: 4, // Messages sent in a row to be warned | ||
kickRow?: 6, // Messages sent in a row to be kicked | ||
banRow?: 8, // Messages sent in a row to be banned | ||
rowInterval?: 2000, // Amount of time in ms to consider spam (2s) | ||
warnDuplicates?: 5, // Duplicated messages sent to be warned | ||
kickDuplicates?: 10, // Duplicated messages sent to be kicked | ||
banDuplicates?: 15, // Duplicated messages sent to be banned | ||
duplicatesInterval?: 600000, // Amount of time in ms to consider spam (10m) | ||
canKick?: false, // If false, the bot dont kick users | ||
canBan?: false, // If false, the bot dont ban users | ||
banDays?: 1, // Amount of days of Ban | ||
} | ||
@@ -85,0 +107,0 @@ ``` |
@@ -0,58 +1,162 @@ | ||
const EasyAntiSpamOptions = { | ||
urls: false, // Delete or not all URLS | ||
discordInvites: false, // Delete or not Discord Invites | ||
allowUrlImages: true, // Delete or not Images provided by URL | ||
dm: false, // If true, send your message with URL to private message | ||
messageLink: "Hey {author}, you are not allowed to send spam.", // Message sent when a user send an URL | ||
messageFlood: "Hey {author}, stop doing spam.", // Message sent when a user is warned for flood | ||
messageKicked: "{author} has been kicked.", // Message sent when a user is kicked | ||
messageBanned: "{author} has been banned.", // Message sent when a user is banned | ||
allowBots: true, // Allow bots | ||
allowedPerms: [], // List of permissions allowed to do spam | ||
warnRow: 4, // Messages sent in a row to be warned | ||
kickRow: 6, // Messages sent in a row to be kicked | ||
banRow: 8, // Messages sent in a row to be banned | ||
rowInterval: 2000, // Amount of time in ms to consider spam (2s) | ||
warnDuplicates: 5, // Duplicated messages sent to be warned | ||
kickDuplicates: 10, // Duplicated messages sent to be kicked | ||
banDuplicates: 15, // Duplicated messages sent to be banned | ||
duplicatesInterval: 600000, // Amount of time in ms to consider spam (10m) | ||
canKick: false, // If false, the bot dont kick users | ||
canBan: false, // If false, the bot dont ban users | ||
banDays: 1, // Amount of days of Ban | ||
} | ||
class EasyAntiSpam { | ||
constructor(options) { | ||
if (typeof options !== "object") | ||
throw "options must be of type object. Received: " + typeof options; | ||
if (!options.type) { | ||
console.log("EasyAntiSpam | No Type Option configured"); | ||
process.exit(1); | ||
constructor(options = {}) { | ||
for (const val in EasyAntiSpamOptions) { | ||
if (!options.hasOwnProperty(val) || typeof options[val] === "undefined" || options[val] === null) options[val] = EasyAntiSpamOptions[val]; | ||
} | ||
if (options.type && typeof options.type !== "number") { | ||
console.log(" EasyAntiSpam | Type option received but wasn't of type number. received: " + typeof options.type); | ||
process.exit(1); | ||
this.options = options; | ||
this.data = { | ||
messages: [], | ||
warned: [], | ||
banned: [], | ||
kicked: [] | ||
} | ||
setInterval(async () => { | ||
this.clearData(); | ||
}, 900000); // 15 min | ||
} | ||
if (options.type > 2 || options.type < 1) { | ||
console.log(" EasyAntiSpam | Type option received but wasn't of correct value. The correct values are:\n\t1. Discord Invites\n\t2. All URLS"); | ||
process.exit(1); | ||
} | ||
init() { | ||
} | ||
this.type = options.type; | ||
this.dm = options.dm; | ||
this.antiStaff = options.antiStaff; | ||
this.warningMessage = options.warningMessage; | ||
} | ||
async run(message) { | ||
let warn = this.warningMessage.replace(/{author}/g, `<@${message.author.id}>`); | ||
const { options, data } = this; | ||
if (!message.guild) return; | ||
if (message.author.bot && options.allowBots) return; | ||
if (options.allowedPerms.some(permission => message.member.hasPermission(permission))) return; | ||
/* Save every message */ | ||
data.messages.push({ | ||
author: message.author.id, | ||
content: message.content, | ||
date: Date.now() | ||
}); | ||
let text = false; | ||
const URLexpression = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi; | ||
const DiscordExpression = /(discord\.(gg|io|me|li)\/.+|discordapp\.com\/invite\/.+)/i; | ||
const ImageExpression = /^(http|https):\/\/.*\.(png|jpg|jpeg|gif)$/i; | ||
let URLexpression = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi; | ||
let DiscordExpression = /(discord\.(gg|io|me|li)\/.+|discordapp\.com\/invite\/.+)/i; | ||
if (this.type == 1) if (DiscordExpression.test(message.content)) text = true; | ||
if (this.type == 2) if (URLexpression.test(message.content)) text = true; | ||
if (options.urls && URLexpression.test(message.content)) text = true; | ||
if (options.discordInvites && DiscordExpression.test(message.content)) text = true; | ||
if (options.allowUrlImages && ImageExpression.test(message.content)) text = false; | ||
if (/^(http|https):\/\/.*\.(png|jpg|jpeg|gif)$/i.test(message.content)) text = false; | ||
if (text) { | ||
if (!this.antiStaff && (message.member.hasPermission("ADMINISTRATOR") || message.member.hasPermission("MANAGE_CHANNELS"))) return; | ||
message.delete(); | ||
if (this.dm) { | ||
if (this.warningMessage) message.channel.send(warn + `. I sent you the message via DM to correct it.`); | ||
else message.channel.send(`Hey <@${message.author.id}>, you are not allowed to send spam. I sent you the message via DM to correct it.`); | ||
if (options.dm) { | ||
message.channel.send(options.messageLink.replace(/{author}/g, message.author.toString()) + ". I sent you the message via DM to correct it."); | ||
message.author.send("```" + message.content + "```") | ||
} else { | ||
if (this.warningMessage) message.channel.send(warn); | ||
else message.channel.send(`Hey <@${message.author.id}>, you are not allowed to send spam.`); | ||
} | ||
else message.channel.send(options.messageLink.replace(/{author}/g, message.author.toString())); | ||
} | ||
const messagesInRow = data.messages.filter(m => m.date > Date.now() - options.rowInterval && m.author === message.author.id).length; | ||
const messagesDuplicated = data.messages.filter(m => m.date > Date.now() - options.duplicatesInterval && m.author === message.author.id && m.content === message.content).length; | ||
if (!data.warned.includes(message.author.id) && (messagesInRow === options.warnRow || messagesDuplicated === options.warnDuplicates)) { | ||
data.warned.push(message.author.id); | ||
this.clearKick(message); | ||
this.clearBan(message); | ||
await message.channel.send(options.messageFlood.replace(/{author}/g, message.author.toString())); | ||
} | ||
if (!data.kicked.includes(message.author.id) && (messagesInRow === options.kickRow || messagesDuplicated === options.kickDuplicates)) { | ||
if (!options.canKick) return; | ||
if (!message.member.kickable) return console.log(`EasyAntiSpam | ${message.author.tag} (ID: ${message.author.id}) could not be kicked, insufficient permissions.`); | ||
try { | ||
await message.member.kick("Spam"); | ||
data.kicked.push(message.author.id); | ||
await message.channel.send(options.messageKicked.replace(/{author}/g, message.author.toString())); | ||
} catch (error) { | ||
return console.log(error); | ||
} | ||
} | ||
if (!data.banned.includes(message.author.id) && (messagesInRow === options.banRow || messagesDuplicated === options.banDuplicates)) { | ||
if (!options.canBan) return; | ||
if (!message.member.bannable) return console.log(`EasyAntiSpam | ${message.author.tag} (ID: ${message.author.id}) could not be banned, insufficient permissions.`); | ||
try { | ||
await message.member.ban({ | ||
reason: "Spam", | ||
days: options.banDays | ||
}); | ||
this.clearKick(message); | ||
this.clearWarn(message); | ||
this.clearMessages(message); | ||
await message.channel.send(options.messageBanned.replace(/{author}/g, message.author.toString())); | ||
} catch (error) { | ||
return console.log(error); | ||
} | ||
} | ||
} | ||
clearWarn(message) { | ||
const data = Object.create(this.data); | ||
let clear = data.warned.filter(function (item) { | ||
return item !== message.author.id; | ||
}); | ||
this.data.warned = clear; | ||
} | ||
clearKick(message) { | ||
const data = Object.create(this.data); | ||
let clear = data.kicked.filter(function (item) { | ||
return item !== message.author.id; | ||
}); | ||
this.data.kicked = clear; | ||
} | ||
clearBan(message) { | ||
const data = Object.create(this.data); | ||
let clear = data.banned.filter(function (item) { | ||
return item !== message.author.id; | ||
}); | ||
this.data.banned = clear; | ||
} | ||
clearMessages(message) { | ||
const data = Object.create(this.data); | ||
let clear = data.messages.filter(function (item) { | ||
return item.author !== message.author.id; | ||
}); | ||
this.data.messages = clear; | ||
} | ||
clearData() { | ||
const data = Object.create(this.data); | ||
this.data.messages = []; | ||
this.data.warned = []; | ||
return data; | ||
} | ||
} | ||
module.exports = EasyAntiSpam; |
declare module "easyantispam" { | ||
interface EasyAntiSpamData { | ||
message: { | ||
author: string; | ||
content: string; | ||
date: number; | ||
}[]; | ||
warned: string[]; | ||
kicked: string[]; | ||
banned: string[]; | ||
} | ||
interface EasyAntiSpamOptions { | ||
type: number; | ||
antiStaff?: boolean; | ||
urls?: boolean; | ||
discordInvites?: boolean; | ||
allowUrlImages?: boolean; | ||
dm?: boolean; | ||
warningMessage?: string; | ||
messageLink?: string; | ||
messageFlood?: string; | ||
messageKicked?: string; | ||
messageBanned?: string; | ||
allowBots?: boolean; | ||
allowedPerms?: string[]; | ||
warnRow?: number; | ||
kickRow?: number; | ||
banRow?: number; | ||
rowInterval?: number; | ||
warnDuplicates?: number; | ||
kickDuplicates?: number; | ||
banDuplicates?: number; | ||
duplicatesInterval?: number; | ||
canKick?: boolean; | ||
canBan?: boolean; | ||
banDays?: number; | ||
} | ||
export class Config { | ||
constructor(options:EasyAntiSpamOptions); | ||
private options: EasyAntiSpamOptions; | ||
public run( | ||
options: EasyAntiSpamOptions | ||
): Promise<boolean>; | ||
export class EasyAntiSpam { | ||
constructor(options?: EasyAntiSpamOptions); | ||
public options: EasyAntiSpamOptions; | ||
public data: EasyAntiSpamData; | ||
public run(message): Promise<boolean>; | ||
} | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
14222
179
114
1