error handling refactor x2

master
Matthew 2022-03-22 12:15:54 -04:00
parent 26102c3bf4
commit c94ff17e2b
No known key found for this signature in database
GPG Key ID: 210AF32ADE3B5C4B
70 changed files with 7616 additions and 5970 deletions

View File

@ -32,6 +32,8 @@
}, },
"dependencies": { "dependencies": {
"@google-cloud/text-to-speech": "^3.4.0", "@google-cloud/text-to-speech": "^3.4.0",
"@sentry/node": "^6.19.1",
"@sentry/tracing": "^6.19.1",
"ari-client": "^2.2.0", "ari-client": "^2.2.0",
"asterisk-manager": "^0.2.0", "asterisk-manager": "^0.2.0",
"auth0": "^2.37.0", "auth0": "^2.37.0",

View File

@ -5,6 +5,8 @@ import pluris from 'pluris';
import mongoose from 'mongoose'; import mongoose from 'mongoose';
import { promises as fs } from 'fs'; import { promises as fs } from 'fs';
import Database from 'cr-db'; import Database from 'cr-db';
import * as Sentry from '@sentry/node';
import * as Tracing from '@sentry/tracing';
import { Collection, Command, InteractionCommand, LocalStorage, Queue, Util, ServerManagement, Event } from '.'; import { Collection, Command, InteractionCommand, LocalStorage, Queue, Util, ServerManagement, Event } from '.';
import { Config } from '../../types'; // eslint-disable-line import { Config } from '../../types'; // eslint-disable-line
@ -40,6 +42,7 @@ export default class Client extends eris.Client {
constructor(token: string, options?: eris.ClientOptions) { constructor(token: string, options?: eris.ClientOptions) {
super(token, options); super(token, options);
this.setupSentry();
this.commands = new Collection<Command>(); this.commands = new Collection<Command>();
this.interactions = new Collection<InteractionCommand>(); this.interactions = new Collection<InteractionCommand>();
this.events = new Collection<Event>(); this.events = new Collection<Event>();
@ -65,6 +68,13 @@ export default class Client extends eris.Client {
} }
public setupSentry() {
Sentry.init({
dsn: 'https://323f6626a7104be7859088750b91abe1@sentry.libraryofcode.org/2',
tracesSampleRate: 0.25,
});
}
public async loadDatabase() { public async loadDatabase() {
mongoose.connect(this.config.mongoDB, { mongoose.connect(this.config.mongoDB, {
minPoolSize: 50, minPoolSize: 50,

View File

@ -45,6 +45,7 @@ export default class Command {
* Determines if the command is enabled or not. * Determines if the command is enabled or not.
*/ */
// eslint-disable-next-line no-use-before-define
public subcommands?: Collection<Command>; public subcommands?: Collection<Command>;
public subcmds?: any[]; public subcmds?: any[];

View File

@ -1,7 +1,7 @@
import { Client } from '.'; import { Client } from '.';
export default class Event { export default class Event {
public client: Client public client: Client;
public event: string; public event: string;

View File

@ -8,7 +8,7 @@ export default class Handler {
public options: { public options: {
available?: boolean, available?: boolean,
} };
constructor(pbx: PBX) { constructor(pbx: PBX) {
this.pbx = pbx; this.pbx = pbx;

View File

@ -7,7 +7,7 @@ type JSONData = [{ key: string, value: any }?];
/** /**
* Persistant local JSON-based storage. * Persistent local JSON-based storage.
* - auto-locking system to prevent corrupted data * - auto-locking system to prevent corrupted data
* - uses gzip compression to keep DB storage space utilization low * - uses gzip compression to keep DB storage space utilization low
* @author Matthew <matthew@staff.libraryofcode.org> * @author Matthew <matthew@staff.libraryofcode.org>

View File

@ -3,31 +3,31 @@
import { EmbedOptions } from 'eris'; import { EmbedOptions } from 'eris';
export default class RichEmbed implements EmbedOptions { export default class RichEmbed implements EmbedOptions {
title?: string title?: string;
type?: string type?: string;
description?: string description?: string;
url?: string url?: string;
timestamp?: string | Date timestamp?: string | Date;
color?: number color?: number;
footer?: { text: string, icon_url?: string, proxy_icon_url?: string} footer?: { text: string, icon_url?: string, proxy_icon_url?: string};
image?: { url?: string, proxy_url?: string, height?: number, width?: number } image?: { url?: string, proxy_url?: string, height?: number, width?: number };
thumbnail?: { url?: string, proxy_url?: string, height?: number, width?: number } thumbnail?: { url?: string, proxy_url?: string, height?: number, width?: number };
video?: { url: string, height?: number, width?: number } video?: { url: string, height?: number, width?: number };
provider?: { name: string, url?: string} provider?: { name: string, url?: string};
author?: { name: string, url?: string, proxy_icon_url?: string, icon_url?: string} author?: { name: string, url?: string, proxy_icon_url?: string, icon_url?: string};
fields?: {name: string, value: string, inline?: boolean}[] fields?: {name: string, value: string, inline?: boolean}[];
constructor(data: EmbedOptions = {}) { constructor(data: EmbedOptions = {}) {
this.title = data.title; this.title = data.title;

View File

@ -6,6 +6,7 @@ import childProcess from 'child_process';
import { promisify } from 'util'; import { promisify } from 'util';
import signale from 'signale'; import signale from 'signale';
import { Member, Message, Guild, PrivateChannel, GroupChannel, Role, AnyGuildChannel, WebhookPayload } from 'eris'; import { Member, Message, Guild, PrivateChannel, GroupChannel, Role, AnyGuildChannel, WebhookPayload } from 'eris';
import * as Sentry from '@sentry/node';
import { Client, Command, Moderation, PBX, Report, RichEmbed } from '.'; import { Client, Command, Moderation, PBX, Report, RichEmbed } from '.';
import { statusMessages as emotes } from '../configs/emotes.json'; import { statusMessages as emotes } from '../configs/emotes.json';
@ -232,24 +233,8 @@ export default class Util {
public async handleError(error: Error, message?: Message, command?: Command, disable = true): Promise<void> { public async handleError(error: Error, message?: Message, command?: Command, disable = true): Promise<void> {
try { try {
Sentry.captureException(error);
this.signale.error(error); this.signale.error(error);
const info: WebhookPayload = { content: `\`\`\`js\n${error.stack || error}\n\`\`\``, embeds: [] };
if (message) {
const embed = new RichEmbed();
embed.setColor('FF0000');
embed.setAuthor(`Error caused by ${message.author.username}#${message.author.discriminator}`, message.author.avatarURL);
embed.setTitle('Message content');
embed.setDescription(message.content);
embed.addField('User', `${message.author.mention} (\`${message.author.id}\`)`, true);
embed.addField('Channel', message.channel.mention, true);
let guild: string;
if (message.channel instanceof PrivateChannel || message.channel instanceof GroupChannel) guild = '@me';
else guild = message.channel.guild.id;
embed.addField('Message link', `[Click here](https://discordapp.com/channels/${guild}/${message.channel.id}/${message.id})`, true);
embed.setTimestamp(new Date(message.timestamp));
info.embeds.push(embed);
}
await this.client.executeWebhook(this.client.config.webhookID, this.client.config.webhookToken, info);
const msg = message ? message.content.slice(this.client.config.prefix.length).trim().split(/ +/g) : []; const msg = message ? message.content.slice(this.client.config.prefix.length).trim().split(/ +/g) : [];
if (command && disable) this.resolveCommand(msg).then((c) => { c.cmd.enabled = false; }); if (command && disable) this.resolveCommand(msg).then((c) => { c.cmd.enabled = false; });
if (message) message.channel.createMessage(`***${this.emojis.ERROR} An unexpected error has occured - please contact a Staff member.${command && disable ? ' This command has been disabled.' : ''}***`); if (message) message.channel.createMessage(`***${this.emojis.ERROR} An unexpected error has occured - please contact a Staff member.${command && disable ? ' This command has been disabled.' : ''}***`);
@ -344,7 +329,6 @@ export default class Util {
} }
public capsFirstLetter(string?: string): string | void { public capsFirstLetter(string?: string): string | void {
if (typeof string !== 'string') return undefined;
return string.substring(0, 1).toUpperCase() + string.substring(1); return string.substring(0, 1).toUpperCase() + string.substring(1);
} }
} }

View File

@ -12,49 +12,45 @@ export default class AddItem extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (args.length < 1) {
if (args.length < 1) { const embed = new RichEmbed();
const embed = new RichEmbed(); embed.setTitle('Whois Data Codes');
embed.setTitle('Whois Data Codes'); embed.addField('Languages', '**Assembly Language:** lang-asm\n**C/C++:** lang-cfam\n**C#:** lang-csharp\n**Go:** lang-go\n**Java:** lang-java\n**JavaScript:** lang-js\n**Kotlin:** lang-kt\n**Python:** lang-py\n**Ruby:** lang-rb\n**Rust:** lang-rs\n**Swift:** lang-swift\n**TypeScript:** lang-ts');
embed.addField('Languages', '**Assembly Language:** lang-asm\n**C/C++:** lang-cfam\n**C#:** lang-csharp\n**Go:** lang-go\n**Java:** lang-java\n**JavaScript:** lang-js\n**Kotlin:** lang-kt\n**Python:** lang-py\n**Ruby:** lang-rb\n**Rust:** lang-rs\n**Swift:** lang-swift\n**TypeScript:** lang-ts'); embed.addField('Operating Systems', '**Arch:** os-arch\n**Debian:** os-deb\n**CentOS:** os-cent\n**Fedora:** os-fedora\n**macOS:** os-mdarwin\n**Manjaro:** os-manjaro\n**RedHat:** os-redhat\n**Ubuntu:** os-ubuntu\n**Windows:** os-win');
embed.addField('Operating Systems', '**Arch:** os-arch\n**Debian:** os-deb\n**CentOS:** os-cent\n**Fedora:** os-fedora\n**macOS:** os-mdarwin\n**Manjaro:** os-manjaro\n**RedHat:** os-redhat\n**Ubuntu:** os-ubuntu\n**Windows:** os-win'); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setFooter(this.client.user.username, this.client.user.avatarURL); embed.setTimestamp();
embed.setTimestamp(); return message.channel.createMessage({ embed });
return message.channel.createMessage({ embed });
}
if (args[0].split('-')[0] === 'os' && ['arch', 'deb', 'cent', 'fedora', 'manjaro', 'mdarwin', 'redhat', 'ubuntu', 'win'].includes(args[0].split('-')[1])) {
const account = await this.client.db.mongo.Member.findOne({ userID: message.member.id });
if (!account) {
const newAccount = new this.client.db.mongo.Member({
userID: message.member.id,
additional: {
operatingSystems: [args[0].split('-')[1]],
},
});
await newAccount.save();
} else {
await account.updateOne({ $addToSet: { 'additional.operatingSystems': args[0].split('-')[1] } });
}
return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added OS code ${args[0]} to profile.***`);
}
if (args[0].split('-')[0] === 'lang' && ['js', 'py', 'rb', 'ts', 'rs', 'go', 'cfam', 'csharp', 'swift', 'java', 'kt', 'asm'].includes(args[0].split('-')[1])) {
const account = await this.client.db.mongo.Member.findOne({ userID: message.member.id });
if (!account) {
const newAccount = new this.client.db.mongo.Member({
userID: message.member.id,
additional: {
langs: [args[0].split('-')[1]],
},
});
await newAccount.save();
} else {
await account.updateOne({ $addToSet: { 'additional.langs': args[0].split('-')[1] } });
}
return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added language code ${args[0]} to profile.***`);
}
return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Invalid data code.***`);
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
if (args[0].split('-')[0] === 'os' && ['arch', 'deb', 'cent', 'fedora', 'manjaro', 'mdarwin', 'redhat', 'ubuntu', 'win'].includes(args[0].split('-')[1])) {
const account = await this.client.db.mongo.Member.findOne({ userID: message.member.id });
if (!account) {
const newAccount = new this.client.db.mongo.Member({
userID: message.member.id,
additional: {
operatingSystems: [args[0].split('-')[1]],
},
});
await newAccount.save();
} else {
await account.updateOne({ $addToSet: { 'additional.operatingSystems': args[0].split('-')[1] } });
}
return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added OS code ${args[0]} to profile.***`);
}
if (args[0].split('-')[0] === 'lang' && ['js', 'py', 'rb', 'ts', 'rs', 'go', 'cfam', 'csharp', 'swift', 'java', 'kt', 'asm'].includes(args[0].split('-')[1])) {
const account = await this.client.db.mongo.Member.findOne({ userID: message.member.id });
if (!account) {
const newAccount = new this.client.db.mongo.Member({
userID: message.member.id,
additional: {
langs: [args[0].split('-')[1]],
},
});
await newAccount.save();
} else {
await account.updateOne({ $addToSet: { 'additional.langs': args[0].split('-')[1] } });
}
return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added language code ${args[0]} to profile.***`);
}
return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Invalid data code.***`);
} }
} }

View File

@ -15,21 +15,17 @@ export default class AddMerchant extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[1]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[1]) return this.client.commands.get('help').run(message, [this.name]); if ((Number(args[0]) !== 0) && (Number(args[0]) !== 1)) return this.error(message.channel, 'Invalid permissions.');
if ((Number(args[0]) !== 0) && (Number(args[0]) !== 1)) return this.error(message.channel, 'Invalid permissions.'); if ((Number(args[1]) !== 0) && (Number(args[1]) !== 1)) return this.error(message.channel, 'Invalid permissions.');
if ((Number(args[1]) !== 0) && (Number(args[1]) !== 1)) return this.error(message.channel, 'Invalid permissions.'); const key = randomBytes(20).toString('hex');
const key = randomBytes(20).toString('hex'); const merchant = await (new this.client.db.mongo.Merchant({
const merchant = await (new this.client.db.mongo.Merchant({ name: args.slice(2).join(' '),
name: args.slice(2).join(' '), privileged: Number(args[0]),
privileged: Number(args[0]), type: Number(args[1]),
type: Number(args[1]), key,
key, pulls: [],
pulls: [], })).save();
})).save(); return this.success(message.channel, `Created merchant (${merchant._id}). \`${args.slice(2).join(' ')}\`\n\n\`${key}\``);
return this.success(message.channel, `Created merchant (${merchant._id}). \`${args.slice(2).join(' ')}\`\n\n\`${key}\``);
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -13,28 +13,24 @@ export default class AddNote extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0] || args.length < 1) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0] || args.length < 1) return this.client.commands.get('help').run(message, [this.name]); let user = this.client.util.resolveMember(args[0], this.mainGuild)?.user;
let user = this.client.util.resolveMember(args[0], this.mainGuild)?.user; if (!user) user = await this.client.getRESTUser(args[0]);
if (!user) user = await this.client.getRESTUser(args[0]); if (!user) return this.error(message.channel, 'The member you specified could not be found.');
if (!user) return this.error(message.channel, 'The member you specified could not be found.');
const note: { userID?: string, staffID: string, date: Date, category?: string, text?: string } = { const note: { userID?: string, staffID: string, date: Date, category?: string, text?: string } = {
userID: user.id, userID: user.id,
date: new Date(), date: new Date(),
staffID: message.author.id, staffID: message.author.id,
}; };
if (args[args.length - 1] !== 'edu' && args[args.length - 1] !== 'comm' && args[args.length - 1] !== 'cs') { if (args[args.length - 1] !== 'edu' && args[args.length - 1] !== 'comm' && args[args.length - 1] !== 'cs') {
note.category = ''; note.category = '';
note.text = args.slice(1).join(' '); note.text = args.slice(1).join(' ');
} else { } else {
note.category = args[args.length - 1]; note.category = args[args.length - 1];
note.text = args.slice(0, args.length - 1).join(' '); note.text = args.slice(0, args.length - 1).join(' ');
}
const saved = await (new this.client.db.mongo.Note(note).save());
return this.success(message.channel, `Successfully created Note # \`${saved._id}\`.`);
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
const saved = await (new this.client.db.mongo.Note(note).save());
return this.success(message.channel, `Successfully created Note # \`${saved._id}\`.`);
} }
} }

View File

@ -14,20 +14,16 @@ export default class AddPromoCode extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
try { try {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); const pcd = await this.client.stripe.promotionCodes.retrieve(args[0]);
try { const promo = new this.client.db.mongo.Promo({
const pcd = await this.client.stripe.promotionCodes.retrieve(args[0]); code: pcd.code,
const promo = new this.client.db.mongo.Promo({ pID: args[0],
code: pcd.code, });
pID: args[0], await promo.save();
});
await promo.save();
} catch (err) {
return this.error(message.channel, 'Promotional API ID doesn\'t exist.');
}
} catch (err) { } catch (err) {
return this.client.util.handleError(err, message, this); return this.error(message.channel, 'Promotional API ID doesn\'t exist.');
} }
} }
} }

View File

@ -13,33 +13,29 @@ export default class AddRank extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); if (!args[1]) return this.error(message.channel, 'Permissions are required.');
if (!args[1]) return this.error(message.channel, 'Permissions are required.'); if (!args[2]) return this.error(message.channel, 'A description is required');
if (!args[2]) return this.error(message.channel, 'A description is required'); const role = this.client.util.resolveRole(args[0], this.mainGuild);
const role = this.client.util.resolveRole(args[0], this.mainGuild); if (!role) return this.error(message.channel, 'The role you specified doesn\'t appear to exist.');
if (!role) return this.error(message.channel, 'The role you specified doesn\'t appear to exist.');
const check = await this.client.db.mongo.Rank.findOne({ roleID: role.id }); const check = await this.client.db.mongo.Rank.findOne({ roleID: role.id });
if (check) return this.error(message.channel, 'This role is already self-assignable.'); if (check) return this.error(message.channel, 'This role is already self-assignable.');
let permissions: string[]; let permissions: string[];
if (args[1] === '0') { if (args[1] === '0') {
permissions = ['0']; permissions = ['0'];
} else { } else {
permissions = args[1].split(':'); permissions = args[1].split(':');
}
const entry = new this.client.db.mongo.Rank({
name: role.name,
roleID: role.id,
permissions,
description: args.slice(2).join(' '),
});
await entry.save();
return this.success(message.channel, `Role ${role.name} is now self-assignable.`);
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
const entry = new this.client.db.mongo.Rank({
name: role.name,
roleID: role.id,
permissions,
description: args.slice(2).join(' '),
});
await entry.save();
return this.success(message.channel, `Role ${role.name} is now self-assignable.`);
} }
} }

View File

@ -13,26 +13,22 @@ export default class AddRedirect extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
const check = await this.client.db.mongo.Redirect.findOne({ key: args[1].toLowerCase() });
if (check) return this.error(message.channel, `Redirect key ${args[1].toLowerCase()} already exists. Linked to: ${check.to}`);
try { try {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); const test = new URL(args[0]);
const check = await this.client.db.mongo.Redirect.findOne({ key: args[1].toLowerCase() }); if (test.protocol !== 'https:') return this.error(message.channel, 'Protocol must be HTTPS.');
if (check) return this.error(message.channel, `Redirect key ${args[1].toLowerCase()} already exists. Linked to: ${check.to}`); } catch {
try { return this.error(message.channel, 'This doesn\'t appear to be a valid URL.');
const test = new URL(args[0]);
if (test.protocol !== 'https:') return this.error(message.channel, 'Protocol must be HTTPS.');
} catch {
return this.error(message.channel, 'This doesn\'t appear to be a valid URL.');
}
if ((/^[a-zA-Z0-9]+$/gi.test(args[1].toLowerCase().replace('-', '').trim()) === false) || args[1].toLowerCase().length > 15) return this.error(message.channel, 'Invalid key. The key must be alphanumeric and less than 16 characters.');
const redirect = new this.client.db.mongo.Redirect({
key: args[1].toLowerCase(),
to: args[0],
visitedCount: 0,
});
await redirect.save();
return this.success(message.channel, `Redirect https://loc.sh/${args[1].toLowerCase()} -> ${args[0]} is now active.`);
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
if ((/^[a-zA-Z0-9]+$/gi.test(args[1].toLowerCase().replace('-', '').trim()) === false) || args[1].toLowerCase().length > 15) return this.error(message.channel, 'Invalid key. The key must be alphanumeric and less than 16 characters.');
const redirect = new this.client.db.mongo.Redirect({
key: args[1].toLowerCase(),
to: args[0],
visitedCount: 0,
});
await redirect.save();
return this.success(message.channel, `Redirect https://loc.sh/${args[1].toLowerCase()} -> ${args[0]} is now active.`);
} }
} }

View File

@ -177,38 +177,34 @@ export default class Apply extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0] || args[0] === 'full') {
if (!args[0] || args[0] === 'full') { const embed = new RichEmbed();
const embed = new RichEmbed(); embed.setTitle('Instant Application Service [IAS]');
embed.setTitle('Instant Application Service [IAS]'); embed.setColor('#556cd6');
embed.setColor('#556cd6'); if (args[0] !== 'full') {
if (args[0] !== 'full') { embed.setDescription(`*These applications are specifically targeted to you based on validation conditions. Run \`${this.client.config.prefix}apply full\` for a full list of all applications.*`);
embed.setDescription(`*These applications are specifically targeted to you based on validation conditions. Run \`${this.client.config.prefix}apply full\` for a full list of all applications.*`); embed.setThumbnail(message.member.avatarURL);
embed.setThumbnail(message.member.avatarURL); embed.setAuthor(message.member.username, message.member.avatarURL);
embed.setAuthor(message.member.username, message.member.avatarURL);
}
for (const service of this.services) {
// eslint-disable-next-line no-await-in-loop
const test = await service[1].validation(message.member);
if (!test && args[0] !== 'full') continue;
embed.addField(service[0], `**Description**: ${service[1].description}\n**Inquiry Type:** ${service[1].type}\n\n${service[1].saaOnly ? '*This application can only be ran as a Staff-Assisted Application and cannot be ran automatically. Please DM <@457750238208327691> to apply.*' : `*Run \`${this.client.config.prefix}apply ${service[0]}\` to apply.*`}`);
}
if (embed.fields?.length <= 0) embed.setDescription(`*We have no offers for you at this time. To see a full list of offers, please run \`${this.client.config.prefix}apply full\`.*`);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
return message.channel.createMessage({ embed });
} }
for (const service of this.services) {
if (!this.services.has(args[0])) return this.error(message.channel, 'Invalid service/product name.'); // eslint-disable-next-line no-await-in-loop
const service = this.services.get(args[0]); const test = await service[1].validation(message.member);
const test = await this.services.get(args[0]).validation(message.member); if (!test && args[0] !== 'full') continue;
if (!test) return this.error(message.channel, 'A condition exists which prevents you from applying, please try again later.'); embed.addField(service[0], `**Description**: ${service[1].description}\n**Inquiry Type:** ${service[1].type}\n\n${service[1].saaOnly ? '*This application can only be ran as a Staff-Assisted Application and cannot be ran automatically. Please DM <@457750238208327691> to apply.*' : `*Run \`${this.client.config.prefix}apply ${service[0]}\` to apply.*`}`);
if (service.saaOnly) return this.error(message.channel, 'This application can only be ran as a Staff-Assisted Application and cannot be ran automatically. Please DM <@457750238208327691> to apply.'); }
const msg = await this.loading(message.channel, 'Thank you for submitting an application. We are currently processing it, you will receive a DM with a decision.'); if (embed.fields?.length <= 0) embed.setDescription(`*We have no offers for you at this time. To see a full list of offers, please run \`${this.client.config.prefix}apply full\`.*`);
return await this.client.queue.processApplication({ channelID: message.channel.id, guildID: this.mainGuild.id, messageID: msg.id }, service.url, message.author.id, service.func ? service.func.toString() : undefined); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
} catch (err) { embed.setTimestamp();
return this.client.util.handleError(err, message, this); return message.channel.createMessage({ embed });
} }
if (!this.services.has(args[0])) return this.error(message.channel, 'Invalid service/product name.');
const service = this.services.get(args[0]);
const test = await this.services.get(args[0]).validation(message.member);
if (!test) return this.error(message.channel, 'A condition exists which prevents you from applying, please try again later.');
if (service.saaOnly) return this.error(message.channel, 'This application can only be ran as a Staff-Assisted Application and cannot be ran automatically. Please DM <@457750238208327691> to apply.');
const msg = await this.loading(message.channel, 'Thank you for submitting an application. We are currently processing it, you will receive a DM with a decision.');
return this.client.queue.processApplication({ channelID: message.channel.id, guildID: this.mainGuild.id, messageID: msg.id }, service.url, message.author.id, service.func ? service.func.toString() : undefined);
} }
public static async apply(client: Client, url: string, userID: string) { public static async apply(client: Client, url: string, userID: string) {

View File

@ -14,40 +14,36 @@ export default class Ban extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); const member = this.client.util.resolveMember(args[0], this.mainGuild);
const member = this.client.util.resolveMember(args[0], this.mainGuild); let user: User;
let user: User; if (!member) {
if (!member) {
try {
user = await this.client.getRESTUser(args[0]);
} catch {
return this.error(message.channel, 'Cannot find user.');
}
} else {
user = member.user;
}
try { try {
await this.mainGuild.getBan(args[0]); user = await this.client.getRESTUser(args[0]);
return this.error(message.channel, 'This user is already banned.'); } catch {
} catch {} // eslint-disable-line no-empty return this.error(message.channel, 'Cannot find user.');
if (member && !this.client.util.moderation.checkPermissions(member, message.member)) return this.error(message.channel, 'Permission Denied.');
message.delete();
let momentMilliseconds: number;
let reason: string;
if (args.length > 1) {
const lockLength = args[1].match(/[a-z]+|[^a-z]+/gi);
const length = Number(lockLength[0]);
const unit = lockLength[1] as unitOfTime.Base;
momentMilliseconds = moment.duration(length, unit).asMilliseconds();
reason = momentMilliseconds ? args.slice(2).join(' ') : args.slice(1).join(' ');
if (reason.length > 512) return this.error(message.channel, 'Ban reasons cannot be longer than 512 characters.');
} }
await this.client.util.moderation.ban(user, message.member, momentMilliseconds, reason); } else {
return this.success(message.channel, `${user.username}#${user.discriminator} has been banned.`); user = member.user;
} catch (err) {
return this.client.util.handleError(err, message, this, false);
} }
try {
await this.mainGuild.getBan(args[0]);
return this.error(message.channel, 'This user is already banned.');
} catch {} // eslint-disable-line no-empty
if (member && !this.client.util.moderation.checkPermissions(member, message.member)) return this.error(message.channel, 'Permission Denied.');
message.delete();
let momentMilliseconds: number;
let reason: string;
if (args.length > 1) {
const lockLength = args[1].match(/[a-z]+|[^a-z]+/gi);
const length = Number(lockLength[0]);
const unit = lockLength[1] as unitOfTime.Base;
momentMilliseconds = moment.duration(length, unit).asMilliseconds();
reason = momentMilliseconds ? args.slice(2).join(' ') : args.slice(1).join(' ');
if (reason.length > 512) return this.error(message.channel, 'Ban reasons cannot be longer than 512 characters.');
}
await this.client.util.moderation.ban(user, message.member, momentMilliseconds, reason);
return this.success(message.channel, `${user.username}#${user.discriminator} has been banned.`);
} }
} }

View File

@ -19,38 +19,34 @@ export default class Billing extends Command {
} }
public async run(message: Message) { public async run(message: Message) {
try { const response = <{
const response = <{ found: boolean,
found: boolean, emailAddress?: string,
emailAddress?: string, tier?: number,
tier?: number, supportKey?: string,
supportKey?: string, }> (await axios.get(`https://api.cloud.libraryofcode.org/wh/info?id=${message.author.id}&authorization=${this.client.config.internalKey}`)).data;
}> (await axios.get(`https://api.cloud.libraryofcode.org/wh/info?id=${message.author.id}&authorization=${this.client.config.internalKey}`)).data; if (!response.found) return this.error(message.channel, 'CS Account not found.');
if (!response.found) return this.error(message.channel, 'CS Account not found.');
const portalKey = randomBytes(50).toString('hex'); const portalKey = randomBytes(50).toString('hex');
const uid = uuid(); const uid = uuid();
const redirect = new this.client.db.mongo.Redirect({ const redirect = new this.client.db.mongo.Redirect({
key: uid, key: uid,
to: `https://loc.sh/dash?q=${portalKey}`, to: `https://loc.sh/dash?q=${portalKey}`,
}); });
const portal = new this.client.db.mongo.CustomerPortal({ const portal = new this.client.db.mongo.CustomerPortal({
key: portalKey, key: portalKey,
username: message.author.username, username: message.author.username,
userID: message.author.id, userID: message.author.id,
emailAddress: response.emailAddress, emailAddress: response.emailAddress,
expiresOn: moment().add(5, 'minutes').toDate(), expiresOn: moment().add(5, 'minutes').toDate(),
used: false, used: false,
}); });
await portal.save(); await portal.save();
await redirect.save(); await redirect.save();
const chan = await this.client.getDMChannel(message.author.id); const chan = await this.client.getDMChannel(message.author.id);
await chan.createMessage(`__***Billing Account Portal***__\nClick here: https://loc.sh/${uid}\n\nYou will be redirected to your billing portal, please note the link expires after 5 minutes.`) await chan.createMessage(`__***Billing Account Portal***__\nClick here: https://loc.sh/${uid}\n\nYou will be redirected to your billing portal, please note the link expires after 5 minutes.`)
.catch(() => { return this.error(message.channel, 'Failed to privately send your billing portal link to you.'); }); .catch(() => this.error(message.channel, 'Failed to privately send your billing portal link to you.'));
return await this.success(message.channel, 'Your Billing Portal information has been DMed to you.'); return this.success(message.channel, 'Your Billing Portal information has been DMed to you.');
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -16,47 +16,43 @@ export default class Billing_T3 extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { await message.delete();
await message.delete(); const response = <{
const response = <{ found: boolean,
found: boolean, emailAddress?: string,
emailAddress?: string, tier?: number,
tier?: number, supportKey?: string,
supportKey?: string, }>(await axios.get(`https://api.cloud.libraryofcode.org/wh/info?id=${message.author.id}&authorization=${this.client.config.internalKey}`)).data;
}>(await axios.get(`https://api.cloud.libraryofcode.org/wh/info?id=${message.author.id}&authorization=${this.client.config.internalKey}`)).data; if (!response.found) return this.error(message.channel, 'CS Account not found.');
if (!response.found) return this.error(message.channel, 'CS Account not found.');
const customer = await this.client.db.mongo.Customer.findOne({ userID: message.author.id }); const customer = await this.client.db.mongo.Customer.findOne({ userID: message.author.id });
if (!customer) return this.error(message.channel, `You do not have a Customer Account. Please run \`${this.client.config.prefix}billing\`, once you visit the Billing Portal via the URL given to you, please try again.`); if (!customer) return this.error(message.channel, `You do not have a Customer Account. Please run \`${this.client.config.prefix}billing\`, once you visit the Billing Portal via the URL given to you, please try again.`);
let promoCode; let promoCode;
if (args[0]) { if (args[0]) {
promoCode = await this.client.db.mongo.Promo.findOne({ code: args[0].toUpperCase() }); promoCode = await this.client.db.mongo.Promo.findOne({ code: args[0].toUpperCase() });
}
let subscription: Stripe.Response<Stripe.Subscription>;
try {
subscription = await this.client.stripe.subscriptions.create({
customer: customer.cusID,
payment_behavior: 'allow_incomplete',
items: [{ price: 'price_1H8e6ODatwI1hQ4WFVvX6Nda' }],
days_until_due: 1,
collection_method: 'send_invoice',
default_tax_rates: ['txr_1HlAadDatwI1hQ4WRHu14S2I'],
promotion_code: promoCode ? promoCode.id : undefined,
});
} catch (err) {
return this.error(message.channel, `Error creating subscription.\n\n${err}`);
}
await this.client.stripe.invoices.finalizeInvoice(subscription.latest_invoice.toString());
const invoice = await this.client.stripe.invoices.retrieve(subscription.latest_invoice.toString());
const chan = await this.client.getDMChannel(message.author.id);
await chan.createMessage(`__**Invoice for New Subscription**__\n${invoice.hosted_invoice_url}\n\n*Please click on the link above to pay for your subscription.*`);
return this.success(message.channel, 'Transaction processed.');
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
let subscription: Stripe.Response<Stripe.Subscription>;
try {
subscription = await this.client.stripe.subscriptions.create({
customer: customer.cusID,
payment_behavior: 'allow_incomplete',
items: [{ price: 'price_1H8e6ODatwI1hQ4WFVvX6Nda' }],
days_until_due: 1,
collection_method: 'send_invoice',
default_tax_rates: ['txr_1HlAadDatwI1hQ4WRHu14S2I'],
promotion_code: promoCode ? promoCode.id : undefined,
});
} catch (err) {
return this.error(message.channel, `Error creating subscription.\n\n${err}`);
}
await this.client.stripe.invoices.finalizeInvoice(subscription.latest_invoice.toString());
const invoice = await this.client.stripe.invoices.retrieve(subscription.latest_invoice.toString());
const chan = await this.client.getDMChannel(message.author.id);
await chan.createMessage(`__**Invoice for New Subscription**__\n${invoice.hosted_invoice_url}\n\n*Please click on the link above to pay for your subscription.*`);
return this.success(message.channel, 'Transaction processed.');
} }
} }

View File

@ -16,37 +16,33 @@ export default class Callback extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); if (message.channel.type === 0) await message.delete();
if (message.channel.type === 0) await message.delete(); const member = this.mainGuild.members.get(message.author.id);
const member = this.mainGuild.members.get(message.author.id); if (!member) return this.error(message.channel, 'Unable to fetch member.');
if (!member) return this.error(message.channel, 'Unable to fetch member.'); const phone = new PhoneNumber(args.join(' '), 'US');
const phone = new PhoneNumber(args.join(' '), 'US'); if (!phone.isValid()) return this.error(message.channel, 'The number you have entered is invalid.');
if (!phone.isValid()) return this.error(message.channel, 'The number you have entered is invalid.'); const embed = new RichEmbed();
const embed = new RichEmbed(); embed.setTitle('Callback Request');
embed.setTitle('Callback Request'); embed.setDescription('Please dial `9` first to reach an the external trunk. For example, to dial 202-750-2585 you would dial 92027502585 on your device.\n\n*Please react with <:modSuccess:578750988907970567> on this message if you are taking the call.*');
embed.setDescription('Please dial `9` first to reach an the external trunk. For example, to dial 202-750-2585 you would dial 92027502585 on your device.\n\n*Please react with <:modSuccess:578750988907970567> on this message if you are taking the call.*'); embed.addField('Member', `${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`, true);
embed.addField('Member', `${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`, true); embed.addField('Phone Number', phone.getNumber('national'), true);
embed.addField('Phone Number', phone.getNumber('national'), true); embed.addField('Phone Number Type', phone.getType(), true);
embed.addField('Phone Number Type', phone.getType(), true); const communityReport = await this.client.db.mongo.Score.findOne({ userID: message.author.id }).lean().exec();
const communityReport = await this.client.db.mongo.Score.findOne({ userID: message.author.id }).lean().exec(); if (communityReport) {
if (communityReport) { await this.client.report.createInquiry(member.user.id, 'Library of Code sp-us | VOIP/PBX Member Support SVCS', 1);
await this.client.report.createInquiry(member.user.id, 'Library of Code sp-us | VOIP/PBX Member Support SVCS', 1); embed.addField('PIN', `${communityReport.pin[0]}-${communityReport.pin[1]}-${communityReport.pin[2]}`, true);
embed.addField('PIN', `${communityReport.pin[0]}-${communityReport.pin[1]}-${communityReport.pin[2]}`, true);
}
try {
const d = await axios.get(`https://api.cloud.libraryofcode.org/wh/info/?id=${message.author.id}&authorization=${this.client.config.internalKey}`);
embed.addField('Email Address', d.data.emailAddress, true);
embed.addField('Support Key', d.data.supportKey, true);
} catch {
this.client.util.signale.warn('No CS Account found for user.');
}
const chan = <TextChannel> this.mainGuild.channels.get('780513128240382002');
const msg = await chan.createMessage({ content: '<@&780519428873781298>', embed });
await msg.addReaction('modSuccess:578750988907970567');
return message.channel.createMessage('__**Callback Request**__\nYour callback request has been sent to our agents, you should receive a callback within 1-24 hours from the date of this request. The number you will be called from is listed below.\n\n**Callback Number:** +1 202-750-2585\n**Callback Region:** Washington, D.C., United States\n\n\n*Your number is never stored on our systems at any time, as soon as your call is taken by an agent your number is deleted from notification channels.*');
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
try {
const d = await axios.get(`https://api.cloud.libraryofcode.org/wh/info/?id=${message.author.id}&authorization=${this.client.config.internalKey}`);
embed.addField('Email Address', d.data.emailAddress, true);
embed.addField('Support Key', d.data.supportKey, true);
} catch {
this.client.util.signale.warn('No CS Account found for user.');
}
const chan = <TextChannel> this.mainGuild.channels.get('780513128240382002');
const msg = await chan.createMessage({ content: '<@&780519428873781298>', embed });
await msg.addReaction('modSuccess:578750988907970567');
return message.channel.createMessage('__**Callback Request**__\nYour callback request has been sent to our agents, you should receive a callback within 1-24 hours from the date of this request. The number you will be called from is listed below.\n\n**Callback Number:** +1 202-750-2585\n**Callback Region:** Washington, D.C., United States\n\n\n*Your number is never stored on our systems at any time, as soon as your call is taken by an agent your number is deleted from notification channels.*');
} }
} }

View File

@ -12,35 +12,31 @@ export default class DelItem extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (args.length < 1) {
if (args.length < 1) { const embed = new RichEmbed();
const embed = new RichEmbed(); embed.setTitle('Whois Data Codes');
embed.setTitle('Whois Data Codes'); embed.addField('Languages', '**Assembly Language:** lang-asm\n**C/C++:** lang-cfam\n**C#:** lang-csharp\n**Go:** lang-go\n**Java:** lang-java\n**JavaScript:** lang-js\n**Kotlin:** lang-kt\n**Python:** lang-py\n**Ruby:** lang-rb\n**Rust:** lang-rs\n**Swift:** lang-swift\n**TypeScript:** lang-ts');
embed.addField('Languages', '**Assembly Language:** lang-asm\n**C/C++:** lang-cfam\n**C#:** lang-csharp\n**Go:** lang-go\n**Java:** lang-java\n**JavaScript:** lang-js\n**Kotlin:** lang-kt\n**Python:** lang-py\n**Ruby:** lang-rb\n**Rust:** lang-rs\n**Swift:** lang-swift\n**TypeScript:** lang-ts'); embed.addField('Operating Systems', '**Arch:** os-arch\n**Debian:** os-deb\n**CentOS:** os-cent\n**Fedora:** os-fedora\n**macOS:** os-mdarwin\n**Manjaro:** os-manjaro\n**RedHat:** os-redhat\n**Ubuntu:** os-ubuntu\n**Windows:** os-win');
embed.addField('Operating Systems', '**Arch:** os-arch\n**Debian:** os-deb\n**CentOS:** os-cent\n**Fedora:** os-fedora\n**macOS:** os-mdarwin\n**Manjaro:** os-manjaro\n**RedHat:** os-redhat\n**Ubuntu:** os-ubuntu\n**Windows:** os-win'); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setFooter(this.client.user.username, this.client.user.avatarURL); embed.setTimestamp();
embed.setTimestamp(); return message.channel.createMessage({ embed });
return message.channel.createMessage({ embed });
}
if (args[0].split('-')[0] === 'os' && ['arch', 'deb', 'cent', 'fedora', 'manjaro', 'mdarwin', 'redhat', 'ubuntu', 'win'].includes(args[0].split('-')[1])) {
const account = await this.client.db.mongo.Member.findOne({ userID: message.member.id });
if (account?.additional.operatingSystems.length < 1) {
return message.channel.createMessage(`***${this.client.util.emojis.ERROR} You don't have any operating systems to remove.***`);
}
await account.updateOne({ $pull: { 'additional.operatingSystems': args[0].split('-')[1] } });
return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Removed OS code ${args[0]} from profile.***`);
}
if (args[0].split('-')[0] === 'lang' && ['js', 'py', 'rb', 'ts', 'rs', 'go', 'cfam', 'csharp', 'swift', 'java', 'kt', 'asm'].includes(args[0].split('-')[1])) {
const account = await this.client.db.mongo.Member.findOne({ userID: message.member.id });
if (account?.additional.langs.length < 1) {
return message.channel.createMessage(`***${this.client.util.emojis.ERROR} You don't have any languages to remove.***`);
}
await account.updateOne({ $pull: { 'additional.langs': args[0].split('-')[1] } });
return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Removed language code ${args[0]} from profile.***`);
}
return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Invalid data code.***`);
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
if (args[0].split('-')[0] === 'os' && ['arch', 'deb', 'cent', 'fedora', 'manjaro', 'mdarwin', 'redhat', 'ubuntu', 'win'].includes(args[0].split('-')[1])) {
const account = await this.client.db.mongo.Member.findOne({ userID: message.member.id });
if (account?.additional.operatingSystems.length < 1) {
return message.channel.createMessage(`***${this.client.util.emojis.ERROR} You don't have any operating systems to remove.***`);
}
await account.updateOne({ $pull: { 'additional.operatingSystems': args[0].split('-')[1] } });
return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Removed OS code ${args[0]} from profile.***`);
}
if (args[0].split('-')[0] === 'lang' && ['js', 'py', 'rb', 'ts', 'rs', 'go', 'cfam', 'csharp', 'swift', 'java', 'kt', 'asm'].includes(args[0].split('-')[1])) {
const account = await this.client.db.mongo.Member.findOne({ userID: message.member.id });
if (account?.additional.langs.length < 1) {
return message.channel.createMessage(`***${this.client.util.emojis.ERROR} You don't have any languages to remove.***`);
}
await account.updateOne({ $pull: { 'additional.langs': args[0].split('-')[1] } });
return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Removed language code ${args[0]} from profile.***`);
}
return message.channel.createMessage(`***${this.client.util.emojis.ERROR} Invalid data code.***`);
} }
} }

View File

@ -14,13 +14,9 @@ export default class DelMerchant extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); const merchant = await this.client.db.mongo.Merchant.findOne({ key: args[0] });
const merchant = await this.client.db.mongo.Merchant.findOne({ key: args[0] }); if (!merchant) return this.error(message.channel, 'Merchant specified does not exist.');
if (!merchant) return this.error(message.channel, 'Merchant specified does not exist.'); return this.success(message.channel, `Deleted merchant \`${merchant._id}\`.`);
return this.success(message.channel, `Deleted merchant \`${merchant._id}\`.`);
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -13,14 +13,10 @@ export default class DelNote extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); const note = await this.client.db.mongo.Note.findOne({ _id: args[0] }).lean().exec().catch(() => {});
const note = await this.client.db.mongo.Note.findOne({ _id: args[0] }).lean().exec().catch(() => {}); if (!note) return this.error(message.channel, 'Could not locate that note.');
if (!note) return this.error(message.channel, 'Could not locate that note.'); await this.client.db.mongo.Note.deleteOne({ _id: note._id });
await this.client.db.mongo.Note.deleteOne({ _id: note._id }); return this.success(message.channel, `Note # \`${note._id}\` has been deleted.`);
return this.success(message.channel, `Note # \`${note._id}\` has been deleted.`);
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -14,16 +14,12 @@ export default class DeletePromoCode extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
try { try {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); await this.client.stripe.promotionCodes.retrieve(args[0]);
try { await this.client.db.mongo.Promo.deleteOne({ pID: args[0] }).lean().exec();
await this.client.stripe.promotionCodes.retrieve(args[0]);
await this.client.db.mongo.Promo.deleteOne({ pID: args[0] }).lean().exec();
} catch (err) {
return this.error(message.channel, 'Promotional API ID doesn\'t exist.');
}
} catch (err) { } catch (err) {
return this.client.util.handleError(err, message, this); return this.error(message.channel, 'Promotional API ID doesn\'t exist.');
} }
} }
} }

View File

@ -13,18 +13,14 @@ export default class DelRank extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); const role = this.client.util.resolveRole(args[0], this.mainGuild);
const role = this.client.util.resolveRole(args[0], this.mainGuild); if (!role) return this.error(message.channel, 'The role you specified doesn\'t appear to exist.');
if (!role) return this.error(message.channel, 'The role you specified doesn\'t appear to exist.');
const check = await this.client.db.mongo.Rank.findOne({ roleID: role.id }); const check = await this.client.db.mongo.Rank.findOne({ roleID: role.id });
if (!check) return this.error(message.channel, 'The entry doesn\'t appear to exist.'); if (!check) return this.error(message.channel, 'The entry doesn\'t appear to exist.');
await this.client.db.mongo.Rank.deleteOne({ roleID: role.id }); await this.client.db.mongo.Rank.deleteOne({ roleID: role.id });
return this.success(message.channel, `Role ${role.name} is no longer self-assignable.`); return this.success(message.channel, `Role ${role.name} is no longer self-assignable.`);
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -13,14 +13,10 @@ export default class DelRedirect extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); const check = await this.client.db.mongo.Redirect.findOne({ key: args[0].toLowerCase() });
const check = await this.client.db.mongo.Redirect.findOne({ key: args[0].toLowerCase() }); if (!check) return this.error(message.channel, `Redirect key ${args[0].toLowerCase()} doesn't exist.`);
if (!check) return this.error(message.channel, `Redirect key ${args[0].toLowerCase()} doesn't exist.`); await this.client.db.mongo.Redirect.deleteOne({ key: args[0].toLowerCase() });
await this.client.db.mongo.Redirect.deleteOne({ key: args[0].toLowerCase() }); return this.success(message.channel, `Deleted redirect https://loc.sh/${args[0].toLowerCase()}.`);
return this.success(message.channel, `Deleted redirect https://loc.sh/${args[0].toLowerCase()}.`);
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -14,24 +14,20 @@ export default class DJS extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
let res: AxiosResponse<EmbedOptions>;
try { try {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); res = await axios.get(`https://djsdocs.sorta.moe/v2/embed?src=master&q=${args[0]}`);
let res: AxiosResponse<EmbedOptions>;
try {
res = await axios.get(`https://djsdocs.sorta.moe/v2/embed?src=master&q=${args[0]}`);
} catch (err) {
return this.error(message.channel, 'Please try again later, something unexpected happened.');
}
if (!res.data) return this.error(message.channel, 'Could not find information. Try something else.');
const embed = new RichEmbed(res.data);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
return message.channel.createMessage({ embed });
} catch (err) { } catch (err) {
return this.client.util.handleError(err, message, this); return this.error(message.channel, 'Please try again later, something unexpected happened.');
} }
if (!res.data) return this.error(message.channel, 'Could not find information. Try something else.');
const embed = new RichEmbed(res.data);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
return message.channel.createMessage({ embed });
} }
} }

View File

@ -14,20 +14,16 @@ export default class Eris extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
let res: AxiosResponse<{embed: EmbedOptions}>;
try { try {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); res = await axios.get('https://erisdocs.cloud.libraryofcode.org/docs', { params: { search: args[0] } });
let res: AxiosResponse<{embed: EmbedOptions}>;
try {
res = await axios.get('https://erisdocs.cloud.libraryofcode.org/docs', { params: { search: args[0] } });
} catch (err) {
if (err.code === 404) return this.error(message.channel, 'Could not find information. Try something else.');
return this.error(message.channel, 'Please try again later, something unexpected happened.');
}
return message.channel.createMessage(res.data);
} catch (err) { } catch (err) {
return this.client.util.handleError(err, message, this); if (err.code === 404) return this.error(message.channel, 'Could not find information. Try something else.');
return this.error(message.channel, 'Please try again later, something unexpected happened.');
} }
return message.channel.createMessage(res.data);
} }
} }

View File

@ -15,54 +15,50 @@ export default class Eval extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { const evalMessage = message.content.slice(this.client.config.prefix.length).trim().split(' ').slice(1);
const evalMessage = message.content.slice(this.client.config.prefix.length).trim().split(' ').slice(1); let evalString = evalMessage.join(' ').trim();
let evalString = evalMessage.join(' ').trim(); let evaled: any;
let evaled: any; let depth = 0;
let depth = 0;
if (args[0] && args[0].startsWith('-d')) { if (args[0] && args[0].startsWith('-d')) {
depth = Number(args[0].replace('-d', '')); depth = Number(args[0].replace('-d', ''));
if (!depth || depth < 0) depth = 0; if (!depth || depth < 0) depth = 0;
const index = evalMessage.findIndex((v) => v.startsWith('-d')) + 1; const index = evalMessage.findIndex((v) => v.startsWith('-d')) + 1;
evalString = evalMessage.slice(index).join(' ').trim(); evalString = evalMessage.slice(index).join(' ').trim();
}
if (args[0] === '-a') {
const index = evalMessage.findIndex((v) => v === '-a') + 1;
evalString = `(async () => { ${evalMessage.slice(index).join(' ').trim()} })()`;
}
try {
// eslint-disable-next-line no-eval
evaled = await eval(evalString);
if (typeof evaled !== 'string') {
evaled = inspect(evaled, { depth });
}
if (evaled === undefined) {
evaled = 'undefined';
}
} catch (error) {
evaled = error.stack;
}
evaled = evaled.replace(new RegExp(this.client.config.token, 'gi'), 'juul');
// evaled = evaled.replace(new RegExp(this.client.config.emailPass, 'gi'), 'juul');
// evaled = evaled.replace(new RegExp(this.client.config.cloudflare, 'gi'), 'juul');
const display = this.client.util.splitString(evaled, 1975);
if (display[5]) {
try {
const { data } = await axios.post('https://snippets.cloud.libraryofcode.org/documents', display.join(''));
return this.success(message.channel, `Your evaluation evaled can be found on https://snippets.cloud.libraryofcode.org/${data.key}`);
} catch (error) {
return this.error(message.channel, `${error}`);
}
}
return display.forEach((m) => message.channel.createMessage(`\`\`\`js\n${m}\n\`\`\``));
} catch (err) {
return this.client.util.handleError(err, message, this, false);
} }
if (args[0] === '-a') {
const index = evalMessage.findIndex((v) => v === '-a') + 1;
evalString = `(async () => { ${evalMessage.slice(index).join(' ').trim()} })()`;
}
try {
// eslint-disable-next-line no-eval
evaled = await eval(evalString);
if (typeof evaled !== 'string') {
evaled = inspect(evaled, { depth });
}
if (evaled === undefined) {
evaled = 'undefined';
}
} catch (error) {
evaled = error.stack;
}
evaled = evaled.replace(new RegExp(this.client.config.token, 'gi'), 'juul');
// evaled = evaled.replace(new RegExp(this.client.config.emailPass, 'gi'), 'juul');
// evaled = evaled.replace(new RegExp(this.client.config.cloudflare, 'gi'), 'juul');
const display = this.client.util.splitString(evaled, 1975);
if (display[5]) {
try {
const { data } = await axios.post('https://snippets.cloud.libraryofcode.org/documents', display.join(''));
return this.success(message.channel, `Your evaluation evaled can be found on https://snippets.cloud.libraryofcode.org/${data.key}`);
} catch (error) {
return this.error(message.channel, `${error}`);
}
}
return display.forEach((m) => message.channel.createMessage(`\`\`\`js\n${m}\n\`\`\``));
} }
} }

View File

@ -2,6 +2,7 @@
import { Activity, Member, Message } from 'eris'; import { Activity, Member, Message } from 'eris';
import { Client, Command, RichEmbed } from '../class'; import { Client, Command, RichEmbed } from '../class';
// eslint-disable-next-line no-shadow
enum ActivityType { enum ActivityType {
PLAYING, PLAYING,
STREAMING, STREAMING,
@ -23,42 +24,38 @@ export default class Game extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { let member: Member;
let member: Member; if (!args[0]) member = message.member;
if (!args[0]) member = message.member; else {
else { member = this.client.util.resolveMember(args.join(' '), this.mainGuild);
member = this.client.util.resolveMember(args.join(' '), this.mainGuild); if (!member) {
if (!member) { return this.error(message.channel, 'Member not found.');
return this.error(message.channel, 'Member not found.');
}
} }
if (!member.activities || member.activities.length <= 0) return this.error(message.channel, 'Cannot find a game for this member.');
const embed = new RichEmbed();
let mainStatus: Activity;
if (member.activities[0]?.type === ActivityType.CUSTOM_STATUS) {
mainStatus = member.activities[1];
embed.setDescription(`*${member.activities[0].state}*`);
} else {
mainStatus = member.activities[0];
}
embed.setAuthor(member.user.username, member.user.avatarURL);
if (mainStatus?.type === ActivityType.LISTENING) {
embed.setTitle('Spotify');
embed.setColor('#1ed760');
embed.addField('Song', mainStatus.details, true);
embed.addField('Artist', mainStatus.state, true);
embed.addField('Album', mainStatus.assets.large_text);
embed.addField('Start', `${new Date(mainStatus.timestamps.start).toLocaleTimeString('en-us')} ET`, true);
embed.addField('End', `${new Date(mainStatus.timestamps.end).toLocaleTimeString('en-us')} ET`, true);
embed.setThumbnail(`https://i.scdn.co/image/${mainStatus.assets.large_image.split(':')[1]}`);
embed.setFooter(`Listening to Spotify | ${this.client.user.username}`, 'https://media.discordapp.net/attachments/358674161566220288/496894273304920064/2000px-Spotify_logo_without_text.png');
embed.setTimestamp();
} else {
return this.error(message.channel, 'Only Spotify games are supported at this time.');
}
return message.channel.createMessage({ embed });
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
if (!member.activities || member.activities.length <= 0) return this.error(message.channel, 'Cannot find a game for this member.');
const embed = new RichEmbed();
let mainStatus: Activity;
if (member.activities[0]?.type === ActivityType.CUSTOM_STATUS) {
mainStatus = member.activities[1];
embed.setDescription(`*${member.activities[0].state}*`);
} else {
mainStatus = member.activities[0];
}
embed.setAuthor(member.user.username, member.user.avatarURL);
if (mainStatus?.type === ActivityType.LISTENING) {
embed.setTitle('Spotify');
embed.setColor('#1ed760');
embed.addField('Song', mainStatus.details, true);
embed.addField('Artist', mainStatus.state, true);
embed.addField('Album', mainStatus.assets.large_text);
embed.addField('Start', `${new Date(mainStatus.timestamps.start).toLocaleTimeString('en-us')} ET`, true);
embed.addField('End', `${new Date(mainStatus.timestamps.end).toLocaleTimeString('en-us')} ET`, true);
embed.setThumbnail(`https://i.scdn.co/image/${mainStatus.assets.large_image.split(':')[1]}`);
embed.setFooter(`Listening to Spotify | ${this.client.user.username}`, 'https://media.discordapp.net/attachments/358674161566220288/496894273304920064/2000px-Spotify_logo_without_text.png');
embed.setTimestamp();
} else {
return this.error(message.channel, 'Only Spotify games are supported at this time.');
}
return message.channel.createMessage({ embed });
} }
} }

View File

@ -14,112 +14,108 @@ export default class Help extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (args.length > 0) {
if (args.length > 0) { const resolved = await this.client.util.resolveCommand(args, message);
const resolved = await this.client.util.resolveCommand(args, message); if (!resolved) return this.error(message.channel, 'The command you provided doesn\'t exist.');
if (!resolved) return this.error(message.channel, 'The command you provided doesn\'t exist.'); const { cmd } = resolved;
const { cmd } = resolved; const embed = new RichEmbed();
const embed = new RichEmbed(); const subcommands = cmd.subcommands.size ? `\n**Subcommands:** ${cmd.subcommands.map((s) => `${cmd.name} ${s.name}`).join(', ')}` : '';
const subcommands = cmd.subcommands.size ? `\n**Subcommands:** ${cmd.subcommands.map((s) => `${cmd.name} ${s.name}`).join(', ')}` : ''; embed.setTitle(`${this.client.config.prefix}${cmd.name}`);
embed.setTitle(`${this.client.config.prefix}${cmd.name}`); embed.addField('Description', cmd.description ?? '-');
embed.addField('Description', cmd.description ?? '-'); embed.addField('Usage', cmd.usage ?? '-');
embed.addField('Usage', cmd.usage ?? '-'); if (subcommands) embed.addField('Sub-commands', subcommands);
if (subcommands) embed.addField('Sub-commands', subcommands); if (cmd.aliases.length > 0) {
if (cmd.aliases.length > 0) { embed.addField('Aliases', cmd.aliases.map((alias) => `${this.client.config.prefix}${alias}`).join(', '));
embed.addField('Aliases', cmd.aliases.map((alias) => `${this.client.config.prefix}${alias}`).join(', '));
}
let description: string = '';
if (!cmd.enabled) {
description += 'This command is disabled.';
}
if (cmd.guildOnly) {
description += 'This command can only be ran in a guild.';
}
embed.setDescription(description);
switch (cmd.permissions) {
case 0:
break;
case 1:
embed.addField('Permissions', 'Associates+');
break;
case 2:
embed.addField('Permissions', 'Core Team+');
break;
case 3:
embed.addField('Permissions', 'Moderators, Supervisor, & Board of Directors');
break;
case 4:
embed.addField('Permissions', 'Technicians, Supervisor, & Board of Directors');
break;
case 5:
embed.addField('Permissions', 'Moderators, Technicians, Supervisor, & Board of Directors');
break;
case 6:
embed.addField('Permissions', 'Supervisor+');
break;
case 7:
embed.addField('Permissions', 'Board of Directors');
break;
default:
break;
}
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
return message.channel.createMessage({ embed });
} }
const cmdList: Command[] = []; let description: string = '';
this.client.commands.forEach((c) => { if (!cmd.enabled) {
if (c.permissions !== 0 && c.guildOnly) { description += 'This command is disabled.';
const check = c.checkCustomPermissions(message.member, c.permissions); }
if (!check) return; if (cmd.guildOnly) {
} description += 'This command can only be ran in a guild.';
cmdList.push(c); }
}); embed.setDescription(description);
const commands = this.client.commands.map((c) => { switch (cmd.permissions) {
const aliases = c.aliases.map((alias) => `${this.client.config.prefix}${alias}`).join(', '); case 0:
let perm: string; break;
switch (c.permissions) { case 1:
case 0: embed.addField('Permissions', 'Associates+');
break; break;
case 1: case 2:
perm = 'Associates+'; embed.addField('Permissions', 'Core Team+');
break; break;
case 2: case 3:
perm = 'Core Team+'; embed.addField('Permissions', 'Moderators, Supervisor, & Board of Directors');
break; break;
case 3: case 4:
perm = 'Moderators, Supervisor, & Board of Directors'; embed.addField('Permissions', 'Technicians, Supervisor, & Board of Directors');
break; break;
case 4: case 5:
perm = 'Technicians, Supervisor, & Board of Directors'; embed.addField('Permissions', 'Moderators, Technicians, Supervisor, & Board of Directors');
break; break;
case 5: case 6:
perm = 'Moderators, Technicians, Supervisor, & Board of Directors'; embed.addField('Permissions', 'Supervisor+');
break; break;
case 6: case 7:
perm = 'Supervisor+'; embed.addField('Permissions', 'Board of Directors');
break; break;
case 7: default:
perm = 'Board of Directors'; break;
break; }
default: embed.setFooter(this.client.user.username, this.client.user.avatarURL);
break; embed.setTimestamp();
} return message.channel.createMessage({ embed });
return { name: `${this.client.config.prefix}${c.name}`, value: `**Description:** ${c.description}\n**Aliases:** ${aliases}\n**Usage:** ${c.usage}\n**Permissions:** ${perm ?? ''}`, inline: false };
});
const splitCommands = this.client.util.splitFields(commands);
const cmdPages: RichEmbed[] = [];
splitCommands.forEach((splitCmd) => {
const embed = new RichEmbed();
embed.setTimestamp(); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setDescription(`Command list for ${this.client.user.username}`);
splitCmd.forEach((c) => embed.addField(c.name, c.value, c.inline));
return cmdPages.push(embed);
});
if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
return createPaginationEmbed(message, cmdPages);
} catch (err) {
return this.client.util.handleError(err, message, this, false);
} }
const cmdList: Command[] = [];
this.client.commands.forEach((c) => {
if (c.permissions !== 0 && c.guildOnly) {
const check = c.checkCustomPermissions(message.member, c.permissions);
if (!check) return;
}
cmdList.push(c);
});
const commands = this.client.commands.map((c) => {
const aliases = c.aliases.map((alias) => `${this.client.config.prefix}${alias}`).join(', ');
let perm: string;
switch (c.permissions) {
case 0:
break;
case 1:
perm = 'Associates+';
break;
case 2:
perm = 'Core Team+';
break;
case 3:
perm = 'Moderators, Supervisor, & Board of Directors';
break;
case 4:
perm = 'Technicians, Supervisor, & Board of Directors';
break;
case 5:
perm = 'Moderators, Technicians, Supervisor, & Board of Directors';
break;
case 6:
perm = 'Supervisor+';
break;
case 7:
perm = 'Board of Directors';
break;
default:
break;
}
return { name: `${this.client.config.prefix}${c.name}`, value: `**Description:** ${c.description}\n**Aliases:** ${aliases}\n**Usage:** ${c.usage}\n**Permissions:** ${perm ?? ''}`, inline: false };
});
const splitCommands = this.client.util.splitFields(commands);
const cmdPages: RichEmbed[] = [];
splitCommands.forEach((splitCmd) => {
const embed = new RichEmbed();
embed.setTimestamp(); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setDescription(`Command list for ${this.client.user.username}`);
splitCmd.forEach((c) => embed.addField(c.name, c.value, c.inline));
return cmdPages.push(embed);
});
if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
return createPaginationEmbed(message, cmdPages);
} }
} }

View File

@ -1,6 +1,7 @@
import { Message } from 'eris'; import { Message } from 'eris';
import { totalmem } from 'os'; import { totalmem } from 'os';
import { Client, Command, RichEmbed } from '../class'; import { Client, Command, RichEmbed } from '../class';
// eslint-disable-next-line import/no-relative-packages
import { version as tsVersion } from '../../node_modules/typescript/package.json'; import { version as tsVersion } from '../../node_modules/typescript/package.json';
export default class Info extends Command { export default class Info extends Command {
@ -14,24 +15,21 @@ export default class Info extends Command {
} }
public async run(message: Message) { public async run(message: Message) {
try { const embed = new RichEmbed();
const embed = new RichEmbed(); embed.setTitle('Information');
embed.setTitle('Information'); embed.setThumbnail(this.client.user.avatarURL);
embed.setThumbnail(this.client.user.avatarURL); embed.setDescription(`*See \`${this.client.config.prefix}sysinfo\` for more information on libraries used by this application.*`);
embed.setDescription(`*See \`${this.client.config.prefix}sysinfo\` for more information on libraries used by this application.*`); embed.addField('Developers', 'Library of Code sp-us | Dept. of Engineering', true);
embed.addField('Version', 'Rolling Release', true); embed.addField('Version', 'Rolling Release', true);
embed.addField('Language(s)', '<:TypeScript:703451285789343774> TypeScript', true); embed.addField('Language(s)', '<:TypeScript:703451285789343774> TypeScript', true);
embed.addField('Runtime', `Node (${process.version})`, true); embed.addField('Runtime', `Node (${process.version})`, true);
embed.addField('Compilers/Transpilers', `TypeScript [tsc] (${tsVersion})`, true); embed.addField('Compilers/Transpilers', `TypeScript [tsc] (${tsVersion})`, true);
embed.addField('Memory Usage', `${Math.round(process.memoryUsage().rss / 1024 / 1024)} MB / ${Math.round(totalmem() / 1024 / 1024 / 1024)} GB`, true); embed.addField('Memory Usage', `${Math.round(process.memoryUsage().rss / 1024 / 1024)} MB / ${Math.round(totalmem() / 1024 / 1024 / 1024)} GB`, true);
embed.addField('Repository', 'https://loc.sh/crgit | Licensed under GNU Affero General Public License V3', true); embed.addField('Repository', 'https://loc.sh/crgit | Licensed under GNU Affero General Public License V3', true);
embed.addField('Branch', await this.client.util.exec('git rev-parse --abbrev-ref HEAD'), true); embed.addField('Branch', await this.client.util.exec('git rev-parse --abbrev-ref HEAD'), true);
embed.addField('Commit', `[${await this.client.util.exec('git rev-parse --short HEAD')}](${await this.client.util.exec('git rev-parse HEAD')})`, true); embed.addField('Commit', `[${await this.client.util.exec('git rev-parse --short HEAD')}](${await this.client.util.exec('git rev-parse HEAD')})`, true);
embed.setFooter(this.client.user.username, this.client.user.avatarURL); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp(); embed.setTimestamp();
message.channel.createMessage({ embed }); message.channel.createMessage({ embed });
} catch (err) {
this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -20,83 +20,79 @@ export default class Inquiry extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
const inquiry = await this.client.db.mongo.Inquiry.findOne({ iid: args[0] }); const inquiry = await this.client.db.mongo.Inquiry.findOne({ iid: args[0] });
if (!inquiry) return this.error(message.channel, 'Could not locate Inquiry information.'); if (!inquiry) return this.error(message.channel, 'Could not locate Inquiry information.');
const currentReport = await this.client.db.mongo.Score.findOne({ userID: inquiry.userID }); const currentReport = await this.client.db.mongo.Score.findOne({ userID: inquiry.userID });
if (!currentReport) return this.error(message.channel, 'Could not find Community Report for this user.'); if (!currentReport) return this.error(message.channel, 'Could not find Community Report for this user.');
const member = this.client.util.resolveMember(inquiry.userID, this.mainGuild); const member = this.client.util.resolveMember(inquiry.userID, this.mainGuild);
if (!member) return this.error(message.channel, 'Could not locate member.'); if (!member) return this.error(message.channel, 'Could not locate member.');
const { report } = inquiry; const { report } = inquiry;
// if (!report) return this.error(message.channel, 'Could not find inquiry information.'); // if (!report) return this.error(message.channel, 'Could not find inquiry information.');
await this.client.report.createInquiry(member.id, 'Library of Code sp-us | Bureau of Community Reports', 1); await this.client.report.createInquiry(member.id, 'Library of Code sp-us | Bureau of Community Reports', 1);
const embed = new RichEmbed(); const embed = new RichEmbed();
embed.setTitle(`Hard Inquiry Information - ${inquiry.iid}`); embed.setTitle(`Hard Inquiry Information - ${inquiry.iid}`);
embed.setAuthor(member.username, member.user.avatarURL); embed.setAuthor(member.username, member.user.avatarURL);
let currentScore = '0'; let currentScore = '0';
if (currentReport.total < 200) currentScore = '---'; if (currentReport.total < 200) currentScore = '---';
else if (currentReport.total > 800) currentScore = '800'; else if (currentReport.total > 800) currentScore = '800';
else currentScore = `${currentReport.total}`; else currentScore = `${currentReport.total}`;
embed.setDescription(`**Current Community Score:** ${currentScore}\n\n**Department/Service:** ${inquiry.name || 'N/A'}\n**Reason:** ${inquiry.reason || 'N/A'}`); embed.setDescription(`**Current Community Score:** ${currentScore}\n\n**Department/Service:** ${inquiry.name || 'N/A'}\n**Reason:** ${inquiry.reason || 'N/A'}`);
let totalScore = '0'; let totalScore = '0';
let activityScore = '0'; let activityScore = '0';
let moderationScore = '0'; let moderationScore = '0';
let roleScore = '0'; let roleScore = '0';
let cloudServicesScore = '0'; let cloudServicesScore = '0';
let otherScore = '0'; let otherScore = '0';
let miscScore = '0'; let miscScore = '0';
if (report.total < 200) totalScore = '---'; if (report.total < 200) totalScore = '---';
else if (report.total > 800) totalScore = '800'; else if (report.total > 800) totalScore = '800';
else totalScore = `${report.total}`; else totalScore = `${report.total}`;
if (report.activity < 10) activityScore = '---'; if (report.activity < 10) activityScore = '---';
else if (report.activity > Math.floor((Math.log1p(getTotalMessageCount(this.client)) * 12))) activityScore = String(Math.floor((Math.log1p(getTotalMessageCount(this.client)) * 12))); else if (report.activity > Math.floor((Math.log1p(getTotalMessageCount(this.client)) * 12))) activityScore = String(Math.floor((Math.log1p(getTotalMessageCount(this.client)) * 12)));
else activityScore = `${report.activity}`; else activityScore = `${report.activity}`;
if (report.roles <= 0) roleScore = '---'; if (report.roles <= 0) roleScore = '---';
else if (report.roles > 54) roleScore = '54'; else if (report.roles > 54) roleScore = '54';
else roleScore = `${report.roles}`; else roleScore = `${report.roles}`;
moderationScore = `${report.moderation}`; moderationScore = `${report.moderation}`;
if (report.other === 0) otherScore = '---'; if (report.other === 0) otherScore = '---';
else otherScore = `${report.other}`; else otherScore = `${report.other}`;
if (report.staff <= 0) miscScore = '---'; if (report.staff <= 0) miscScore = '---';
else miscScore = `${report.staff}`; else miscScore = `${report.staff}`;
if (report.cloudServices === 0) cloudServicesScore = '---'; if (report.cloudServices === 0) cloudServicesScore = '---';
else if (report.cloudServices > 10) cloudServicesScore = '10'; else if (report.cloudServices > 10) cloudServicesScore = '10';
else cloudServicesScore = `${report.cloudServices}`; else cloudServicesScore = `${report.cloudServices}`;
let color = '🔴'; let color = '🔴';
let additionalText = 'POOR'; let additionalText = 'POOR';
embed.setColor('FF0000'); embed.setColor('FF0000');
if (report.total >= 550) { color = '🟠'; additionalText = 'FAIR'; embed.setColor('FFA500'); } if (report.total >= 550) { color = '🟠'; additionalText = 'FAIR'; embed.setColor('FFA500'); }
if (report.total >= 630) { color = '🟡'; additionalText = 'GOOD'; embed.setColor('FFFF00'); } if (report.total >= 630) { color = '🟡'; additionalText = 'GOOD'; embed.setColor('FFFF00'); }
if (report.total >= 700) { color = '🟢'; additionalText = 'EXCELLENT'; embed.setColor('66FF66'); } if (report.total >= 700) { color = '🟢'; additionalText = 'EXCELLENT'; embed.setColor('66FF66'); }
if (report.total >= 770) { color = '✨'; additionalText = 'EXCEPTIONAL'; embed.setColor('#99FFFF'); } if (report.total >= 770) { color = '✨'; additionalText = 'EXCEPTIONAL'; embed.setColor('#99FFFF'); }
embed.addField('Total | 200 to 800', report ? `${color} ${totalScore} | ${additionalText}` : 'N/C', true); embed.addField('Total | 200 to 800', report ? `${color} ${totalScore} | ${additionalText}` : 'N/C', true);
embed.addField(`Activity | 10 to ${Math.floor(Math.log1p(getTotalMessageCount(this.client)) * 12)}`, activityScore || 'N/C', true); embed.addField(`Activity | 10 to ${Math.floor(Math.log1p(getTotalMessageCount(this.client)) * 12)}`, activityScore || 'N/C', true);
embed.addField('Roles | 1 to N/A', roleScore || 'N/C', true); embed.addField('Roles | 1 to N/A', roleScore || 'N/C', true);
embed.addField('Moderation | N/A to 2' || 'N/C', moderationScore, true); embed.addField('Moderation | N/A to 2' || 'N/C', moderationScore, true);
embed.addField('Cloud Services | N/A to 10+', cloudServicesScore || 'N/C', true); embed.addField('Cloud Services | N/A to 10+', cloudServicesScore || 'N/C', true);
embed.addField('Other', otherScore || 'N/C', true); embed.addField('Other', otherScore || 'N/C', true);
embed.addField('Misc', miscScore || 'N/C', true); embed.addField('Misc', miscScore || 'N/C', true);
if (currentReport.pin?.length > 0) { if (currentReport.pin?.length > 0) {
embed.addField('PIN', currentReport.pin.join('-'), true); embed.addField('PIN', currentReport.pin.join('-'), true);
}
embed.setTimestamp();
embed.setFooter('Inquiry performed on', this.client.user.avatarURL);
return message.channel.createMessage({ embed });
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
embed.setTimestamp();
embed.setFooter('Inquiry performed on', this.client.user.avatarURL);
return message.channel.createMessage({ embed });
} }
} }

View File

@ -1,4 +1,5 @@
import { Message, TextChannel } from 'eris'; import { Message, TextChannel } from 'eris';
import axios from 'axios';
import { apply as Apply } from '.'; import { apply as Apply } from '.';
import { Client, Command, RichEmbed } from '../class'; import { Client, Command, RichEmbed } from '../class';
@ -17,40 +18,45 @@ export default class Inquiry_Remove extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
const inquiry = await this.client.db.mongo.Inquiry.findOne({ iid: args[0] });
if (!inquiry) return this.error(message.channel, 'Unable to find Inquiry.');
const member = this.client.util.resolveMember(inquiry.userID, this.mainGuild);
if (!member) return this.error(message.channel, 'Unable to locate member.');
const report = await this.client.db.mongo.Score.findOne({ userID: member.id });
if (!report) return this.error(message.channel, 'Unable to locate Community Report.');
if (inquiry.type !== 0) return this.error(message.channel, 'You can only remove Hard Inquiries.');
await this.client.db.mongo.Inquiry.deleteOne({ iid: args[0] });
const embed = new RichEmbed();
embed.setTitle('Inquiry - Removed');
embed.addField('IID', inquiry.iid);
embed.addField('Member', `${member.username}#${member.discriminator} | <@${member.id}>`);
embed.addField('Department/Service', inquiry.name || 'N/A');
embed.addField('Reason', inquiry.reason || 'N/A');
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
try { try {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); await axios({
method: 'DELETE',
const inquiry = await this.client.db.mongo.Inquiry.findOne({ iid: args[0] }); url: `https://eds.libraryofcode.org/dec/${inquiry.iid}?auth=${this.client.config.internalKey}`,
if (!inquiry) return this.error(message.channel, 'Unable to find Inquiry.'); });
const member = await this.client.util.resolveMember(inquiry.userID, this.mainGuild); } catch (e) {
if (!member) return this.error(message.channel, 'Unable to locate member.'); this.error(message.channel, `An error occurred while changing EDS data: ${e}\n*(This does not mean that the operation failed.)*`);
const report = await this.client.db.mongo.Score.findOne({ userID: member.id });
if (!report) return this.error(message.channel, 'Unable to locate Community Report.');
if (inquiry.type !== 0) return this.error(message.channel, 'You can only remove Hard Inquiries.');
await this.client.db.mongo.Inquiry.deleteOne({ iid: args[0] });
const embed = new RichEmbed();
embed.setTitle('Inquiry - Removed');
embed.addField('IID', inquiry.iid);
embed.addField('Member', `${member.username}#${member.discriminator} | <@${member.id}>`);
embed.addField('Department/Service', inquiry.name || 'N/A');
embed.addField('Reason', inquiry.reason || 'N/A');
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
const log = <TextChannel> this.client.guilds.get(this.client.config.guildID).channels.get('611584771356622849');
log.createMessage({ embed });
const chan = await this.client.getDMChannel(member.id);
if (chan) {
chan.createMessage({ embed }).catch(() => {});
}
return this.success(message.channel, 'Inquiry successfully deleted.');
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
const log = <TextChannel> this.client.guilds.get(this.client.config.guildID).channels.get('611584771356622849');
log.createMessage({ embed });
const chan = await this.client.getDMChannel(member.id);
if (chan) {
chan.createMessage({ embed }).catch(() => {});
}
return this.success(message.channel, 'Inquiry successfully deleted.');
} }
} }

View File

@ -14,32 +14,28 @@ export default class Intercom extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); const loading = await this.loading(message.channel, 'Synthesizing text...');
const loading = await this.loading(message.channel, 'Synthesizing text...');
const recordingLocation = await MiscPBXActions.TTS(this.client.util.pbx, `Hello, this is the Library of Code Private Branch Exchange dialing you at the request of ${message.author.username} to deliver you a message. Playing message: ${args.slice(1).join(' ')}`, 'MALE'); const recordingLocation = await MiscPBXActions.TTS(this.client.util.pbx, `Hello, this is the Library of Code Private Branch Exchange dialing you at the request of ${message.author.username} to deliver you a message. Playing message: ${args.slice(1).join(' ')}`, 'MALE');
await loading.edit(`***${this.client.util.emojis.LOADING} Preparing to dial...***`); await loading.edit(`***${this.client.util.emojis.LOADING} Preparing to dial...***`);
this.client.util.pbx.ami.action({ this.client.util.pbx.ami.action({
action: 'originate', action: 'originate',
channel: `PJSIP/${args[0]}`, channel: `PJSIP/${args[0]}`,
exten: args[0], exten: args[0],
context: 'from-internal', context: 'from-internal',
CallerID: `TTS INTC FRM ${message.author.username} <000>`, CallerID: `TTS INTC FRM ${message.author.username} <000>`,
application: 'PlayBack', application: 'PlayBack',
priority: '1', priority: '1',
data: `beep&${recordingLocation.split(':')[1]}`, data: `beep&${recordingLocation.split(':')[1]}`,
variable: { variable: {
'PJSIP_HEADER(add,Call-Info)': '<uri>;answer-after=0', 'PJSIP_HEADER(add,Call-Info)': '<uri>;answer-after=0',
'PJSIP_HEADER(add,Alert-Info)': 'Ring Answer', 'PJSIP_HEADER(add,Alert-Info)': 'Ring Answer',
}, },
}, async (err: Error) => { }, async (err: Error) => {
if (err) return loading.edit(`***${this.client.util.emojis.ERROR} Failed to dial extension.***`); if (err) return loading.edit(`***${this.client.util.emojis.ERROR} Failed to dial extension.***`);
return loading.edit(`***${this.client.util.emojis.SUCCESS} Successfully queued intercom message to EXT \`${args[0]}\`.***`); return loading.edit(`***${this.client.util.emojis.SUCCESS} Successfully queued intercom message to EXT \`${args[0]}\`.***`);
}); });
return undefined; return undefined;
} catch (err) {
return this.client.util.handleError(err, message, this, false);
}
} }
} }

View File

@ -17,10 +17,6 @@ export default class Judgement extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -15,77 +15,73 @@ export default class Judgement_Add extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, ['judgement', 'add']);
if (!args[0]) return this.client.commands.get('help').run(message, ['judgement', 'add']); if (args.length < 4) return this.client.commands.get('help').run(message, ['judgement', 'add']);
if (args.length < 4) return this.client.commands.get('help').run(message, ['judgement', 'add']);
const member = this.client.util.resolveMember(args[0], this.mainGuild); const member = this.client.util.resolveMember(args[0], this.mainGuild);
if (!member) return this.error(message.channel, 'Unable to locate member.'); if (!member) return this.error(message.channel, 'Unable to locate member.');
const staff = await this.client.db.mongo.Staff.findOne({ userID: message.author.id }).lean().exec(); const staff = await this.client.db.mongo.Staff.findOne({ userID: message.author.id }).lean().exec();
if (!staff) return this.error(message.channel, 'Unable to locate Staff information.'); if (!staff) return this.error(message.channel, 'Unable to locate Staff information.');
if (Number.isNaN(Number(args[1]))) return this.error(message.channel, 'Severity must be a number.'); if (Number.isNaN(Number(args[1]))) return this.error(message.channel, 'Severity must be a number.');
if (Number(args[1]) < 0 || Number(args[1]) > 2) return this.error(message.channel, 'Severity must be greater than -1 and less than 3.'); if (Number(args[1]) < 0 || Number(args[1]) > 2) return this.error(message.channel, 'Severity must be greater than -1 and less than 3.');
let momentMilliseconds: number; let momentMilliseconds: number;
const now: number = Date.now(); const now: number = Date.now();
let date: Date; let date: Date;
if (args[2] !== '0') { if (args[2] !== '0') {
const lockLength = args[2].match(/[a-z]+|[^a-z]+/gi); const lockLength = args[2].match(/[a-z]+|[^a-z]+/gi);
const length = Number(lockLength[0]); const length = Number(lockLength[0]);
const unit = lockLength[1] as unitOfTime.Base; const unit = lockLength[1] as unitOfTime.Base;
momentMilliseconds = moment.duration(length, unit).asMilliseconds(); momentMilliseconds = moment.duration(length, unit).asMilliseconds();
date = new Date(momentMilliseconds + now); date = new Date(momentMilliseconds + now);
}
const jid = nanoid(11);
const entry = new this.client.db.mongo.Judgement({
jid,
userID: member.user.id,
enteredBy: message.author.id,
severity: Number(args[1]),
date: new Date(),
expires: date ?? undefined,
description: args.slice(3).join(' '),
});
await entry.save();
let severity: string;
switch (Number(args[1])) {
case 0:
severity = 'LOW';
break;
case 1:
severity = 'MEDIUM';
break;
case 2:
severity = 'HIGH';
break;
default:
break;
}
const log = <TextChannel> this.client.guilds.get(this.client.config.guildID).channels.get('611584771356622849');
const embed = new RichEmbed();
embed.setTitle('Judgement - Creation');
embed.setDescription(entry.description);
embed.addField('Member', `${member.username}#${member.discriminator} (<@${member.id}>)`, true);
embed.addField('Entered by', `${message.author.username}, ${staff.pn.slice(0, 2).join(', ')}`, true);
embed.addField('Severity', severity, true);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
if (date) {
embed.addField('Expires on', date.toLocaleString('en-us'), true);
} else {
embed.addField('Expires on', 'INDEFINITE', true);
}
log.createMessage({ embed });
return this.success(message.channel, `Judgement \`${jid}\` successfully recorded.`);
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
const jid = nanoid(11);
const entry = new this.client.db.mongo.Judgement({
jid,
userID: member.user.id,
enteredBy: message.author.id,
severity: Number(args[1]),
date: new Date(),
expires: date ?? undefined,
description: args.slice(3).join(' '),
});
await entry.save();
let severity: string;
switch (Number(args[1])) {
case 0:
severity = 'LOW';
break;
case 1:
severity = 'MEDIUM';
break;
case 2:
severity = 'HIGH';
break;
default:
break;
}
const log = <TextChannel> this.client.guilds.get(this.client.config.guildID).channels.get('611584771356622849');
const embed = new RichEmbed();
embed.setTitle('Judgement - Creation');
embed.setDescription(entry.description);
embed.addField('Member', `${member.username}#${member.discriminator} (<@${member.id}>)`, true);
embed.addField('Entered by', `${message.author.username}, ${staff.pn.slice(0, 2).join(', ')}`, true);
embed.addField('Severity', severity, true);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
if (date) {
embed.addField('Expires on', date.toLocaleString('en-us'), true);
} else {
embed.addField('Expires on', 'INDEFINITE', true);
}
log.createMessage({ embed });
return this.success(message.channel, `Judgement \`${jid}\` successfully recorded.`);
} }
} }

View File

@ -14,29 +14,25 @@ export default class Judgement_Delete extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, ['judgement', 'delete']);
if (!args[0]) return this.client.commands.get('help').run(message, ['judgement', 'delete']);
const member = this.client.util.resolveMember(args[0], this.mainGuild); const member = this.client.util.resolveMember(args[0], this.mainGuild);
if (!member) return this.error(message.channel, 'Unable to locate member.'); if (!member) return this.error(message.channel, 'Unable to locate member.');
const staff = await this.client.db.mongo.Staff.findOne({ userID: message.author.id }).lean().exec(); const staff = await this.client.db.mongo.Staff.findOne({ userID: message.author.id }).lean().exec();
if (!staff) return this.error(message.channel, 'Unable to locate Staff information.'); if (!staff) return this.error(message.channel, 'Unable to locate Staff information.');
const judgement = await this.client.db.mongo.Judgement.findOne({ jid: args[0] }); const judgement = await this.client.db.mongo.Judgement.findOne({ jid: args[0] });
if (!judgement) return this.error(message.channel, 'Unable to locate judgement.'); if (!judgement) return this.error(message.channel, 'Unable to locate judgement.');
await judgement.delete(); await judgement.delete();
const log = <TextChannel> this.client.guilds.get(this.client.config.guildID).channels.get('611584771356622849'); const log = <TextChannel> this.client.guilds.get(this.client.config.guildID).channels.get('611584771356622849');
const embed = new RichEmbed(); const embed = new RichEmbed();
embed.setTitle('Judgement - Rescind'); embed.setTitle('Judgement - Rescind');
embed.addField('Member', `${member.username}#${member.discriminator} (<@${member.id}>)`, true); embed.addField('Member', `${member.username}#${member.discriminator} (<@${member.id}>)`, true);
embed.addField('Rescinded by', `${message.author.username}, ${staff.pn.slice(0, 2).join(', ')}`, true); embed.addField('Rescinded by', `${message.author.username}, ${staff.pn.slice(0, 2).join(', ')}`, true);
embed.setFooter(this.client.user.username, this.client.user.avatarURL); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp(); embed.setTimestamp();
log.createMessage({ embed }); log.createMessage({ embed });
return this.success(message.channel, `Judgement \`${args[0]}\` successfully rescinded.`); return this.success(message.channel, `Judgement \`${args[0]}\` successfully rescinded.`);
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -13,25 +13,21 @@ export default class Kick extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); let user: Member = this.client.util.resolveMember(args[0], this.mainGuild);
let user: Member = this.client.util.resolveMember(args[0], this.mainGuild); if (!user) {
if (!user) { try {
try { user = await this.client.getRESTGuildMember(this.mainGuild.id, args[0]);
user = await this.client.getRESTGuildMember(this.mainGuild.id, args[0]); } catch {
} catch { return this.error(message.channel, 'Cannot find user.');
return this.error(message.channel, 'Cannot find user.');
}
} }
if (user && !this.client.util.moderation.checkPermissions(user, message.member)) return this.error(message.channel, 'Permission Denied.');
message.delete();
const reason: string = args.slice(1).join(' ');
if (reason.length > 512) return this.error(message.channel, 'Kick reasons cannot be longer than 512 characters.');
await this.client.util.moderation.kick(user, message.member, reason);
return this.success(message.channel, `${user.username}#${user.discriminator} has been kicked.`);
} catch (err) {
return this.client.util.handleError(err, message, this, false);
} }
if (user && !this.client.util.moderation.checkPermissions(user, message.member)) return this.error(message.channel, 'Permission Denied.');
message.delete();
const reason: string = args.slice(1).join(' ');
if (reason.length > 512) return this.error(message.channel, 'Kick reasons cannot be longer than 512 characters.');
await this.client.util.moderation.kick(user, message.member, reason);
return this.success(message.channel, `${user.username}#${user.discriminator} has been kicked.`);
} }
} }

View File

@ -14,39 +14,35 @@ export default class DelRedirect extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (args[0]) {
if (args[0]) { const redirects = await this.client.db.mongo.Redirect.find({ $or: [{ key: args[0].toLowerCase() }, { to: args[0].toLowerCase() }] });
const redirects = await this.client.db.mongo.Redirect.find({ $or: [{ key: args[0].toLowerCase() }, { to: args[0].toLowerCase() }] }); if (redirects.length <= 0) return this.error(message.channel, 'Could not find an entry matching that query.');
if (redirects.length <= 0) return this.error(message.channel, 'Could not find an entry matching that query.'); const embed = new RichEmbed();
const embed = new RichEmbed(); embed.setTitle('Redirect Information');
embed.setTitle('Redirect Information');
for (const redirect of redirects) {
embed.addField(`${redirect.key} | visited ${redirect.visitedCount} times`, redirect.to);
}
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
return message.channel.createMessage({ embed });
}
const redirects = await this.client.db.mongo.Redirect.find();
if (!redirects) return this.error(message.channel, 'No redirect links found.');
const redirectArray: [{ name: string, value: string }?] = [];
for (const redirect of redirects) { for (const redirect of redirects) {
redirectArray.push({ name: `${redirect.key} | visited ${redirect.visitedCount} times`, value: redirect.to }); embed.addField(`${redirect.key} | visited ${redirect.visitedCount} times`, redirect.to);
} }
const splitRedirects = this.client.util.splitFields(redirectArray); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
const cmdPages: RichEmbed[] = []; embed.setTimestamp();
splitRedirects.forEach((split) => { return message.channel.createMessage({ embed });
const embed = new RichEmbed();
embed.setTitle('Redirect Information');
embed.setTimestamp();
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
split.forEach((c) => embed.addField(c.name, c.value));
return cmdPages.push(embed);
});
if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
return createPaginationEmbed(message, cmdPages);
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
const redirects = await this.client.db.mongo.Redirect.find();
if (!redirects) return this.error(message.channel, 'No redirect links found.');
const redirectArray: [{ name: string, value: string }?] = [];
for (const redirect of redirects) {
redirectArray.push({ name: `${redirect.key} | visited ${redirect.visitedCount} times`, value: redirect.to });
}
const splitRedirects = this.client.util.splitFields(redirectArray);
const cmdPages: RichEmbed[] = [];
splitRedirects.forEach((split) => {
const embed = new RichEmbed();
embed.setTitle('Redirect Information');
embed.setTimestamp();
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
split.forEach((c) => embed.addField(c.name, c.value));
return cmdPages.push(embed);
});
if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
return createPaginationEmbed(message, cmdPages);
} }
} }

View File

@ -14,46 +14,42 @@ export default class Market extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
let stock: stockInfo.Stock;
try { try {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); stock = await stockInfo.getSingleStockInfo(args[0]);
let stock: stockInfo.Stock;
try {
stock = await stockInfo.getSingleStockInfo(args[0]);
} catch (err) {
return this.error(message.channel, `Unable to fetch information for that ticker. | ${err}`);
}
const embed = new RichEmbed();
embed.setTitle(stock.longName ?? stock.symbol);
let type: string;
switch (stock.quoteType) {
case 'EQUITY':
type = 'Common/Preferred Stock';
break;
case 'ETF':
type = 'Exchange Traded Fund (ETF)';
break;
case 'MUTUALFUND':
type = 'Mutual Fund';
break;
default:
type = 'N/A or Unknown';
break;
}
embed.addField('Type', type, true);
embed.addField('Market Cap', `${stock.marketCap ? this.client.util.hrn(stock.marketCap, undefined, undefined) : 'N/A'}`, true);
embed.addField('Day Quote Price', stock.regularMarketPrice ? `$${Number(stock.regularMarketPrice).toFixed(2)}` : 'N/A', true);
embed.addField('Day G/L', stock.regularMarketChange ? `$${Number(stock.regularMarketChange.toFixed(2))}` : 'N/A', true);
embed.addField('Day Range', stock.regularMarketDayRange ?? 'N/A', true);
embed.addField('Bid/Ask', `Bid: $${stock.bid?.toFixed(2) ?? 'N/A'} | Ask: $${stock.ask?.toFixed(2) ?? 'N/A'}`, true);
embed.addField('Forward P/E (Price/Earnings)', `${stock.forwardPE?.toFixed(2) ?? 'N/A'}`, true);
embed.addField('Forward EPS (Earnings Per Share)', `${stock.epsForward?.toFixed(2) ?? 'N/A'}`, true);
embed.addField('Exchange', `${stock.fullExchangeName?.toUpperCase() ?? 'N/A'}`, true);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
return message.channel.createMessage({ embed });
} catch (err) { } catch (err) {
return this.client.util.handleError(err, message, this, false); return this.error(message.channel, `Unable to fetch information for that ticker. | ${err}`);
} }
const embed = new RichEmbed();
embed.setTitle(stock.longName ?? stock.symbol);
let type: string;
switch (stock.quoteType) {
case 'EQUITY':
type = 'Common/Preferred Stock';
break;
case 'ETF':
type = 'Exchange Traded Fund (ETF)';
break;
case 'MUTUALFUND':
type = 'Mutual Fund';
break;
default:
type = 'N/A or Unknown';
break;
}
embed.addField('Type', type, true);
embed.addField('Market Cap', `${stock.marketCap ? this.client.util.hrn(stock.marketCap, undefined, undefined) : 'N/A'}`, true);
embed.addField('Day Quote Price', stock.regularMarketPrice ? `$${Number(stock.regularMarketPrice).toFixed(2)}` : 'N/A', true);
embed.addField('Day G/L', stock.regularMarketChange ? `$${Number(stock.regularMarketChange.toFixed(2))}` : 'N/A', true);
embed.addField('Day Range', stock.regularMarketDayRange ?? 'N/A', true);
embed.addField('Bid/Ask', `Bid: $${stock.bid?.toFixed(2) ?? 'N/A'} | Ask: $${stock.ask?.toFixed(2) ?? 'N/A'}`, true);
embed.addField('Forward P/E (Price/Earnings)', `${stock.forwardPE?.toFixed(2) ?? 'N/A'}`, true);
embed.addField('Forward EPS (Earnings Per Share)', `${stock.epsForward?.toFixed(2) ?? 'N/A'}`, true);
embed.addField('Exchange', `${stock.fullExchangeName?.toUpperCase() ?? 'N/A'}`, true);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
return message.channel.createMessage({ embed });
} }
} }

View File

@ -14,74 +14,70 @@ export default class Members extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { await this.mainGuild.fetchAllMembers();
await this.mainGuild.fetchAllMembers(); if (!args[0]) {
if (!args[0]) { const embed = new RichEmbed();
const embed = new RichEmbed(); const membersOnline = this.mainGuild.members.filter((member) => member.status === 'online');
const membersOnline = this.mainGuild.members.filter((member) => member.status === 'online'); const membersIdle = this.mainGuild.members.filter((member) => member.status === 'idle');
const membersIdle = this.mainGuild.members.filter((member) => member.status === 'idle'); const membersDnd = this.mainGuild.members.filter((member) => member.status === 'dnd');
const membersDnd = this.mainGuild.members.filter((member) => member.status === 'dnd'); const membersOffline = this.mainGuild.members.filter((member) => member.status === 'offline' || member.status === undefined);
const membersOffline = this.mainGuild.members.filter((member) => member.status === 'offline' || member.status === undefined); const membersBots = this.mainGuild.members.filter((member) => member.user.bot === true);
const membersBots = this.mainGuild.members.filter((member) => member.user.bot === true); const membersHuman = this.mainGuild.members.filter((member) => member.user.bot === false);
const membersHuman = this.mainGuild.members.filter((member) => member.user.bot === false);
embed.setTitle('Members'); embed.setTitle('Members');
embed.setDescription(`**Total:** ${this.mainGuild.members.size}\n**Humans:** ${membersHuman.length}\n**Bots:** ${membersBots.length}\n\n**<:online:732025023547834369> Online:** ${membersOnline.length}\n**<:idle:732025087896715344> Idle:** ${membersIdle.length}\n**<:dnd:732024861853089933> Do Not Disturb:** ${membersDnd.length}\n**<:offline:732024920518688849> Offline:** ${membersOffline.length}`); embed.setDescription(`**Total:** ${this.mainGuild.members.size}\n**Humans:** ${membersHuman.length}\n**Bots:** ${membersBots.length}\n\n**<:online:732025023547834369> Online:** ${membersOnline.length}\n**<:idle:732025087896715344> Idle:** ${membersIdle.length}\n**<:dnd:732024861853089933> Do Not Disturb:** ${membersDnd.length}\n**<:offline:732024920518688849> Offline:** ${membersOffline.length}`);
embed.setFooter(this.client.user.username, this.client.user.avatarURL); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp(); embed.setTimestamp();
return message.channel.createMessage({ embed }); return message.channel.createMessage({ embed });
}
const role = this.client.util.resolveRole(args.join(' '), this.mainGuild);
if (!role) return this.error(message.channel, 'The role you specified doesn\'t exist.');
const check = this.mainGuild.members.filter((m) => m.roles.includes(role.id));
if (!check || check?.length < 1) return this.error(message.channel, 'There are no members in this role.');
const statusArray: string[] = [];
const membersOnline: string[] = [];
const membersIdle: string[] = [];
const membersDnd: string[] = [];
const membersOffline: string[] = [];
for (const member of this.mainGuild.members.filter((m) => m.roles.includes(role.id)).sort((a, b) => a.username.localeCompare(b.username))) {
switch (member.status) {
case 'online':
membersOnline.push(`<:online:732025023547834369> ${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`);
break;
case 'idle':
membersIdle.push(`<:idle:732025087896715344> ${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`);
break;
case 'dnd':
membersDnd.push(`<:dnd:732024861853089933> ${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`);
break;
case 'offline':
membersOffline.push(`<:offline:732024920518688849> ${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`);
break;
case undefined:
membersOffline.push(`<:offline:732024920518688849> ${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`);
break;
default:
break;
}
}
if (membersOnline.length > 0) statusArray.push(membersOnline.join('\n'));
if (membersIdle.length > 0) statusArray.push(membersIdle.join('\n'));
if (membersDnd.length > 0) statusArray.push(membersDnd.join('\n'));
if (membersOffline.length > 0) statusArray.push(membersOffline.join('\n'));
const statusSplit = this.client.util.splitString(statusArray.join('\n'), 2000);
const cmdPages: RichEmbed[] = [];
statusSplit.forEach((split) => {
const embed = new RichEmbed();
embed.setTitle(`Members in ${role.name}`);
embed.setDescription(`Members in Role: ${membersOnline.length + membersIdle.length + membersDnd.length + membersOffline.length}\n\n${split}`);
embed.setColor(role.color);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
return cmdPages.push(embed);
});
if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
return createPaginationEmbed(message, cmdPages);
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
const role = this.client.util.resolveRole(args.join(' '), this.mainGuild);
if (!role) return this.error(message.channel, 'The role you specified doesn\'t exist.');
const check = this.mainGuild.members.filter((m) => m.roles.includes(role.id));
if (!check || check?.length < 1) return this.error(message.channel, 'There are no members in this role.');
const statusArray: string[] = [];
const membersOnline: string[] = [];
const membersIdle: string[] = [];
const membersDnd: string[] = [];
const membersOffline: string[] = [];
for (const member of this.mainGuild.members.filter((m) => m.roles.includes(role.id)).sort((a, b) => a.username.localeCompare(b.username))) {
switch (member.status) {
case 'online':
membersOnline.push(`<:online:732025023547834369> ${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`);
break;
case 'idle':
membersIdle.push(`<:idle:732025087896715344> ${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`);
break;
case 'dnd':
membersDnd.push(`<:dnd:732024861853089933> ${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`);
break;
case 'offline':
membersOffline.push(`<:offline:732024920518688849> ${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`);
break;
case undefined:
membersOffline.push(`<:offline:732024920518688849> ${member.user.username}#${member.user.discriminator} | <@${member.user.id}>`);
break;
default:
break;
}
}
if (membersOnline.length > 0) statusArray.push(membersOnline.join('\n'));
if (membersIdle.length > 0) statusArray.push(membersIdle.join('\n'));
if (membersDnd.length > 0) statusArray.push(membersDnd.join('\n'));
if (membersOffline.length > 0) statusArray.push(membersOffline.join('\n'));
const statusSplit = this.client.util.splitString(statusArray.join('\n'), 2000);
const cmdPages: RichEmbed[] = [];
statusSplit.forEach((split) => {
const embed = new RichEmbed();
embed.setTitle(`Members in ${role.name}`);
embed.setDescription(`Members in Role: ${membersOnline.length + membersIdle.length + membersDnd.length + membersOffline.length}\n\n${split}`);
embed.setColor(role.color);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
return cmdPages.push(embed);
});
if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
return createPaginationEmbed(message, cmdPages);
} }
} }

View File

@ -14,32 +14,28 @@ export default class Mute extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
const member = this.client.util.resolveMember(args[0], this.mainGuild);
if (!member) return this.error(message.channel, 'Cannot find user.');
try { try {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); const res1 = await this.client.db.local.muted.get<boolean>(`muted-${member.id}`);
const member = this.client.util.resolveMember(args[0], this.mainGuild); if (res1 || this.mainGuild.members.get(member.id).roles.includes('478373942638149643')) return this.error(message.channel, 'This user is already muted.');
if (!member) return this.error(message.channel, 'Cannot find user.'); } catch {} // eslint-disable-line no-empty
if (member && !this.client.util.moderation.checkPermissions(member, message.member)) return this.error(message.channel, 'Permission Denied.');
message.delete();
try { let momentMilliseconds: number;
const res1 = await this.client.db.local.muted.get<boolean>(`muted-${member.id}`); let reason: string;
if (res1 || this.mainGuild.members.get(member.id).roles.includes('478373942638149643')) return this.error(message.channel, 'This user is already muted.'); if (args.length > 1) {
} catch {} // eslint-disable-line no-empty const lockLength = args[1].match(/[a-z]+|[^a-z]+/gi);
if (member && !this.client.util.moderation.checkPermissions(member, message.member)) return this.error(message.channel, 'Permission Denied.'); const length = Number(lockLength[0]);
message.delete(); const unit = lockLength[1] as unitOfTime.Base;
momentMilliseconds = moment.duration(length, unit).asMilliseconds();
let momentMilliseconds: number; reason = momentMilliseconds ? args.slice(2).join(' ') : args.slice(1).join(' ');
let reason: string; if (reason.length > 512) return this.error(message.channel, 'Mute reasons cannot be longer than 512 characters.');
if (args.length > 1) {
const lockLength = args[1].match(/[a-z]+|[^a-z]+/gi);
const length = Number(lockLength[0]);
const unit = lockLength[1] as unitOfTime.Base;
momentMilliseconds = moment.duration(length, unit).asMilliseconds();
reason = momentMilliseconds ? args.slice(2).join(' ') : args.slice(1).join(' ');
if (reason.length > 512) return this.error(message.channel, 'Mute reasons cannot be longer than 512 characters.');
}
await this.client.util.moderation.mute(member.user, message.member, momentMilliseconds, reason);
return this.success(message.channel, `${member.user.username}#${member.user.discriminator} has been muted.`);
} catch (err) {
return this.client.util.handleError(err, message, this, false);
} }
await this.client.util.moderation.mute(member.user, message.member, momentMilliseconds, reason);
return this.success(message.channel, `${member.user.username}#${member.user.discriminator} has been muted.`);
} }
} }

View File

@ -14,78 +14,74 @@ export default class Notes extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); let member: Member | User = this.client.util.resolveMember(args[0], this.mainGuild);
let member: Member | User = this.client.util.resolveMember(args[0], this.mainGuild); if (!member) {
if (!member) { try {
try { member = await this.client.getRESTUser(args[0]);
member = await this.client.getRESTUser(args[0]); } catch {
} catch { member = undefined;
member = undefined;
}
} }
if (!member) return this.error(message.channel, 'User specified could not be found.');
const notes = await this.client.db.mongo.Note.find({ userID: member.id });
if (!notes || notes?.length < 1) return this.error(message.channel, 'No notes exist for this user.');
const noteArray: [{ name: string, value: string, inline: boolean }?] = [];
if (args[1] === 'comm' || args[1] === 'cs' || args[1] === 'edu') {
switch (args[1]) {
case 'comm':
for (const note of notes.sort((a, b) => b.date.getTime() - a.date.getTime()).filter((r) => r.category === 'comm')) {
noteArray.push({
name: `${note._id}${note.category === '' ? '' : `, ${note.category.toUpperCase()}`} | ${note.date.toLocaleString('en-us')} ET | Staff: ${this.client.users.get(note.staffID) ? `${this.client.users.get(note.staffID).username}#${this.client.users.get(note.staffID).discriminator}` : 'N/A'}`,
value: note.text,
inline: true,
});
}
break;
case 'cs':
for (const note of notes.sort((a, b) => b.date.getTime() - a.date.getTime()).filter((r) => r.category === 'cs')) {
noteArray.push({
name: `${note._id}${note.category === '' ? '' : `, ${note.category.toUpperCase()}`} | ${note.date.toLocaleString('en-us')} ET | Staff: ${this.client.users.get(note.staffID) ? `${this.client.users.get(note.staffID).username}#${this.client.users.get(note.staffID).discriminator}` : 'N/A'}`,
value: note.text,
inline: true,
});
}
break;
case 'edu':
for (const note of notes.sort((a, b) => b.date.getTime() - a.date.getTime()).filter((r) => r.category === 'edu')) {
noteArray.push({
name: `${note._id}${note.category === '' ? '' : `, ${note.category.toUpperCase()}`}} | ${note.date.toLocaleString('en-us')} ET | Staff: Staff: ${this.client.users.get(note.staffID) ? `${this.client.users.get(note.staffID).username}#${this.client.users.get(note.staffID).discriminator}` : 'N/A'}`,
value: note.text,
inline: true,
});
}
break;
default:
break;
}
} else {
for (const note of notes.sort((a, b) => b.date.getTime() - a.date.getTime())) {
noteArray.push({
name: `${note._id}${note.category === '' ? '' : `, ${note.category}`} | ${note.date.toLocaleString('en-us')} ET | Staff: ${this.client.users.get(note.staffID) ? `${this.client.users.get(note.staffID).username}#${this.client.users.get(note.staffID).discriminator}` : 'N/A'}`,
value: note.text,
inline: true,
});
}
}
const noteSplit = this.client.util.splitFields(noteArray);
const cmdPages: RichEmbed[] = [];
noteSplit.forEach((split) => {
const embed = new RichEmbed();
embed.setColor('#0000FF');
embed.setAuthor(`${member.username}#${member.discriminator}`, member.avatarURL);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
split.forEach((c) => embed.addField(c.name, c.value, c.inline));
return cmdPages.push(embed);
});
if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
return createPaginationEmbed(message, cmdPages);
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
if (!member) return this.error(message.channel, 'User specified could not be found.');
const notes = await this.client.db.mongo.Note.find({ userID: member.id });
if (!notes || notes?.length < 1) return this.error(message.channel, 'No notes exist for this user.');
const noteArray: [{ name: string, value: string, inline: boolean }?] = [];
if (args[1] === 'comm' || args[1] === 'cs' || args[1] === 'edu') {
switch (args[1]) {
case 'comm':
for (const note of notes.sort((a, b) => b.date.getTime() - a.date.getTime()).filter((r) => r.category === 'comm')) {
noteArray.push({
name: `${note._id}${note.category === '' ? '' : `, ${note.category.toUpperCase()}`} | ${note.date.toLocaleString('en-us')} ET | Staff: ${this.client.users.get(note.staffID) ? `${this.client.users.get(note.staffID).username}#${this.client.users.get(note.staffID).discriminator}` : 'N/A'}`,
value: note.text,
inline: true,
});
}
break;
case 'cs':
for (const note of notes.sort((a, b) => b.date.getTime() - a.date.getTime()).filter((r) => r.category === 'cs')) {
noteArray.push({
name: `${note._id}${note.category === '' ? '' : `, ${note.category.toUpperCase()}`} | ${note.date.toLocaleString('en-us')} ET | Staff: ${this.client.users.get(note.staffID) ? `${this.client.users.get(note.staffID).username}#${this.client.users.get(note.staffID).discriminator}` : 'N/A'}`,
value: note.text,
inline: true,
});
}
break;
case 'edu':
for (const note of notes.sort((a, b) => b.date.getTime() - a.date.getTime()).filter((r) => r.category === 'edu')) {
noteArray.push({
name: `${note._id}${note.category === '' ? '' : `, ${note.category.toUpperCase()}`}} | ${note.date.toLocaleString('en-us')} ET | Staff: Staff: ${this.client.users.get(note.staffID) ? `${this.client.users.get(note.staffID).username}#${this.client.users.get(note.staffID).discriminator}` : 'N/A'}`,
value: note.text,
inline: true,
});
}
break;
default:
break;
}
} else {
for (const note of notes.sort((a, b) => b.date.getTime() - a.date.getTime())) {
noteArray.push({
name: `${note._id}${note.category === '' ? '' : `, ${note.category}`} | ${note.date.toLocaleString('en-us')} ET | Staff: ${this.client.users.get(note.staffID) ? `${this.client.users.get(note.staffID).username}#${this.client.users.get(note.staffID).discriminator}` : 'N/A'}`,
value: note.text,
inline: true,
});
}
}
const noteSplit = this.client.util.splitFields(noteArray);
const cmdPages: RichEmbed[] = [];
noteSplit.forEach((split) => {
const embed = new RichEmbed();
embed.setColor('#0000FF');
embed.setAuthor(`${member.username}#${member.discriminator}`, member.avatarURL);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
split.forEach((c) => embed.addField(c.name, c.value, c.inline));
return cmdPages.push(embed);
});
if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
return createPaginationEmbed(message, cmdPages);
} }
} }

View File

@ -14,52 +14,48 @@ export default class NPM extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
const res = await axios.get(`https://registry.npmjs.com/${args[0]}`, { validateStatus: (_) => true }); const res = await axios.get(`https://registry.npmjs.com/${args[0]}`, { validateStatus: (_) => true });
if (res.status === 404) return this.error(message.channel, 'Could not find the library, try something else.'); if (res.status === 404) return this.error(message.channel, 'Could not find the library, try something else.');
const { data } = res; const { data } = res;
const bugs: string = data.bugs?.url || ''; const bugs: string = data.bugs?.url || '';
const description: string = data.description || 'None'; const description: string = data.description || 'None';
const version: string = data['dist-tags']?.latest || 'Unknown'; const version: string = data['dist-tags']?.latest || 'Unknown';
const homepage: string = data.homepage || ''; const homepage: string = data.homepage || '';
let license: string = 'None'; let license: string = 'None';
if (typeof data.license === 'object') { if (typeof data.license === 'object') {
license = data.license.type; license = data.license.type;
} else if (typeof data.license === 'string') { } else if (typeof data.license === 'string') {
license = data.license; license = data.license;
}
let dependencies: string = 'None';
if (version !== 'Unknown' && data.versions[version].dependencies !== undefined && Object.keys(data.versions[version].dependencies).length > 0) {
dependencies = Object.keys(data.versions[version].dependencies).join(', ');
if (dependencies.length > 1024) dependencies = `${dependencies.substr(0, 1021)}...`;
}
const name: string = data.name || 'None';
const repository: string = bugs.replace('/issues', '') || '';
const creation: string = data?.time.created ? new Date(data.time.created).toLocaleString('en') : 'None';
const modification: string = data?.time.modified ? new Date(data.time.modified).toLocaleString('en') : 'None';
const embed = new RichEmbed();
embed.setColor(0xCC3534);
embed.setTimestamp();
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setAuthor('NPM', 'https://i.imgur.com/ErKf5Y0.png', 'https://www.npmjs.com/');
embed.setDescription(`[NPM](https://www.npmjs.com/package/${args[0]}) | [Homepage](${homepage}) | [Repository](${repository}) | [Bugs](${bugs})`);
embed.addField('Name', name, true);
embed.addField('Latest version', version, true);
embed.addField('License', license, true);
embed.addField('Description', description, false);
embed.addField('Dependencies', dependencies, false);
embed.addField('Creation Date', creation, true);
embed.addField('Modification Date', modification, true);
return message.channel.createMessage({ embed });
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
let dependencies: string = 'None';
if (version !== 'Unknown' && data.versions[version].dependencies !== undefined && Object.keys(data.versions[version].dependencies).length > 0) {
dependencies = Object.keys(data.versions[version].dependencies).join(', ');
if (dependencies.length > 1024) dependencies = `${dependencies.substr(0, 1021)}...`;
}
const name: string = data.name || 'None';
const repository: string = bugs.replace('/issues', '') || '';
const creation: string = data?.time.created ? new Date(data.time.created).toLocaleString('en') : 'None';
const modification: string = data?.time.modified ? new Date(data.time.modified).toLocaleString('en') : 'None';
const embed = new RichEmbed();
embed.setColor(0xCC3534);
embed.setTimestamp();
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setAuthor('NPM', 'https://i.imgur.com/ErKf5Y0.png', 'https://www.npmjs.com/');
embed.setDescription(`[NPM](https://www.npmjs.com/package/${args[0]}) | [Homepage](${homepage}) | [Repository](${repository}) | [Bugs](${bugs})`);
embed.addField('Name', name, true);
embed.addField('Latest version', version, true);
embed.addField('License', license, true);
embed.addField('Description', description, false);
embed.addField('Dependencies', dependencies, false);
embed.addField('Creation Date', creation, true);
embed.addField('Modification Date', modification, true);
return message.channel.createMessage({ embed });
} }
} }

View File

@ -16,35 +16,31 @@ export default class Offer extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); const member = this.client.util.resolveMember(args[0], this.mainGuild);
const member = this.client.util.resolveMember(args[0], this.mainGuild); if (!member) return this.error(message.channel, 'Could not find member.');
if (!member) return this.error(message.channel, 'Could not find member.'); const score = await this.client.db.mongo.Score.findOne({ userID: member.user.id }).lean().exec();
const score = await this.client.db.mongo.Score.findOne({ userID: member.user.id }).lean().exec(); if (!score) return this.error(message.channel, 'Could not find score report for this user.');
if (!score) return this.error(message.channel, 'Could not find score report for this user.');
if (score.locked) return this.error(message.channel, 'This user\'s score report is locked.'); if (score.locked) return this.error(message.channel, 'This user\'s score report is locked.');
const name = args.slice(1).join(' ').split(':')[0]; const name = args.slice(1).join(' ').split(':')[0];
const dept = args.slice(1).join(' ').split(':')[1]; const dept = args.slice(1).join(' ').split(':')[1];
if (!name || !dept) return this.error(message.channel, 'Invalid arguments.'); if (!name || !dept) return this.error(message.channel, 'Invalid arguments.');
const token = jwt.sign({ const token = jwt.sign({
userID: member.user.id, userID: member.user.id,
staffID: message.author.id, staffID: message.author.id,
channelID: message.channel.id, channelID: message.channel.id,
messageID: message.id, messageID: message.id,
pin: score.pin.join('-'), pin: score.pin.join('-'),
name, name,
department: dept, department: dept,
date: new Date(), date: new Date(),
}, this.client.config.internalKey, { expiresIn: '12h' }); }, this.client.config.internalKey, { expiresIn: '12h' });
this.client.getDMChannel(member.user.id).then((chan) => { this.client.getDMChannel(member.user.id).then((chan) => {
chan.createMessage(`__**Offer Pre-Qualified**__\nYou have been pre-approved for an offer! If you wish to accept this offer, please enter the offer code at https://report.libraryofcode.org/. Do not share this code with anyone else. This offer automatically expires in 12 hours. Your report will be Hard Inquiried immediately after accepting this offer.\n\n**Department:** ${dept.toUpperCase()}\n**Offer for:** ${name}\n\n\`${token}\``); chan.createMessage(`__**Offer Pre-Qualified**__\nYou have been pre-approved for an offer! If you wish to accept this offer, please enter the offer code at https://report.libraryofcode.org/. Do not share this code with anyone else. This offer automatically expires in 12 hours. Your report will be Hard Inquiried immediately after accepting this offer.\n\n**Department:** ${dept.toUpperCase()}\n**Offer for:** ${name}\n\n\`${token}\``);
}).catch(() => this.error(message.channel, 'Could not DM member.')); }).catch(() => this.error(message.channel, 'Could not DM member.'));
return this.success(message.channel, `Offer sent.\n\n\`${token}\``); return this.success(message.channel, `Offer sent.\n\n\`${token}\``);
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -41,65 +41,61 @@ export default class Page extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) {
if (!args[0]) { this.client.commands.get('help').run(message, [this.name]);
this.client.commands.get('help').run(message, [this.name]); const embed = new RichEmbed();
const embed = new RichEmbed(); embed.setTitle('Special Emergency/Department Numbers & Pager Codes');
embed.setTitle('Special Emergency/Department Numbers & Pager Codes'); embed.addField('Special Emergency Numbers', '`#0` | Broadcast - all Staff/Associates\n`#1` | Authoritative Broadcast - all Directors, Supervisors, Technicians, and Moderators\n`#2` | Systems Administrators/Technicians Broadcast - Matthew, Bsian, NightRaven, and all Technicians\n`#3` | Community/Moderation Team Broadcast - all Directors, Supervisors, Moderators, and Core Team');
embed.addField('Special Emergency Numbers', '`#0` | Broadcast - all Staff/Associates\n`#1` | Authoritative Broadcast - all Directors, Supervisors, Technicians, and Moderators\n`#2` | Systems Administrators/Technicians Broadcast - Matthew, Bsian, NightRaven, and all Technicians\n`#3` | Community/Moderation Team Broadcast - all Directors, Supervisors, Moderators, and Core Team'); embed.addField('Department Numbers', '`00` | Board of Directors\n`01` | Supervisors\n`10` | Technicians\n`20` | Moderators\n`21` | Core Team\n`22` | Associates');
embed.addField('Department Numbers', '`00` | Board of Directors\n`01` | Supervisors\n`10` | Technicians\n`20` | Moderators\n`21` | Core Team\n`22` | Associates'); embed.addField('Pager Codes', '"Pager" term in this field refers to the Staff member that initially paged. This is a list of valid codes you can send via a page.\n\n`911` - Pager is requesting EMERGENCY assistance\n`811` - Pager is requesting immediate/ASAP assistance\n`210` - Pager is informing you they acknowledged your request, usually sent in response to OK the initial page.\n`265` - Pager is requesting that you check your email\n`411` - Pager is requesting information/counsel from you\n`419` - Pager didn\'t recognize your request\n`555` - Pager is requesting that you contact them\n`556` - Pager is requesting that you contact them via DMs\n`557` - Pager is requesting that you contact them via PBX/their extension.\n`558` - Pager is requesting if they are able to call you via PBX. If so, please send the pager back a 210 page.');
embed.addField('Pager Codes', '"Pager" term in this field refers to the Staff member that initially paged. This is a list of valid codes you can send via a page.\n\n`911` - Pager is requesting EMERGENCY assistance\n`811` - Pager is requesting immediate/ASAP assistance\n`210` - Pager is informing you they acknowledged your request, usually sent in response to OK the initial page.\n`265` - Pager is requesting that you check your email\n`411` - Pager is requesting information/counsel from you\n`419` - Pager didn\'t recognize your request\n`555` - Pager is requesting that you contact them\n`556` - Pager is requesting that you contact them via DMs\n`557` - Pager is requesting that you contact them via PBX/their extension.\n`558` - Pager is requesting if they are able to call you via PBX. If so, please send the pager back a 210 page.'); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setFooter(this.client.user.username, this.client.user.avatarURL); embed.setTimestamp();
embed.setTimestamp(); return message.channel.createMessage({ embed });
return message.channel.createMessage({ embed });
}
if (args[0] === 'settings') {
const pager = await this.client.db.mongo.PagerNumber.findOne({ individualAssignID: message.author.id });
if (!pager) return this.error(message.channel, 'You do not have a Pager Number.');
switch (args[1]) {
case 'email':
if (args[2] === 'off') {
if (pager.receiveEmail === false) return this.error(message.channel, 'You are already set to not receive email notifications.');
await pager.updateOne({ $set: { receiveEmail: false } });
return this.success(message.channel, 'You will no longer receive notifications by email for pages.');
}
if (args[2] === 'on') {
if (pager.receiveEmail === true) return this.error(message.channel, 'You are already set to receive email notifications.');
await pager.updateOne({ $set: { receiveEmail: true } });
return this.success(message.channel, 'You will now receive notifications by email for pages.');
}
break;
case 'phone':
if (args[2] === 'off') {
if (pager.receivePhone === false) return this.error(message.channel, 'You are already set to not receive PBX calls.');
await pager.updateOne({ $set: { receivePhone: false } });
return this.success(message.channel, 'You will no longer receive PBX calls for pages.');
}
if (args[2] === 'on') {
if (pager.receivePhone === true) return this.error(message.channel, 'You are already set to receive PBX calls.');
await pager.updateOne({ $set: { receivePhone: true } });
return this.success(message.channel, 'You will now receive PBX calls for pages.');
}
break;
default:
this.error(message.channel, 'Invalid response provided.');
break;
}
}
message.delete();
const loading = await this.loading(message.channel, 'Paging...');
const sender = await this.client.db.mongo.PagerNumber.findOne({ individualAssignID: message.author.id });
if (!sender) return this.error(message.channel, 'You do not have a Pager Number.');
const page = await this.page(args[0], sender.num, args[1], message, args[2] ? args.slice(2).join(' ') : undefined);
if (page.status === true) {
loading.delete();
return this.success(message.channel, page.message);
}
loading.delete();
return this.error(message.channel, page.message);
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
if (args[0] === 'settings') {
const pager = await this.client.db.mongo.PagerNumber.findOne({ individualAssignID: message.author.id });
if (!pager) return this.error(message.channel, 'You do not have a Pager Number.');
switch (args[1]) {
case 'email':
if (args[2] === 'off') {
if (pager.receiveEmail === false) return this.error(message.channel, 'You are already set to not receive email notifications.');
await pager.updateOne({ $set: { receiveEmail: false } });
return this.success(message.channel, 'You will no longer receive notifications by email for pages.');
}
if (args[2] === 'on') {
if (pager.receiveEmail === true) return this.error(message.channel, 'You are already set to receive email notifications.');
await pager.updateOne({ $set: { receiveEmail: true } });
return this.success(message.channel, 'You will now receive notifications by email for pages.');
}
break;
case 'phone':
if (args[2] === 'off') {
if (pager.receivePhone === false) return this.error(message.channel, 'You are already set to not receive PBX calls.');
await pager.updateOne({ $set: { receivePhone: false } });
return this.success(message.channel, 'You will no longer receive PBX calls for pages.');
}
if (args[2] === 'on') {
if (pager.receivePhone === true) return this.error(message.channel, 'You are already set to receive PBX calls.');
await pager.updateOne({ $set: { receivePhone: true } });
return this.success(message.channel, 'You will now receive PBX calls for pages.');
}
break;
default:
this.error(message.channel, 'Invalid response provided.');
break;
}
}
message.delete();
const loading = await this.loading(message.channel, 'Paging...');
const sender = await this.client.db.mongo.PagerNumber.findOne({ individualAssignID: message.author.id });
if (!sender) return this.error(message.channel, 'You do not have a Pager Number.');
const page = await this.page(args[0], sender.num, args[1], message, args[2] ? args.slice(2).join(' ') : undefined);
if (page.status === true) {
loading.delete();
return this.success(message.channel, page.message);
}
loading.delete();
return this.error(message.channel, page.message);
} }
public logPage(sender: { number: string, user?: string }, recipient: { number: string, user?: string }, type: 'discord' | 'email' | 'phone', code: string): void { public logPage(sender: { number: string, user?: string }, recipient: { number: string, user?: string }, type: 'discord' | 'email' | 'phone', code: string): void {

View File

@ -12,12 +12,8 @@ export default class Ping extends Command {
} }
public async run(message: Message) { public async run(message: Message) {
try { const clientStart: number = Date.now();
const clientStart: number = Date.now(); const msg: Message = await message.channel.createMessage('🏓 Pong!');
const msg: Message = await message.channel.createMessage('🏓 Pong!'); msg.edit(`🏓 Pong!\nClient: \`${Date.now() - clientStart}ms\`\nResponse: \`${msg.createdAt - message.createdAt}ms\``);
msg.edit(`🏓 Pong!\nClient: \`${Date.now() - clientStart}ms\`\nResponse: \`${msg.createdAt - message.createdAt}ms\``);
} catch (err) {
this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -14,60 +14,56 @@ export default class Rank extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) {
if (!args[0]) { const roles = await this.client.db.mongo.Rank.find();
const roles = await this.client.db.mongo.Rank.find(); const rankArray: [{ name: string, value: string }?] = [];
const rankArray: [{ name: string, value: string }?] = []; for (const rank of roles.sort((a, b) => a.name.localeCompare(b.name))) {
for (const rank of roles.sort((a, b) => a.name.localeCompare(b.name))) { let perms: string;
let perms: string; if (rank.permissions.includes('0')) {
if (rank.permissions.includes('0')) { perms = 'Everyone';
perms = 'Everyone';
} else {
const rolesArray: Role[] = [];
rank.permissions.forEach((r) => {
rolesArray.push(this.mainGuild.roles.get(r));
});
perms = rolesArray.map((r) => this.mainGuild.roles.get(r.id)).sort((a, b) => b.position - a.position).map((r) => `<@&${r.id}>`).join(', ');
}
let hasRank = false;
if (message.member.roles.includes(rank.roleID)) hasRank = true;
rankArray.push({ name: rank.name, value: `${hasRank ? '*You have this role.*\n' : ''}__Description:__ ${rank.description}\n__Permissions:__ ${perms}` });
}
const ranksSplit = this.client.util.splitFields(rankArray);
const cmdPages: RichEmbed[] = [];
ranksSplit.forEach((split) => {
const embed = new RichEmbed();
embed.setTitle('Ranks');
embed.setDescription(`Use \`${this.client.config.prefix}rank <rank name>\` to join/leave the rank.`);
embed.setFooter(`Requested by: ${message.author.username}#${message.author.discriminator} | ${this.client.user.username}`, message.author.avatarURL);
embed.setTimestamp();
split.forEach((c) => embed.addField(c.name, c.value));
return cmdPages.push(embed);
});
if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
return createPaginationEmbed(message, cmdPages);
}
const role = this.client.util.resolveRole(args.join(' '), this.client.guilds.get(this.client.config.guildID));
if (!role) return this.error(message.channel, 'The role you specified doesn\'t exist.');
const entry = await this.client.db.mongo.Rank.findOne({ roleID: role.id }).lean().exec();
if (!entry) return this.error(message.channel, 'The rank you specified doesn\'t exist.');
if (!message.member.roles.includes(entry.roleID)) {
let permCheck: boolean;
if (entry.permissions.includes('0')) {
permCheck = true;
} else { } else {
permCheck = entry.permissions.some((item) => message.member.roles.includes(item)); const rolesArray: Role[] = [];
rank.permissions.forEach((r) => {
rolesArray.push(this.mainGuild.roles.get(r));
});
perms = rolesArray.map((r) => this.mainGuild.roles.get(r.id)).sort((a, b) => b.position - a.position).map((r) => `<@&${r.id}>`).join(', ');
} }
if (!permCheck) return this.error(message.channel, 'Permission denied.'); let hasRank = false;
await message.member.addRole(entry.roleID, 'User self-assigned this role.'); if (message.member.roles.includes(rank.roleID)) hasRank = true;
this.success(message.channel, `You have self-assigned ${entry.name}.`); rankArray.push({ name: rank.name, value: `${hasRank ? '*You have this role.*\n' : ''}__Description:__ ${rank.description}\n__Permissions:__ ${perms}` });
} else if (message.member.roles.includes(entry.roleID)) {
await message.member.removeRole(entry.roleID, 'User has removed a self-assignable role.');
this.success(message.channel, `You have removed ${entry.name}.`);
} }
return null; const ranksSplit = this.client.util.splitFields(rankArray);
} catch (err) { const cmdPages: RichEmbed[] = [];
return this.client.util.handleError(err, message, this); ranksSplit.forEach((split) => {
const embed = new RichEmbed();
embed.setTitle('Ranks');
embed.setDescription(`Use \`${this.client.config.prefix}rank <rank name>\` to join/leave the rank.`);
embed.setFooter(`Requested by: ${message.author.username}#${message.author.discriminator} | ${this.client.user.username}`, message.author.avatarURL);
embed.setTimestamp();
split.forEach((c) => embed.addField(c.name, c.value));
return cmdPages.push(embed);
});
if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
return createPaginationEmbed(message, cmdPages);
} }
const role = this.client.util.resolveRole(args.join(' '), this.client.guilds.get(this.client.config.guildID));
if (!role) return this.error(message.channel, 'The role you specified doesn\'t exist.');
const entry = await this.client.db.mongo.Rank.findOne({ roleID: role.id }).lean().exec();
if (!entry) return this.error(message.channel, 'The rank you specified doesn\'t exist.');
if (!message.member.roles.includes(entry.roleID)) {
let permCheck: boolean;
if (entry.permissions.includes('0')) {
permCheck = true;
} else {
permCheck = entry.permissions.some((item) => message.member.roles.includes(item));
}
if (!permCheck) return this.error(message.channel, 'Permission denied.');
await message.member.addRole(entry.roleID, 'User self-assigned this role.');
this.success(message.channel, `You have self-assigned ${entry.name}.`);
} else if (message.member.roles.includes(entry.roleID)) {
await message.member.removeRole(entry.roleID, 'User has removed a self-assignable role.');
this.success(message.channel, `You have removed ${entry.name}.`);
}
return null;
} }
} }

View File

@ -12,62 +12,58 @@ export default class Role extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (args.length < 2) return this.client.commands.get('help').run(message, [this.name]);
if (args.length < 2) return this.client.commands.get('help').run(message, [this.name]); const member = this.client.util.resolveMember(args[0], this.mainGuild);
const member = this.client.util.resolveMember(args[0], this.mainGuild); if (!member) return this.error(message.channel, 'Member not found');
if (!member) return this.error(message.channel, 'Member not found'); // if (!this.client.util.moderation.checkPermissions(member, message.member)) return this.error(message.channel, 'Permission denied.');
// if (!this.client.util.moderation.checkPermissions(member, message.member)) return this.error(message.channel, 'Permission denied.'); const rolesList = args.slice(1).join(' ').split(', ');
const rolesList = args.slice(1).join(' ').split(', '); const rolesToAdd = [];
const rolesToAdd = []; const rolesToRemove = [];
const rolesToRemove = []; let stop = false;
let stop = false; for (const arg of rolesList) {
for (const arg of rolesList) { const action = arg[0];
const action = arg[0]; let role: DRole;
let role: DRole; if (action !== '+' && action !== '-') {
if (action !== '+' && action !== '-') { role = this.client.util.resolveRole(arg, this.mainGuild);
role = this.client.util.resolveRole(arg, this.mainGuild); if (!role) {
if (!role) { stop = true;
stop = true; return this.error(message.channel, `Role \`${arg}\` not found.`);
return this.error(message.channel, `Role \`${arg}\` not found.`);
}
if (member.roles.includes(role.id)) return rolesToRemove.push(role);
rolesToAdd.push(role);
continue;
}
if (action === '+') {
role = this.client.util.resolveRole(arg.slice(1), this.mainGuild);
if (!role) {
stop = true;
return this.error(message.channel, `Role \`${arg.slice(1)}\` not found.`);
}
if (member.roles.includes(role.id)) {
stop = true;
return this.error(message.channel, `You already have the role \`${role.name}\`.`);
}
rolesToAdd.push(role);
continue;
}
if (action === '-') {
role = this.client.util.resolveRole(arg.slice(1), this.mainGuild);
if (!role) {
stop = true;
return this.error(message.channel, `Role \`${arg.slice(1)}\` not found.`);
}
if (!member.roles.includes(role.id)) {
stop = true;
return this.error(message.channel, `You don't have the role \`${role.name}\``);
}
rolesToRemove.push(role);
continue;
} }
if (member.roles.includes(role.id)) return rolesToRemove.push(role);
rolesToAdd.push(role);
continue;
}
if (action === '+') {
role = this.client.util.resolveRole(arg.slice(1), this.mainGuild);
if (!role) {
stop = true;
return this.error(message.channel, `Role \`${arg.slice(1)}\` not found.`);
}
if (member.roles.includes(role.id)) {
stop = true;
return this.error(message.channel, `You already have the role \`${role.name}\`.`);
}
rolesToAdd.push(role);
continue;
}
if (action === '-') {
role = this.client.util.resolveRole(arg.slice(1), this.mainGuild);
if (!role) {
stop = true;
return this.error(message.channel, `Role \`${arg.slice(1)}\` not found.`);
}
if (!member.roles.includes(role.id)) {
stop = true;
return this.error(message.channel, `You don't have the role \`${role.name}\``);
}
rolesToRemove.push(role);
continue;
} }
// eslint-disable-next-line
// if (stop) return;
rolesToAdd.forEach((role) => member.addRole(role.id));
rolesToRemove.forEach((role) => member.removeRole(role.id));
return this.success(message.channel, `Changed roles for ${member.username}#${member.discriminator}${rolesToAdd.length > 0 ? `, added \`${rolesToAdd.map((r) => r.name).join('`, `')}\`` : ''}${rolesToRemove.length > 0 ? `, removed \`${rolesToRemove.map((r) => r.name).join('`, `')}\`` : ''}`);
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
// eslint-disable-next-line
// if (stop) return;
rolesToAdd.forEach((role) => member.addRole(role.id));
rolesToRemove.forEach((role) => member.removeRole(role.id));
return this.success(message.channel, `Changed roles for ${member.username}#${member.discriminator}${rolesToAdd.length > 0 ? `, added \`${rolesToAdd.map((r) => r.name).join('`, `')}\`` : ''}${rolesToRemove.length > 0 ? `, removed \`${rolesToRemove.map((r) => r.name).join('`, `')}\`` : ''}`);
} }
} }

View File

@ -14,44 +14,40 @@ export default class Roleinfo extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
const role = this.client.util.resolveRole(args.join(' '), this.mainGuild); const role = this.client.util.resolveRole(args.join(' '), this.mainGuild);
if (!role) return this.error(message.channel, 'Could not find role.'); if (!role) return this.error(message.channel, 'Could not find role.');
const perms = role.permissions; const perms = role.permissions;
const permsArray: string[] = []; const permsArray: string[] = [];
if (perms.has('administrator')) permsArray.push('Administrator'); if (perms.has('administrator')) permsArray.push('Administrator');
if (perms.has('manageGuild')) permsArray.push('Manage Server'); if (perms.has('manageGuild')) permsArray.push('Manage Server');
if (perms.has('manageChannels')) permsArray.push('Manage Channels'); if (perms.has('manageChannels')) permsArray.push('Manage Channels');
if (perms.has('manageRoles')) permsArray.push('Manage Roles'); if (perms.has('manageRoles')) permsArray.push('Manage Roles');
if (perms.has('manageMessages')) permsArray.push('Manage Messages'); if (perms.has('manageMessages')) permsArray.push('Manage Messages');
if (perms.has('manageNicknames')) permsArray.push('Manage Nicknames'); if (perms.has('manageNicknames')) permsArray.push('Manage Nicknames');
if (perms.has('manageEmojis')) permsArray.push('Manage Emojis'); if (perms.has('manageEmojis')) permsArray.push('Manage Emojis');
if (perms.has('banMembers')) permsArray.push('Ban Members'); if (perms.has('banMembers')) permsArray.push('Ban Members');
if (perms.has('kickMembers')) permsArray.push('Kick Members'); if (perms.has('kickMembers')) permsArray.push('Kick Members');
const embed = new RichEmbed(); const embed = new RichEmbed();
embed.setTitle('Role Information'); embed.setTitle('Role Information');
embed.setDescription(`<@&${role.id}> ID: \`${role.id}\``); embed.setDescription(`<@&${role.id}> ID: \`${role.id}\``);
embed.setColor(role.color); embed.setColor(role.color);
embed.addField('Name', role.name, true); embed.addField('Name', role.name, true);
embed.addField('Color', role.color ? this.client.util.decimalToHex(role.color) : 'None', true); embed.addField('Color', role.color ? this.client.util.decimalToHex(role.color) : 'None', true);
embed.addField('Members', String(this.client.guilds.get(this.client.config.guildID).members.filter((m) => m.roles.includes(role.id)).length), true); embed.addField('Members', String(this.client.guilds.get(this.client.config.guildID).members.filter((m) => m.roles.includes(role.id)).length), true);
embed.addField('Hoisted', role.hoist ? 'Yes' : 'No', true); embed.addField('Hoisted', role.hoist ? 'Yes' : 'No', true);
embed.addField('Position', String(role.position), true); embed.addField('Position', String(role.position), true);
embed.addField('Creation Date', `${moment(new Date(role.createdAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true); embed.addField('Creation Date', `${moment(new Date(role.createdAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true);
embed.addField('Mentionable', role.mentionable ? 'Yes' : 'No', true); embed.addField('Mentionable', role.mentionable ? 'Yes' : 'No', true);
embed.setFooter(this.client.user.username, this.client.user.avatarURL); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp(); embed.setTimestamp();
if (permsArray.length > 0) { if (permsArray.length > 0) {
embed.addField('Permissions', permsArray.join(', '), true); embed.addField('Permissions', permsArray.join(', '), true);
}
return message.channel.createMessage({ embed });
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
return message.channel.createMessage({ embed });
} }
} }

View File

@ -22,90 +22,86 @@ export default class StaffAssistedApplication extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
const member = this.client.util.resolveMember(args[0], this.mainGuild); const member = this.client.util.resolveMember(args[0], this.mainGuild);
if (!member) return this.error(message.channel, 'Unable to locate member.'); if (!member) return this.error(message.channel, 'Unable to locate member.');
const report = await this.client.db.mongo.Score.findOne({ userID: member.id }).lean().exec(); const report = await this.client.db.mongo.Score.findOne({ userID: member.id }).lean().exec();
if (!report) return this.error(message.channel, 'Unable to locate Community Report.'); if (!report) return this.error(message.channel, 'Unable to locate Community Report.');
const staff = await this.client.db.mongo.Staff.findOne({ userID: message.author.id }).lean().exec(); const staff = await this.client.db.mongo.Staff.findOne({ userID: message.author.id }).lean().exec();
if (!staff) return this.error(message.channel, 'Unable to locate Staff information.'); if (!staff) return this.error(message.channel, 'Unable to locate Staff information.');
const service = this.applyCommand.services.get(args[1]); const service = this.applyCommand.services.get(args[1]);
if (!service) return this.error(message.channel, 'Invalid service code.'); if (!service) return this.error(message.channel, 'Invalid service code.');
if (service.type !== 'HARD') return this.error(message.channel, 'SAAs cannot be ran for services that do not require a Hard Inquiry or pre-approvals.'); if (service.type !== 'HARD') return this.error(message.channel, 'SAAs cannot be ran for services that do not require a Hard Inquiry or pre-approvals.');
const preValidationTest = await service.validation(member); const preValidationTest = await service.validation(member);
if (!preValidationTest) return this.error(message.channel, 'This member does not meet pre-validation requirements. A SAA cannot be executed.'); if (!preValidationTest) return this.error(message.channel, 'This member does not meet pre-validation requirements. A SAA cannot be executed.');
const loading = await this.loading(message.channel, 'Processing application with EDS. Please hold on a moment.'); const loading = await this.loading(message.channel, 'Processing application with EDS. Please hold on a moment.');
const application = await Apply.apply(this.client, service.url, member.id); const application = await Apply.apply(this.client, service.url, member.id);
await (new this.client.db.mongo.SAA({ await (new this.client.db.mongo.SAA({
userID: member.id, userID: member.id,
applicationID: application.id, applicationID: application.id,
serviceCode: args[1], serviceCode: args[1],
edsToken: application.token, edsToken: application.token,
})).save(); })).save();
await this.client.commands.get('score').run(message, [member.id, 'soft']); await this.client.commands.get('score').run(message, [member.id, 'soft']);
const edsEmbed = new RichEmbed(); const edsEmbed = new RichEmbed();
edsEmbed.setTitle('Decision from EDS'); edsEmbed.setTitle('Decision from EDS');
if (member) { if (member) {
edsEmbed.setAuthor(member.username, member.avatarURL); edsEmbed.setAuthor(member.username, member.avatarURL);
}
if (application.decision === 'APPROVED') {
edsEmbed.setColor('#50c878');
} else if (application.decision === 'DECLINED') {
edsEmbed.setColor('#fe0000');
} else if (application.decision === 'PRE-DECLINE') {
edsEmbed.setColor('#ffa500');
} else {
edsEmbed.setColor('#eeeeee');
}
let description = `This application was processed by __${application.processedBy}__ on behalf of the vendor, department, or service who operates this application. Please contact the vendor for further information about this application if needed.`;
if (application.token) description += `\n\n*This document provides detailed information about the decision given by EDS.*: https://eds.libraryofcode.org/dec/${application.token}`;
edsEmbed.setDescription(description);
edsEmbed.addField('Status', application.decision, true);
edsEmbed.addField('User ID', member.id, true);
edsEmbed.addField('Application ID', application.id, true);
edsEmbed.setFooter(`${this.client.user.username} via Electronic Decision Service [EDS]`, this.client.user.avatarURL);
edsEmbed.setTimestamp();
await message.channel.createMessage({ embed: edsEmbed });
const embed = new RichEmbed();
embed.setTitle('Information Panel');
embed.setDescription('You have been provided with a full report as well as a recommendation from EDS. You should use the information from the Community Report as well as EDS\' recommendation, and other information (such as ?whois, historical report, notes, ect.) to make your decision. If you need assistance, please page a Director.');
embed.addField('Approve', `Run \`${this.client.config.prefix}saa approve ${application.id}\``);
embed.addField('Decline', `Run \`${this.client.config.prefix}saa decline ${application.id}\``);
embed.setFooter(`${this.client.user.username} | Staff-assisted Application via Electronic Decision Service [EDS]`, this.client.user.avatarURL);
embed.setTimestamp();
await message.channel.createMessage({ embed });
const notificationEmbed = new RichEmbed();
notificationEmbed.setTitle('Staff Assisted Application - Queued');
// eslint-disable-next-line no-useless-escape
notificationEmbed.addField('User', `${member.username}#${member.discriminator} | XXX-XX-${report.pin[2]}`);
notificationEmbed.addField('Decision', 'PROCESSING');
notificationEmbed.addField('Initiated by', `${message.author.username}, ${staff.pn.slice(0, 2).join(', ')} *on behalf of Library of Code sp-us*`);
notificationEmbed.addField('Application ID', application.id);
notificationEmbed.addField('Service Code', args[1]);
notificationEmbed.setFooter(this.client.user.username, this.client.user.avatarURL);
notificationEmbed.setTimestamp();
const log = <TextChannel> this.client.guilds.get(this.client.config.guildID).channels.get('611584771356622849');
log.createMessage({ embed: notificationEmbed });
notificationEmbed.setDescription('*A Staff Assisted Application has been queued in your name. If you didn\'t request a SAA to be ran, please contact the Staff Team as soon as possible.\nYou should receive a decision soon, if you do not receive a decision within 72 hours please contact the Staff Team for further information.*');
const chan = await this.client.getDMChannel(member.id);
chan.createMessage({ embed: notificationEmbed }).then(() => this.success(message.channel, 'SAA successfully queued.')).catch(() => this.error(message.channel, 'Unable to deliver notification to user.'));
loading.delete().catch(() => {});
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
if (application.decision === 'APPROVED') {
edsEmbed.setColor('#50c878');
} else if (application.decision === 'DECLINED') {
edsEmbed.setColor('#fe0000');
} else if (application.decision === 'PRE-DECLINE') {
edsEmbed.setColor('#ffa500');
} else {
edsEmbed.setColor('#eeeeee');
}
let description = `This application was processed by __${application.processedBy}__ on behalf of the vendor, department, or service who operates this application. Please contact the vendor for further information about this application if needed.`;
if (application.token) description += `\n\n*This document provides detailed information about the decision given by EDS.*: https://eds.libraryofcode.org/dec/${application.token}`;
edsEmbed.setDescription(description);
edsEmbed.addField('Status', application.decision, true);
edsEmbed.addField('User ID', member.id, true);
edsEmbed.addField('Application ID', application.id, true);
edsEmbed.setFooter(`${this.client.user.username} via Electronic Decision Service [EDS]`, this.client.user.avatarURL);
edsEmbed.setTimestamp();
await message.channel.createMessage({ embed: edsEmbed });
const embed = new RichEmbed();
embed.setTitle('Information Panel');
embed.setDescription('You have been provided with a full report as well as a recommendation from EDS. You should use the information from the Community Report as well as EDS\' recommendation, and other information (such as ?whois, historical report, notes, ect.) to make your decision. If you need assistance, please page a Director.');
embed.addField('Approve', `Run \`${this.client.config.prefix}saa approve ${application.id}\``);
embed.addField('Decline', `Run \`${this.client.config.prefix}saa decline ${application.id}\``);
embed.setFooter(`${this.client.user.username} | Staff-assisted Application via Electronic Decision Service [EDS]`, this.client.user.avatarURL);
embed.setTimestamp();
await message.channel.createMessage({ embed });
const notificationEmbed = new RichEmbed();
notificationEmbed.setTitle('Staff Assisted Application - Queued');
// eslint-disable-next-line no-useless-escape
notificationEmbed.addField('User', `${member.username}#${member.discriminator} | XXX-XX-${report.pin[2]}`);
notificationEmbed.addField('Decision', 'PROCESSING');
notificationEmbed.addField('Initiated by', `${message.author.username}, ${staff.pn.slice(0, 2).join(', ')} *on behalf of Library of Code sp-us*`);
notificationEmbed.addField('Application ID', application.id);
notificationEmbed.addField('Service Code', args[1]);
notificationEmbed.setFooter(this.client.user.username, this.client.user.avatarURL);
notificationEmbed.setTimestamp();
const log = <TextChannel> this.client.guilds.get(this.client.config.guildID).channels.get('611584771356622849');
log.createMessage({ embed: notificationEmbed });
notificationEmbed.setDescription('*A Staff Assisted Application has been queued in your name. If you didn\'t request a SAA to be ran, please contact the Staff Team as soon as possible.\nYou should receive a decision soon, if you do not receive a decision within 72 hours please contact the Staff Team for further information.*');
const chan = await this.client.getDMChannel(member.id);
chan.createMessage({ embed: notificationEmbed }).then(() => this.success(message.channel, 'SAA successfully queued.')).catch(() => this.error(message.channel, 'Unable to deliver notification to user.'));
loading.delete().catch(() => {});
} }
} }

View File

@ -19,52 +19,48 @@ export default class SAA_Approve extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
const saa = await this.client.db.mongo.SAA.findOne({ applicationID: args[0] }).lean().exec();
if (!saa) return this.error(message.channel, 'Unable to locate SAA.');
const member = this.client.util.resolveMember(saa.userID, this.mainGuild);
if (!member) return this.error(message.channel, 'Unable to locate member.');
const report = await this.client.db.mongo.Score.findOne({ userID: saa.userID }).lean().exec();
if (!report) return this.error(message.channel, 'Unable to locate Community Report.');
const staff = await this.client.db.mongo.Staff.findOne({ userID: message.author.id }).lean().exec();
if (!staff) return this.error(message.channel, 'Unable to locate Staff information.');
await this.applyCommand.services.get(saa.serviceCode).func(this.client, member.id);
const embed = new RichEmbed();
embed.setTitle('Staff Assisted Application - Decision');
embed.setColor('#50c878');
// eslint-disable-next-line no-useless-escape
embed.addField('User', `${member.username}#${member.discriminator} | XXX-XX-${report.pin[2]}`);
embed.addField('Decision', 'APPROVED');
embed.addField('Underwriter', `${message.author.username}, ${staff.pn.slice(0, 2).join(', ')} *on behalf of Library of Code sp-us*`);
embed.addField('Application ID', saa.applicationID);
embed.addField('Service Code', saa.serviceCode);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
const log = <TextChannel> this.client.guilds.get(this.client.config.guildID).channels.get('611584771356622849');
log.createMessage({ embed });
embed.setDescription(`*A SAA has been ran in your name for a service, this embed contains the information about the result of that decision.*\n\nAccess link to the EDS recommendation for this decision: https://eds.libraryofcode.org/dec/${saa.edsToken}`);
const chan = await this.client.getDMChannel(saa.userID);
chan.createMessage({ embed }).then(() => this.success(message.channel, 'SAA successfully processed.')).catch(() => this.error(message.channel, 'Unable to deliver decision to user.'));
try { try {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); await axios({
method: 'PATCH',
const saa = await this.client.db.mongo.SAA.findOne({ applicationID: args[0] }).lean().exec(); url: `https://eds.libraryofcode.org/dec/${saa.applicationID}?auth=${this.client.config.internalKey}`,
if (!saa) return this.error(message.channel, 'Unable to locate SAA.'); data: { status: true },
const member = this.client.util.resolveMember(saa.userID, this.mainGuild); });
if (!member) return this.error(message.channel, 'Unable to locate member.'); } catch (e) {
const report = await this.client.db.mongo.Score.findOne({ userID: saa.userID }).lean().exec(); this.error(message.channel, `An error occurred while changing EDS data: ${e}`);
if (!report) return this.error(message.channel, 'Unable to locate Community Report.');
const staff = await this.client.db.mongo.Staff.findOne({ userID: message.author.id }).lean().exec();
if (!staff) return this.error(message.channel, 'Unable to locate Staff information.');
await this.applyCommand.services.get(saa.serviceCode).func(this.client, member.id);
const embed = new RichEmbed();
embed.setTitle('Staff Assisted Application - Decision');
embed.setColor('#50c878');
// eslint-disable-next-line no-useless-escape
embed.addField('User', `${member.username}#${member.discriminator} | XXX-XX-${report.pin[2]}`);
embed.addField('Decision', 'APPROVED');
embed.addField('Underwriter', `${message.author.username}, ${staff.pn.slice(0, 2).join(', ')} *on behalf of Library of Code sp-us*`);
embed.addField('Application ID', saa.applicationID);
embed.addField('Service Code', saa.serviceCode);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
const log = <TextChannel> this.client.guilds.get(this.client.config.guildID).channels.get('611584771356622849');
log.createMessage({ embed });
embed.setDescription(`*A SAA has been ran in your name for a service, this embed contains the information about the result of that decision.*\n\nAccess link to the EDS recommendation for this decision: https://eds.libraryofcode.org/dec/${saa.edsToken}`);
const chan = await this.client.getDMChannel(saa.userID);
chan.createMessage({ embed }).then(() => this.success(message.channel, 'SAA successfully processed.')).catch(() => this.error(message.channel, 'Unable to deliver decision to user.'));
try {
await axios({
method: 'PATCH',
url: `https://eds.libraryofcode.org/dec/${saa.applicationID}?auth=${this.client.config.internalKey}`,
data: { status: true },
});
} catch (e) {
this.error(message.channel, `An error occurred while changing EDS data: ${e}`);
}
await this.client.db.mongo.SAA.deleteOne({ _id: saa._id }).lean().exec();
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
await this.client.db.mongo.SAA.deleteOne({ _id: saa._id }).lean().exec();
} }
} }

View File

@ -18,40 +18,36 @@ export default class SAA_Decline extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
const saa = await this.client.db.mongo.SAA.findOne({ applicationID: args[0] }).lean().exec(); const saa = await this.client.db.mongo.SAA.findOne({ applicationID: args[0] }).lean().exec();
if (!saa) return this.error(message.channel, 'Unable to locate SAA.'); if (!saa) return this.error(message.channel, 'Unable to locate SAA.');
const member = this.client.util.resolveMember(saa.userID, this.mainGuild); const member = this.client.util.resolveMember(saa.userID, this.mainGuild);
if (!member) return this.error(message.channel, 'Unable to locate member.'); if (!member) return this.error(message.channel, 'Unable to locate member.');
const report = await this.client.db.mongo.Score.findOne({ userID: saa.userID }).lean().exec(); const report = await this.client.db.mongo.Score.findOne({ userID: saa.userID }).lean().exec();
if (!report) return this.error(message.channel, 'Unable to locate Community Report.'); if (!report) return this.error(message.channel, 'Unable to locate Community Report.');
const staff = await this.client.db.mongo.Staff.findOne({ userID: message.author.id }).lean().exec(); const staff = await this.client.db.mongo.Staff.findOne({ userID: message.author.id }).lean().exec();
if (!staff) return this.error(message.channel, 'Unable to locate Staff information.'); if (!staff) return this.error(message.channel, 'Unable to locate Staff information.');
const embed = new RichEmbed(); const embed = new RichEmbed();
embed.setTitle('Staff Assisted Application - Decision'); embed.setTitle('Staff Assisted Application - Decision');
embed.setColor('#fe0000'); embed.setColor('#fe0000');
// eslint-disable-next-line no-useless-escape // eslint-disable-next-line no-useless-escape
embed.addField('User', `${member.username}#${member.discriminator} | XXX-XX-${report.pin[2]}`); embed.addField('User', `${member.username}#${member.discriminator} | XXX-XX-${report.pin[2]}`);
embed.addField('Decision', 'DECLINED'); embed.addField('Decision', 'DECLINED');
embed.addField('Underwriter', `${message.author.username}, ${staff.pn.slice(0, 2).join(', ')} *on behalf of Library of Code sp-us*`); embed.addField('Underwriter', `${message.author.username}, ${staff.pn.slice(0, 2).join(', ')} *on behalf of Library of Code sp-us*`);
embed.addField('Application ID', saa.applicationID); embed.addField('Application ID', saa.applicationID);
embed.addField('Service Code', saa.serviceCode); embed.addField('Service Code', saa.serviceCode);
embed.setFooter(this.client.user.username, this.client.user.avatarURL); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp(); embed.setTimestamp();
const log = <TextChannel> this.client.guilds.get(this.client.config.guildID).channels.get('611584771356622849'); const log = <TextChannel> this.client.guilds.get(this.client.config.guildID).channels.get('611584771356622849');
log.createMessage({ embed }); log.createMessage({ embed });
embed.setDescription(`*A SAA has been ran in your name for a service, this embed contains the information about the result of that decision.*\n\nAccess link to the EDS recommendation for this decision: https://eds.libraryofcode.org/dec/${saa.edsToken}`); embed.setDescription(`*A SAA has been ran in your name for a service, this embed contains the information about the result of that decision.*\n\nAccess link to the EDS recommendation for this decision: https://eds.libraryofcode.org/dec/${saa.edsToken}`);
const chan = await this.client.getDMChannel(saa.userID); const chan = await this.client.getDMChannel(saa.userID);
chan.createMessage({ embed }).then(() => this.success(message.channel, 'SAA successfully processed.')).catch(() => this.error(message.channel, 'Unable to deliver decision to user.')); chan.createMessage({ embed }).then(() => this.success(message.channel, 'SAA successfully processed.')).catch(() => this.error(message.channel, 'Unable to deliver decision to user.'));
await this.client.db.mongo.SAA.deleteOne({ _id: saa._id }).lean().exec(); await this.client.db.mongo.SAA.deleteOne({ _id: saa._id }).lean().exec();
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -23,186 +23,182 @@ export default class Score extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { let check = false;
let check = false; let user: User;
let user: User; if (!args[0] || !this.checkCustomPermissions(this.client.util.resolveMember(message.author.id, this.mainGuild), 4)) {
if (!args[0] || !this.checkCustomPermissions(this.client.util.resolveMember(message.author.id, this.mainGuild), 4)) { user = message.author;
user = message.author;
if (!user) return this.error(message.channel, 'Member not found.');
await this.client.report.createInquiry(user.id, `${user.username} via Discord`, 1);
check = true;
} else {
user = this.client.util.resolveMember(args[0], this.mainGuild)?.user;
if (!user) {
const sc = await this.client.db.mongo.Score.findOne({ pin: [Number(args[0].split('-')[0]), Number(args[0].split('-')[1]), Number(args[0].split('-')[2])] });
if (!sc) return this.error(message.channel, 'Member not found.');
user = this.client.util.resolveMember(sc.userID, this.mainGuild)?.user;
}
if (args[1] !== 'soft' && args[1] !== 'hard') return this.error(message.channel, 'Invalid syntax. Report pull type must be "soft" or "hard".');
if (!user) return this.error(message.channel, 'Member not found.');
if (message.channel.type !== 0) return this.error(message.channel, 'Hard Inquiries must be initiated in a guild.');
if (args[1] === 'hard') {
if (args.length < 3) return this.client.commands.get('help').run(message, [this.name]);
const name = args.slice(2).join(' ').split(':')[0];
const reason = args.slice(2).join(' ').split(':')[1];
const score = await this.client.db.mongo.Score.findOne({ userID: user.id });
if (!score) return this.error(message.channel, 'Score not calculated yet.');
if (score.locked) return this.error(message.channel, 'The score report you have requested has been locked.');
await this.client.report.createInquiry(score.userID, name, 0, reason);
}
}
if (!user) return this.error(message.channel, 'Member not found.'); if (!user) return this.error(message.channel, 'Member not found.');
const score = await this.client.db.mongo.Score.findOne({ userID: user.id }); await this.client.report.createInquiry(user.id, `${user.username} via Discord`, 1);
const inqs = await this.client.db.mongo.Inquiry.find({ userID: user.id, type: 0 }); check = true;
if (!score) return this.error(message.channel, 'Community Report has not been generated yet.'); } else {
let totalScore = '0'; user = this.client.util.resolveMember(args[0], this.mainGuild)?.user;
let activityScore = '0'; if (!user) {
let moderationScore = '0'; const sc = await this.client.db.mongo.Score.findOne({ pin: [Number(args[0].split('-')[0]), Number(args[0].split('-')[1]), Number(args[0].split('-')[2])] });
let roleScore = '0'; if (!sc) return this.error(message.channel, 'Member not found.');
let cloudServicesScore = '0'; user = this.client.util.resolveMember(sc.userID, this.mainGuild)?.user;
let otherScore = '0';
let miscScore = '0';
if (score) {
if (score.total < 200) totalScore = '---';
else if (score.total > 800) totalScore = '800';
else totalScore = `${score.total}`;
if (score.activity < 10) activityScore = '---';
else if (score.activity > Math.floor((Math.log1p(getTotalMessageCount(this.client)) * 12))) activityScore = String(Math.floor((Math.log1p(getTotalMessageCount(this.client)) * 12)));
else activityScore = `${score.activity}`;
if (score.roles <= 0) roleScore = '---';
else if (score.roles > 54) roleScore = '54';
else roleScore = `${score.roles}`;
moderationScore = `${score.moderation}`;
if (score.other === 0) otherScore = '---';
else otherScore = `${score.other}`;
if (score.staff <= 0) miscScore = '---';
else miscScore = `${score.staff}`;
if (score.cloudServices === 0) cloudServicesScore = '---';
else if (score.cloudServices > 10) cloudServicesScore = '10';
else cloudServicesScore = `${score.cloudServices}`;
} // else return this.error(message.channel, 'Community Score has not been calculated yet.');
const set = [];
const accounts = await this.client.db.mongo.Score.find().lean().exec();
for (const sc of accounts) {
if (sc.total < 200) { continue; }
if (sc.total > 800) { set.push(800); continue; }
set.push(sc.total);
} }
const percentile = this.client.util.percentile(set, score.total); if (args[1] !== 'soft' && args[1] !== 'hard') return this.error(message.channel, 'Invalid syntax. Report pull type must be "soft" or "hard".');
const embed = new RichEmbed(); if (!user) return this.error(message.channel, 'Member not found.');
embed.setTitle('Community Report'); if (message.channel.type !== 0) return this.error(message.channel, 'Hard Inquiries must be initiated in a guild.');
embed.setAuthor(user.username, user.avatarURL); if (args[1] === 'hard') {
embed.setThumbnail(user.avatarURL); if (args.length < 3) return this.client.commands.get('help').run(message, [this.name]);
/* for (const role of member.roles.map((r) => this.mainGuild.roles.get(r)).sort((a, b) => b.position - a.position)) { const name = args.slice(2).join(' ').split(':')[0];
if (role?.color !== 0) { const reason = args.slice(2).join(' ').split(':')[1];
embed.setColor(role.color); const score = await this.client.db.mongo.Score.findOne({ userID: user.id });
if (!score) return this.error(message.channel, 'Score not calculated yet.');
if (score.locked) return this.error(message.channel, 'The score report you have requested has been locked.');
await this.client.report.createInquiry(score.userID, name, 0, reason);
}
}
if (!user) return this.error(message.channel, 'Member not found.');
const score = await this.client.db.mongo.Score.findOne({ userID: user.id });
const inqs = await this.client.db.mongo.Inquiry.find({ userID: user.id, type: 0 });
if (!score) return this.error(message.channel, 'Community Report has not been generated yet.');
let totalScore = '0';
let activityScore = '0';
let moderationScore = '0';
let roleScore = '0';
let cloudServicesScore = '0';
let otherScore = '0';
let miscScore = '0';
if (score) {
if (score.total < 200) totalScore = '---';
else if (score.total > 800) totalScore = '800';
else totalScore = `${score.total}`;
if (score.activity < 10) activityScore = '---';
else if (score.activity > Math.floor((Math.log1p(getTotalMessageCount(this.client)) * 12))) activityScore = String(Math.floor((Math.log1p(getTotalMessageCount(this.client)) * 12)));
else activityScore = `${score.activity}`;
if (score.roles <= 0) roleScore = '---';
else if (score.roles > 54) roleScore = '54';
else roleScore = `${score.roles}`;
moderationScore = `${score.moderation}`;
if (score.other === 0) otherScore = '---';
else otherScore = `${score.other}`;
if (score.staff <= 0) miscScore = '---';
else miscScore = `${score.staff}`;
if (score.cloudServices === 0) cloudServicesScore = '---';
else if (score.cloudServices > 10) cloudServicesScore = '10';
else cloudServicesScore = `${score.cloudServices}`;
} // else return this.error(message.channel, 'Community Score has not been calculated yet.');
const set = [];
const accounts = await this.client.db.mongo.Score.find().lean().exec();
for (const sc of accounts) {
if (sc.total < 200) { continue; }
if (sc.total > 800) { set.push(800); continue; }
set.push(sc.total);
}
const percentile = this.client.util.percentile(set, score.total);
const embed = new RichEmbed();
embed.setTitle('Community Report');
embed.setAuthor(user.username, user.avatarURL);
embed.setThumbnail(user.avatarURL);
/* for (const role of member.roles.map((r) => this.mainGuild.roles.get(r)).sort((a, b) => b.position - a.position)) {
if (role?.color !== 0) {
embed.setColor(role.color);
break;
}
} */
let inqAdded = 0;
if (inqs?.length > 0) {
let desc = '__**Hard Inquiries**__\n*These inquiries will fall off your report within 2 months, try to keep your hard inquiries to a minimum. If you want to file a dispute, please DM Ramirez.*\n\n';
inqs.forEach((inq) => {
const testDate = (new Date(new Date(inq.date).setHours(1460)));
// eslint-disable-next-line no-useless-escape
if (testDate > new Date()) {
desc += `${inq.iid ? `__[${inq.iid}]__\n` : ''}**Department/Service:** ${inq.name.replace(/\*/gmi, '')}\n**Reason:** ${inq.reason}\n**Date:** ${moment(inq.date).format('MMMM Do YYYY, h:mm:ss')}\n**Expires:** ${moment(testDate).calendar()}\n\n`;
inqAdded++;
}
});
if (inqAdded <= 0) desc = '';
if (desc.length >= 1900) {
embed.setDescription('__***Too many Hard Inquiries to show, please see https://report.libraryofcode.org***__');
} else {
embed.setDescription(desc);
}
}
let color = '🔴';
let additionalText = 'POOR';
embed.setColor('FF0000');
if (score.total >= 550) { color = '🟠'; additionalText = 'FAIR'; embed.setColor('FFA500'); }
if (score.total >= 630) { color = '🟡'; additionalText = 'GOOD'; embed.setColor('FFFF00'); }
if (score.total >= 700) { color = '🟢'; additionalText = 'EXCELLENT'; embed.setColor('66FF66'); }
if (score.total >= 770) { color = '✨'; additionalText = 'EXCEPTIONAL'; embed.setColor('#99FFFF'); }
embed.addField('CommScore™ | 200 to 800', score ? `${color} ${totalScore} | ${additionalText} | ${this.client.util.ordinal(Math.round(percentile))} Percentile` : 'N/C', true);
embed.addField(`Activity | 10 to ${Math.floor(Math.log1p(getTotalMessageCount(this.client)) * 12)}`, activityScore || 'N/C', true);
embed.addField('Roles | 1 to N/A', roleScore || 'N/C', true);
embed.addField('Moderation | N/A to 2' || 'N/C', moderationScore, true);
embed.addField('Cloud Services | N/A to 10+', cloudServicesScore || 'N/C', true);
embed.addField('Other', otherScore || 'N/C', true);
embed.addField('Misc', miscScore || 'N/C', true);
let judgementsStr: string = '';
const judgements = await this.client.db.mongo.Judgement.find({ userID: user.id }).lean().exec();
if (judgements?.length > 0) {
for (const judgement of judgements) {
let severity: string;
switch (judgement.severity) {
case 0:
severity = 'LOW';
break;
case 1:
severity = 'MEDIUM';
break;
case 2:
severity = 'HIGH';
break;
default:
break;
}
judgementsStr += `__**Docket #\`${judgement.jid}\`**__\n${judgement.description}\n**Severity:** ${severity}\n**Entered at:** ${moment(judgement.date).format('MMMM Do YYYY, h:mm:ss')}\n**Expiration:** ${judgement.expires ? `${moment(judgement.expires).format('MMMM Do YYYY, h:mm:ss')}` : 'INDEFINITE'}\n\n`;
}
if (judgementsStr?.length > 1000) embed.addField('Judgements', '*Too many to list.*');
else embed.addField('Judgements', judgementsStr);
}
if (score.locked) {
embed.addField('Status', 'Score Report Locked');
}
if (score.pin?.length > 0 && message.channel.type === 1) {
embed.addField('PIN', score.pin.join('-'), true);
}
if (score.lastUpdate) {
embed.setFooter('Report last updated', this.client.user.avatarURL);
embed.setTimestamp(score.lastUpdate);
} else {
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
}
// eslint-disable-next-line no-mixed-operators
if ((args[1] === 'hard' || args[1] === 'soft') && this.checkCustomPermissions(this.client.util.resolveMember(message.author.id, this.mainGuild), 4)) {
if (score.pin?.length > 0) embed.addField('PIN', score.pin.join('-'), true);
if (args[1] === 'soft' && !check) {
let name = '';
// eslint-disable-next-line no-unreachable-loop
for (const role of this.client.util.resolveMember(message.author.id, this.mainGuild).roles.map((r) => this.mainGuild.roles.get(r)).sort((a, b) => b.position - a.position)) {
name = `Library of Code sp-us | ${role.name}`;
break; break;
} }
} */ await this.client.report.createInquiry(user.id, name, 1);
let inqAdded = 0;
if (inqs?.length > 0) {
let desc = '__**Hard Inquiries**__\n*These inquiries will fall off your report within 2 months, try to keep your hard inquiries to a minimum. If you want to file a dispute, please DM Ramirez.*\n\n';
inqs.forEach((inq) => {
const testDate = (new Date(new Date(inq.date).setHours(1460)));
// eslint-disable-next-line no-useless-escape
if (testDate > new Date()) {
desc += `${inq.iid ? `__[${inq.iid}]__\n` : ''}**Department/Service:** ${inq.name.replace(/\*/gmi, '')}\n**Reason:** ${inq.reason}\n**Date:** ${moment(inq.date).format('MMMM Do YYYY, h:mm:ss')}\n**Expires:** ${moment(testDate).calendar()}\n\n`;
inqAdded++;
}
});
if (inqAdded <= 0) desc = '';
if (desc.length >= 1900) {
embed.setDescription('__***Too many Hard Inquiries to show, please see https://report.libraryofcode.org***__');
} else {
embed.setDescription(desc);
}
} }
let color = '🔴';
let additionalText = 'POOR';
embed.setColor('FF0000');
if (score.total >= 550) { color = '🟠'; additionalText = 'FAIR'; embed.setColor('FFA500'); }
if (score.total >= 630) { color = '🟡'; additionalText = 'GOOD'; embed.setColor('FFFF00'); }
if (score.total >= 700) { color = '🟢'; additionalText = 'EXCELLENT'; embed.setColor('66FF66'); }
if (score.total >= 770) { color = '✨'; additionalText = 'EXCEPTIONAL'; embed.setColor('#99FFFF'); }
embed.addField('CommScore™ | 200 to 800', score ? `${color} ${totalScore} | ${additionalText} | ${this.client.util.ordinal(Math.round(percentile))} Percentile` : 'N/C', true);
embed.addField(`Activity | 10 to ${Math.floor(Math.log1p(getTotalMessageCount(this.client)) * 12)}`, activityScore || 'N/C', true);
embed.addField('Roles | 1 to N/A', roleScore || 'N/C', true);
embed.addField('Moderation | N/A to 2' || 'N/C', moderationScore, true);
embed.addField('Cloud Services | N/A to 10+', cloudServicesScore || 'N/C', true);
embed.addField('Other', otherScore || 'N/C', true);
embed.addField('Misc', miscScore || 'N/C', true);
let judgementsStr: string = '';
const judgements = await this.client.db.mongo.Judgement.find({ userID: user.id }).lean().exec();
if (judgements?.length > 0) {
for (const judgement of judgements) {
let severity: string;
switch (judgement.severity) {
case 0:
severity = 'LOW';
break;
case 1:
severity = 'MEDIUM';
break;
case 2:
severity = 'HIGH';
break;
default:
break;
}
judgementsStr += `__**Docket #\`${judgement.jid}\`**__\n${judgement.description}\n**Severity:** ${severity}\n**Entered at:** ${moment(judgement.date).format('MMMM Do YYYY, h:mm:ss')}\n**Expiration:** ${judgement.expires ? `${moment(judgement.expires).format('MMMM Do YYYY, h:mm:ss')}` : 'INDEFINITE'}\n\n`;
}
if (judgementsStr?.length > 1000) embed.addField('Judgements', '*Too many to list.*');
else embed.addField('Judgements', judgementsStr);
}
if (score.locked) {
embed.addField('Status', 'Score Report Locked');
}
if (score.pin?.length > 0 && message.channel.type === 1) {
embed.addField('PIN', score.pin.join('-'), true);
}
if (score.lastUpdate) {
embed.setFooter('Report last updated', this.client.user.avatarURL);
embed.setTimestamp(score.lastUpdate);
} else {
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
}
// eslint-disable-next-line no-mixed-operators
if ((args[1] === 'hard' || args[1] === 'soft') && this.checkCustomPermissions(this.client.util.resolveMember(message.author.id, this.mainGuild), 4)) {
if (score.pin?.length > 0) embed.addField('PIN', score.pin.join('-'), true);
if (args[1] === 'soft' && !check) {
let name = '';
// eslint-disable-next-line no-unreachable-loop
for (const role of this.client.util.resolveMember(message.author.id, this.mainGuild).roles.map((r) => this.mainGuild.roles.get(r)).sort((a, b) => b.position - a.position)) {
name = `Library of Code sp-us | ${role.name}`;
break;
}
await this.client.report.createInquiry(user.id, name, 1);
}
}
if (args[1] === 'hard' && this.checkCustomPermissions(this.client.util.resolveMember(message.author.id, this.mainGuild), 6)) {
await message.channel.createMessage({ embed });
await message.channel.createMessage('***===BEGIN ADDITIONAL INFORMATION===***');
await this.client.commands.get('score').subcommands.get('hist').run(message, [user.id]);
await this.client.commands.get('whois').run(message, [user.id]);
await this.client.commands.get('notes').run(message, [user.id]);
const whoisMessage = await message.channel.createMessage(`=whois ${user.id} --full`);
await whoisMessage.delete();
const modlogsMessage = await message.channel.createMessage(`=modlogs ${user.id}`);
await modlogsMessage.delete();
return await message.channel.createMessage('***===END ADDITIONAL INFORMATION===***');
}
return message.channel.createMessage({ embed });
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
if (args[1] === 'hard' && this.checkCustomPermissions(this.client.util.resolveMember(message.author.id, this.mainGuild), 6)) {
await message.channel.createMessage({ embed });
await message.channel.createMessage('***===BEGIN ADDITIONAL INFORMATION===***');
await this.client.commands.get('score').subcommands.get('hist').run(message, [user.id]);
await this.client.commands.get('whois').run(message, [user.id]);
await this.client.commands.get('notes').run(message, [user.id]);
const whoisMessage = await message.channel.createMessage(`=whois ${user.id} --full`);
await whoisMessage.delete();
const modlogsMessage = await message.channel.createMessage(`=modlogs ${user.id}`);
await modlogsMessage.delete();
return message.channel.createMessage('***===END ADDITIONAL INFORMATION===***');
}
return message.channel.createMessage({ embed });
} }
} }

View File

@ -18,116 +18,113 @@ export default class Score_Hist extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { let user: User;
let user: User; if (!this.checkCustomPermissions(message.member, 4)) {
if (!this.checkCustomPermissions(message.member, 4)) { user = message.author;
user = message.author; await this.client.report.createInquiry(user.id, `${user.username}#${user.discriminator} VIA DISCORD - [HISTORICAL]`, 1);
await this.client.report.createInquiry(user.id, `${user.username}#${user.discriminator} VIA DISCORD - [HISTORICAL]`, 1); } else if (!args[0]) {
} else if (!args[0]) { user = message.author;
user = message.author; await this.client.report.createInquiry(user.id, `${user.username}#${user.discriminator} VIA DISCORD - [HISTORICAL]`, 1);
await this.client.report.createInquiry(user.id, `${user.username}#${user.discriminator} VIA DISCORD - [HISTORICAL]`, 1); } else {
} else { user = this.client.util.resolveMember(args[0], this.mainGuild)?.user;
user = this.client.util.resolveMember(args[0], this.mainGuild)?.user; if (!user) {
if (!user) { const sc = await this.client.db.mongo.Score.findOne({ pin: [Number(args[0].split('-')[0]), Number(args[0].split('-')[1]), Number(args[0].split('-')[2])] });
const sc = await this.client.db.mongo.Score.findOne({ pin: [Number(args[0].split('-')[0]), Number(args[0].split('-')[1]), Number(args[0].split('-')[2])] }); user = this.client.util.resolveMember(sc.userID, this.mainGuild)?.user;
user = this.client.util.resolveMember(sc.userID, this.mainGuild)?.user;
let name = ''; let name = '';
for (const role of this.client.util.resolveMember(message.author.id, this.mainGuild).roles.map((r) => this.mainGuild.roles.get(r)).sort((a, b) => b.position - a.position)) { // eslint-disable-next-line no-unreachable-loop
name = `Library of Code sp-us | ${role.name} - [HISTORICAL]`; for (const role of this.client.util.resolveMember(message.author.id, this.mainGuild).roles.map((r) => this.mainGuild.roles.get(r)).sort((a, b) => b.position - a.position)) {
break; name = `Library of Code sp-us | ${role.name} - [HISTORICAL]`;
} break;
await this.client.report.createInquiry(user.id, name, 1);
} }
await this.client.report.createInquiry(user.id, name, 1);
} }
if (!user) return this.error(message.channel, 'Member not found.');
const hists = await this.client.db.mongo.ScoreHistorical.find({ userID: user.id }).lean().exec();
if (!hists) return this.error(message.channel, 'No history found.');
if (hists.length < 1) return this.error(message.channel, 'No history found.');
const totalArray: number[] = [];
const activityArray: number[] = [];
const moderationArray: number[] = [];
const roleArray: number[] = [];
const cloudServicesArray: number[] = [];
const otherArray: number[] = [];
const miscArray: number[] = [];
for (const hist of hists) {
totalArray.push(hist.report.total);
activityArray.push(hist.report.activity);
moderationArray.push(hist.report.moderation);
roleArray.push(hist.report.roles);
cloudServicesArray.push(hist.report.cloudServices);
otherArray.push(hist.report.other);
miscArray.push(hist.report.staff);
}
const stat = {
totalMean: mean(totalArray),
totalMode: mode(totalArray),
totalMedian: median(totalArray),
activityMean: mean(activityArray),
rolesMean: mean(roleArray),
moderationMean: mean(moderationArray),
cloudServicesMean: mean(cloudServicesArray),
otherMean: mean(otherArray),
miscMean: mean(miscArray),
};
let totalMean = '0';
let totalMedian = '0';
let totalMode = '0';
let activityMean = '0';
let moderationMean = '0';
let roleMean = '0';
let cloudServicesMean = '0';
let otherMean = '0';
let miscMean = '0';
if (stat.totalMean < 200) totalMean = '---';
else if (stat.totalMean > 800) totalMean = '800';
else totalMean = `${stat.totalMean}`;
if (stat.totalMedian < 200) totalMedian = '---';
else if (stat.totalMedian > 800) totalMedian = '800';
else totalMedian = `${stat.totalMedian}`;
if (stat.totalMode < 200) totalMode = '---';
else if (stat.totalMode > 800) totalMode = '800';
else totalMode = `${stat.totalMode}`;
if (stat.activityMean < 10) activityMean = '---';
else if (stat.activityMean > Math.floor((Math.log1p(getTotalMessageCount(this.client)) * 12))) activityMean = String(Math.floor((Math.log1p(getTotalMessageCount(this.client)) * 12)));
else activityMean = `${stat.activityMean}`;
if (stat.rolesMean <= 0) roleMean = '---';
else if (stat.rolesMean > 54) roleMean = '54';
else roleMean = `${stat.rolesMean}`;
moderationMean = `${stat.moderationMean}`;
if (stat.otherMean === 0) otherMean = '---';
else otherMean = `${stat.otherMean}`;
if (stat.miscMean <= 0) miscMean = '---';
else miscMean = `${stat.miscMean}`;
if (stat.cloudServicesMean === 0) cloudServicesMean = '---';
else if (stat.cloudServicesMean > 10) cloudServicesMean = '10';
else cloudServicesMean = `${stat.cloudServicesMean}`;
const embed = new RichEmbed();
embed.setTitle('Historical Community Report');
embed.setAuthor(user.username, user.avatarURL);
embed.setThumbnail(user.avatarURL);
embed.setDescription(`__**Statistical Averages**__\n**CommScore™ Mean:** ${Number(totalMean).toFixed(2)} | **CommScore™ Mode:** ${Number(totalMode).toFixed(2)} | **CommScore™ Median:** ${Number(totalMedian).toFixed(2)}\n\n**Activity Mean:** ${Number(activityMean).toFixed(2)}\n**Roles Mean:** ${Number(roleMean).toFixed(2)}\n**Moderation Mean:** ${Number(moderationMean).toFixed(2)}\n**Cloud Services Mean:** ${Number(cloudServicesMean).toFixed(2)}\n**Other Mean:** ${Number(otherMean).toFixed(2)}\n**Misc Mean:** ${Number(miscMean).toFixed(2)}`);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
return message.channel.createMessage({ embed });
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
if (!user) return this.error(message.channel, 'Member not found.');
const hists = await this.client.db.mongo.ScoreHistorical.find({ userID: user.id }).lean().exec();
if (!hists) return this.error(message.channel, 'No history found.');
if (hists.length < 1) return this.error(message.channel, 'No history found.');
const totalArray: number[] = [];
const activityArray: number[] = [];
const moderationArray: number[] = [];
const roleArray: number[] = [];
const cloudServicesArray: number[] = [];
const otherArray: number[] = [];
const miscArray: number[] = [];
for (const hist of hists) {
totalArray.push(hist.report.total);
activityArray.push(hist.report.activity);
moderationArray.push(hist.report.moderation);
roleArray.push(hist.report.roles);
cloudServicesArray.push(hist.report.cloudServices);
otherArray.push(hist.report.other);
miscArray.push(hist.report.staff);
}
const stat = {
totalMean: mean(totalArray),
totalMode: mode(totalArray),
totalMedian: median(totalArray),
activityMean: mean(activityArray),
rolesMean: mean(roleArray),
moderationMean: mean(moderationArray),
cloudServicesMean: mean(cloudServicesArray),
otherMean: mean(otherArray),
miscMean: mean(miscArray),
};
let totalMean = '0';
let totalMedian = '0';
let totalMode = '0';
let activityMean = '0';
let moderationMean = '0';
let roleMean = '0';
let cloudServicesMean = '0';
let otherMean = '0';
let miscMean = '0';
if (stat.totalMean < 200) totalMean = '---';
else if (stat.totalMean > 800) totalMean = '800';
else totalMean = `${stat.totalMean}`;
if (stat.totalMedian < 200) totalMedian = '---';
else if (stat.totalMedian > 800) totalMedian = '800';
else totalMedian = `${stat.totalMedian}`;
if (stat.totalMode < 200) totalMode = '---';
else if (stat.totalMode > 800) totalMode = '800';
else totalMode = `${stat.totalMode}`;
if (stat.activityMean < 10) activityMean = '---';
else if (stat.activityMean > Math.floor((Math.log1p(getTotalMessageCount(this.client)) * 12))) activityMean = String(Math.floor((Math.log1p(getTotalMessageCount(this.client)) * 12)));
else activityMean = `${stat.activityMean}`;
if (stat.rolesMean <= 0) roleMean = '---';
else if (stat.rolesMean > 54) roleMean = '54';
else roleMean = `${stat.rolesMean}`;
moderationMean = `${stat.moderationMean}`;
if (stat.otherMean === 0) otherMean = '---';
else otherMean = `${stat.otherMean}`;
if (stat.miscMean <= 0) miscMean = '---';
else miscMean = `${stat.miscMean}`;
if (stat.cloudServicesMean === 0) cloudServicesMean = '---';
else if (stat.cloudServicesMean > 10) cloudServicesMean = '10';
else cloudServicesMean = `${stat.cloudServicesMean}`;
const embed = new RichEmbed();
embed.setTitle('Historical Community Report');
embed.setAuthor(user.username, user.avatarURL);
embed.setThumbnail(user.avatarURL);
embed.setDescription(`__**Statistical Averages**__\n**CommScore™ Mean:** ${Number(totalMean).toFixed(2)} | **CommScore™ Mode:** ${Number(totalMode).toFixed(2)} | **CommScore™ Median:** ${Number(totalMedian).toFixed(2)}\n\n**Activity Mean:** ${Number(activityMean).toFixed(2)}\n**Roles Mean:** ${Number(roleMean).toFixed(2)}\n**Moderation Mean:** ${Number(moderationMean).toFixed(2)}\n**Cloud Services Mean:** ${Number(cloudServicesMean).toFixed(2)}\n**Other Mean:** ${Number(otherMean).toFixed(2)}\n**Misc Mean:** ${Number(miscMean).toFixed(2)}`);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
return message.channel.createMessage({ embed });
} }
} }

View File

@ -13,24 +13,20 @@ export default class Score_Notify extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { const user = message.author;
const user = message.author; if (!user) return this.error(message.channel, 'Member not found.');
if (!user) return this.error(message.channel, 'Member not found.'); const score = await this.client.db.mongo.Score.findOne({ userID: message.author.id });
const score = await this.client.db.mongo.Score.findOne({ userID: message.author.id }); if (!score) return this.error(message.channel, 'Score not calculated yet.');
if (!score) return this.error(message.channel, 'Score not calculated yet.'); if (!score.notify) await this.client.db.mongo.Score.updateOne({ userID: message.author.id }, { $set: { notify: false } });
if (!score.notify) await this.client.db.mongo.Score.updateOne({ userID: message.author.id }, { $set: { notify: false } }); switch (args[0]) {
switch (args[0]) { case 'on':
case 'on': await this.client.db.mongo.Score.updateOne({ userID: message.author.id }, { $set: { notify: true } });
await this.client.db.mongo.Score.updateOne({ userID: message.author.id }, { $set: { notify: true } }); return this.success(message.channel, 'You will now be sent notifications whenever your score is hard-pulled.');
return this.success(message.channel, 'You will now be sent notifications whenever your score is hard-pulled.'); case 'off':
case 'off': await this.client.db.mongo.Score.updateOne({ userID: message.author.id }, { $set: { notify: false } });
await this.client.db.mongo.Score.updateOne({ userID: message.author.id }, { $set: { notify: false } }); return this.success(message.channel, 'You will no longer be sent notifications when your score is hard-pulled.');
return this.success(message.channel, 'You will no longer be sent notifications when your score is hard-pulled.'); default:
default: return this.error(message.channel, 'Invalid option. Valid options are `on` and `off`.');
return this.error(message.channel, 'Invalid option. Valid options are `on` and `off`.');
}
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
} }
} }

View File

@ -13,23 +13,19 @@ export default class Score_Pref extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!message.author) return this.error(message.channel, 'Member not found.');
if (!message.author) return this.error(message.channel, 'Member not found.'); const score = await this.client.db.mongo.Score.findOne({ userID: message.author.id });
const score = await this.client.db.mongo.Score.findOne({ userID: message.author.id }); if (!score) return this.error(message.channel, 'Score not calculated yet.');
if (!score) return this.error(message.channel, 'Score not calculated yet.'); if (!score.locked) await this.client.db.mongo.Score.updateOne({ userID: message.author.id }, { $set: { locked: false } });
if (!score.locked) await this.client.db.mongo.Score.updateOne({ userID: message.author.id }, { $set: { locked: false } }); switch (args[0]) {
switch (args[0]) { case 'lock':
case 'lock': await this.client.db.mongo.Score.updateOne({ userID: message.author.id }, { $set: { locked: true } });
await this.client.db.mongo.Score.updateOne({ userID: message.author.id }, { $set: { locked: true } }); return this.success(message.channel, 'Your report is now locked.');
return this.success(message.channel, 'Your report is now locked.'); case 'unlock':
case 'unlock': await this.client.db.mongo.Score.updateOne({ userID: message.author.id }, { $set: { locked: false } });
await this.client.db.mongo.Score.updateOne({ userID: message.author.id }, { $set: { locked: false } }); return this.success(message.channel, 'Your report is now unlocked.');
return this.success(message.channel, 'Your report is now unlocked.'); default:
default: return this.error(message.channel, 'Invalid input');
return this.error(message.channel, 'Invalid input');
}
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
} }
} }

View File

@ -13,17 +13,13 @@ export default class Setnick extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); const member = this.client.util.resolveMember(args[0], this.mainGuild);
const member = this.client.util.resolveMember(args[0], this.mainGuild); if (!member) return this.error(message.channel, 'Cannot find user.');
if (!member) return this.error(message.channel, 'Cannot find user.'); let nickname = args.slice(1).join(' ');
let nickname = args.slice(1).join(' '); if (args.length === 1) nickname = null;
if (args.length === 1) nickname = null; if (nickname?.length > 32) return this.error(message.channel, 'New nickname may not be more than 32 characters long.');
if (nickname?.length > 32) return this.error(message.channel, 'New nickname may not be more than 32 characters long.'); await member.edit({ nick: nickname });
await member.edit({ nick: nickname }); return this.success(message.channel, `Updated the nickname of ${member.user.username}#${member.user.discriminator}.`);
return this.success(message.channel, `Updated the nickname of ${member.user.username}#${member.user.discriminator}.`);
} catch (err) {
return this.client.util.handleError(err, message, this, false);
}
} }
} }

