worked on transcripts

pull/11/head
TheCodedProf 3 years ago
parent faae533c40
commit f8ef79403f

@ -87,10 +87,8 @@ export default async function (interaction: Discord.CommandInteraction | ButtonI
new EmojiEmbed() new EmojiEmbed()
.setTitle("Archived Ticket") .setTitle("Archived Ticket")
.setDescription(`This ticket has been Archived. Type ${getCommandMentionByName("ticket/close")} to delete it.\n` + .setDescription(`This ticket has been Archived. Type ${getCommandMentionByName("ticket/close")} to delete it.\n` +
"Creating a transcript will delete all messages in this ticket" + hasPremium ? ("Creating a transcript will delete all messages in this ticket" +
hasPremium ? `\n\nFor more info on transcripts, check ${getCommandMentionByName("privacy")}`): "")
`\n\nFor more info on transcripts, check ${getCommandMentionByName("privacy")}` :
"")
.setStatus("Warning") .setStatus("Warning")
.setEmoji("GUILD.TICKET.ARCHIVED") .setEmoji("GUILD.TICKET.ARCHIVED")
], ],

@ -156,6 +156,8 @@ const runServer = (client: NucleusClient) => {
if (entry === null) return res.status(404).send("Could not find a transcript by that code"); if (entry === null) return res.status(404).send("Could not find a transcript by that code");
// Convert to a human readable format // Convert to a human readable format
const data = client.database.transcripts.toHumanReadable(entry); const data = client.database.transcripts.toHumanReadable(entry);
res.attachment(`${code}.txt`);
res.type("txt");
return res.status(200).send(data); return res.status(200).send(data);
}); });
@ -168,6 +170,28 @@ const runServer = (client: NucleusClient) => {
return res.status(200).send(entry); return res.status(200).send(entry);
}); });
app.get("/channels/:id", jsonParser, async function (req: express.Request, res: express.Response) {
const id = req.params.id;
if (id === undefined) return res.status(400).send("No id provided");
const channel = await client.channels.fetch(id);
if (channel === null) return res.status(404).send("Could not find a channel by that id");
if (channel.isDMBased()) return res.status(400).send("Cannot get a DM channel");
return res.status(200).send(channel.name);
});
app.get("/users/:id", jsonParser, async function (req: express.Request, res: express.Response) {
const id = req.params.id;
if (id === undefined) return res.status(400).send("No id provided");
let user;
try {
user = await client.users.fetch(id);
} catch (e) {
console.log(e)
return res.status(404).send("Could not find a user by that id");
}
return res.status(200).send(user.username);
});
app.listen(port); app.listen(port);
}; };

