resetting linux lol
diff --git a/COPYING.md b/COPYING.md
index 2a301ce..ceffdf6 100644
--- a/COPYING.md
+++ b/COPYING.md
@@ -1,6 +1,6 @@
# Nucleus by Clicks
-## TLDR:
+## In Short:
You **may**:
- Modify our code
@@ -13,7 +13,29 @@
- Mention the code is originally by Clicks, and include a link to our [website](https://clicks.codes) or [GitHub](https://github.com/clicksminuteper)
- Release your project with the same license [GNU Affero General Public License V3.0](https://choosealicense.com/licenses/agpl-3.0/)
-## The legal bit
+
+## How to:
+
+We hide the config file with our important data like the bot token. Below you can find a copy of `src/config/main.json`.
+
+```json
+{
+ "token": "your-token-here",
+ "developmentToken": "dev-token-here",
+ "managementGuildID": "your-management-guild-id-here",
+ "developmentGuildID": "your-development-guild-id-here",
+ "enableDevelopment": true,
+ "owners": [
+ "your-discord-id",
+ ],
+ "verifySecret": "if making a verify command, this is the value that checks if requests are from the website",
+ "mongoUrl": "mongodb://your-mongo-ip-and-port",
+ "baseUrl": "your website url, e.g. https://clicks.codes",
+}
+```
+
+
+## The legal bit:
```
GNU AFFERO GENERAL PUBLIC LICENSE
diff --git a/TODO.json b/TODO.json
new file mode 100644
index 0000000..b4b2524
--- /dev/null
+++ b/TODO.json
@@ -0,0 +1,94 @@
+{
+ "filters": {
+ "images": {
+ "NSFW": false,
+ "size": false
+ },
+ "malware": false,
+ "wordFilter": {
+ "enabled": false,
+ "words": {
+ "strict": [],
+ "loose": []
+ },
+ "allowed": {
+ "users": [],
+ "roles": [],
+ "channels": []
+ }
+ },
+ "invite": {
+ "enabled": false,
+ "allowed": {
+ "users": [],
+ "channels": [],
+ "roles": []
+ }
+ },
+ "pings": {
+ "mass": 5,
+ "everyone": true,
+ "roles": true,
+ "allowed": {
+ "roles": [],
+ "rolesToMention": [],
+ "users": [],
+ "channels": []
+ }
+ }
+ },
+ "welcome": {
+ "enabled": false,
+ "welcomeRole": null,
+ "channel": null,
+ "message": null
+ },
+ "stats": [
+ {
+ "enabled": true,
+ "channel": "9849175359",
+ "text": "{count} members | {count:bots} bots | {count:humans} humans"
+ }
+ ],
+ "moderation": {
+ "mute": {
+ "timeout": true,
+ "role": null,
+ "text": null,
+ "link": null
+ },
+ "kick": {
+ "text": null,
+ "link": null
+ },
+ "ban": {
+ "text": null,
+ "link": null
+ },
+ "softban": {
+ "text": null,
+ "link": null
+ },
+ "warn": {
+ "text": null,
+ "link": null
+ },
+ "role": {
+ "role": null
+ }
+ },
+ "tracks": [
+ ],
+ "logging": {
+ "logs": {
+ "enabled": true,
+ "toLog": "3fffff"
+ }
+ },
+ "roleMenu": {
+ "enabled": true,
+ "allowWebUI": true,
+ "options": [
+ ]
+ }
+}
\ No newline at end of file
diff --git a/src/api/index.ts b/src/api/index.ts
index 00c866d..b2edc66 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -18,7 +18,6 @@
app.post('/verify/:code', jsonParser, async function (req, res) {
const code = req.params.code;
const secret = req.body.secret;
- const { log, NucleusColors, entry, renderUser } = client.logger
if (secret === client.config.verifySecret) {
let guild = await client.guilds.fetch(client.verify[code].gID);
if (!guild) { return res.status(404) }
@@ -36,6 +35,8 @@
.setEmoji("MEMBER.JOIN")
], components: []});
}
+ delete client.verify[code];
+ const { log, NucleusColors, entry, renderUser } = client.logger
try {
let data = {
meta:{
@@ -47,7 +48,7 @@
timestamp: new Date().getTime()
},
list: {
- id: entry(member.id, `\`${member.id}\``),
+ memberId: entry(member.id, `\`${member.id}\``),
member: entry(member.id, renderUser(member))
},
hidden: {
@@ -62,25 +63,20 @@
}
});
- app.patch('/verify/:code', (req, res) => {
- const code = req.params.code;
- try {
- let interaction = client.verify[code].interaction;
- if (interaction) {
- interaction.editReply({embeds: [new EmojiEmbed()
- .setTitle("Verify")
- .setDescription(`Verify was opened in another tab or window, please complete the CAPTCHA there to continue`)
- .setStatus("Success")
- .setEmoji("MEMBER.JOIN")
- ]});
- }
- } catch {}
- res.sendStatus(200);
- })
-
app.get('/verify/:code', jsonParser, function (req, res) {
const code = req.params.code;
if (client.verify[code]) {
+ try {
+ let interaction = client.verify[code].interaction;
+ if (interaction) {
+ interaction.editReply({embeds: [new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription(`Verify was opened in another tab or window, please complete the CAPTCHA there to continue`)
+ .setStatus("Success")
+ .setEmoji("MEMBER.JOIN")
+ ]});
+ }
+ } catch {}
let data = structuredClone(client.verify[code])
delete data.interaction;
return res.status(200).send(data);
@@ -88,6 +84,44 @@
return res.sendStatus(404);
})
+ app.post('/rolemenu/:code', jsonParser, async function (req, res) {
+ const code = req.params.code;
+ const secret = req.body.secret;
+ const data = req.body.data;
+ if (secret === client.config.verifySecret) {
+ console.table(data)
+ let guild = await client.guilds.fetch(client.roleMenu[code].guild); // TODO: do checks here to like max roles because people are fucking annoying and will edit the source :)
+ if (!guild) { return res.status(404) }
+ let member = await guild.members.fetch(client.roleMenu[code].user);
+ if (!member) { return res.status(404) }
+ res.sendStatus(200);
+ } else {
+ res.sendStatus(403);
+ }
+ });
+
+ app.get('/rolemenu/:code', jsonParser, function (req, res) {
+ const code = req.params.code;
+ if (client.roleMenu[code] !== undefined) {
+ try {
+ let interaction = client.roleMenu[code].interaction;
+ if (interaction) {
+ interaction.editReply({embeds: [new EmojiEmbed()
+ .setTitle("Roles")
+ .setDescription(`The role menu was opened in another tab or window, please select your roles there to continue`)
+ .setStatus("Success")
+ .setEmoji("GUILD.GREEN")
+ ], components: []});
+ }
+ } catch {}
+ let data = structuredClone(client.roleMenu[code])
+ delete data.interaction;
+ console.log(data)
+ return res.status(200).send(data);
+ }
+ return res.sendStatus(404);
+ })
+
app.listen(port);
}
diff --git a/src/automations/createModActionTicket.ts b/src/automations/createModActionTicket.ts
index fad9a62..2ab9a46 100644
--- a/src/automations/createModActionTicket.ts
+++ b/src/automations/createModActionTicket.ts
@@ -54,7 +54,7 @@
`Ticket created by a Moderator\n` +
`**Support type:** Appeal submission\n` + (reason != null ? `**Reason:**\n> ${reason}\n` : "") +
`**Ticket ID:** \`${c.id}\`\n` +
- `Type \`/ticket close\` to archive this ticket.`,
+ `Type \`/ticket close\` to close this ticket.`,
)
.setStatus("Success")
.setEmoji("GUILD.TICKET.OPEN")
diff --git a/src/automations/guide.ts b/src/automations/guide.ts
index 8e0e6cd..655d781 100644
--- a/src/automations/guide.ts
+++ b/src/automations/guide.ts
@@ -37,8 +37,9 @@
"Nucleus can log server events and keep you informed with what content is being posted to your server.\n" +
"We have 2 different types of logs, which each can be configured to send to a channel of your choice:\n" +
"**General Logs:** These are events like kicks and channel changes etc.\n" +
- "**Warning Logs:** Warnings like NSFW avatars and spam etc that may require action by a server staff member.\n\n" +
- "A general log channel can be set with `/settings log channel`\n" +
+ "**Warning Logs:** Warnings like NSFW avatars and spam etc. that may require action by a server staff member. " +
+ "These go to to a separate staff notifications channel.\n\n" +
+ "A general log channel can be set with `/settings log`\n" +
"A warning log channel can be set with `/settings warnings channel`"
)
.setEmoji("NUCLEUS.LOGO")
@@ -69,7 +70,7 @@
"Nucleus has a verification system that allows users to prove they aren't bots.\n" +
"This is done by running `/verify` which sends a message only the user can see, giving them a link to a CAPTCHA to verify.\n" +
"After the user complete's the CAPTCHA, they are given a role and can use the permissions accordingly.\n" +
- "You can set the role given with `/settings verify role`"
+ "You can set the role given with `/settings verify`"
)
.setEmoji("NUCLEUS.LOGO")
.setStatus("Danger")
@@ -80,7 +81,7 @@
.setDescription(
"Nucleus has a content scanning system that automatically scans links and images sent by users.\n" +
"Nucleus can detect, delete, and punish users for sending NSFW content, or links to scam or adult sites.\n" +
- "You can set the threshold for this in `/settings automation`"
+ "You can set the threshold for this in `/settings automation`" // TODO
)
.setEmoji("NUCLEUS.LOGO")
.setStatus("Danger")
@@ -91,7 +92,7 @@
.setDescription(
"Nucleus has a ticket system that allows users to create tickets and have a support team respond to them.\n" +
"Tickets can be created with `/ticket create` and a channel is created, pinging the user and support role.\n" +
- "When the ticket is resolved, anyone can run `/ticket close` to archive it.\n" +
+ "When the ticket is resolved, anyone can run `/ticket close` (or click the button) to close it.\n" +
"Running `/ticket close` again will delete the ticket."
)
.setEmoji("NUCLEUS.LOGO")
diff --git a/src/automations/roleMenu.ts b/src/automations/roleMenu.ts
index e82c82c..318a0dd 100644
--- a/src/automations/roleMenu.ts
+++ b/src/automations/roleMenu.ts
@@ -44,8 +44,11 @@
}
client.roleMenu[code] = {
guild: interaction.guild.id,
+ guildName: interaction.guild.name,
guildIcon: interaction.guild.iconURL({format: "png"}),
user: interaction.member.user.id,
+ username: interaction.member.user.username,
+ data: config.roleMenu.options,
interaction: interaction
};
m = await interaction.editReply({
@@ -58,7 +61,8 @@
new MessageButton()
.setLabel("Online")
.setStyle("LINK")
- .setURL(`https://clicks.codes/nuclues/rolemenu?code=${code}`),
+ .setDisabled(false) // TODO check if the server is up
+ .setURL(`${client.config.baseUrl}/nucleus/rolemenu?code=${code}`),
new MessageButton()
.setLabel("Manual")
.setStyle("PRIMARY")
diff --git a/src/automations/tickets/create.ts b/src/automations/tickets/create.ts
index 8eee3b2..8d58493 100644
--- a/src/automations/tickets/create.ts
+++ b/src/automations/tickets/create.ts
@@ -167,7 +167,7 @@
`Ticket created by <@${interaction.member.user.id}>\n` +
`**Support type:** ${chosenType != null ? (emoji) + " " + capitalize(chosenType) : "General"}\n` +
`**Ticket ID:** \`${c.id}\`\n${content}\n` +
- `Type \`/ticket close\` to archive this ticket.`,
+ `Type \`/ticket close\` to close this ticket.`,
)
.setStatus("Success")
.setEmoji("GUILD.TICKET.OPEN")
diff --git a/src/automations/unscan.ts b/src/automations/unscan.ts
index 940a1fe..d1fa7d4 100644
--- a/src/automations/unscan.ts
+++ b/src/automations/unscan.ts
@@ -12,9 +12,7 @@
} catch {}
detections.push({tags: element.tags || [], safe: element.safe})
});
- console.log(1)
await Promise.all(promises);
- console.log(2)
let types = [
"PHISHING", "DATING", "TRACKERS", "ADVERTISEMENTS", "FACEBOOK",
"AMP", "FACEBOOK TRACKERS", "IP GRABBERS", "PORN",
@@ -27,7 +25,6 @@
// if (!element.safe) return "UNSAFE"
return undefined
}).filter(element => element !== undefined)
- console.log(detectionsTypes)
return detectionsTypes.length > 0
}
@@ -56,22 +53,22 @@
}
}
-export function TestString(string, soft, strict): string {
+export function TestString(string, soft, strict): object | null {
for(let word of strict || []) {
if (string.toLowerCase().includes(word)) {
- return "strict"
+ return {word: word, type: "strict"}
}
}
for(let word of soft) {
for(let word2 of string.match(/[a-z]+/gi) || []) {
if (word2 == word) {
- return "loose"
+ return {word: word, type: "strict"}
}
}
}
- return "none"
+ return null
}
-export async function TestImage(element): Promise<string> {
- return "";
+export async function TestImage(element): Promise<string | null> {
+ return null;
}
diff --git a/src/automations/verify.ts b/src/automations/verify.ts
index ed24d25..710439a 100644
--- a/src/automations/verify.ts
+++ b/src/automations/verify.ts
@@ -88,7 +88,7 @@
.setStatus("Warning")
.setEmoji("NUCLEUS.LOADING")
]});
- if (TestString((interaction.member as Discord.GuildMember).displayName, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict) != "none") {
+ if (TestString((interaction.member as Discord.GuildMember).displayName, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict) !== null) {
return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`Your name contained a word we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake` + step(2))
@@ -124,7 +124,7 @@
gID: interaction.guild.id,
rID: config.verify.role,
rName: (await interaction.guild.roles.fetch(config.verify.role)).name,
- mCount: interaction.guild.memberCount,
+ uName: interaction.member.user.username,
gName: interaction.guild.name,
gIcon: interaction.guild.iconURL({format: "png"}),
interaction: interaction
diff --git a/src/commands/mod/ban.ts b/src/commands/mod/ban.ts
index 4581c0f..11c6c79 100644
--- a/src/commands/mod/ban.ts
+++ b/src/commands/mod/ban.ts
@@ -75,7 +75,7 @@
timestamp: new Date().getTime()
},
list: {
- id: entry(member.user.id, `\`${member.user.id}\``),
+ memberId: entry(member.user.id, `\`${member.user.id}\``),
name: entry(member.user.id, renderUser(member.user)),
banned: entry(new Date().getTime(), renderDelta(new Date().getTime())),
bannedBy: entry(interaction.user.id, renderUser(interaction.user)),
diff --git a/src/commands/mod/kick.ts b/src/commands/mod/kick.ts
index 97ead7b..b1464ee 100644
--- a/src/commands/mod/kick.ts
+++ b/src/commands/mod/kick.ts
@@ -71,7 +71,7 @@
timestamp: new Date().getTime()
},
list: {
- id: entry(member.id, `\`${member.id}\``),
+ memberId: entry(member.id, `\`${member.id}\``),
name: entry(member.id, renderUser(member.user)),
joined: entry(member.joinedAt, renderDelta(member.joinedAt)),
kicked: entry(new Date().getTime(), renderDelta(new Date().getTime())),
diff --git a/src/commands/mod/mute.ts b/src/commands/mod/mute.ts
index 5f42b27..4c326e7 100644
--- a/src/commands/mod/mute.ts
+++ b/src/commands/mod/mute.ts
@@ -163,7 +163,7 @@
}
if (config.moderation.mute.role) {
member.roles.add(config.moderation.mute.role)
- }
+ } // make sure this gets removed
} catch {
await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.MUTE.RED")
diff --git a/src/commands/mod/nick.ts b/src/commands/mod/nick.ts
index e154277..8dcbf62 100644
--- a/src/commands/mod/nick.ts
+++ b/src/commands/mod/nick.ts
@@ -73,7 +73,7 @@
timestamp: new Date().getTime()
},
list: {
- id: entry(member.id, `\`${member.id}\``),
+ memberId: entry(member.id, `\`${member.id}\``),
before: entry(before, before ? before : '*None*'),
after: entry(nickname, nickname ? nickname : '*None*'),
updated: entry(new Date().getTime(), renderDelta(new Date().getTime())),
diff --git a/src/commands/mod/purge.ts b/src/commands/mod/purge.ts
index 9aab260..fd8e6b8 100644
--- a/src/commands/mod/purge.ts
+++ b/src/commands/mod/purge.ts
@@ -144,7 +144,7 @@
timestamp: new Date().getTime()
},
list: {
- id: entry(interaction.user.id, `\`${interaction.user.id}\``),
+ memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
purgedBy: entry(interaction.user.id, renderUser(interaction.user)),
channel: entry(interaction.channel.id, renderChannel(interaction.channel)),
messagesCleared: entry(deleted.length, deleted.length),
@@ -246,7 +246,7 @@
timestamp: new Date().getTime()
},
list: {
- id: entry(interaction.user.id, `\`${interaction.user.id}\``),
+ memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
purgedBy: entry(interaction.user.id, renderUser(interaction.user)),
channel: entry(interaction.channel.id, renderChannel(interaction.channel)),
messagesCleared: entry(messages.size, messages.size),
diff --git a/src/commands/mod/unban.ts b/src/commands/mod/unban.ts
index 7f605d9..e512084 100644
--- a/src/commands/mod/unban.ts
+++ b/src/commands/mod/unban.ts
@@ -53,7 +53,7 @@
timestamp: new Date().getTime()
},
list: {
- id: entry(member.id, `\`${member.id}\``),
+ memberId: entry(member.id, `\`${member.id}\``),
name: entry(member.id, renderUser(member)),
unbanned: entry(new Date().getTime(), renderDelta(new Date().getTime())),
unbannedBy: entry(interaction.user.id, renderUser(interaction.user)),
diff --git a/src/commands/mod/viewas.ts b/src/commands/mod/viewas.ts
index b3875a7..684fc3a 100644
--- a/src/commands/mod/viewas.ts
+++ b/src/commands/mod/viewas.ts
@@ -97,7 +97,6 @@
const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
- return true // FIXME FOR RELEASE
let member = (interaction.member as GuildMember)
if (! member.permissions.has("MANAGE_ROLES")) throw "You do not have the Manage roles permission";
return true
diff --git a/src/commands/rolemenu.ts b/src/commands/rolemenu.ts
new file mode 100644
index 0000000..f53e10a
--- /dev/null
+++ b/src/commands/rolemenu.ts
@@ -0,0 +1,20 @@
+import { CommandInteraction } from "discord.js";
+import { SlashCommandBuilder } from "@discordjs/builders";
+import { WrappedCheck } from "jshaiku";
+import { callback as roleMenu } from "../automations/roleMenu.js"
+
+const command = new SlashCommandBuilder()
+ .setName("rolemenu")
+ .setDescription("Lets you choose from sets of roles to apply to yourself")
+
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+ await roleMenu(interaction);
+}
+
+const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
+ return true;
+}
+
+export { command };
+export { callback };
+export { check };
diff --git a/src/commands/settings/logs/channel.ts b/src/commands/settings/logs/channel.ts
index 19a389b..10a5887 100644
--- a/src/commands/settings/logs/channel.ts
+++ b/src/commands/settings/logs/channel.ts
@@ -53,6 +53,28 @@
if (confirmation.success) {
try {
await client.database.guilds.write(interaction.guild.id, {"logging.logs.channel": channel.id})
+ const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger
+ try {
+ let data = {
+ meta:{
+ type: 'logChannelUpdate',
+ displayName: 'Log Channel Changed',
+ calculateType: 'nucleusSettingsUpdated',
+ color: NucleusColors.yellow,
+ emoji: "CHANNEL.TEXT.EDIT",
+ timestamp: new Date().getTime()
+ },
+ list: {
+ memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
+ changedBy: entry(interaction.user.id, renderUser(interaction.user)),
+ channel: entry(channel.id, renderChannel(channel)),
+ },
+ hidden: {
+ guild: channel.guild.id
+ }
+ }
+ log(data);
+ } catch {}
} catch (e) {
console.log(e)
return interaction.editReply({embeds: [new EmojiEmbed()
@@ -120,7 +142,7 @@
const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
let member = (interaction.member as Discord.GuildMember)
- if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the `manage_server` permission to use this command"
+ if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the Manage Server permission to use this command"
return true;
}
diff --git a/src/commands/settings/logs/ignore.ts b/src/commands/settings/logs/ignore.ts
index 12af085..3b81d42 100644
--- a/src/commands/settings/logs/ignore.ts
+++ b/src/commands/settings/logs/ignore.ts
@@ -103,14 +103,38 @@
if (role) data.logging.logs.ignore.roles.concat([role.id])
if (interaction.options.getString("action") == "add") {
await client.database.guilds.append(interaction.guild.id, data)
+ } else {
+ await client.database.guilds.remove(interaction.guild.id, data)
}
+ const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger
+ try {
+ let data = {
+ meta:{
+ type: 'logIgnoreUpdated',
+ displayName: 'Ignored Groups Changed',
+ calculateType: 'nucleusSettingsUpdated',
+ color: NucleusColors.yellow,
+ emoji: "CHANNEL.TEXT.EDIT",
+ timestamp: new Date().getTime()
+ },
+ list: {
+ memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
+ changedBy: entry(interaction.user.id, renderUser(interaction.user)),
+ channel: entry(channel.id, renderChannel(channel)),
+ },
+ hidden: {
+ guild: interaction.guild.id
+ }
+ }
+ log(data);
+ } catch {}
}
}
}
const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
let member = (interaction.member as Discord.GuildMember)
- if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the `manage_server` permission to use this command"
+ if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the Manage Server permission to use this command"
return true;
}
diff --git a/src/commands/settings/rolemenu.ts b/src/commands/settings/rolemenu.ts
new file mode 100644
index 0000000..ec54820
--- /dev/null
+++ b/src/commands/settings/rolemenu.ts
@@ -0,0 +1,26 @@
+import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import confirmationMessage from "../../utils/confirmationMessage.js";
+import getEmojiByName from "../../utils/getEmojiByName.js";
+import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
+import { WrappedCheck } from "jshaiku";
+import client from "../../utils/client.js";
+
+const command = (builder: SlashCommandSubcommandBuilder) =>
+ builder
+ .setName("role")
+ .setDescription("Sets or shows the role given to users after using /verify")
+ .addRoleOption(option => option.setName("role").setDescription("The role to give after verifying"))
+
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+}
+
+const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
+ let member = (interaction.member as Discord.GuildMember)
+ if (!member.permissions.has("MANAGE_ROLES")) throw "You must have the Manage roles permission to use this command"
+ return true;
+}
+
+export { command };
+export { callback };
+export { check };
\ No newline at end of file
diff --git a/src/commands/settings/staff/channel.ts b/src/commands/settings/staff.ts
similarity index 77%
rename from src/commands/settings/staff/channel.ts
rename to src/commands/settings/staff.ts
index 74605cf..e0d2776 100644
--- a/src/commands/settings/staff/channel.ts
+++ b/src/commands/settings/staff.ts
@@ -1,19 +1,19 @@
import { ChannelType } from 'discord-api-types';
import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
-import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
-import confirmationMessage from "../../../utils/confirmationMessage.js";
-import getEmojiByName from "../../../utils/getEmojiByName.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import confirmationMessage from "../../utils/confirmationMessage.js";
+import getEmojiByName from "../../utils/getEmojiByName.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import client from "../../../utils/client.js";
+import client from "../../utils/client.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
- .setName("channel")
- .setDescription("Sets or shows the staff notifications channel")
+ .setName("staff")
+ .setDescription("Settings for the staff notifications channel")
.addChannelOption(option => option.setName("channel").setDescription("The channel to set the staff notifications channel to").addChannelTypes([
ChannelType.GuildNews, ChannelType.GuildText
- ]))
+ ]).setRequired(false))
const callback = async (interaction: CommandInteraction): Promise<any> => {
let m;
@@ -56,6 +56,28 @@
if (confirmation.success) {
try {
await client.database.guilds.write(interaction.guild.id, {"logging.staff.channel": channel.id})
+ const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger
+ try {
+ let data = {
+ meta:{
+ type: 'logIgnoreUpdated',
+ displayName: 'Staff Notifications Channel Updated',
+ calculateType: 'nucleusSettingsUpdated',
+ color: NucleusColors.yellow,
+ emoji: "CHANNEL.TEXT.EDIT",
+ timestamp: new Date().getTime()
+ },
+ list: {
+ memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
+ changedBy: entry(interaction.user.id, renderUser(interaction.user)),
+ channel: entry(channel.id, renderChannel(channel)),
+ },
+ hidden: {
+ guild: interaction.guild.id
+ }
+ }
+ log(data);
+ } catch {}
} catch (e) {
return interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Staff Notifications Channel")
@@ -122,7 +144,7 @@
const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
let member = (interaction.member as Discord.GuildMember)
- if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the `manage_server` permission to use this command"
+ if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the Manage Server permission to use this command"
return true;
}
diff --git a/src/commands/settings/staff/_meta.ts b/src/commands/settings/staff/_meta.ts
deleted file mode 100644
index 9c3cd62..0000000
--- a/src/commands/settings/staff/_meta.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-const name = "warnings";
-const description = "Settings for mod warnings";
-
-export { name, description };
\ No newline at end of file
diff --git a/src/commands/settings/tickets.ts b/src/commands/settings/tickets.ts
index b505c5c..e664bd0 100644
--- a/src/commands/settings/tickets.ts
+++ b/src/commands/settings/tickets.ts
@@ -404,7 +404,7 @@
const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
let member = (interaction.member as Discord.GuildMember)
- if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the `manage_server` permission to use this command"
+ if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the Manage Server permission to use this command"
return true;
}
diff --git a/src/commands/settings/verify/role.ts b/src/commands/settings/verify.ts
similarity index 75%
rename from src/commands/settings/verify/role.ts
rename to src/commands/settings/verify.ts
index 44406e9..7a68c64 100644
--- a/src/commands/settings/verify/role.ts
+++ b/src/commands/settings/verify.ts
@@ -1,16 +1,16 @@
import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
-import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
-import confirmationMessage from "../../../utils/confirmationMessage.js";
-import getEmojiByName from "../../../utils/getEmojiByName.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import confirmationMessage from "../../utils/confirmationMessage.js";
+import getEmojiByName from "../../utils/getEmojiByName.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import client from "../../../utils/client.js";
+import client from "../../utils/client.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
- .setName("role")
- .setDescription("Sets or shows the role given to users after using /verify")
- .addRoleOption(option => option.setName("role").setDescription("The role to give after verifying"))
+ .setName("verify")
+ .setDescription("Manage the role given after typing /verify")
+ .addRoleOption(option => option.setName("role").setDescription("The role to give after verifying").setRequired(false))
const callback = async (interaction: CommandInteraction): Promise<any> => {
let m;
@@ -50,6 +50,28 @@
if (confirmation.success) {
try {
await client.database.guilds.write(interaction.guild.id, {"verify.role": role.id, "verify.enabled": true});
+ const { log, NucleusColors, entry, renderUser, renderRole } = client.logger
+ try {
+ let data = {
+ meta:{
+ type: 'verifyRoleChanged',
+ displayName: 'Ignored Groups Changed',
+ calculateType: 'nucleusSettingsUpdated',
+ color: NucleusColors.green,
+ emoji: "CONTROL.BLOCKTICK",
+ timestamp: new Date().getTime()
+ },
+ list: {
+ memberId: entry(interaction.user.id, `\`${interaction.user.id}\``),
+ changedBy: entry(interaction.user.id, renderUser(interaction.user)),
+ role: entry(role.id, renderRole(role)),
+ },
+ hidden: {
+ guild: interaction.guild.id
+ }
+ }
+ log(data);
+ } catch {}
} catch (e) {
console.log(e)
return interaction.editReply({embeds: [new EmojiEmbed()
@@ -117,7 +139,7 @@
const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
let member = (interaction.member as Discord.GuildMember)
- if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the `manage_server` permission to use this command"
+ if (!member.permissions.has("MANAGE_GUILD")) throw "You must have the Manage Server permission to use this command"
return true;
}
diff --git a/src/commands/settings/verify/_meta.ts b/src/commands/settings/verify/_meta.ts
deleted file mode 100644
index 999c50b..0000000
--- a/src/commands/settings/verify/_meta.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-const name = "verify";
-const description = "Settings for verification";
-
-export { name, description };
\ No newline at end of file
diff --git a/src/commands/tags/create.ts b/src/commands/tags/create.ts
index c1ed839..6dbecf4 100644
--- a/src/commands/tags/create.ts
+++ b/src/commands/tags/create.ts
@@ -78,7 +78,7 @@
const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
let member = (interaction.member as Discord.GuildMember)
- if (!member.permissions.has("MANAGE_MESSAGES")) throw "You must have the `manage_messages` permission to use this command"
+ if (!member.permissions.has("MANAGE_MESSAGES")) throw "You must have the Manage Messages permission to use this command"
return true;
}
diff --git a/src/commands/tags/delete.ts b/src/commands/tags/delete.ts
index f24a5fc..2707465 100644
--- a/src/commands/tags/delete.ts
+++ b/src/commands/tags/delete.ts
@@ -60,7 +60,7 @@
const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
let member = (interaction.member as Discord.GuildMember)
- if (!member.permissions.has("MANAGE_MESSAGES")) throw "You must have the `manage_messages` permission to use this command"
+ if (!member.permissions.has("MANAGE_MESSAGES")) throw "You must have the Manage Messages permission to use this command"
return true;
}
diff --git a/src/commands/tags/edit.ts b/src/commands/tags/edit.ts
index b0a4835..77e21ae 100644
--- a/src/commands/tags/edit.ts
+++ b/src/commands/tags/edit.ts
@@ -93,7 +93,7 @@
const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
let member = (interaction.member as Discord.GuildMember)
- if (!member.permissions.has("MANAGE_MESSAGES")) throw "You must have the `manage_messages` permission to use this command"
+ if (!member.permissions.has("MANAGE_MESSAGES")) throw "You must have the Manage Messages permission to use this command"
return true;
}
diff --git a/src/config/emojis.json b/src/config/emojis.json
index f6eabe0..e9fb578 100644
--- a/src/config/emojis.json
+++ b/src/config/emojis.json
@@ -119,6 +119,7 @@
"DELETE": "752070251948146768"
},
"MESSAGE": {
+ "CREATE": "751762088229339136",
"EDIT": "729065958584614925",
"DELETE": "729064530432360461",
"PIN": "729064530755190894",
diff --git a/src/events/channelCreate.ts b/src/events/channelCreate.ts
index 3bde0f2..2d48255 100644
--- a/src/events/channelCreate.ts
+++ b/src/events/channelCreate.ts
@@ -55,7 +55,7 @@
timestamp: channel.createdTimestamp
},
list: {
- id: entry(channel.id, `\`${channel.id}\``),
+ channelId: entry(channel.id, `\`${channel.id}\``),
name: entry(channel.name, renderChannel(channel)),
type: entry(channel.type, readableType),
category: entry(channel.parent ? channel.parent.id : null, channel.parent ? channel.parent.name : "Uncategorised"),
diff --git a/src/events/channelDelete.ts b/src/events/channelDelete.ts
index 2188141..5c7139a 100644
--- a/src/events/channelDelete.ts
+++ b/src/events/channelDelete.ts
@@ -39,7 +39,7 @@
}
}
let list = {
- id: entry(channel.id, `\`${channel.id}\``),
+ channelIid: entry(channel.id, `\`${channel.id}\``),
name: entry(channel.id, `${channel.name}`),
topic: null,
type: entry(channel.type, readableType),
diff --git a/src/events/channelUpdate.ts b/src/events/channelUpdate.ts
index 560ca11..50a3de1 100644
--- a/src/events/channelUpdate.ts
+++ b/src/events/channelUpdate.ts
@@ -18,7 +18,7 @@
let readableType:string;
let displayName:string ;
let changes = {
- id: entry(nc.id, `\`${nc.id}\``),
+ channelId: entry(nc.id, `\`${nc.id}\``),
channel: entry(nc.id, renderChannel(nc)),
edited: entry(new Date().getTime(), renderDelta(new Date().getTime())),
editedBy: entry(audit.executor.id, renderUser((await nc.guild.members.fetch(audit.executor.id)).user)),
diff --git a/src/events/emojiCreate.ts b/src/events/emojiCreate.ts
index 1048869..25d1b62 100644
--- a/src/events/emojiCreate.ts
+++ b/src/events/emojiCreate.ts
@@ -16,7 +16,7 @@
timestamp: emoji.createdTimestamp
},
list: {
- id: entry(emoji.id, `\`${emoji.id}\``),
+ emojiId: entry(emoji.id, `\`${emoji.id}\``),
emoji: entry(emoji.name, renderEmoji(emoji)),
createdBy: entry(audit.executor.id, renderUser(audit.executor)),
created: entry(emoji.createdTimestamp, renderDelta(emoji.createdTimestamp))
diff --git a/src/events/emojiDelete.ts b/src/events/emojiDelete.ts
index 02bec0d..2dcb685 100644
--- a/src/events/emojiDelete.ts
+++ b/src/events/emojiDelete.ts
@@ -16,7 +16,7 @@
timestamp: audit.createdTimestamp,
},
list: {
- id: entry(emoji.id, `\`${emoji.id}\``),
+ emojiId: entry(emoji.id, `\`${emoji.id}\``),
emoji: entry(emoji.name, renderEmoji(emoji)),
deletedBy: entry(audit.executor.id, renderUser(audit.executor)),
created: entry(emoji.createdTimestamp, renderDelta(emoji.createdTimestamp)),
diff --git a/src/events/emojiUpdate.ts b/src/events/emojiUpdate.ts
index eb39cb9..79fb171 100644
--- a/src/events/emojiUpdate.ts
+++ b/src/events/emojiUpdate.ts
@@ -12,7 +12,7 @@
if (audit.executor.id == client.user.id) return;
let changes = {
- id: entry(ne.id, `\`${ne.id}\``),
+ emojiId: entry(ne.id, `\`${ne.id}\``),
emoji: entry(ne.id, renderEmoji(ne)),
edited: entry(ne.createdTimestamp, renderDelta(ne.createdTimestamp)),
editedBy: entry(audit.executor.id, renderUser((await ne.guild.members.fetch(audit.executor.id)).user)),
diff --git a/src/events/guildBanAdd.ts b/src/events/guildBanAdd.ts
index a1848fd..05b98ed 100644
--- a/src/events/guildBanAdd.ts
+++ b/src/events/guildBanAdd.ts
@@ -22,7 +22,7 @@
timestamp: new Date().getTime()
},
list: {
- id: entry(ban.user.id, `\`${ban.user.id}\``),
+ memberId: entry(ban.user.id, `\`${ban.user.id}\``),
name: entry(ban.user.id, renderUser(ban.user)),
banned: entry(new Date().getTime(), renderDelta(new Date().getTime())),
bannedBy: entry(audit.executor.id, renderUser(audit.executor)),
diff --git a/src/events/guildBanRemove.ts b/src/events/guildBanRemove.ts
index 59fbf7a..85dc2af 100644
--- a/src/events/guildBanRemove.ts
+++ b/src/events/guildBanRemove.ts
@@ -23,7 +23,7 @@
timestamp: new Date().getTime()
},
list: {
- id: entry(ban.user.id, `\`${ban.user.id}\``),
+ memberId: entry(ban.user.id, `\`${ban.user.id}\``),
name: entry(ban.user.id, renderUser(ban.user)),
unbanned: entry(new Date().getTime(), renderDelta(new Date().getTime())),
unbannedBy: entry(audit.executor.id, renderUser(audit.executor)),
diff --git a/src/events/guildMemberUpdate.ts b/src/events/guildMemberUpdate.ts
index 2175aaf..dab89fa 100644
--- a/src/events/guildMemberUpdate.ts
+++ b/src/events/guildMemberUpdate.ts
@@ -23,7 +23,7 @@
timestamp: new Date().getTime()
},
list: {
- id: entry(after.id, `\`${after.id}\``),
+ memberId: entry(after.id, `\`${after.id}\``),
before: entry(before.nickname, before.nickname ? before.nickname : '*None*'),
after: entry(after.nickname, after.nickname ? after.nickname : '*None*'),
updated: entry(new Date().getTime(), renderDelta(new Date().getTime())),
diff --git a/src/events/memberJoin.ts b/src/events/memberJoin.ts
index f3c4d18..2031b12 100644
--- a/src/events/memberJoin.ts
+++ b/src/events/memberJoin.ts
@@ -21,7 +21,7 @@
timestamp: member.joinedTimestamp
},
list: {
- id: entry(member.id, `\`${member.id}\``),
+ memberId: entry(member.id, `\`${member.id}\``),
name: entry(member.id, renderUser(member.user)),
joined: entry(member.joinedAt, renderDelta(member.joinedAt)),
accountCreated: entry(member.user.createdAt, renderDelta(member.user.createdAt)),
diff --git a/src/events/memberLeave.ts b/src/events/memberLeave.ts
index 43e78bd..b9d6e84 100644
--- a/src/events/memberLeave.ts
+++ b/src/events/memberLeave.ts
@@ -31,7 +31,7 @@
timestamp: new Date().getTime()
},
list: {
- id: entry(member.id, `\`${member.id}\``),
+ memberId: entry(member.id, `\`${member.id}\``),
name: entry(member.id, renderUser(member.user)),
joined: entry(member.joinedAt, renderDelta(member.joinedAt)),
kicked: entry(new Date().getTime(), renderDelta(new Date().getTime())),
@@ -57,7 +57,7 @@
timestamp: new Date().getTime()
},
list: {
- id: entry(member.id, `\`${member.id}\``),
+ memberId: entry(member.id, `\`${member.id}\``),
name: entry(member.id, renderUser(member.user)),
joined: entry(member.joinedTimestamp, renderDelta(member.joinedAt)),
left: entry(new Date().getTime(), renderDelta(new Date().getTime())),
diff --git a/src/events/messageChecks.ts b/src/events/messageChecks.ts
index 4e99c61..2755ff1 100644
--- a/src/events/messageChecks.ts
+++ b/src/events/messageChecks.ts
@@ -1,9 +1,11 @@
import { LinkCheck, MalwareCheck, NSFWCheck, SizeCheck, TestString, TestImage } from '../automations/unscan.js'
import { Message } from 'discord.js'
+import client from '../utils/client.js'
export const event = 'messageCreate'
export async function callback(client, message) {
+ const { log, NucleusColors, entry, renderUser } = client.logger
if (message.author.bot) return
if (message.channel.type === 'dm') return
@@ -16,8 +18,7 @@
!message.author.roles.cache.some(role => config.filters.invite.allowed.roles.includes(role.id))
) {
if ((/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/.test(content))) {
- message.delete();
- return toLog(message, 'invite', content.match(/(?:https?:\/\/)?discord(?:app)?\.(?:com\/invite|gg)\/[a-zA-Z0-9]+\/?/))
+ return message.delete();
}
}
}
@@ -34,22 +35,19 @@
if(/\.+(webp|png|jpg|jpeg|bmp)/.test(url)) {
if (config.filters.images.NSFW && !message.channel.nsfw) {
if (await NSFWCheck(url)) {
- await message.delete()
- return toLog(message, 'NSFW', url)
+ return await message.delete()
}
}
if (config.filters.images.size) {
if(!url.match(/\.+(webp|png|jpg)$/gi)) return
if(!await SizeCheck(element)) {
- await message.delete()
- return toLog(message, 'size', url)
+ return await message.delete()
}
}
}
if (config.filters.malware) {
if (!MalwareCheck(url)) {
- await message.delete()
- return toLog(message, 'malware', url)
+ return await message.delete()
}
}
}
@@ -58,15 +56,13 @@
if(!message) return;
if (await LinkCheck(message)) {
- await message.delete()
- return toLog(message, 'link')
+ return await message.delete()
}
if (config.filters.wordFilter.enabled) {
let check = TestString(content, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict)
- if(check != "none") {
- await message.delete()
- return toLog(message, 'wordFilter', content)
+ if(check !== null) {
+ return await message.delete()
}
}
@@ -75,26 +71,19 @@
!message.author.roles.cache.some(role => config.filters.pings.allowed.roles.includes(role.id))
) {
if (config.filters.pings.everyone && message.mentions.everyone) {
- message.delete();
- return toLog(message, 'mention everyone')
+ return message.delete();
}
if (config.filters.pings.roles) {
for(let role of message.mentions.roles) {
if(!message) return;
if (!config.filters.pings.allowed.roles.includes(role.id)) {
- message.delete();
- return toLog(message, 'mention role')
+ return message.delete();
}
}
}
if(!message) return;
if (message.mentions.users.size >= config.filters.pings.mass && config.filters.pings.mass) {
- message.delete();
- return toLog(message, 'Mass Pings')
+ return message.delete();
}
}
}
-
-async function toLog(message: Message, reason: string, data?: any) {
- // log(message.guild.id, {type: reason, data: data})
-}
diff --git a/src/events/messageDelete.ts b/src/events/messageDelete.ts
index 229b126..f0fbb57 100644
--- a/src/events/messageDelete.ts
+++ b/src/events/messageDelete.ts
@@ -25,7 +25,7 @@
start: content ? `**Message:**\n\`\`\`${content}\`\`\`` : '**Message:** *Message had no content*',
},
list: {
- id: entry(message.id, `\`${message.id}\``),
+ messageId: entry(message.id, `\`${message.id}\``),
sentBy: entry(message.author.id, renderUser(message.author)),
sentIn: entry(message.channel.id, renderChannel(message.channel)),
deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
diff --git a/src/events/messageEdit.ts b/src/events/messageEdit.ts
index 0d42fb9..3502963 100644
--- a/src/events/messageEdit.ts
+++ b/src/events/messageEdit.ts
@@ -7,7 +7,37 @@
newMessage.reference = newMessage.reference || {}
let newContent = newMessage.cleanContent.replaceAll("`", "‘")
let oldContent = oldMessage.cleanContent.replaceAll("`", "‘")
- if (newContent == oldContent) return;
+ if (newContent == oldContent) {
+ if (!oldMessage.flags.has("CROSSPOSTED") && newMessage.flags.has("CROSSPOSTED")) {
+ let data = {
+ meta: {
+ type: 'messageAnnounce',
+ displayName: 'Message Published',
+ calculateType: 'messageAnnounce',
+ color: NucleusColors.yellow,
+ emoji: 'MESSAGE.CREATE',
+ timestamp: newMessage.editedTimestamp
+ },
+ separate: {
+ end: `[[Jump to message]](${newMessage.url})`
+ },
+ list: {
+ messageId: entry(newMessage.id, `\`${newMessage.id}\``),
+ sentBy: entry(newMessage.author.id, renderUser(newMessage.author)),
+ sentIn: entry(newMessage.channel.id, renderChannel(newMessage.channel)),
+ sent: entry(new Date(newMessage.createdTimestamp), renderDelta(new Date(newMessage.createdTimestamp))),
+ published: entry(new Date(newMessage.editedTimestamp), renderDelta(new Date(newMessage.editedTimestamp))),
+ mentions: renderNumberDelta(oldMessage.mentions.users.size, newMessage.mentions.users.size),
+ attachments: renderNumberDelta(oldMessage.attachments.size, newMessage.attachments.size)
+ },
+ hidden: {
+ guild: newMessage.channel.guild.id
+ }
+ }
+ log(data);
+ }
+ return
+ };
if (newContent.length > 256) newContent = newContent.substring(0, 253) + '...'
if (oldContent.length > 256) oldContent = oldContent.substring(0, 253) + '...'
let data = {
@@ -25,7 +55,7 @@
end: `[[Jump to message]](${newMessage.url})`
},
list: {
- id: entry(newMessage.id, `\`${newMessage.id}\``),
+ messageId: entry(newMessage.id, `\`${newMessage.id}\``),
sentBy: entry(newMessage.author.id, renderUser(newMessage.author)),
sentIn: entry(newMessage.channel.id, renderChannel(newMessage.channel)),
sent: entry(new Date(newMessage.createdTimestamp), renderDelta(new Date(newMessage.createdTimestamp))),
diff --git a/src/events/roleCreate.ts b/src/events/roleCreate.ts
index 61d0a87..6fded26 100644
--- a/src/events/roleCreate.ts
+++ b/src/events/roleCreate.ts
@@ -17,7 +17,7 @@
timestamp: role.createdTimestamp
},
list: {
- id: entry(role.id, `\`${role.id}\``),
+ roleId: entry(role.id, `\`${role.id}\``),
role: entry(role.name, renderRole(role)),
createdBy: entry(audit.executor.id, renderUser(audit.executor)),
created: entry(role.createdTimestamp, renderDelta(role.createdTimestamp))
diff --git a/src/events/roleDelete.ts b/src/events/roleDelete.ts
index b0cb0f7..6a23d9e 100644
--- a/src/events/roleDelete.ts
+++ b/src/events/roleDelete.ts
@@ -19,7 +19,7 @@
timestamp: audit.createdTimestamp,
},
list: {
- id: entry(role.id, `\`${role.id}\``),
+ roleId: entry(role.id, `\`${role.id}\``),
role: entry(role.name, role.name),
color: entry(role.hexColor, `\`${role.hexColor}\``),
showInMemberList: entry(role.hoist, role.hoist ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`),
diff --git a/src/events/roleUpdate.ts b/src/events/roleUpdate.ts
index 982d915..baf4399 100644
--- a/src/events/roleUpdate.ts
+++ b/src/events/roleUpdate.ts
@@ -11,7 +11,7 @@
if (audit.executor.id == client.user.id) return;
let changes = {
- id: entry(nr.id, `\`${nr.id}\``),
+ roleId: entry(nr.id, `\`${nr.id}\``),
role: entry(nr.id, renderRole(nr)),
edited: entry(nr.createdTimestamp, renderDelta(nr.createdTimestamp)),
editedBy: entry(audit.executor.id, renderUser((await nr.guild.members.fetch(audit.executor.id)).user)),
diff --git a/src/events/stickerCreate.ts b/src/events/stickerCreate.ts
new file mode 100644
index 0000000..b9511b0
--- /dev/null
+++ b/src/events/stickerCreate.ts
@@ -0,0 +1,30 @@
+export const event = 'stickerCreate'
+
+export async function callback(client, emoji) {
+ try {
+ const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = emoji.client.logger
+ let auditLog = await getAuditLog(emoji.guild, 'STICKER_CREATE');
+ let audit = auditLog.entries.filter(entry => entry.target.id == emoji.id).first();
+ if (audit.executor.id == client.user.id) return;
+ let data = {
+ meta: {
+ type: 'stickerCreate',
+ displayName: 'Sticker Created',
+ calculateType: 'stickerUpdate',
+ color: NucleusColors.green,
+ emoji: "GUILD.EMOJI.CREATE",
+ timestamp: emoji.createdTimestamp
+ },
+ list: {
+ stickerId: entry(emoji.id, `\`${emoji.id}\``),
+ emoji: entry(emoji.name, `\`:${emoji.name}:\``),
+ createdBy: entry(audit.executor.id, renderUser(audit.executor)),
+ created: entry(emoji.createdTimestamp, renderDelta(emoji.createdTimestamp))
+ },
+ hidden: {
+ guild: emoji.guild.id
+ }
+ }
+ log(data);
+ } catch {}
+}
diff --git a/src/events/stickerDelete.ts b/src/events/stickerDelete.ts
new file mode 100644
index 0000000..7490851
--- /dev/null
+++ b/src/events/stickerDelete.ts
@@ -0,0 +1,31 @@
+export const event = 'stickerDelete'
+
+export async function callback(client, emoji) {
+ try{
+ const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = emoji.client.logger
+ let auditLog = await getAuditLog(emoji.guild, 'STICKER_DELETE');
+ let audit = auditLog.entries.filter(entry => entry.target.id == emoji.id).first();
+ if (audit.executor.id == client.user.id) return;
+ let data = {
+ meta: {
+ type: 'stickerDelete',
+ displayName: 'Sticker Deleted',
+ calculateType: 'stickerUpdate',
+ color: NucleusColors.red,
+ emoji: "GUILD.EMOJI.DELETE",
+ timestamp: audit.createdTimestamp,
+ },
+ list: {
+ stickerId:entry(emoji.id, `\`${emoji.id}\``),
+ sticker: entry(emoji.name, `\`${emoji.name}\``),
+ deletedBy: entry(audit.executor.id, renderUser(audit.executor)),
+ created: entry(emoji.createdTimestamp, renderDelta(emoji.createdTimestamp)),
+ deleted: entry(audit.createdTimestamp, renderDelta(audit.createdTimestamp)),
+ },
+ hidden: {
+ guild: emoji.guild.id
+ }
+ }
+ log(data);
+ } catch {}
+}
diff --git a/src/events/stickerUpdate.ts b/src/events/stickerUpdate.ts
new file mode 100644
index 0000000..7cb745f
--- /dev/null
+++ b/src/events/stickerUpdate.ts
@@ -0,0 +1,34 @@
+export const event = 'stickerUpdate';
+
+export async function callback(client, oe, ne) {
+ try {
+ const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser, renderEmoji } = client.logger
+
+ if (oe.name == ne.name) return
+ let auditLog = await getAuditLog(ne.guild, 'EMOJI_UPDATE');
+ let audit = auditLog.entries.first();
+ if (audit.executor.id == client.user.id) return;
+
+ let changes = {
+ stickerId:entry(ne.id, `\`${ne.id}\``),
+ edited: entry(ne.createdTimestamp, renderDelta(ne.createdTimestamp)),
+ editedBy: entry(audit.executor.id, renderUser((await ne.guild.members.fetch(audit.executor.id)).user)),
+ name: entry([oe.name, ne.name], `\`:${oe.name}:\` -> \`:${ne.name}:\``),
+ }
+ let data = {
+ meta:{
+ type: 'stickerUpdate',
+ displayName: 'Sticker Edited',
+ calculateType: 'stickerUpdate',
+ color: NucleusColors.yellow,
+ emoji: "GUILD.EMOJI.EDIT",
+ timestamp: audit.createdTimestamp
+ },
+ list: changes,
+ hidden: {
+ guild: ne.guild.id
+ }
+ }
+ log(data);
+ } catch {}
+}
\ No newline at end of file
diff --git a/src/events/threadCreate.ts b/src/events/threadCreate.ts
index 5c65d78..ff69e35 100644
--- a/src/events/threadCreate.ts
+++ b/src/events/threadCreate.ts
@@ -17,7 +17,7 @@
timestamp: thread.createdTimestamp
},
list: {
- id: entry(thread.id, `\`${thread.id}\``),
+ threadId:entry(thread.id, `\`${thread.id}\``),
name: entry(thread.name, renderChannel(thread)),
parentChannel: entry(thread.parentId, renderChannel(thread.parent)),
category: entry(thread.parent.parent ? thread.parent.parent.name : 'None', thread.parent.parent ? renderChannel(thread.parent.parent) : 'None'),
diff --git a/src/events/threadDelete.ts b/src/events/threadDelete.ts
index 9507469..14c5820 100644
--- a/src/events/threadDelete.ts
+++ b/src/events/threadDelete.ts
@@ -17,7 +17,7 @@
timestamp: new Date().getTime()
},
list: {
- id: entry(thread.id, `\`${thread.id}\``),
+ threadId:entry(thread.id, `\`${thread.id}\``),
name: entry(thread.name, thread.name),
parentChannel: entry(thread.parentId, renderChannel(thread.parent)),
category: entry(thread.parent.parent ? thread.parent.parent.name : 'None', thread.parent.parent ? renderChannel(thread.parent.parent) : 'None'),
diff --git a/src/events/threadUpdate.ts b/src/events/threadUpdate.ts
index f554a6c..4e13193 100644
--- a/src/events/threadUpdate.ts
+++ b/src/events/threadUpdate.ts
@@ -8,7 +8,7 @@
let audit = auditLog.entries.filter(entry => entry.target.id == after.id).first();
if (audit.executor.id == client.user.id) return;
let list = {
- id: entry(after.id, `\`${after.id}\``),
+ threadId:entry(after.id, `\`${after.id}\``),
thread: entry(after.name, renderChannel(after)),
parentChannel: entry(after.parentId, renderChannel(after.parent)),
}
diff --git a/src/events/webhookUpdate.ts b/src/events/webhookUpdate.ts
new file mode 100644
index 0000000..a20608c
--- /dev/null
+++ b/src/events/webhookUpdate.ts
@@ -0,0 +1,78 @@
+import humanizeDuration from 'humanize-duration';
+export const event = 'webhookUpdate'
+
+export async function callback(client, channel) {
+ try {
+ const { getAuditLog, log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger
+ let auditLogCreate = getAuditLog(channel.guild, 'WEBHOOK_CREATE');
+ let auditLogUpdate = getAuditLog(channel.guild, 'WEBHOOK_UPDATE');
+ let auditLogDelete = getAuditLog(channel.guild, 'WEBHOOK_DELETE');
+ [auditLogCreate, auditLogUpdate, auditLogDelete] = await Promise.all([auditLogCreate, auditLogUpdate, auditLogDelete]);
+ let auditCreate = auditLogCreate.entries.filter(entry => entry.target.channelId == channel.id).first();
+ let auditUpdate = auditLogUpdate.entries.filter(entry => entry.target.channelId == channel.id).first();
+ let auditDelete = auditLogDelete.entries.filter(entry => entry.target.channelId == channel.id).first();
+ if (!auditCreate && !auditUpdate && !auditDelete) return;
+ let audit = auditCreate;
+ let action = "Create";
+ let list = {} as any;
+ if (auditUpdate && auditUpdate.createdTimestamp > audit.createdTimestamp) {
+ let {before, after} = auditUpdate.changes.reduce(
+ (acc, change) => { acc.before[change.key] = change.old; acc.after[change.key] = change.new; return acc; },
+ {before: {}, after: {}}
+ );
+ if (before.name !== after.name) list['name'] = entry([before.name, after.name], `${before.name} -> ${after.name}`)
+ if (before.channel_id !== after.channel_id) list['channel'] = entry([before.channel_id, after.channel_id], renderChannel(await client.channels.fetch(before.channel_id)) + ` -> ` + renderChannel(await client.channels.fetch(after.channel_id)))
+ if (!(Object.keys(list)).length) return;
+ list.created = entry(auditUpdate.target.createdTimestamp, renderDelta(auditUpdate.target.createdTimestamp));
+ list.edited = entry(after.editedTimestamp, renderDelta(new Date().getTime()));
+ list.editedBy = entry(auditUpdate.executor.id, renderUser(auditUpdate.executor));
+ audit = auditUpdate;
+ action = "Update"
+ } else if (auditDelete && auditDelete.createdTimestamp > audit.createdTimestamp) {
+ let {before, after} = auditDelete.changes.reduce(
+ (acc, change) => { acc.before[change.key] = change.old; acc.after[change.key] = change.new; return acc; },
+ {before: {}, after: {}}
+ );
+ list = {
+ name: entry(before.name, `${before.name}`),
+ channel: entry(before.channel_id, renderChannel(await client.channels.fetch(before.channel_id))),
+ created: entry(auditDelete.target.createdTimestamp, renderDelta(auditDelete.target.createdTimestamp)),
+ deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ deletedBy: entry(auditDelete.executor.id, renderUser((await channel.guild.members.fetch(auditDelete.executor.id)).user)),
+ }
+ audit = auditDelete;
+ action = "Delete"
+ } else {
+ let {before, after} = auditDelete.changes.reduce(
+ (acc, change) => { acc.before[change.key] = change.old; acc.after[change.key] = change.new; return acc; },
+ {before: {}, after: {}}
+ );
+ list = {
+ name: entry(before.name, `${before.name}`),
+ channel: entry(before.channel_id, renderChannel(await client.channels.fetch(before.channel_id))),
+ createdBy: entry(auditCreate.executor.id, renderUser((await channel.guild.members.fetch(auditCreate.executor.id)).user)),
+ created: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ }
+ }
+ let cols = {
+ "Create": "green",
+ "Update": "yellow",
+ "Delete": "red",
+ }
+ let data = {
+ meta: {
+ type: 'webhook' + action,
+ displayName: `Webhook ${action}d`,
+ calculateType: 'webhookUpdate',
+ color: NucleusColors[cols[action]],
+ emoji: "WEBHOOK." + action.toUpperCase(),
+ timestamp: new Date().getTime()
+ },
+ list: list,
+ hidden: {
+ guild: channel.guild.id
+ }
+ } // TODO
+ log(data);
+ } catch(e) { console.log(e) }
+}
diff --git a/src/utils/calculate.ts b/src/utils/calculate.ts
index a58fae1..7f3b16d 100644
--- a/src/utils/calculate.ts
+++ b/src/utils/calculate.ts
@@ -1,8 +1,7 @@
const logs = [
"channelUpdate",
- "channelPinsUpdate", // TODO
"emojiUpdate",
- "stickerUpdate", // TODO
+ "stickerUpdate",
"guildUpdate",
"guildMemberUpdate",
"guildMemberPunish",
@@ -14,13 +13,12 @@
"messageReactionUpdate",
"messagePing",
"messageMassPing",
- "messageAnnounce", // TODO
+ "messageAnnounce",
"threadUpdate",
- "webhookUpdate", // TODO
+ "webhookUpdate",
"guildMemberVerify",
- "autoModeratorDeleted", // TODO
- "nucleusSettingsUpdated", // TODO
- ""
+ "autoModeratorDeleted", // TODO: Not implemented
+ "nucleusSettingsUpdated"
]
const tickets = [
@@ -51,7 +49,7 @@
let permissions = [];
let int = (BigInt("0x" + permissionsHex)).toString(2).split('').reverse();
for (let index in int) {
- if (int[index] == "1") {
+ if (int[index] == "1" && array.length > index) {
permissions.push(array[index]);
}
}
diff --git a/src/utils/log.ts b/src/utils/log.ts
index 55f8f4c..987e256 100644
--- a/src/utils/log.ts
+++ b/src/utils/log.ts
@@ -46,10 +46,10 @@
}
- async getAuditLog(guild: Discord.Guild, event) {
+ async getAuditLog(guild: Discord.Guild, event): Promise<Discord.GuildAuditLogsEntry[]>{
await wait(250)
let auditLog = await guild.fetchAuditLogs({type: event});
- return auditLog;
+ return auditLog as unknown as Discord.GuildAuditLogsEntry[];
}
async log(log: any): Promise<void> {