View File

@ -16,72 +16,68 @@ export default class SIP extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { const staff = await this.client.db.mongo.Staff.findOne({ userID: message.author.id });
const staff = await this.client.db.mongo.Staff.findOne({ userID: message.author.id }); if (!staff || !staff?.extension) return this.error(message.channel, 'You must have an extension to complete this action.');
if (!staff || !staff?.extension) return this.error(message.channel, 'You must have an extension to complete this action.'); this.success(message.channel, 'Queued call.');
this.success(message.channel, 'Queued call.');
const bridge = await this.client.pbx.ari.Bridge().create(); const bridge = await this.client.pbx.ari.Bridge().create();
let receiver: Channel = this.client.pbx.ari.Channel(); let receiver: Channel = this.client.pbx.ari.Channel();
let sender: Channel = this.client.pbx.ari.Channel(); let sender: Channel = this.client.pbx.ari.Channel();
try {
sender = await this.client.pbx.ari.channels.originate({
endpoint: `PJSIP/${staff.extension}`,
extension: staff.extension,
callerId: 'LOC PBX OPERATOR <operator>',
context: 'from-internal',
priority: 1,
app: 'cr-zero',
});
} catch {
return this.error(message.channel, 'Unable to dial your extension.');
}
sender.once('StasisStart', async () => {
await Misc.play(this.client.pbx, sender, 'sound:pls-hold-while-try');
await sender.ring();
try { try {
sender = await this.client.pbx.ari.channels.originate({ receiver = await receiver.originate({
endpoint: `PJSIP/${staff.extension}`, endpoint: `SIP/${args.join(' ')}`,
extension: staff.extension,
callerId: 'LOC PBX OPERATOR <operator>', callerId: 'LOC PBX OPERATOR <operator>',
context: 'from-internal', context: 'from-internal',
priority: 1, priority: 1,
app: 'cr-zero', app: 'cr-zero',
}); });
} catch { } catch {
return this.error(message.channel, 'Unable to dial your extension.'); await Misc.play(this.client.pbx, sender, 'sound:discon-or-out-of-service');
await sender.hangup().catch(() => {});
return false;
} }
sender.once('StasisStart', async () => { // receiver.once('StasisStart', )
await Misc.play(this.client.pbx, sender, 'sound:pls-hold-while-try'); });
await sender.ring();
try { receiver.once('StasisStart', async () => {
receiver = await receiver.originate({ await sender.ringStop();
endpoint: `SIP/${args.join(' ')}`, await bridge.addChannel({ channel: [receiver.id, sender.id] });
callerId: 'LOC PBX OPERATOR <operator>', await bridge.play({ media: 'sound:beep' });
context: 'from-internal', });
priority: 1,
app: 'cr-zero',
});
} catch {
await Misc.play(this.client.pbx, sender, 'sound:discon-or-out-of-service');
await sender.hangup().catch(() => {});
return false;
}
// receiver.once('StasisStart', ) receiver.once('ChannelDestroyed', async () => {
}); if (!sender.connected) return;
await Misc.play(this.client.pbx, sender, ['sound:the-number-u-dialed', 'sound:T-is-not-available', 'sound:please-try-again-later']);
await sender.hangup().catch(() => {});
await bridge.destroy().catch(() => {});
});
receiver.once('StasisStart', async () => { receiver.once('StasisEnd', async () => {
await sender.ringStop(); await sender.hangup().catch(() => {});
await bridge.addChannel({ channel: [receiver.id, sender.id] }); await bridge.destroy().catch(() => {});
await bridge.play({ media: 'sound:beep' }); });
}); sender.once('StasisEnd', async () => {
await receiver.hangup().catch(() => {});
receiver.once('ChannelDestroyed', async () => { await bridge.destroy().catch(() => {});
if (!sender.connected) return; });
await Misc.play(this.client.pbx, sender, ['sound:the-number-u-dialed', 'sound:T-is-not-available', 'sound:please-try-again-later']);
await sender.hangup().catch(() => {});
await bridge.destroy().catch(() => {});
});
receiver.once('StasisEnd', async () => {
await sender.hangup().catch(() => {});
await bridge.destroy().catch(() => {});
});
sender.once('StasisEnd', async () => {
await receiver.hangup().catch(() => {});
await bridge.destroy().catch(() => {});
});
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -17,18 +17,14 @@ export default class Slowmode extends Command {
} }
public async run(message: Message<GuildTextableChannel>, args: string[]) { public async run(message: Message<GuildTextableChannel>, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
const [length, unit] = args[0].match(this.regex); const [length, unit] = args[0].match(this.regex);
if (Number.isNaN(Number(length))) return this.error(message.channel, 'Could not determine the slowmode time.'); if (Number.isNaN(Number(length))) return this.error(message.channel, 'Could not determine the slowmode time.');
const momentSeconds: number = Math.round(moment.duration(length, unit as unitOfTime.Base || 's').asSeconds()); const momentSeconds: number = Math.round(moment.duration(length, unit as unitOfTime.Base || 's').asSeconds());
if (momentSeconds > 21600 || momentSeconds < 0) return this.error(message.channel, 'Slowmode must be between 0 seconds and 6 hours.'); if (momentSeconds > 21600 || momentSeconds < 0) return this.error(message.channel, 'Slowmode must be between 0 seconds and 6 hours.');
return message.channel.edit({ rateLimitPerUser: momentSeconds }).then((c) => message.addReaction(':success:477618704155410452')); return message.channel.edit({ rateLimitPerUser: momentSeconds }).then((c) => message.addReaction(':success:477618704155410452'));
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -22,10 +22,6 @@ export default class StaffAccountSelfServ extends Command {
} }
public async run(message: Message) { public async run(message: Message) {
try { return this.client.commands.get('help').run(message, [this.name]);
return this.client.commands.get('help').run(message, [this.name]);
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -13,25 +13,21 @@ export default class Stats extends Command {
} }
public async run(message: Message) { public async run(message: Message) {
try { const messages = await this.client.db.mongo.Stat.findOne({ name: 'messages' });
const messages = await this.client.db.mongo.Stat.findOne({ name: 'messages' }); const commands = await this.client.db.mongo.Stat.findOne({ name: 'commands' });
const commands = await this.client.db.mongo.Stat.findOne({ name: 'commands' }); const pages = await this.client.db.mongo.Stat.findOne({ name: 'pages' });
const pages = await this.client.db.mongo.Stat.findOne({ name: 'pages' }); const requests = await this.client.db.mongo.Stat.findOne({ name: 'requests' });
const requests = await this.client.db.mongo.Stat.findOne({ name: 'requests' });
const embed = new RichEmbed(); const embed = new RichEmbed();
embed.setTitle('Statistics'); embed.setTitle('Statistics');
embed.setThumbnail(this.client.user.avatarURL); embed.setThumbnail(this.client.user.avatarURL);
embed.addField('Messages Seen', `${messages.value}`, true); embed.addField('Messages Seen', `${messages.value}`, true);
embed.addField('Commands Executed', `${commands.value}`, true); embed.addField('Commands Executed', `${commands.value}`, true);
embed.addField('HTTP Requests Served', `${requests.value}`, true); embed.addField('HTTP Requests Served', `${requests.value}`, true);
embed.addField('Pages Sent', `${pages.value}`, true); embed.addField('Pages Sent', `${pages.value}`, true);
embed.addField('Jobs Processed', `${(await this.client.queue.jobCounts()).completed}`, true); embed.addField('Jobs Processed', `${(await this.client.queue.jobCounts()).completed}`, true);
embed.setFooter(this.client.user.username, this.client.user.avatarURL); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp(); embed.setTimestamp();
return message.channel.createMessage({ embed }); return message.channel.createMessage({ embed });
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -15,38 +15,34 @@ export default class StoreMessages extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); const check = this.client.util.resolveGuildChannel(args[0], this.mainGuild, false);
const check = this.client.util.resolveGuildChannel(args[0], this.mainGuild, false); if (!check || check.type !== 0) return this.error(message.channel, 'The channel you specified either doesn\'t exist or isn\'t a textable guild channel.');
if (!check || check.type !== 0) return this.error(message.channel, 'The channel you specified either doesn\'t exist or isn\'t a textable guild channel.'); const chan = <TextChannel> this.mainGuild.channels.get(check.id);
const chan = <TextChannel> this.mainGuild.channels.get(check.id); const loadingMessage = await this.loading(message.channel, 'Fetching messages...');
const loadingMessage = await this.loading(message.channel, 'Fetching messages...'); let messages = await chan.getMessages(10000);
let messages = await chan.getMessages(10000); if (args[1]) {
if (args[1]) { messages = messages.filter((m) => m.author.id === args[1]);
messages = messages.filter((m) => m.author.id === args[1]);
}
let html = `<strong><i>CLASSIFIED RESOURCE: CL-GEN/AD</i></strong><br><h3>Library of Code sp-us</h3><strong>Channel:</strong> ${chan.name} (${chan.id})<br><strong>Generated by:</strong> ${message.author.username}#${message.author.discriminator}<br><strong>Generated at:</strong> ${new Date().toLocaleString('en-us')}<br><br>`;
for (const msg of messages) {
html += `(<i>${new Date(msg.timestamp).toLocaleString('en-us')}</i>) [<strong>${msg.author.username}#${msg.author.discriminator} - ${msg.author.id}</strong>]: ${msg.cleanContent}<br>`;
}
message.delete();
const identifier = randomBytes(20).toString('hex');
const comp = await LocalStorage.compress(html);
const file = new this.client.db.mongo.File({
name: `${chan.name}-${new Date().toLocaleString('en-us')}.html.gz`,
identifier,
mimeType: 'application/gzip',
data: comp,
downloaded: 0,
maxDownloads: 20,
});
await file.save();
loadingMessage.delete();
this.client.getDMChannel(message.author.id).then((c) => c.createMessage(`https://cr.ins/m/${identifier}.html.gz || https://cr.ins/m/${identifier}.html?d=1`)).catch(() => this.error(message.channel, 'Could not send a DM to you.'));
return this.success(message.channel, `Fetched messages for <#${chan.id}>. Check your DMs for link to access.`);
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
let html = `<strong><i>CLASSIFIED RESOURCE: CL-GEN/AD</i></strong><br><h3>Library of Code sp-us</h3><strong>Channel:</strong> ${chan.name} (${chan.id})<br><strong>Generated by:</strong> ${message.author.username}#${message.author.discriminator}<br><strong>Generated at:</strong> ${new Date().toLocaleString('en-us')}<br><br>`;
for (const msg of messages) {
html += `(<i>${new Date(msg.timestamp).toLocaleString('en-us')}</i>) [<strong>${msg.author.username}#${msg.author.discriminator} - ${msg.author.id}</strong>]: ${msg.cleanContent}<br>`;
}
message.delete();
const identifier = randomBytes(20).toString('hex');
const comp = await LocalStorage.compress(html);
const file = new this.client.db.mongo.File({
name: `${chan.name}-${new Date().toLocaleString('en-us')}.html.gz`,
identifier,
mimeType: 'application/gzip',
data: comp,
downloaded: 0,
maxDownloads: 20,
});
await file.save();
loadingMessage.delete();
this.client.getDMChannel(message.author.id).then((c) => c.createMessage(`https://cr.ins/m/${identifier}.html.gz || https://cr.ins/m/${identifier}.html?d=1`)).catch(() => this.error(message.channel, 'Could not send a DM to you.'));
return this.success(message.channel, `Fetched messages for <#${chan.id}>. Check your DMs for link to access.`);
} }
} }

View File

@ -1,3 +1,4 @@
/* eslint-disable import/no-relative-packages */
// ?e require('mongoose').connections[0].db.command({ buildInfo: 1 }) // ?e require('mongoose').connections[0].db.command({ buildInfo: 1 })
import { Message } from 'eris'; import { Message } from 'eris';
@ -25,30 +26,26 @@ export default class SysInfo extends Command {
} }
public async run(message: Message) { public async run(message: Message) {
try { const embed = new RichEmbed();
const embed = new RichEmbed(); embed.setTitle('System & Service Information');
embed.setTitle('System & Service Information'); embed.setDescription('__Format of Services__\n- {Server/Service Name} + {various server stats} | {Node Library Used for Communication w/ Server or Service}');
embed.setDescription('__Format of Services__\n- {Server/Service Name} + {various server stats} | {Node Library Used for Communication w/ Server or Service}'); const mongoBuild = await mongoose.connections[0].db.command({ buildInfo: 1 });
const mongoBuild = await mongoose.connections[0].db.command({ buildInfo: 1 }); const mongoDatabase: {
const mongoDatabase: { collections?: number,
collections?: number, objects?: number,
objects?: number, dataSize?: number,
dataSize?: number, } = await mongoose.connections[0].db.command({ dbStats: 1 });
} = await mongoose.connections[0].db.command({ dbStats: 1 }); const asteriskInformation = await this.client.util.pbx.ari.asterisk.getInfo();
const asteriskInformation = await this.client.util.pbx.ari.asterisk.getInfo(); const redisVersion = await this.client.util.exec('redis-cli info | grep "redis_version"');
const redisVersion = await this.client.util.exec('redis-cli info | grep "redis_version"'); embed.addField('Database', `- [MongoDB v${mongoBuild.version}](https://www.mongodb.com/) + Documents: ${mongoDatabase.objects} | [Mongoose ODM v${mongooseVersion}](https://github.com/Automattic/mongoose)\n- CR Local Storage w/ GZIP Compression | Internal\n- [Redis v${redisVersion.split(':')[1]}](https://redis.io/) | [IORedis v${ioredisVersion}](https://github.com/luin/ioredis)`, true);
embed.addField('Database', `- [MongoDB v${mongoBuild.version}](https://www.mongodb.com/) + Documents: ${mongoDatabase.objects} | [Mongoose ODM v${mongooseVersion}](https://github.com/Automattic/mongoose)\n- CR Local Storage w/ GZIP Compression | Internal\n- [Redis v${redisVersion.split(':')[1]}](https://redis.io/) | [IORedis v${ioredisVersion}](https://github.com/luin/ioredis)`, true); embed.addField('Telephony/PBX', `- [Asterisk v${asteriskInformation.system.version}](https://www.asterisk.org/) | [Asterisk ARI Node.js Client v${ariVersion}](https://github.com/asterisk/node-ari-client) & [Asterisk AMI Node.js Client v${amiVersion}](https://github.com/danjenkins/node-asterisk-ami)`, true);
embed.addField('Telephony/PBX', `- [Asterisk v${asteriskInformation.system.version}](https://www.asterisk.org/) | [Asterisk ARI Node.js Client v${ariVersion}](https://github.com/asterisk/node-ari-client) & [Asterisk AMI Node.js Client v${amiVersion}](https://github.com/danjenkins/node-asterisk-ami)`, true); embed.addField('Email', `- [Postfix SMTP v3.1.12](http://www.postfix.org/) | [Nodemailer v${nodeMailerVersion}](https://github.com/nodemailer/nodemailer)`, true);
embed.addField('Email', `- [Postfix SMTP v3.1.12](http://www.postfix.org/) | [Nodemailer v${nodeMailerVersion}](https://github.com/nodemailer/nodemailer)`, true); embed.addField('Discord', `- N/A | [Eris v${erisVersion}](https://github.com/abalabahaha/eris)`, true);
embed.addField('Discord', `- N/A | [Eris v${erisVersion}](https://github.com/abalabahaha/eris)`, true); embed.addField('Payments', `- [Stripe API](https://stripe.com/) | [Stripe Node.js Client v${stripeVersion}](https://github.com/stripe/stripe-node)`, true);
embed.addField('Payments', `- [Stripe API](https://stripe.com/) | [Stripe Node.js Client v${stripeVersion}](https://github.com/stripe/stripe-node)`, true); embed.addField('Scheduling', `- [Cron](https://systemd.io/) | [Cron Scheduling Node.js v${cronVersion}](https://github.com/node-cron/node-cron)\n- Internal Queue | [Bull v${bullVersion}](https://github.com/OptimalBits/bull) w/ IORedis`, true);
embed.addField('Scheduling', `- [Cron](https://systemd.io/) | [Cron Scheduling Node.js v${cronVersion}](https://github.com/node-cron/node-cron)\n- Internal Queue | [Bull v${bullVersion}](https://github.com/OptimalBits/bull) w/ IORedis`, true); embed.addField('Audio & Voice', `- [Google Cloud ML](https://cloud.google.com/text-to-speech) | [Google Cloud Node.js Text to Speech Synthesizer v${ttsVersion}](https://github.com/googleapis/nodejs-text-to-speech)\n - [FFMPEG](https://ffmpeg.org/) | Internal`, true);
embed.addField('Audio & Voice', `- [Google Cloud ML](https://cloud.google.com/text-to-speech) | [Google Cloud Node.js Text to Speech Synthesizer v${ttsVersion}](https://github.com/googleapis/nodejs-text-to-speech)\n - [FFMPEG](https://ffmpeg.org/) | Internal`, true); embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setFooter(this.client.user.username, this.client.user.avatarURL); embed.setTimestamp();
embed.setTimestamp(); message.channel.createMessage({ embed });
message.channel.createMessage({ embed });
} catch (err) {
this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -15,22 +15,18 @@ export default class TTS extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); if (args.length > 200) return this.error(message.channel, 'Cannot synthesize more than 200 characters.');
if (args.length > 200) return this.error(message.channel, 'Cannot synthesize more than 200 characters.'); const msg = await this.loading(message.channel, 'Synthesizing...');
const msg = await this.loading(message.channel, 'Synthesizing...'); const d = await axios({
const d = await axios({ method: 'GET',
method: 'GET', url: `https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&q=${encodeURIComponent(args.join(' '))}&tl=en`,
url: `https://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&q=${encodeURIComponent(args.join(' '))}&tl=en`, headers: {
headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0', },
}, responseType: 'arraybuffer',
responseType: 'arraybuffer', });
}); msg.delete();
msg.delete(); return message.channel.createMessage(undefined, { name: `${uuid()}.mp3`, file: d.data });
return message.channel.createMessage(undefined, { name: `${uuid()}.mp3`, file: d.data });
} catch (err) {
return this.client.util.handleError(err, message, this);
}
} }
} }