@ -650,19 +650,19 @@ const cleanMenu = async (interaction: StringSelectMenuInteraction, m: Message, c
channels?: string[], channels?: string[],
allowed?: { allowed?: {
roles: string[], roles: string[],
user: string[] users: string[]
} }
}): Promise<{ }): Promise<{
channels: string[], channels: string[],
allowed: { allowed: {
roles: string[], roles: string[],
user: string[] users: string[]
} }
}> => { }> => {
let closed = false; let closed = false;
if(!current) current = {channels: [], allowed: {roles: [], user: []}}; if(!current) current = {channels: [], allowed: {roles: [], users: []}};
if(!current.channels) current.channels = []; if(!current.channels) current.channels = [];
if(!current.allowed) current.allowed = {roles: [], user: []}; if(!current.allowed) current.allowed = {roles: [], users: []};
const channelMenu = new ActionRowBuilder<ChannelSelectMenuBuilder>() const channelMenu = new ActionRowBuilder<ChannelSelectMenuBuilder>()
.addComponents( .addComponents(
@ -773,7 +773,7 @@ const cleanMenu = async (interaction: StringSelectMenuInteraction, m: Message, c
case "allowed": { case "allowed": {
switch (i.values[0]) { switch (i.values[0]) {
case "users": { case "users": {
current.allowed.user = await toSelectMenu(interaction, m, current.allowed.user, "member", "Mention Settings"); current.allowed.users = await toSelectMenu(interaction, m, current.allowed.users, "member", "Mention Settings");
break; break;
} }
case "roles": { case "roles": {
@ -792,7 +792,7 @@ const cleanMenu = async (interaction: StringSelectMenuInteraction, m: Message, c
channels: string[], channels: string[],
allowed: { allowed: {
roles: string[], roles: string[],
user: string[] users: string[]
} }
}; };

@ -21,6 +21,7 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
while (!timedOut) { while (!timedOut) {
const config = await client.database.guilds.read(interaction.guild!.id); const config = await client.database.guilds.read(interaction.guild!.id);
const moderation = config.moderation; const moderation = config.moderation;
console.log(moderation)
await interaction.editReply({ await interaction.editReply({
embeds: [ embeds: [
new EmojiEmbed() new EmojiEmbed()

@ -1,122 +0,0 @@
{
"id": "default",
"version": 1,
"singleEventNotifications": {
"statsChannelDeleted": false
},
"filters": {
"images": {
"NSFW": false,
"size": false
},
"malware": false,
"wordFilter": {
"enabled": false,
"words": {
"strict": [],
"loose": []
},
"allowed": {
"user": [],
"roles": [],
"channels": []
}
},
"invite": {
"enabled": false,
"allowed": {
"user": [],
"roles": [],
"channels": []
}
},
"pings": {
"mass": 5,
"everyone": true,
"roles": true,
"allowed": {
"user": [],
"roles": [],
"channels": [],
"rolesToMention": []
}
},
"clean": {
"channels": [],
"allowed": {
"user": [],
"roles": []
}
}
},
"welcome": {
"enabled": false,
"role": null,
"ping": null,
"channel": null,
"message": null
},
"stats": {},
"logging": {
"logs": {
"enabled": true,
"channel": null,
"toLog": "3fffff"
},
"staff": {
"channel": null
},
"attachments": {
"channel": null,
"saved": {}
}
},
"verify": {
"enabled": false,
"role": null
},
"tickets": {
"enabled": false,
"category": null,
"types": "3f",
"customTypes": null,
"useCustom": false,
"supportRole": null,
"maxTickets": 5
},
"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
},
"nick": {
"text": null,
"link": null
}
},
"tracks": [],
"roleMenu": [],
"tags": {},
"autoPublish": {
"enabled": false,
"channels": []
}
}

@ -28,7 +28,7 @@ export async function callback(_client: NucleusClient, message: Message) {
if(config.filters.clean.channels.includes(message.channel.id)) { if(config.filters.clean.channels.includes(message.channel.id)) {
const memberRoles = message.member!.roles.cache.map(role => role.id); const memberRoles = message.member!.roles.cache.map(role => role.id);
const roleAllow = config.filters.clean.allowed.roles.some(role => memberRoles.includes(role)); const roleAllow = config.filters.clean.allowed.roles.some(role => memberRoles.includes(role));
const userAllow = config.filters.clean.allowed.user.includes(message.author.id); const userAllow = config.filters.clean.allowed.users.includes(message.author.id);
if(!roleAllow && !userAllow) return await message.delete(); if(!roleAllow && !userAllow) return await message.delete();
} }

@ -86,7 +86,7 @@ export default async function (interaction: CommandInteraction | MessageComponen
], ],
components: [ components: [
new ActionRowBuilder<ButtonBuilder>().addComponents([ new ActionRowBuilder<ButtonBuilder>().addComponents([
new ButtonBuilder().setLabel("View").setStyle(ButtonStyle.Link).setURL(`https://clicks.codes/nucleus/transcript?code=${code}`), new ButtonBuilder().setLabel("View").setStyle(ButtonStyle.Link).setURL(`https://clicks.codes/nucleus/transcript/${code}`),
new ButtonBuilder() new ButtonBuilder()
.setLabel("Delete") .setLabel("Delete")
.setStyle(ButtonStyle.Danger) .setStyle(ButtonStyle.Danger)
@ -118,7 +118,8 @@ export default async function (interaction: CommandInteraction | MessageComponen
list: { list: {
ticketFor: entry(member.id, renderUser(member.user)), ticketFor: entry(member.id, renderUser(member.user)),
deletedBy: entry(interaction.member!.user.id, renderUser(interaction.member!.user as User)), deletedBy: entry(interaction.member!.user.id, renderUser(interaction.member!.user as User)),
deleted: entry(Date.now().toString(), renderDelta(Date.now())) deleted: entry(Date.now().toString(), renderDelta(Date.now())),
transcript: entry(code, `https://clicks.codes/nucleus/transcript/${code}`)
}, },
hidden: { hidden: {
guild: interaction.guild!.id guild: interaction.guild!.id

@ -41,7 +41,7 @@ class NucleusClient extends Client {
} }
} }
const client = new NucleusClient({ const client = new NucleusClient({
guilds: await new Guilds().setup(), guilds: await new Guilds(),
history: new History(), history: new History(),
notes: new ModNotes(), notes: new ModNotes(),
premium: new Premium(), premium: new Premium(),

@ -4,7 +4,8 @@ import { Collection, MongoClient } from "mongodb";
import config from "../config/main.js"; import config from "../config/main.js";
import client from "../utils/client.js"; import client from "../utils/client.js";
import * as crypto from "crypto"; import * as crypto from "crypto";
import _ from "lodash";
import defaultData from '../config/default.js';
// config.mongoOptions.host, { // config.mongoOptions.host, {
// auth: { // auth: {
// username: config.mongoOptions.username, // username: config.mongoOptions.username,
@ -23,27 +24,22 @@ const collectionOptions = { authdb: "admin" };
export class Guilds { export class Guilds {
guilds: Collection<GuildConfig>; guilds: Collection<GuildConfig>;
defaultData: GuildConfig | null; defaultData: GuildConfig;
constructor() { constructor() {
this.guilds = database.collection<GuildConfig>("guilds"); this.guilds = database.collection<GuildConfig>("guilds");
this.defaultData = null; this.defaultData = defaultData;
}
async setup(): Promise<Guilds> {
this.defaultData = (await import("../config/default.json", { assert: { type: "json" } }))
.default as unknown as GuildConfig;
return this;
} }
async read(guild: string): Promise<GuildConfig> { async read(guild: string): Promise<GuildConfig> {
console.log("Guild read") // console.log("Guild read")
const entry = await this.guilds.findOne({ id: guild }); const entry = await this.guilds.findOne({ id: guild });
return Object.assign({}, this.defaultData, entry); const data = _.clone(this.defaultData!);
return _.merge(data, entry ?? {});
} }
async write(guild: string, set: object | null, unset: string[] | string = []) { async write(guild: string, set: object | null, unset: string[] | string = []) {
console.log("Guild write") // console.log("Guild write")
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const uo: Record<string, any> = {}; const uo: Record<string, any> = {};
if (!Array.isArray(unset)) unset = [unset]; if (!Array.isArray(unset)) unset = [unset];
@ -58,7 +54,7 @@ export class Guilds {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
async append(guild: string, key: string, value: any) { async append(guild: string, key: string, value: any) {
console.log("Guild append") // console.log("Guild append")
if (Array.isArray(value)) { if (Array.isArray(value)) {
await this.guilds.updateOne( await this.guilds.updateOne(
{ id: guild }, { id: guild },
@ -85,7 +81,7 @@ export class Guilds {
value: any, value: any,
innerKey?: string | null innerKey?: string | null
) { ) {
console.log("Guild remove") // console.log("Guild remove")
if (innerKey) { if (innerKey) {
await this.guilds.updateOne( await this.guilds.updateOne(
{ id: guild }, { id: guild },
@ -114,7 +110,7 @@ export class Guilds {
} }
async delete(guild: string) { async delete(guild: string) {
console.log("Guild delete") // console.log("Guild delete")
await this.guilds.deleteOne({ id: guild }); await this.guilds.deleteOne({ id: guild });
} }
} }
@ -202,7 +198,7 @@ export class Transcript {
} }
async create(transcript: Omit<TranscriptSchema, "code">) { async create(transcript: Omit<TranscriptSchema, "code">) {
console.log("Transcript create") // console.log("Transcript create")
let code; let code;
do { do {
code = crypto.randomBytes(64).toString("base64").replace(/=/g, "").replace(/\//g, "_").replace(/\+/g, "-"); code = crypto.randomBytes(64).toString("base64").replace(/=/g, "").replace(/\//g, "_").replace(/\+/g, "-");
@ -214,7 +210,7 @@ export class Transcript {
} }
async read(code: string) { async read(code: string) {
console.log("Transcript read") // console.log("Transcript read")
return await this.transcripts.findOne({ code: code }); return await this.transcripts.findOne({ code: code });
} }
@ -322,9 +318,9 @@ export class Transcript {
} }
else out += `> [Reply To] ${message.referencedMessage}\n`; else out += `> [Reply To] ${message.referencedMessage}\n`;
} }
out += `${message.author.nickname ?? message.author.username}#${message.author.discriminator} (${message.author.id}) (${message.id}) `; out += `${message.author.nickname ?? message.author.username}#${message.author.discriminator} (${message.author.id}) (${message.id})`;
out += `[${new Date(message.createdTimestamp).toISOString()}] `; out += ` [${new Date(message.createdTimestamp).toISOString()}]`;
if (message.editedTimestamp) out += `[Edited: ${new Date(message.editedTimestamp).toISOString()}] `; if (message.editedTimestamp) out += ` [Edited: ${new Date(message.editedTimestamp).toISOString()}]`;
out += "\n"; out += "\n";
if (message.content) out += `[Content]\n${message.content}\n\n`; if (message.content) out += `[Content]\n${message.content}\n\n`;
if (message.embeds) { if (message.embeds) {
@ -380,7 +376,7 @@ export class History {
after?: string | null, after?: string | null,
amount?: string | null amount?: string | null
) { ) {
console.log("History create"); // console.log("History create");
await this.histories.insertOne({ await this.histories.insertOne({
type: type, type: type,
guild: guild, guild: guild,
@ -395,7 +391,7 @@ export class History {
} }
async read(guild: string, user: string, year: number) { async read(guild: string, user: string, year: number) {
console.log("History read"); // console.log("History read");
const entry = (await this.histories const entry = (await this.histories
.find({ .find({
guild: guild, guild: guild,
@ -410,7 +406,7 @@ export class History {
} }
async delete(guild: string) { async delete(guild: string) {
console.log("History delete"); // console.log("History delete");
await this.histories.deleteMany({ guild: guild }); await this.histories.deleteMany({ guild: guild });
} }
} }
@ -430,17 +426,17 @@ export class ScanCache {
} }
async read(hash: string) { async read(hash: string) {
console.log("ScanCache read"); // console.log("ScanCache read");
return await this.scanCache.findOne({ hash: hash }); return await this.scanCache.findOne({ hash: hash });
} }
async write(hash: string, data: boolean, tags?: string[]) { async write(hash: string, data: boolean, tags?: string[]) {
console.log("ScanCache write"); // console.log("ScanCache write");
await this.scanCache.insertOne({ hash: hash, data: data, tags: tags ?? [], addedAt: new Date() }, collectionOptions); await this.scanCache.insertOne({ hash: hash, data: data, tags: tags ?? [], addedAt: new Date() }, collectionOptions);
} }
async cleanup() { async cleanup() {
console.log("ScanCache cleanup"); // console.log("ScanCache cleanup");
await this.scanCache.deleteMany({ addedAt: { $lt: new Date(Date.now() - (1000 * 60 * 60 * 24 * 31)) }, hash: { $not$text: "http"} }); await this.scanCache.deleteMany({ addedAt: { $lt: new Date(Date.now() - (1000 * 60 * 60 * 24 * 31)) }, hash: { $not$text: "http"} });
} }
} }
@ -453,12 +449,12 @@ export class PerformanceTest {
} }
async record(data: PerformanceDataSchema) { async record(data: PerformanceDataSchema) {
console.log("PerformanceTest record"); // console.log("PerformanceTest record");
data.timestamp = new Date(); data.timestamp = new Date();
await this.performanceData.insertOne(data, collectionOptions); await this.performanceData.insertOne(data, collectionOptions);
} }
async read() { async read() {
console.log("PerformanceTest read"); // console.log("PerformanceTest read");
return await this.performanceData.find({}).toArray(); return await this.performanceData.find({}).toArray();
} }
} }
@ -482,18 +478,18 @@ export class ModNotes {
} }
async create(guild: string, user: string, note: string | null) { async create(guild: string, user: string, note: string | null) {
console.log("ModNotes create"); // console.log("ModNotes create");
await this.modNotes.updateOne({ guild: guild, user: user }, { $set: { note: note } }, { upsert: true }); await this.modNotes.updateOne({ guild: guild, user: user }, { $set: { note: note } }, { upsert: true });
} }
async read(guild: string, user: string) { async read(guild: string, user: string) {
console.log("ModNotes read"); // console.log("ModNotes read");
const entry = await this.modNotes.findOne({ guild: guild, user: user }); const entry = await this.modNotes.findOne({ guild: guild, user: user });
return entry?.note ?? null; return entry?.note ?? null;
} }
async delete(guild: string) { async delete(guild: string) {
console.log("ModNotes delete"); // console.log("ModNotes delete");
await this.modNotes.deleteMany({ guild: guild }); await this.modNotes.deleteMany({ guild: guild });
} }
} }
@ -509,24 +505,24 @@ export class Premium {
} }
async updateUser(user: string, level: number) { async updateUser(user: string, level: number) {
console.log("Premium updateUser"); // console.log("Premium updateUser");
if(!(await this.userExists(user))) await this.createUser(user, level); if(!(await this.userExists(user))) await this.createUser(user, level);
await this.premium.updateOne({ user: user }, { $set: { level: level } }, { upsert: true }); await this.premium.updateOne({ user: user }, { $set: { level: level } }, { upsert: true });
} }
async userExists(user: string): Promise<boolean> { async userExists(user: string): Promise<boolean> {
console.log("Premium userExists"); // console.log("Premium userExists");
const entry = await this.premium.findOne({ user: user }); const entry = await this.premium.findOne({ user: user });
return entry ? true : false; return entry ? true : false;
} }
async createUser(user: string, level: number) { async createUser(user: string, level: number) {
console.log("Premium createUser"); // console.log("Premium createUser");
await this.premium.insertOne({ user: user, appliesTo: [], level: level }, collectionOptions); await this.premium.insertOne({ user: user, appliesTo: [], level: level }, collectionOptions);
} }
async hasPremium(guild: string): Promise<[boolean, string, number, boolean] | null> { async hasPremium(guild: string): Promise<[boolean, string, number, boolean] | null> {
console.log("Premium hasPremium"); // console.log("Premium hasPremium");
// [Has premium, user giving premium, level, is mod: if given automatically] // [Has premium, user giving premium, level, is mod: if given automatically]
const cached = this.cache.get(guild); const cached = this.cache.get(guild);
if (cached && cached[4].getTime() < Date.now()) return [cached[0], cached[1], cached[2], cached[3]]; if (cached && cached[4].getTime() < Date.now()) return [cached[0], cached[1], cached[2], cached[3]];
@ -566,14 +562,14 @@ export class Premium {
} }
async fetchUser(user: string): Promise<PremiumSchema | null> { async fetchUser(user: string): Promise<PremiumSchema | null> {
console.log("Premium fetchUser"); // console.log("Premium fetchUser");
const entry = await this.premium.findOne({ user: user }); const entry = await this.premium.findOne({ user: user });
if (!entry) return null; if (!entry) return null;
return entry; return entry;
} }
async checkAllPremium(member?: GuildMember) { async checkAllPremium(member?: GuildMember) {
console.log("Premium checkAllPremium"); // console.log("Premium checkAllPremium");
const entries = await this.premium.find({}).toArray(); const entries = await this.premium.find({}).toArray();
if(member) { if(member) {
const entry = entries.find(e => e.user === member.id); const entry = entries.find(e => e.user === member.id);
@ -627,14 +623,14 @@ export class Premium {
} }
async addPremium(user: string, guild: string) { async addPremium(user: string, guild: string) {
console.log("Premium addPremium"); // console.log("Premium addPremium");
const { level } = (await this.fetchUser(user))!; const { level } = (await this.fetchUser(user))!;
this.cache.set(guild, [true, user, level, false, new Date(Date.now() + this.cacheTimeout)]); this.cache.set(guild, [true, user, level, false, new Date(Date.now() + this.cacheTimeout)]);
return this.premium.updateOne({ user: user }, { $addToSet: { appliesTo: guild } }, { upsert: true }); return this.premium.updateOne({ user: user }, { $addToSet: { appliesTo: guild } }, { upsert: true });
} }
removePremium(user: string, guild: string) { removePremium(user: string, guild: string) {
console.log("Premium removePremium"); // console.log("Premium removePremium");
this.cache.set(guild, [false, "", 0, false, new Date(Date.now() + this.cacheTimeout)]); this.cache.set(guild, [false, "", 0, false, new Date(Date.now() + this.cacheTimeout)]);
return this.premium.updateOne({ user: user }, { $pull: { appliesTo: guild } }); return this.premium.updateOne({ user: user }, { $pull: { appliesTo: guild } });
} }
@ -684,7 +680,7 @@ export interface GuildConfig {
clean: { clean: {
channels: string[]; channels: string[];
allowed: { allowed: {
user: string[]; users: string[];
roles: string[]; roles: string[];
} }
} }

Loading…
Cancel
Save