View File

@ -13,25 +13,21 @@ export default class Unban extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
let user: User;
try { try {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); user = await this.client.getRESTUser(args[0]);
let user: User; } catch {
try { return this.error(message.channel, 'Could find find user.');
user = await this.client.getRESTUser(args[0]);
} catch {
return this.error(message.channel, 'Could find find user.');
}
try {
await this.mainGuild.getBan(args[0]);
} catch {
return this.error(message.channel, 'This user is not banned.');
}
message.delete();
await this.client.util.moderation.unban(user.id, message.member, args.slice(1).join(' '));
return this.success(message.channel, `${user.username}#${user.discriminator} has been unbanned.`);
} catch (err) {
return this.client.util.handleError(err, message, this, false);
} }
try {
await this.mainGuild.getBan(args[0]);
} catch {
return this.error(message.channel, 'This user is not banned.');
}
message.delete();
await this.client.util.moderation.unban(user.id, message.member, args.slice(1).join(' '));
return this.success(message.channel, `${user.username}#${user.discriminator} has been unbanned.`);
} }
} }

View File

@ -13,22 +13,18 @@ export default class Unmute extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
const member = this.client.util.resolveMember(args[0], this.mainGuild);
if (!member) return this.error(message.channel, 'Cannot find user.');
try { try {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]); const res1 = await this.client.db.local.muted.get<boolean>(`muted-${member.id}`);
const member = this.client.util.resolveMember(args[0], this.mainGuild); if (!res1 || !this.mainGuild.members.get(member.id).roles.includes('478373942638149643')) return this.error(message.channel, 'This user is already unmuted.');
if (!member) return this.error(message.channel, 'Cannot find user.'); } catch {} // eslint-disable-line no-empty
if (member && !this.client.util.moderation.checkPermissions(member, message.member)) return this.error(message.channel, 'Permission Denied.');
message.delete();
try { await this.client.util.moderation.unmute(member.user.id, message.member, args.slice(1).join(' '));
const res1 = await this.client.db.local.muted.get<boolean>(`muted-${member.id}`); return this.success(message.channel, `${member.user.username}#${member.user.discriminator} has been unmuted.`);
if (!res1 || !this.mainGuild.members.get(member.id).roles.includes('478373942638149643')) return this.error(message.channel, 'This user is already unmuted.');
} catch {} // eslint-disable-line no-empty
if (member && !this.client.util.moderation.checkPermissions(member, message.member)) return this.error(message.channel, 'Permission Denied.');
message.delete();
await this.client.util.moderation.unmute(member.user.id, message.member, args.slice(1).join(' '));
return this.success(message.channel, `${member.user.username}#${member.user.discriminator} has been unmuted.`);
} catch (err) {
return this.client.util.handleError(err, message, this, false);
}
} }
} }

View File

@ -25,225 +25,221 @@ export default class Whois extends Command {
} }
public async run(message: Message, args: string[]) { public async run(message: Message, args: string[]) {
try { let member: Member;
let member: Member; if (!args[0]) member = message.member;
if (!args[0]) member = message.member; else {
else { member = this.client.util.resolveMember(args.join(' '), this.mainGuild);
member = this.client.util.resolveMember(args.join(' '), this.mainGuild); try {
try { if (!member) member = await this.mainGuild.getRESTMember(args[0]);
if (!member) member = await this.mainGuild.getRESTMember(args[0]); } catch {
} catch {
return this.error(message.channel, 'Member not found.');
}
}
if (!member) {
return this.error(message.channel, 'Member not found.'); return this.error(message.channel, 'Member not found.');
} }
const embed = new RichEmbed();
embed.setThumbnail(member.avatarURL);
const ackResolve = await this.client.db.mongo.Staff.findOne({ userID: member.id }).lean().exec();
const mpn = this.memberPostNominals(member);
let title = `${member.user.username}#${member.user.discriminator}`;
if (!ackResolve && mpn) {
title += `, ${mpn.join(', ')}`;
}
if (ackResolve?.pn?.length > 0) title += `, ${ackResolve.pn.join(', ')}`;
embed.setAuthor(title, member.user.avatarURL);
let description = '';
let titleAndDepartment = '';
if (ackResolve?.title && ackResolve?.dept) {
titleAndDepartment += `${emotes.titleAndDepartment} __**${ackResolve.title}**__, __${ackResolve.dept}__\n\n`;
} else if (ackResolve?.dept) {
titleAndDepartment += `${emotes.titleAndDepartment} __${ackResolve.dept}__\n\n`;
}
if (titleAndDepartment.length > 0) description += titleAndDepartment;
if (ackResolve?.emailAddress) {
description += `${emotes.email} ${ackResolve.emailAddress}\n`;
}
const pager = await this.client.db.mongo.PagerNumber.findOne({ individualAssignID: member.user.id }).lean().exec();
if (pager?.num) {
description += `📟 ${pager.num}\n`;
}
if (ackResolve?.extension) {
description += `☎️ ${ackResolve.extension}\n`;
}
const memberProfile = await this.client.db.mongo.Member.findOne({ userID: member.id }).lean().exec();
if (memberProfile?.additional?.gitlab) {
description += `${emotes.gitlab} ${memberProfile?.additional.gitlab}\n`;
}
if (memberProfile?.additional?.github) {
description += `${emotes.github} ${memberProfile?.additional.github}\n`;
}
if (memberProfile?.additional?.bio) {
description += `${emotes.bio} *${memberProfile?.additional.bio}*\n`;
}
description += `\n<@${member.id}>`;
embed.setDescription(description);
for (const role of member.roles.map((r) => this.mainGuild.roles.get(r)).sort((a, b) => b.position - a.position)) {
if (role?.color !== 0) {
embed.setColor(role.color);
break;
}
}
embed.addField('Status', member.status === 'dnd' ? 'Do Not Disturb' : this.client.util.capsFirstLetter(member.status) || 'Offline', true);
embed.addField('Joined At', `${moment(new Date(member.joinedAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true);
embed.addField('Created At', `${moment(new Date(member.user.createdAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true);
const score = await this.client.db.mongo.Score.findOne({ userID: member.id }).lean().exec();
if (score) {
await this.client.report.createInquiry(member.id, 'Library of Code sp-us | Bureau of Community Reports', 1);
let totalScore = '0';
if (score.total < 200) totalScore = '---';
else if (score.total > 800) totalScore = '800';
else totalScore = `${score.total}`;
embed.addField('CommScore™', totalScore, true);
} else embed.addField('CommScore™', 'N/C', true);
if (member.roles.length > 0) {
embed.addField(`Roles [${member.roles.length}]`, member.roles.map((r) => this.mainGuild.roles.get(r)).sort((a, b) => b.position - a.position).map((r) => `<@&${r.id}>`).join(', '));
}
const flags: string[] = [];
if (member.user.publicFlags) {
if ((member.user.publicFlags & (1 << 12)) === 1 << 12) flags.push('<:System:768370601265201152>');
if ((member.user.publicFlags & (1 << 0)) === 1 << 0) flags.push('<:DiscordStaff:768370601882025985>');
if ((member.user.publicFlags & (1 << 1)) === 1 << 1) flags.push('<:Partnered:768370601395879936>');
if ((member.user.publicFlags & (1 << 3)) === 1 << 3) flags.push('<:BugHunter:768370601105555467>');
if ((member.user.publicFlags & (1 << 14)) === 1 << 14) flags.push('<:BugHunter:768370601105555467>');
if ((member.user.publicFlags & (1 << 2)) === 1 << 2) flags.push('<:HypeSquadEvents:768370600745762846>');
if ((member.user.publicFlags & (1 << 6)) === 1 << 6) flags.push('<:HypeSquadBravery:768370601328640011> ');
if ((member.user.publicFlags & (1 << 7)) === 1 << 7) flags.push('<:HypeSquadBrilliance:768370600842362900>');
if ((member.user.publicFlags & (1 << 8)) === 1 << 8) flags.push('<:HypeSquadBalance:768370599584071751> ');
if ((member.user.publicFlags & (1 << 9)) === 1 << 9) flags.push('<:EarlySupporter:768370601873768468>');
if ((member.user.publicFlags & (1 << 16)) === 1 << 16) flags.push('<:VerifiedBot:768370599252197396>');
if ((member.user.publicFlags & (1 << 17)) === 1 << 17) flags.push('<:VerifiedBotDeveloper:768370601701933077>');
}
if (flags.length > 0) embed.addField('Flags', flags.join(' '));
const permissions: string[] = [];
const serverAcknowledgements: string[] = [];
const bit = Number(member.permissions.allow);
if (this.mainGuild.ownerID === member.id) serverAcknowledgements.push('Server Owner');
if (bit & 8) { permissions.push('Administrator'); serverAcknowledgements.push('Server Admin'); }
if (bit & 32) { permissions.push('Manage Server'); serverAcknowledgements.push('Server Manager'); }
if (bit & 16) permissions.push('Manage Channels');
if (bit & 268435456) permissions.push('Manage Roles');
if (bit & 8192) { permissions.push('Manage Messages'); serverAcknowledgements.push('Server Moderator'); }
if (bit & 134217728) permissions.push('Manage Nicknames');
if (bit & 1073741824) permissions.push('Manage Emojis');
if (bit & 4) permissions.push('Ban Members');
if (bit & 2) permissions.push('Kick Members');
const account = await this.client.db.mongo.Member.findOne({ userID: member.id }).lean().exec();
if (account?.additional?.langs?.length > 0) {
const langs: string[] = [];
for (const lang of account.additional.langs.sort((a, b) => a.localeCompare(b))) {
switch (lang) {
case 'asm':
langs.push('<:AssemblyLanguage:703448714248716442> Assembly Language');
break;
case 'cfam':
langs.push('<:clang:553684262193332278> C/C++');
break;
case 'csharp':
langs.push('<:csharp:553684277280112660> C#');
break;
case 'go':
langs.push('<:Go:703449475405971466> Go');
break;
case 'java':
langs.push('<:Java:703449725181100135> Java');
break;
case 'js':
langs.push('<:JavaScriptECMA:703449987916496946> JavaScript');
break;
case 'kt':
langs.push('<:Kotlin:703450201838321684> Kotlin');
break;
case 'py':
langs.push('<:python:553682965482176513> Python');
break;
case 'rb':
langs.push('<:ruby:604812470451699712> Ruby');
break;
case 'rs':
langs.push('<:Rust:703450901960196206> Rust');
break;
case 'swift':
langs.push('<:Swift:703451096093294672> Swift');
break;
case 'ts':
langs.push('<:TypeScript:703451285789343774> TypeScript');
break;
default:
break;
}
}
embed.addField('Known Languages', langs.join(', '));
}
if (account?.additional?.operatingSystems?.length > 0) {
const operatingSystems: string[] = [];
for (const os of account.additional.operatingSystems.sort((a, b) => a.localeCompare(b))) {
switch (os) {
case 'arch':
operatingSystems.push('<:arch:707694976523304960> Arch');
break;
case 'deb':
operatingSystems.push('<:debian:707695042617147589> Debian');
break;
case 'cent':
operatingSystems.push('<:centos:707702165816213525> CentOS');
break;
case 'fedora':
operatingSystems.push('<:fedora:707695073151680543> Fedora');
break;
case 'manjaro':
operatingSystems.push('<:manjaro:707701473680556062> Manjaro');
break;
case 'mdarwin':
operatingSystems.push('<:mac:707695427754917919> macOS');
break;
case 'redhat':
operatingSystems.push('<:redhat:707695102159749271> RedHat Enterprise Linux');
break;
case 'ubuntu':
operatingSystems.push('<:ubuntu:707695136888586300> Ubuntu');
break;
case 'win':
operatingSystems.push('<:windows10:707695160259248208> Windows');
break;
default:
break;
}
}
embed.addField('Used Operating Systems', operatingSystems.join(', '));
}
if (permissions.length > 0) {
embed.addField('Permissions', permissions.join(', '));
}
if (account?.x509 || account?.pgp) {
if (account.x509 && account.pgp) {
embed.addField('Credentials', `[PGP](https://comm.libraryofcode.org/keys/~/pgp/${member.id}) | [x509](https://comm.libraryofcode.org/keys/~/x509/${member.id})`);
} else if (account.pgp) {
embed.addField('Credentials', `[PGP](https://comm.libraryofcode.org/keys/~/pgp/${member.id})`);
} else if (account.x509) {
embed.addField('Credentials', `[x509](https://comm.libraryofcode.org/keys/~/x509/${member.id})`);
}
}
if (serverAcknowledgements.length > 0) {
embed.addField('Acknowledgements', serverAcknowledgements[0]);
}
if (ackResolve?.additionalRoles?.length > 0) {
embed.addField('Additional Acknowledgements', ackResolve.additionalRoles.join(', '));
}
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
return message.channel.createMessage({ embed });
} catch (err) {
return this.client.util.handleError(err, message, this);
} }
if (!member) {
return this.error(message.channel, 'Member not found.');
}
const embed = new RichEmbed();
embed.setThumbnail(member.avatarURL);
const ackResolve = await this.client.db.mongo.Staff.findOne({ userID: member.id }).lean().exec();
const mpn = this.memberPostNominals(member);
let title = `${member.user.username}#${member.user.discriminator}`;
if (!ackResolve && mpn) {
title += `, ${mpn.join(', ')}`;
}
if (ackResolve?.pn?.length > 0) title += `, ${ackResolve.pn.join(', ')}`;
embed.setAuthor(title, member.user.avatarURL);
let description = '';
let titleAndDepartment = '';
if (ackResolve?.title && ackResolve?.dept) {
titleAndDepartment += `${emotes.titleAndDepartment} __**${ackResolve.title}**__, __${ackResolve.dept}__\n\n`;
} else if (ackResolve?.dept) {
titleAndDepartment += `${emotes.titleAndDepartment} __${ackResolve.dept}__\n\n`;
}
if (titleAndDepartment.length > 0) description += titleAndDepartment;
if (ackResolve?.emailAddress) {
description += `${emotes.email} ${ackResolve.emailAddress}\n`;
}
const pager = await this.client.db.mongo.PagerNumber.findOne({ individualAssignID: member.user.id }).lean().exec();
if (pager?.num) {
description += `📟 ${pager.num}\n`;
}
if (ackResolve?.extension) {
description += `☎️ ${ackResolve.extension}\n`;
}
const memberProfile = await this.client.db.mongo.Member.findOne({ userID: member.id }).lean().exec();
if (memberProfile?.additional?.gitlab) {
description += `${emotes.gitlab} ${memberProfile?.additional.gitlab}\n`;
}
if (memberProfile?.additional?.github) {
description += `${emotes.github} ${memberProfile?.additional.github}\n`;
}
if (memberProfile?.additional?.bio) {
description += `${emotes.bio} *${memberProfile?.additional.bio}*\n`;
}
description += `\n<@${member.id}>`;
embed.setDescription(description);
for (const role of member.roles.map((r) => this.mainGuild.roles.get(r)).sort((a, b) => b.position - a.position)) {
if (role?.color !== 0) {
embed.setColor(role.color);
break;
}
}
embed.addField('Status', member.status === 'dnd' ? 'Do Not Disturb' : this.client.util.capsFirstLetter(member.status) || 'Offline', true);
embed.addField('Joined At', `${moment(new Date(member.joinedAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true);
embed.addField('Created At', `${moment(new Date(member.user.createdAt)).format('dddd, MMMM Do YYYY, h:mm:ss A')} ET`, true);
const score = await this.client.db.mongo.Score.findOne({ userID: member.id }).lean().exec();
if (score) {
await this.client.report.createInquiry(member.id, 'Library of Code sp-us | Bureau of Community Reports', 1);
let totalScore = '0';
if (score.total < 200) totalScore = '---';
else if (score.total > 800) totalScore = '800';
else totalScore = `${score.total}`;
embed.addField('CommScore™', totalScore, true);
} else embed.addField('CommScore™', 'N/C', true);
if (member.roles.length > 0) {
embed.addField(`Roles [${member.roles.length}]`, member.roles.map((r) => this.mainGuild.roles.get(r)).sort((a, b) => b.position - a.position).map((r) => `<@&${r.id}>`).join(', '));
}
const flags: string[] = [];
if (member.user.publicFlags) {
if ((member.user.publicFlags & (1 << 12)) === 1 << 12) flags.push('<:System:768370601265201152>');
if ((member.user.publicFlags & (1 << 0)) === 1 << 0) flags.push('<:DiscordStaff:768370601882025985>');
if ((member.user.publicFlags & (1 << 1)) === 1 << 1) flags.push('<:Partnered:768370601395879936>');
if ((member.user.publicFlags & (1 << 3)) === 1 << 3) flags.push('<:BugHunter:768370601105555467>');
if ((member.user.publicFlags & (1 << 14)) === 1 << 14) flags.push('<:BugHunter:768370601105555467>');
if ((member.user.publicFlags & (1 << 2)) === 1 << 2) flags.push('<:HypeSquadEvents:768370600745762846>');
if ((member.user.publicFlags & (1 << 6)) === 1 << 6) flags.push('<:HypeSquadBravery:768370601328640011> ');
if ((member.user.publicFlags & (1 << 7)) === 1 << 7) flags.push('<:HypeSquadBrilliance:768370600842362900>');
if ((member.user.publicFlags & (1 << 8)) === 1 << 8) flags.push('<:HypeSquadBalance:768370599584071751> ');
if ((member.user.publicFlags & (1 << 9)) === 1 << 9) flags.push('<:EarlySupporter:768370601873768468>');
if ((member.user.publicFlags & (1 << 16)) === 1 << 16) flags.push('<:VerifiedBot:768370599252197396>');
if ((member.user.publicFlags & (1 << 17)) === 1 << 17) flags.push('<:VerifiedBotDeveloper:768370601701933077>');
}
if (flags.length > 0) embed.addField('Flags', flags.join(' '));
const permissions: string[] = [];
const serverAcknowledgements: string[] = [];
const bit = Number(member.permissions.allow);
if (this.mainGuild.ownerID === member.id) serverAcknowledgements.push('Server Owner');
if (bit & 8) { permissions.push('Administrator'); serverAcknowledgements.push('Server Admin'); }
if (bit & 32) { permissions.push('Manage Server'); serverAcknowledgements.push('Server Manager'); }
if (bit & 16) permissions.push('Manage Channels');
if (bit & 268435456) permissions.push('Manage Roles');
if (bit & 8192) { permissions.push('Manage Messages'); serverAcknowledgements.push('Server Moderator'); }
if (bit & 134217728) permissions.push('Manage Nicknames');
if (bit & 1073741824) permissions.push('Manage Emojis');
if (bit & 4) permissions.push('Ban Members');
if (bit & 2) permissions.push('Kick Members');
const account = await this.client.db.mongo.Member.findOne({ userID: member.id }).lean().exec();
if (account?.additional?.langs?.length > 0) {
const langs: string[] = [];
for (const lang of account.additional.langs.sort((a, b) => a.localeCompare(b))) {
switch (lang) {
case 'asm':
langs.push('<:AssemblyLanguage:703448714248716442> Assembly Language');
break;
case 'cfam':
langs.push('<:clang:553684262193332278> C/C++');
break;
case 'csharp':
langs.push('<:csharp:553684277280112660> C#');
break;
case 'go':
langs.push('<:Go:703449475405971466> Go');
break;
case 'java':
langs.push('<:Java:703449725181100135> Java');
break;
case 'js':
langs.push('<:JavaScriptECMA:703449987916496946> JavaScript');
break;
case 'kt':
langs.push('<:Kotlin:703450201838321684> Kotlin');
break;
case 'py':
langs.push('<:python:553682965482176513> Python');
break;
case 'rb':
langs.push('<:ruby:604812470451699712> Ruby');
break;
case 'rs':
langs.push('<:Rust:703450901960196206> Rust');
break;
case 'swift':
langs.push('<:Swift:703451096093294672> Swift');
break;
case 'ts':
langs.push('<:TypeScript:703451285789343774> TypeScript');
break;
default:
break;
}
}
embed.addField('Known Languages', langs.join(', '));
}
if (account?.additional?.operatingSystems?.length > 0) {
const operatingSystems: string[] = [];
for (const os of account.additional.operatingSystems.sort((a, b) => a.localeCompare(b))) {
switch (os) {
case 'arch':
operatingSystems.push('<:arch:707694976523304960> Arch');
break;
case 'deb':
operatingSystems.push('<:debian:707695042617147589> Debian');
break;
case 'cent':
operatingSystems.push('<:centos:707702165816213525> CentOS');
break;
case 'fedora':
operatingSystems.push('<:fedora:707695073151680543> Fedora');
break;
case 'manjaro':
operatingSystems.push('<:manjaro:707701473680556062> Manjaro');
break;
case 'mdarwin':
operatingSystems.push('<:mac:707695427754917919> macOS');
break;
case 'redhat':
operatingSystems.push('<:redhat:707695102159749271> RedHat Enterprise Linux');
break;
case 'ubuntu':
operatingSystems.push('<:ubuntu:707695136888586300> Ubuntu');
break;
case 'win':
operatingSystems.push('<:windows10:707695160259248208> Windows');
break;
default:
break;
}
}
embed.addField('Used Operating Systems', operatingSystems.join(', '));
}
if (permissions.length > 0) {
embed.addField('Permissions', permissions.join(', '));
}
if (account?.x509 || account?.pgp) {
if (account.x509 && account.pgp) {
embed.addField('Credentials', `[PGP](https://comm.libraryofcode.org/keys/~/pgp/${member.id}) | [x509](https://comm.libraryofcode.org/keys/~/x509/${member.id})`);
} else if (account.pgp) {
embed.addField('Credentials', `[PGP](https://comm.libraryofcode.org/keys/~/pgp/${member.id})`);
} else if (account.x509) {
embed.addField('Credentials', `[x509](https://comm.libraryofcode.org/keys/~/x509/${member.id})`);
}
}
if (serverAcknowledgements.length > 0) {
embed.addField('Acknowledgements', serverAcknowledgements[0]);
}
if (ackResolve?.additionalRoles?.length > 0) {
embed.addField('Additional Acknowledgements', ackResolve.additionalRoles.join(', '));
}
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
return message.channel.createMessage({ embed });
} }
} }

View File

@ -1,5 +1,6 @@
/* eslint-disable no-useless-return */ /* eslint-disable no-useless-return */
import { Message, TextChannel, NewsChannel } from 'eris'; import { Message, TextChannel, NewsChannel } from 'eris';
import * as Sentry from '@sentry/node';
import { Client, Event } from '../class'; import { Client, Event } from '../class';
export default class CommandHandler extends Event { export default class CommandHandler extends Event {
@ -11,6 +12,7 @@ export default class CommandHandler extends Event {
} }
public async run(message: Message) { public async run(message: Message) {
const transaction = Sentry.startTransaction({ name: 'command-handler' });
try { try {
this.client.db.mongo.Stat.updateOne({ name: 'messages' }, { $inc: { value: 1 } }).exec(); this.client.db.mongo.Stat.updateOne({ name: 'messages' }, { $inc: { value: 1 } }).exec();
if (message.author.bot) return; if (message.author.bot) return;
@ -25,10 +27,17 @@ export default class CommandHandler extends Event {
message.channel.guild.members.add(await message.channel.guild.getRESTMember(message.author.id)); message.channel.guild.members.add(await message.channel.guild.getRESTMember(message.author.id));
} }
this.client.util.signale.log(`User '${message.author.username}#${message.author.discriminator}' ran command '${resolved.cmd.name}' in '${message.channel.id}'.`); this.client.util.signale.log(`User '${message.author.username}#${message.author.discriminator}' ran command '${resolved.cmd.name}' in '${message.channel.id}'.`);
await resolved.cmd.run(message, resolved.args); try {
this.client.db.mongo.Stat.updateOne({ name: 'commands' }, { $inc: { value: 1 } }).exec(); await resolved.cmd.run(message, resolved.args);
} catch (err) {
this.client.util.handleError(err, message, resolved.cmd);
} finally {
this.client.db.mongo.Stat.updateOne({ name: 'commands' }, { $inc: { value: 1 } }).exec();
}
} catch (err) { } catch (err) {
this.client.util.handleError(err, message); this.client.util.handleError(err, message);
} finally {
transaction.finish();
} }
} }
} }

9259
yarn.lock

File diff suppressed because it is too large Load Diff