Reduced channel.send() to send()

This commit is contained in:
WatDuhHekBro 2021-04-10 08:34:55 -05:00
parent e8def0aec3
commit e1e6910b1d
39 changed files with 286 additions and 303 deletions

View File

@ -10,6 +10,7 @@
- Changed `help` to display a paginated embed - Changed `help` to display a paginated embed
- Various changes to core - Various changes to core
- Added `guild` subcommand type (only accessible when `id` is set to `guild`) - Added `guild` subcommand type (only accessible when `id` is set to `guild`)
- Further reduced `channel.send()` to `send()` because it's used in *every, single, command*
# 3.2.0 - Internal refactor, more subcommand types, and more command type guards (2021-04-09) # 3.2.0 - Internal refactor, more subcommand types, and more command type guards (2021-04-09)
- The custom logger changed: `$.log` no longer exists, it's just `console.log`. Now you don't have to do `import $ from "../core/lib"` at the top of every file that uses the custom logger. - The custom logger changed: `$.log` no longer exists, it's just `console.log`. Now you don't have to do `import $ from "../core/lib"` at the top of every file that uses the custom logger.

View File

@ -31,9 +31,9 @@ export default new NamedCommand({
run: "Please provide a question.", run: "Please provide a question.",
any: new Command({ any: new Command({
description: "Question to ask the 8-ball.", description: "Question to ask the 8-ball.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const sender = message.author; const sender = message.author;
channel.send(`${random(responses)} <@${sender.id}>`); send(`${random(responses)} <@${sender.id}>`);
} }
}) })
}); });

View File

@ -31,21 +31,21 @@ export default new NamedCommand({
run: ":cookie: Here's a cookie!", run: ":cookie: Here's a cookie!",
subcommands: { subcommands: {
all: new NamedCommand({ all: new NamedCommand({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.send(`${author} gave everybody a cookie!`); send(`${author} gave everybody a cookie!`);
} }
}) })
}, },
id: "user", id: "user",
user: new Command({ user: new Command({
description: "User to give cookie to.", description: "User to give cookie to.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const sender = author; const sender = author;
const mention: User = args[0]; const mention: User = args[0];
if (mention.id == sender.id) return channel.send("You can't give yourself cookies!"); if (mention.id == sender.id) return send("You can't give yourself cookies!");
return channel.send( return send(
`:cookie: <@${sender.id}> ${parseVars(random(cookies), { `:cookie: <@${sender.id}> ${parseVars(random(cookies), {
target: mention.toString() target: mention.toString()
})}` })}`

View File

@ -8,8 +8,8 @@ import {GuildMember} from "discord.js";
export default new NamedCommand({ export default new NamedCommand({
description: "Economy command for Monika.", description: "Economy command for Monika.",
async run({guild, channel, author}) { async run({send, guild, channel, author}) {
if (isAuthorized(guild, channel)) channel.send(getMoneyEmbed(author)); if (isAuthorized(guild, channel)) send(getMoneyEmbed(author));
}, },
subcommands: { subcommands: {
daily: DailyCommand, daily: DailyCommand,
@ -29,17 +29,17 @@ export default new NamedCommand({
id: "user", id: "user",
user: new Command({ user: new Command({
description: "See how much money someone else has by using their user ID or pinging them.", description: "See how much money someone else has by using their user ID or pinging them.",
async run({guild, channel, args}) { async run({send, guild, channel, args}) {
if (isAuthorized(guild, channel)) channel.send(getMoneyEmbed(args[0])); if (isAuthorized(guild, channel)) send(getMoneyEmbed(args[0]));
} }
}), }),
any: new Command({ any: new Command({
description: "See how much money someone else has by using their username.", description: "See how much money someone else has by using their username.",
async run({guild, channel, args, message}) { async run({send, guild, channel, args, message}) {
if (isAuthorized(guild, channel)) { if (isAuthorized(guild, channel)) {
const member = await getMemberByName(guild!, args.join(" ")); const member = await getMemberByName(guild!, args.join(" "));
if (member instanceof GuildMember) channel.send(getMoneyEmbed(member.user)); if (member instanceof GuildMember) send(getMoneyEmbed(member.user));
else channel.send(member); else send(member);
} }
} }
}) })

View File

@ -3,10 +3,10 @@ import figlet from "figlet";
export default new NamedCommand({ export default new NamedCommand({
description: "Generates a figlet of your input.", description: "Generates a figlet of your input.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const input = args.join(" "); const input = args.join(" ");
if (!args[0]) return channel.send("You have to provide input for me to create a figlet!"); if (!args[0]) return send("You have to provide input for me to create a figlet!");
return channel.send( return send(
"```" + "```" +
figlet.textSync(`${input}`, { figlet.textSync(`${input}`, {
horizontalLayout: "full" horizontalLayout: "full"

View File

@ -2,10 +2,10 @@ import {Command, NamedCommand} from "../../core";
export default new NamedCommand({ export default new NamedCommand({
description: "Insult TravBot! >:D", description: "Insult TravBot! >:D",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.startTyping(); channel.startTyping();
setTimeout(() => { setTimeout(() => {
channel.send( send(
`${author} What the fuck did you just fucking say about me, you little bitch? I'll have you know I graduated top of my class in the Navy Seals, and I've been involved in numerous secret raids on Al-Quaeda, and I have over 300 confirmed kills. I am trained in gorilla warfare and I'm the top sniper in the entire US armed forces. You are nothing to me but just another target. I will wipe you the fuck out with precision the likes of which has never been seen before on this Earth, mark my fucking words. You think you can get away with saying that shit to me over the Internet? Think again, fucker. As we speak I am contacting my secret network of spies across the USA and your IP is being traced right now so you better prepare for the storm, maggot. The storm that wipes out the pathetic little thing you call your life. You're fucking dead, kid. I can be anywhere, anytime, and I can kill you in over seven hundred ways, and that's just with my bare hands. Not only am I extensively trained in unarmed combat, but I have access to the entire arsenal of the United States Marine Corps and I will use it to its full extent to wipe your miserable ass off the face of the continent, you little shit. If only you could have known what unholy retribution your little "clever" comment was about to bring down upon you, maybe you would have held your fucking tongue. But you couldn't, you didn't, and now you're paying the price, you goddamn idiot. I will shit fury all over you and you will drown in it. You're fucking dead, kiddo.` `${author} What the fuck did you just fucking say about me, you little bitch? I'll have you know I graduated top of my class in the Navy Seals, and I've been involved in numerous secret raids on Al-Quaeda, and I have over 300 confirmed kills. I am trained in gorilla warfare and I'm the top sniper in the entire US armed forces. You are nothing to me but just another target. I will wipe you the fuck out with precision the likes of which has never been seen before on this Earth, mark my fucking words. You think you can get away with saying that shit to me over the Internet? Think again, fucker. As we speak I am contacting my secret network of spies across the USA and your IP is being traced right now so you better prepare for the storm, maggot. The storm that wipes out the pathetic little thing you call your life. You're fucking dead, kid. I can be anywhere, anytime, and I can kill you in over seven hundred ways, and that's just with my bare hands. Not only am I extensively trained in unarmed combat, but I have access to the entire arsenal of the United States Marine Corps and I will use it to its full extent to wipe your miserable ass off the face of the continent, you little shit. If only you could have known what unholy retribution your little "clever" comment was about to bring down upon you, maybe you would have held your fucking tongue. But you couldn't, you didn't, and now you're paying the price, you goddamn idiot. I will shit fury all over you and you will drown in it. You're fucking dead, kiddo.`
); );
channel.stopTyping(); channel.stopTyping();

View File

@ -3,8 +3,8 @@ import {Command, NamedCommand, CHANNEL_TYPE} from "../../core";
export default new NamedCommand({ export default new NamedCommand({
description: "Chooses someone to love.", description: "Chooses someone to love.",
channelType: CHANNEL_TYPE.GUILD, channelType: CHANNEL_TYPE.GUILD,
async run({message, channel, guild, author, client, args}) { async run({send, message, channel, guild, author, client, args}) {
const member = guild!.members.cache.random(); const member = guild!.members.cache.random();
channel.send(`I love ${member.nickname ?? member.user.username}!`); send(`I love ${member.nickname ?? member.user.username}!`);
} }
}); });

View File

@ -11,21 +11,21 @@ export const BetCommand = new NamedCommand({
user: new Command({ user: new Command({
description: "User to bet with.", description: "User to bet with.",
// handles missing amount argument // handles missing amount argument
async run({args, author, channel, guild}) { async run({send, args, author, channel, guild}) {
if (isAuthorized(guild, channel)) { if (isAuthorized(guild, channel)) {
const target = args[0]; const target = args[0];
// handle invalid target // handle invalid target
if (target.id == author.id) return channel.send("You can't bet Mons with yourself!"); if (target.id == author.id) return send("You can't bet Mons with yourself!");
else if (target.bot && process.argv[2] !== "dev") return channel.send("You can't bet Mons with a bot!"); else if (target.bot && process.argv[2] !== "dev") return send("You can't bet Mons with a bot!");
return channel.send("How much are you betting?"); return send("How much are you betting?");
} else return; } else return;
}, },
number: new Command({ number: new Command({
description: "Amount of Mons to bet.", description: "Amount of Mons to bet.",
// handles missing duration argument // handles missing duration argument
async run({args, author, channel, guild}) { async run({send, args, author, channel, guild}) {
if (isAuthorized(guild, channel)) { if (isAuthorized(guild, channel)) {
const sender = Storage.getUser(author.id); const sender = Storage.getUser(author.id);
const target = args[0] as User; const target = args[0] as User;
@ -33,23 +33,22 @@ export const BetCommand = new NamedCommand({
const amount = Math.floor(args[1]); const amount = Math.floor(args[1]);
// handle invalid target // handle invalid target
if (target.id == author.id) return channel.send("You can't bet Mons with yourself!"); if (target.id == author.id) return send("You can't bet Mons with yourself!");
else if (target.bot && process.argv[2] !== "dev") else if (target.bot && process.argv[2] !== "dev") return send("You can't bet Mons with a bot!");
return channel.send("You can't bet Mons with a bot!");
// handle invalid amount // handle invalid amount
if (amount <= 0) return channel.send("You must bet at least one Mon!"); if (amount <= 0) return send("You must bet at least one Mon!");
else if (sender.money < amount) else if (sender.money < amount)
return channel.send("You don't have enough Mons for that.", getMoneyEmbed(author)); return send("You don't have enough Mons for that.", getMoneyEmbed(author));
else if (receiver.money < amount) else if (receiver.money < amount)
return channel.send("They don't have enough Mons for that.", getMoneyEmbed(target)); return send("They don't have enough Mons for that.", getMoneyEmbed(target));
return channel.send("How long until the bet ends?"); return send("How long until the bet ends?");
} else return; } else return;
}, },
any: new Command({ any: new Command({
description: "Duration of the bet.", description: "Duration of the bet.",
async run({client, args, author, message, channel, guild}) { async run({send, client, args, author, message, channel, guild}) {
if (isAuthorized(guild, channel)) { if (isAuthorized(guild, channel)) {
// [Pertinence to make configurable on the fly.] // [Pertinence to make configurable on the fly.]
// Lower and upper bounds for bet // Lower and upper bounds for bet
@ -62,27 +61,26 @@ export const BetCommand = new NamedCommand({
const duration = parseDuration(args[2].trim()); const duration = parseDuration(args[2].trim());
// handle invalid target // handle invalid target
if (target.id == author.id) return channel.send("You can't bet Mons with yourself!"); if (target.id == author.id) return send("You can't bet Mons with yourself!");
else if (target.bot && process.argv[2] !== "dev") else if (target.bot && process.argv[2] !== "dev") return send("You can't bet Mons with a bot!");
return channel.send("You can't bet Mons with a bot!");
// handle invalid amount // handle invalid amount
if (amount <= 0) return channel.send("You must bet at least one Mon!"); if (amount <= 0) return send("You must bet at least one Mon!");
else if (sender.money < amount) else if (sender.money < amount)
return channel.send("You don't have enough Mons for that.", getMoneyEmbed(author)); return send("You don't have enough Mons for that.", getMoneyEmbed(author));
else if (receiver.money < amount) else if (receiver.money < amount)
return channel.send("They don't have enough Mons for that.", getMoneyEmbed(target)); return send("They don't have enough Mons for that.", getMoneyEmbed(target));
// handle invalid duration // handle invalid duration
if (duration <= 0) return channel.send("Invalid bet duration"); if (duration <= 0) return send("Invalid bet duration");
else if (duration <= parseDuration(durationBounds.min)) else if (duration <= parseDuration(durationBounds.min))
return channel.send(`Bet duration is too short, maximum duration is ${durationBounds.min}`); return send(`Bet duration is too short, maximum duration is ${durationBounds.min}`);
else if (duration >= parseDuration(durationBounds.max)) else if (duration >= parseDuration(durationBounds.max))
return channel.send(`Bet duration is too long, maximum duration is ${durationBounds.max}`); return send(`Bet duration is too long, maximum duration is ${durationBounds.max}`);
// Ask target whether or not they want to take the bet. // Ask target whether or not they want to take the bet.
const takeBet = await askYesOrNo( const takeBet = await askYesOrNo(
await channel.send( await send(
`<@${target.id}>, do you want to take this bet of ${pluralise(amount, "Mon", "s")}` `<@${target.id}>, do you want to take this bet of ${pluralise(amount, "Mon", "s")}`
), ),
target.id target.id
@ -99,7 +97,7 @@ export const BetCommand = new NamedCommand({
Storage.save(); Storage.save();
// Notify both users. // Notify both users.
await channel.send( await send(
`<@${target.id}> has taken <@${author.id}>'s bet, the bet amount of ${pluralise( `<@${target.id}> has taken <@${author.id}>'s bet, the bet amount of ${pluralise(
amount, amount,
"Mon", "Mon",
@ -114,7 +112,7 @@ export const BetCommand = new NamedCommand({
const receiver = Storage.getUser(target.id); const receiver = Storage.getUser(target.id);
// [TODO: when D.JSv13 comes out, inline reply to clean up.] // [TODO: when D.JSv13 comes out, inline reply to clean up.]
// When bet is over, give a vote to ask people their thoughts. // When bet is over, give a vote to ask people their thoughts.
const voteMsg = await channel.send( const voteMsg = await send(
`VOTE: do you think that <@${ `VOTE: do you think that <@${
target.id target.id
}> has won the bet?\nhttps://discord.com/channels/${guild!.id}/${channel.id}/${ }> has won the bet?\nhttps://discord.com/channels/${guild!.id}/${channel.id}/${
@ -142,18 +140,18 @@ export const BetCommand = new NamedCommand({
if (ok > no) { if (ok > no) {
receiver.money += amount * 2; receiver.money += amount * 2;
channel.send( send(
`By the people's votes, <@${target.id}> has won the bet that <@${author.id}> had sent them.` `By the people's votes, <@${target.id}> has won the bet that <@${author.id}> had sent them.`
); );
} else if (ok < no) { } else if (ok < no) {
sender.money += amount * 2; sender.money += amount * 2;
channel.send( send(
`By the people's votes, <@${target.id}> has lost the bet that <@${author.id}> had sent them.` `By the people's votes, <@${target.id}> has lost the bet that <@${author.id}> had sent them.`
); );
} else { } else {
sender.money += amount; sender.money += amount;
receiver.money += amount; receiver.money += amount;
channel.send( send(
`By the people's votes, <@${target.id}> couldn't be determined to have won or lost the bet that <@${author.id}> had sent them.` `By the people's votes, <@${target.id}> couldn't be determined to have won or lost the bet that <@${author.id}> had sent them.`
); );
} }
@ -162,7 +160,7 @@ export const BetCommand = new NamedCommand({
Storage.save(); Storage.save();
}); });
}, duration); }, duration);
} else return await channel.send(`<@${target.id}> has rejected your bet, <@${author.id}>`); } else return await send(`<@${target.id}> has rejected your bet, <@${author.id}>`);
} else return; } else return;
} }
}) })

View File

@ -6,7 +6,7 @@ import {isAuthorized, getMoneyEmbed, getSendEmbed, ECO_EMBED_COLOR} from "./eco-
export const DailyCommand = new NamedCommand({ export const DailyCommand = new NamedCommand({
description: "Pick up your daily Mons. The cooldown is per user and every 22 hours to allow for some leeway.", description: "Pick up your daily Mons. The cooldown is per user and every 22 hours to allow for some leeway.",
aliases: ["get"], aliases: ["get"],
async run({author, channel, guild}) { async run({send, author, channel, guild}) {
if (isAuthorized(guild, channel)) { if (isAuthorized(guild, channel)) {
const user = Storage.getUser(author.id); const user = Storage.getUser(author.id);
const now = Date.now(); const now = Date.now();
@ -15,7 +15,7 @@ export const DailyCommand = new NamedCommand({
user.money++; user.money++;
user.lastReceived = now; user.lastReceived = now;
Storage.save(); Storage.save();
channel.send({ send({
embed: { embed: {
title: "Daily Reward", title: "Daily Reward",
description: "You received 1 Mon!", description: "You received 1 Mon!",
@ -23,7 +23,7 @@ export const DailyCommand = new NamedCommand({
} }
}); });
} else } else
channel.send({ send({
embed: { embed: {
title: "Daily Reward", title: "Daily Reward",
description: `It's too soon to pick up your daily Mons. You have about ${( description: `It's too soon to pick up your daily Mons. You have about ${(
@ -39,7 +39,7 @@ export const DailyCommand = new NamedCommand({
export const GuildCommand = new NamedCommand({ export const GuildCommand = new NamedCommand({
description: "Get info on the guild's economy as a whole.", description: "Get info on the guild's economy as a whole.",
async run({guild, channel}) { async run({send, guild, channel}) {
if (isAuthorized(guild, channel)) { if (isAuthorized(guild, channel)) {
const users = Storage.users; const users = Storage.users;
let totalAmount = 0; let totalAmount = 0;
@ -49,7 +49,7 @@ export const GuildCommand = new NamedCommand({
totalAmount += user.money; totalAmount += user.money;
} }
channel.send({ send({
embed: { embed: {
title: `The Bank of ${guild!.name}`, title: `The Bank of ${guild!.name}`,
color: ECO_EMBED_COLOR, color: ECO_EMBED_COLOR,
@ -77,7 +77,7 @@ export const GuildCommand = new NamedCommand({
export const LeaderboardCommand = new NamedCommand({ export const LeaderboardCommand = new NamedCommand({
description: "See the richest players.", description: "See the richest players.",
aliases: ["top"], aliases: ["top"],
async run({guild, channel, client}) { async run({send, guild, channel, client}) {
if (isAuthorized(guild, channel)) { if (isAuthorized(guild, channel)) {
const users = Storage.users; const users = Storage.users;
const ids = Object.keys(users); const ids = Object.keys(users);
@ -94,7 +94,7 @@ export const LeaderboardCommand = new NamedCommand({
}); });
} }
channel.send({ send({
embed: { embed: {
title: "Top 10 Richest Players", title: "Top 10 Richest Players",
color: ECO_EMBED_COLOR, color: ECO_EMBED_COLOR,
@ -116,24 +116,23 @@ export const PayCommand = new NamedCommand({
user: new Command({ user: new Command({
run: "You need to enter an amount you're sending!", run: "You need to enter an amount you're sending!",
number: new Command({ number: new Command({
async run({args, author, channel, guild}): Promise<any> { async run({send, args, author, channel, guild}): Promise<any> {
if (isAuthorized(guild, channel)) { if (isAuthorized(guild, channel)) {
const amount = Math.floor(args[1]); const amount = Math.floor(args[1]);
const sender = Storage.getUser(author.id); const sender = Storage.getUser(author.id);
const target = args[0]; const target = args[0];
const receiver = Storage.getUser(target.id); const receiver = Storage.getUser(target.id);
if (amount <= 0) return channel.send("You must send at least one Mon!"); if (amount <= 0) return send("You must send at least one Mon!");
else if (sender.money < amount) else if (sender.money < amount)
return channel.send("You don't have enough Mons for that.", getMoneyEmbed(author)); return send("You don't have enough Mons for that.", getMoneyEmbed(author));
else if (target.id === author.id) return channel.send("You can't send Mons to yourself!"); else if (target.id === author.id) return send("You can't send Mons to yourself!");
else if (target.bot && process.argv[2] !== "dev") else if (target.bot && process.argv[2] !== "dev") return send("You can't send Mons to a bot!");
return channel.send("You can't send Mons to a bot!");
sender.money -= amount; sender.money -= amount;
receiver.money += amount; receiver.money += amount;
Storage.save(); Storage.save();
return channel.send(getSendEmbed(author, target, amount)); return send(getSendEmbed(author, target, amount));
} }
} }
}) })
@ -142,21 +141,20 @@ export const PayCommand = new NamedCommand({
run: "You must use the format `eco pay <user> <amount>`!" run: "You must use the format `eco pay <user> <amount>`!"
}), }),
any: new Command({ any: new Command({
async run({args, author, channel, guild}) { async run({send, args, author, channel, guild}) {
if (isAuthorized(guild, channel)) { if (isAuthorized(guild, channel)) {
const last = args.pop(); const last = args.pop();
if (!/\d+/g.test(last) && args.length === 0) if (!/\d+/g.test(last) && args.length === 0) return send("You need to enter an amount you're sending!");
return channel.send("You need to enter an amount you're sending!");
const amount = Math.floor(last); const amount = Math.floor(last);
const sender = Storage.getUser(author.id); const sender = Storage.getUser(author.id);
if (amount <= 0) return channel.send("You must send at least one Mon!"); if (amount <= 0) return send("You must send at least one Mon!");
else if (sender.money < amount) else if (sender.money < amount)
return channel.send("You don't have enough Mons to do that!", getMoneyEmbed(author)); return send("You don't have enough Mons to do that!", getMoneyEmbed(author));
else if (!guild) else if (!guild)
return channel.send("You have to use this in a server if you want to send Mons with a username!"); return send("You have to use this in a server if you want to send Mons with a username!");
const username = args.join(" "); const username = args.join(" ");
const member = ( const member = (
@ -167,17 +165,16 @@ export const PayCommand = new NamedCommand({
).first(); ).first();
if (!member) if (!member)
return channel.send( return send(
`Couldn't find a user by the name of \`${username}\`! If you want to send Mons to someone in a different server, you have to use their user ID!` `Couldn't find a user by the name of \`${username}\`! If you want to send Mons to someone in a different server, you have to use their user ID!`
); );
else if (member.user.id === author.id) return channel.send("You can't send Mons to yourself!"); else if (member.user.id === author.id) return send("You can't send Mons to yourself!");
else if (member.user.bot && process.argv[2] !== "dev") else if (member.user.bot && process.argv[2] !== "dev") return send("You can't send Mons to a bot!");
return channel.send("You can't send Mons to a bot!");
const target = member.user; const target = member.user;
return prompt( return prompt(
await channel.send( await send(
`Are you sure you want to send ${pluralise( `Are you sure you want to send ${pluralise(
amount, amount,
"Mon", "Mon",
@ -202,7 +199,7 @@ export const PayCommand = new NamedCommand({
sender.money -= amount; sender.money -= amount;
receiver.money += amount; receiver.money += amount;
Storage.save(); Storage.save();
channel.send(getSendEmbed(author, target, amount)); send(getSendEmbed(author, target, amount));
} }
); );
} }

View File

@ -8,7 +8,7 @@ const WEEKDAY = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday
export const MondayCommand = new NamedCommand({ export const MondayCommand = new NamedCommand({
description: "Use this on a UTC Monday to get an extra Mon. Does not affect your 22 hour timer for `eco daily`.", description: "Use this on a UTC Monday to get an extra Mon. Does not affect your 22 hour timer for `eco daily`.",
async run({guild, channel, author}) { async run({send, guild, channel, author}) {
if (isAuthorized(guild, channel)) { if (isAuthorized(guild, channel)) {
const user = Storage.getUser(author.id); const user = Storage.getUser(author.id);
const now = new Date(); const now = new Date();
@ -21,13 +21,13 @@ export const MondayCommand = new NamedCommand({
user.money++; user.money++;
user.lastMonday = now.getTime(); user.lastMonday = now.getTime();
Storage.save(); Storage.save();
channel.send("It is **Mon**day, my dudes.", getMoneyEmbed(author)); send("It is **Mon**day, my dudes.", getMoneyEmbed(author));
} else channel.send("You've already claimed your **Mon**day reward for this week."); } else send("You've already claimed your **Mon**day reward for this week.");
} else { } else {
const weekdayName = WEEKDAY[weekday]; const weekdayName = WEEKDAY[weekday];
const hourText = now.getUTCHours().toString().padStart(2, "0"); const hourText = now.getUTCHours().toString().padStart(2, "0");
const minuteText = now.getUTCMinutes().toString().padStart(2, "0"); const minuteText = now.getUTCMinutes().toString().padStart(2, "0");
channel.send( send(
`Come back when it's **Mon**day. Right now, it's ${weekdayName}, ${hourText}:${minuteText} (UTC).` `Come back when it's **Mon**day. Right now, it's ${weekdayName}, ${hourText}:${minuteText} (UTC).`
); );
} }
@ -41,19 +41,19 @@ export const AwardCommand = new NamedCommand({
aliases: ["give"], aliases: ["give"],
run: "You need to specify a user!", run: "You need to specify a user!",
user: new Command({ user: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
if (author.id === "394808963356688394" || IS_DEV_MODE) { if (author.id === "394808963356688394" || IS_DEV_MODE) {
const target = args[0] as User; const target = args[0] as User;
const user = Storage.getUser(target.id); const user = Storage.getUser(target.id);
user.money++; user.money++;
Storage.save(); Storage.save();
channel.send(`1 Mon given to ${target.username}.`, getMoneyEmbed(target)); send(`1 Mon given to ${target.username}.`, getMoneyEmbed(target));
} else { } else {
channel.send("This command is restricted to the bean."); send("This command is restricted to the bean.");
} }
}, },
number: new Command({ number: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
if (author.id === "394808963356688394" || IS_DEV_MODE) { if (author.id === "394808963356688394" || IS_DEV_MODE) {
const target = args[0] as User; const target = args[0] as User;
const amount = Math.floor(args[1]); const amount = Math.floor(args[1]);
@ -62,15 +62,12 @@ export const AwardCommand = new NamedCommand({
const user = Storage.getUser(target.id); const user = Storage.getUser(target.id);
user.money += amount; user.money += amount;
Storage.save(); Storage.save();
channel.send( send(`${pluralise(amount, "Mon", "s")} given to ${target.username}.`, getMoneyEmbed(target));
`${pluralise(amount, "Mon", "s")} given to ${target.username}.`,
getMoneyEmbed(target)
);
} else { } else {
channel.send("You need to enter a number greater than 0."); send("You need to enter a number greater than 0.");
} }
} else { } else {
channel.send("This command is restricted to the bean."); send("This command is restricted to the bean.");
} }
} }
}) })

View File

@ -7,7 +7,7 @@ import {EmbedField} from "discord.js";
export const ShopCommand = new NamedCommand({ export const ShopCommand = new NamedCommand({
description: "Displays the list of items you can buy in the shop.", description: "Displays the list of items you can buy in the shop.",
async run({guild, channel, author}) { async run({send, guild, channel, author}) {
if (isAuthorized(guild, channel)) { if (isAuthorized(guild, channel)) {
function getShopEmbed(selection: ShopItem[], title: string) { function getShopEmbed(selection: ShopItem[], title: string) {
const fields: EmbedField[] = []; const fields: EmbedField[] = [];
@ -34,7 +34,7 @@ export const ShopCommand = new NamedCommand({
const shopPages = split(ShopItems, 5); const shopPages = split(ShopItems, 5);
const pageAmount = shopPages.length; const pageAmount = shopPages.length;
paginate(channel.send, author.id, pageAmount, (page, hasMultiplePages) => { paginate(send, author.id, pageAmount, (page, hasMultiplePages) => {
return getShopEmbed( return getShopEmbed(
shopPages[page], shopPages[page],
hasMultiplePages ? `Shop (Page ${page + 1} of ${pageAmount})` : "Shop" hasMultiplePages ? `Shop (Page ${page + 1} of ${pageAmount})` : "Shop"
@ -47,7 +47,7 @@ export const ShopCommand = new NamedCommand({
export const BuyCommand = new NamedCommand({ export const BuyCommand = new NamedCommand({
description: "Buys an item from the shop.", description: "Buys an item from the shop.",
usage: "<item>", usage: "<item>",
async run({guild, channel, args, message, author}) { async run({send, guild, channel, args, message, author}) {
if (isAuthorized(guild, channel)) { if (isAuthorized(guild, channel)) {
let found = false; let found = false;
@ -65,7 +65,7 @@ export const BuyCommand = new NamedCommand({
const cost = item.cost * amount; const cost = item.cost * amount;
if (cost > user.money) { if (cost > user.money) {
channel.send("Not enough Mons!"); send("Not enough Mons!");
} else { } else {
user.money -= cost; user.money -= cost;
Storage.save(); Storage.save();
@ -77,7 +77,7 @@ export const BuyCommand = new NamedCommand({
} }
} }
if (!found) channel.send(`There's no item in the shop that goes by \`${requested}\`!`); if (!found) send(`There's no item in the shop that goes by \`${requested}\`!`);
} }
} }
}); });

View File

@ -36,19 +36,17 @@ const endpoints: {sfw: {[key: string]: string}} = {
export default new NamedCommand({ export default new NamedCommand({
description: "Provides you with a random image with the selected argument.", description: "Provides you with a random image with the selected argument.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.send( send(`Please provide an image type. Available arguments:\n\`[${Object.keys(endpoints.sfw).join(", ")}]\`.`);
`Please provide an image type. Available arguments:\n\`[${Object.keys(endpoints.sfw).join(", ")}]\`.`
);
}, },
any: new Command({ any: new Command({
description: "Image type to send.", description: "Image type to send.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const arg = args[0]; const arg = args[0];
if (!(arg in endpoints.sfw)) return channel.send("Couldn't find that endpoint!"); if (!(arg in endpoints.sfw)) return send("Couldn't find that endpoint!");
let url = new URL(`https://nekos.life/api/v2${endpoints.sfw[arg]}`); let url = new URL(`https://nekos.life/api/v2${endpoints.sfw[arg]}`);
const content = await getContent(url.toString()); const content = await getContent(url.toString());
return channel.send(content.url); return send(content.url);
} }
}) })
}); });

View File

@ -61,7 +61,7 @@ const responses = [
export default new NamedCommand({ export default new NamedCommand({
description: "Sends random ok message.", description: "Sends random ok message.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.send(`ok ${random(responses)}`); send(`ok ${random(responses)}`);
} }
}); });

View File

@ -4,9 +4,9 @@ import {URL} from "url";
export default new NamedCommand({ export default new NamedCommand({
description: "OwO-ifies the input.", description: "OwO-ifies the input.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
let url = new URL(`https://nekos.life/api/v2/owoify?text=${args.join(" ")}`); let url = new URL(`https://nekos.life/api/v2/owoify?text=${args.join(" ")}`);
const content = (await getContent(url.toString())) as any; // Apparently, the object in question is {owo: string}. const content = (await getContent(url.toString())) as any; // Apparently, the object in question is {owo: string}.
channel.send(content.owo); send(content.owo);
} }
}); });

View File

@ -2,8 +2,8 @@ import {Command, NamedCommand} from "../../core";
export default new NamedCommand({ export default new NamedCommand({
description: "Initiates a celebratory stream from the bot.", description: "Initiates a celebratory stream from the bot.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.send("This calls for a celebration!"); send("This calls for a celebration!");
client.user!.setActivity({ client.user!.setActivity({
type: "STREAMING", type: "STREAMING",
url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ", url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",

View File

@ -7,7 +7,7 @@ export default new NamedCommand({
run: "Please provide a question.", run: "Please provide a question.",
any: new Command({ any: new Command({
description: "Question for the poll.", description: "Question for the poll.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const embed = new MessageEmbed() const embed = new MessageEmbed()
.setAuthor( .setAuthor(
`Poll created by ${message.author.username}`, `Poll created by ${message.author.username}`,
@ -16,7 +16,7 @@ export default new NamedCommand({
.setColor(0xffffff) .setColor(0xffffff)
.setFooter("React to vote.") .setFooter("React to vote.")
.setDescription(args.join(" ")); .setDescription(args.join(" "));
const msg = await channel.send(embed); const msg = await send(embed);
await msg.react("✅"); await msg.react("✅");
await msg.react("⛔"); await msg.react("⛔");
message.delete({ message.delete({

View File

@ -4,8 +4,8 @@ import {Random} from "../../lib";
export default new NamedCommand({ export default new NamedCommand({
description: "Ravioli ravioli...", description: "Ravioli ravioli...",
usage: "[number from 1 to 9]", usage: "[number from 1 to 9]",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.send({ send({
embed: { embed: {
title: "Ravioli ravioli...", title: "Ravioli ravioli...",
image: { image: {
@ -18,11 +18,11 @@ export default new NamedCommand({
}); });
}, },
number: new Command({ number: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const arg: number = args[0]; const arg: number = args[0];
if (arg >= 1 && arg <= 9) { if (arg >= 1 && arg <= 9) {
channel.send({ send({
embed: { embed: {
title: "Ravioli ravioli...", title: "Ravioli ravioli...",
image: { image: {
@ -31,7 +31,7 @@ export default new NamedCommand({
} }
}); });
} else { } else {
channel.send("Please provide a number between 1 and 9."); send("Please provide a number between 1 and 9.");
} }
} }
}) })

View File

@ -34,9 +34,9 @@ let phrase = "I have no currently set phrase!";
export default new NamedCommand({ export default new NamedCommand({
description: "Transforms your text into .", description: "Transforms your text into .",
usage: "thonk ([text])", usage: "thonk ([text])",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
if (args.length > 0) phrase = args.join(" "); if (args.length > 0) phrase = args.join(" ");
const msg = await channel.send(transform(phrase)); const msg = await send(transform(phrase));
msg.createReactionCollector( msg.createReactionCollector(
(reaction, user) => { (reaction, user) => {
if (user.id === author.id && reaction.emoji.name === "❌") msg.delete(); if (user.id === author.id && reaction.emoji.name === "❌") msg.delete();

View File

@ -6,7 +6,7 @@ export default new NamedCommand({
description: "Gives you a definition of the inputted word.", description: "Gives you a definition of the inputted word.",
run: "Please input a word.", run: "Please input a word.",
any: new Command({ any: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
// [Bug Fix]: Use encodeURIComponent() when emojis are used: "TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters" // [Bug Fix]: Use encodeURIComponent() when emojis are used: "TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters"
urban(encodeURIComponent(args.join(" "))) urban(encodeURIComponent(args.join(" ")))
.then((res) => { .then((res) => {
@ -21,10 +21,10 @@ export default new NamedCommand({
if (res.tags && res.tags.length > 0 && res.tags.join(" ").length < 1024) if (res.tags && res.tags.length > 0 && res.tags.join(" ").length < 1024)
embed.addField("Tags", res.tags.join(", "), true); embed.addField("Tags", res.tags.join(", "), true);
channel.send(embed); send(embed);
}) })
.catch(() => { .catch(() => {
channel.send("Sorry, that word was not found."); send("Sorry, that word was not found.");
}); });
} }
}) })

View File

@ -25,10 +25,10 @@ export default new NamedCommand({
description: "Transforms your text into .", description: "Transforms your text into .",
run: "You need to enter some text!", run: "You need to enter some text!",
any: new Command({ any: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const text = getVaporwaveText(args.join(" ")); const text = getVaporwaveText(args.join(" "));
if (text !== "") channel.send(text); if (text !== "") send(text);
else channel.send("Make sure to enter at least one valid character."); else send("Make sure to enter at least one valid character.");
} }
}) })
}); });

View File

@ -6,15 +6,15 @@ export default new NamedCommand({
description: "Shows weather info of specified location.", description: "Shows weather info of specified location.",
run: "You need to provide a city.", run: "You need to provide a city.",
any: new Command({ any: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
find( find(
{ {
search: args.join(" "), search: args.join(" "),
degreeType: "C" degreeType: "C"
}, },
function (error, result) { function (error, result) {
if (error) return channel.send(error.toString()); if (error) return send(error.toString());
if (result.length === 0) return channel.send("No city found by that name."); if (result.length === 0) return send("No city found by that name.");
var current = result[0].current; var current = result[0].current;
var location = result[0].location; var location = result[0].location;
const embed = new MessageEmbed() const embed = new MessageEmbed()
@ -28,7 +28,7 @@ export default new NamedCommand({
.addField("Feels like", `${current.feelslike} Degrees`, true) .addField("Feels like", `${current.feelslike} Degrees`, true)
.addField("Winds", current.winddisplay, true) .addField("Winds", current.winddisplay, true)
.addField("Humidity", `${current.humidity}%`, true); .addField("Humidity", `${current.humidity}%`, true);
return channel.send({ return send({
embed embed
}); });
} }

View File

@ -43,44 +43,42 @@ const registry: {[id: string]: string} = {
export default new NamedCommand({ export default new NamedCommand({
description: "Tells you who you or the specified user is.", description: "Tells you who you or the specified user is.",
aliases: ["whoami"], aliases: ["whoami"],
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const id = author.id; const id = author.id;
if (id in registry) { if (id in registry) {
channel.send(registry[id]); send(registry[id]);
} else { } else {
channel.send("You haven't been added to the registry yet!"); send("You haven't been added to the registry yet!");
} }
}, },
id: "user", id: "user",
user: new Command({ user: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const user: User = args[0]; const user: User = args[0];
const id = user.id; const id = user.id;
if (id in registry) { if (id in registry) {
channel.send(`\`${user.username}\` - ${registry[id]}`); send(`\`${user.username}\` - ${registry[id]}`);
} else { } else {
channel.send(`\`${user.tag}\` hasn't been added to the registry yet!`); send(`\`${user.tag}\` hasn't been added to the registry yet!`);
} }
} }
}), }),
any: new Command({ any: new Command({
channelType: CHANNEL_TYPE.GUILD, channelType: CHANNEL_TYPE.GUILD,
async run({message, channel, guild, author, client, args}) { async run({send, message, channel, guild, author, client, args}) {
const query = args.join(" ") as string; const query = args.join(" ") as string;
const member = await getMemberByName(guild!, query); const member = await getMemberByName(guild!, query);
if (member instanceof GuildMember) { if (member instanceof GuildMember) {
if (member.id in registry) { if (member.id in registry) {
channel.send(`\`${member.nickname ?? member.user.username}\` - ${registry[member.id]}`); send(`\`${member.nickname ?? member.user.username}\` - ${registry[member.id]}`);
} else { } else {
channel.send( send(`\`${member.nickname ?? member.user.username}\` hasn't been added to the registry yet!`);
`\`${member.nickname ?? member.user.username}\` hasn't been added to the registry yet!`
);
} }
} else { } else {
channel.send(member); send(member);
} }
} }
}) })

View File

@ -21,9 +21,9 @@ const statuses = ["online", "idle", "dnd", "invisible"];
export default new NamedCommand({ export default new NamedCommand({
description: description:
"An all-in-one command to do admin stuff. You need to be either an admin of the server or one of the bot's mechanics to use this command.", "An all-in-one command to do admin stuff. You need to be either an admin of the server or one of the bot's mechanics to use this command.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const permLevel = getPermissionLevel(author, member); const permLevel = getPermissionLevel(author, member);
return channel.send(`${author}, your permission level is \`${getPermissionName(permLevel)}\` (${permLevel}).`); return send(`${author}, your permission level is \`${getPermissionName(permLevel)}\` (${permLevel}).`);
}, },
subcommands: { subcommands: {
set: new NamedCommand({ set: new NamedCommand({
@ -35,26 +35,26 @@ export default new NamedCommand({
prefix: new NamedCommand({ prefix: new NamedCommand({
description: "Set a custom prefix for your guild. Removes your custom prefix if none is provided.", description: "Set a custom prefix for your guild. Removes your custom prefix if none is provided.",
usage: "(<prefix>) (<@bot>)", usage: "(<prefix>) (<@bot>)",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
Storage.getGuild(guild!.id).prefix = null; Storage.getGuild(guild!.id).prefix = null;
Storage.save(); Storage.save();
channel.send( send(
`The custom prefix for this guild has been removed. My prefix is now back to \`${Config.prefix}\`.` `The custom prefix for this guild has been removed. My prefix is now back to \`${Config.prefix}\`.`
); );
}, },
any: new Command({ any: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
Storage.getGuild(guild!.id).prefix = args[0]; Storage.getGuild(guild!.id).prefix = args[0];
Storage.save(); Storage.save();
channel.send(`The custom prefix for this guild is now \`${args[0]}\`.`); send(`The custom prefix for this guild is now \`${args[0]}\`.`);
}, },
user: new Command({ user: new Command({
description: "Specifies the bot in case of conflicting prefixes.", description: "Specifies the bot in case of conflicting prefixes.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
if ((args[1] as User).id === client.user!.id) { if ((args[1] as User).id === client.user!.id) {
Storage.getGuild(guild!.id).prefix = args[0]; Storage.getGuild(guild!.id).prefix = args[0];
Storage.save(); Storage.save();
channel.send(`The custom prefix for this guild is now \`${args[0]}\`.`); send(`The custom prefix for this guild is now \`${args[0]}\`.`);
} }
} }
}) })
@ -69,25 +69,25 @@ export default new NamedCommand({
description: description:
"Sets how welcome messages are displayed for your server. Removes welcome messages if unspecified.", "Sets how welcome messages are displayed for your server. Removes welcome messages if unspecified.",
usage: "`none`/`text`/`graphical`", usage: "`none`/`text`/`graphical`",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
Storage.getGuild(guild!.id).welcomeType = "none"; Storage.getGuild(guild!.id).welcomeType = "none";
Storage.save(); Storage.save();
channel.send("Set this server's welcome type to `none`."); send("Set this server's welcome type to `none`.");
}, },
// I should probably make this a bit more dynamic... Oh well. // I should probably make this a bit more dynamic... Oh well.
subcommands: { subcommands: {
text: new NamedCommand({ text: new NamedCommand({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
Storage.getGuild(guild!.id).welcomeType = "text"; Storage.getGuild(guild!.id).welcomeType = "text";
Storage.save(); Storage.save();
channel.send("Set this server's welcome type to `text`."); send("Set this server's welcome type to `text`.");
} }
}), }),
graphical: new NamedCommand({ graphical: new NamedCommand({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
Storage.getGuild(guild!.id).welcomeType = "graphical"; Storage.getGuild(guild!.id).welcomeType = "graphical";
Storage.save(); Storage.save();
channel.send("Set this server's welcome type to `graphical`."); send("Set this server's welcome type to `graphical`.");
} }
}) })
} }
@ -95,18 +95,18 @@ export default new NamedCommand({
channel: new NamedCommand({ channel: new NamedCommand({
description: "Sets the welcome channel for your server. Type `#` to reference the channel.", description: "Sets the welcome channel for your server. Type `#` to reference the channel.",
usage: "(<channel mention>)", usage: "(<channel mention>)",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
Storage.getGuild(guild!.id).welcomeChannel = channel.id; Storage.getGuild(guild!.id).welcomeChannel = channel.id;
Storage.save(); Storage.save();
channel.send(`Successfully set ${channel} as the welcome channel for this server.`); send(`Successfully set ${channel} as the welcome channel for this server.`);
}, },
id: "channel", id: "channel",
channel: new Command({ channel: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const result = args[0] as TextChannel; const result = args[0] as TextChannel;
Storage.getGuild(guild!.id).welcomeChannel = result.id; Storage.getGuild(guild!.id).welcomeChannel = result.id;
Storage.save(); Storage.save();
channel.send(`Successfully set this server's welcome channel to ${result}.`); send(`Successfully set this server's welcome channel to ${result}.`);
} }
}) })
}), }),
@ -114,17 +114,17 @@ export default new NamedCommand({
description: description:
"Sets a custom welcome message for your server. Use `%user%` as the placeholder for the user.", "Sets a custom welcome message for your server. Use `%user%` as the placeholder for the user.",
usage: "(<message>)", usage: "(<message>)",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
Storage.getGuild(guild!.id).welcomeMessage = null; Storage.getGuild(guild!.id).welcomeMessage = null;
Storage.save(); Storage.save();
channel.send("Reset your server's welcome message to the default."); send("Reset your server's welcome message to the default.");
}, },
any: new Command({ any: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const newMessage = args.join(" "); const newMessage = args.join(" ");
Storage.getGuild(guild!.id).welcomeMessage = newMessage; Storage.getGuild(guild!.id).welcomeMessage = newMessage;
Storage.save(); Storage.save();
channel.send(`Set your server's welcome message to \`${newMessage}\`.`); send(`Set your server's welcome message to \`${newMessage}\`.`);
} }
}) })
}) })
@ -133,26 +133,26 @@ export default new NamedCommand({
stream: new NamedCommand({ stream: new NamedCommand({
description: "Set a channel to send stream notifications. Type `#` to reference the channel.", description: "Set a channel to send stream notifications. Type `#` to reference the channel.",
usage: "(<channel mention>)", usage: "(<channel mention>)",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const targetGuild = Storage.getGuild(guild!.id); const targetGuild = Storage.getGuild(guild!.id);
if (targetGuild.streamingChannel) { if (targetGuild.streamingChannel) {
targetGuild.streamingChannel = null; targetGuild.streamingChannel = null;
channel.send("Removed your server's stream notifications channel."); send("Removed your server's stream notifications channel.");
} else { } else {
targetGuild.streamingChannel = channel.id; targetGuild.streamingChannel = channel.id;
channel.send(`Set your server's stream notifications channel to ${channel}.`); send(`Set your server's stream notifications channel to ${channel}.`);
} }
Storage.save(); Storage.save();
}, },
id: "channel", id: "channel",
channel: new Command({ channel: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const result = args[0] as TextChannel; const result = args[0] as TextChannel;
Storage.getGuild(guild!.id).streamingChannel = result.id; Storage.getGuild(guild!.id).streamingChannel = result.id;
Storage.save(); Storage.save();
channel.send(`Successfully set this server's stream notifications channel to ${result}.`); send(`Successfully set this server's stream notifications channel to ${result}.`);
} }
}) })
}) })
@ -161,17 +161,17 @@ export default new NamedCommand({
diag: new NamedCommand({ diag: new NamedCommand({
description: 'Requests a debug log with the "info" verbosity level.', description: 'Requests a debug log with the "info" verbosity level.',
permission: PERMISSIONS.BOT_SUPPORT, permission: PERMISSIONS.BOT_SUPPORT,
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.send(getLogBuffer("info")); send(getLogBuffer("info"));
}, },
any: new Command({ any: new Command({
description: `Select a verbosity to listen to. Available levels: \`[${Object.keys(logs).join(", ")}]\``, description: `Select a verbosity to listen to. Available levels: \`[${Object.keys(logs).join(", ")}]\``,
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const type = args[0]; const type = args[0];
if (type in logs) channel.send(getLogBuffer(type)); if (type in logs) send(getLogBuffer(type));
else else
channel.send( send(
`Couldn't find a verbosity level named \`${type}\`! The available types are \`[${Object.keys( `Couldn't find a verbosity level named \`${type}\`! The available types are \`[${Object.keys(
logs logs
).join(", ")}]\`.` ).join(", ")}]\`.`
@ -182,17 +182,17 @@ export default new NamedCommand({
status: new NamedCommand({ status: new NamedCommand({
description: "Changes the bot's status.", description: "Changes the bot's status.",
permission: PERMISSIONS.BOT_SUPPORT, permission: PERMISSIONS.BOT_SUPPORT,
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.send("Setting status to `online`..."); send("Setting status to `online`...");
}, },
any: new Command({ any: new Command({
description: `Select a status to set to. Available statuses: \`[${statuses.join(", ")}]\`.`, description: `Select a status to set to. Available statuses: \`[${statuses.join(", ")}]\`.`,
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
if (!statuses.includes(args[0])) { if (!statuses.includes(args[0])) {
return channel.send("That status doesn't exist!"); return send("That status doesn't exist!");
} else { } else {
client.user?.setStatus(args[0]); client.user?.setStatus(args[0]);
return channel.send(`Setting status to \`${args[0]}\`...`); return send(`Setting status to \`${args[0]}\`...`);
} }
} }
}) })
@ -201,7 +201,7 @@ export default new NamedCommand({
description: "Purges the bot's own messages.", description: "Purges the bot's own messages.",
permission: PERMISSIONS.BOT_SUPPORT, permission: PERMISSIONS.BOT_SUPPORT,
channelType: CHANNEL_TYPE.GUILD, channelType: CHANNEL_TYPE.GUILD,
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
// It's probably better to go through the bot's own messages instead of calling bulkDelete which requires MANAGE_MESSAGES. // It's probably better to go through the bot's own messages instead of calling bulkDelete which requires MANAGE_MESSAGES.
if (botHasPermission(guild, Permissions.FLAGS.MANAGE_MESSAGES)) { if (botHasPermission(guild, Permissions.FLAGS.MANAGE_MESSAGES)) {
message.delete(); message.delete();
@ -210,16 +210,14 @@ export default new NamedCommand({
}); });
const travMessages = msgs.filter((m) => m.author.id === client.user?.id); const travMessages = msgs.filter((m) => m.author.id === client.user?.id);
await channel.send(`Found ${travMessages.size} messages to delete.`).then((m) => await send(`Found ${travMessages.size} messages to delete.`).then((m) =>
m.delete({ m.delete({
timeout: 5000 timeout: 5000
}) })
); );
await (channel as TextChannel).bulkDelete(travMessages); await (channel as TextChannel).bulkDelete(travMessages);
} else { } else {
channel.send( send("This command must be executed in a guild where I have the `MANAGE_MESSAGES` permission.");
"This command must be executed in a guild where I have the `MANAGE_MESSAGES` permission."
);
} }
} }
}), }),
@ -230,7 +228,7 @@ export default new NamedCommand({
run: "A number was not provided.", run: "A number was not provided.",
number: new Command({ number: new Command({
description: "Amount of messages to delete.", description: "Amount of messages to delete.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
message.delete(); message.delete();
const fetched = await channel.messages.fetch({ const fetched = await channel.messages.fetch({
limit: args[0] limit: args[0]
@ -244,15 +242,15 @@ export default new NamedCommand({
usage: "<code>", usage: "<code>",
permission: PERMISSIONS.BOT_OWNER, permission: PERMISSIONS.BOT_OWNER,
// You have to bring everything into scope to use them. AFAIK, there isn't a more maintainable way to do this, but at least TS will let you know if anything gets removed. // You have to bring everything into scope to use them. AFAIK, there isn't a more maintainable way to do this, but at least TS will let you know if anything gets removed.
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
try { try {
const code = args.join(" "); const code = args.join(" ");
let evaled = eval(code); let evaled = eval(code);
if (typeof evaled !== "string") evaled = require("util").inspect(evaled); if (typeof evaled !== "string") evaled = require("util").inspect(evaled);
channel.send(clean(evaled), {code: "js", split: true}); send(clean(evaled), {code: "js", split: true});
} catch (err) { } catch (err) {
channel.send(clean(err), {code: "js", split: true}); send(clean(err), {code: "js", split: true});
} }
} }
}), }),
@ -260,43 +258,43 @@ export default new NamedCommand({
description: "Change the bot's nickname.", description: "Change the bot's nickname.",
permission: PERMISSIONS.BOT_SUPPORT, permission: PERMISSIONS.BOT_SUPPORT,
channelType: CHANNEL_TYPE.GUILD, channelType: CHANNEL_TYPE.GUILD,
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const nickName = args.join(" "); const nickName = args.join(" ");
await guild!.me?.setNickname(nickName); await guild!.me?.setNickname(nickName);
if (botHasPermission(guild, Permissions.FLAGS.MANAGE_MESSAGES)) message.delete({timeout: 5000}); if (botHasPermission(guild, Permissions.FLAGS.MANAGE_MESSAGES)) message.delete({timeout: 5000});
channel.send(`Nickname set to \`${nickName}\``).then((m) => m.delete({timeout: 5000})); send(`Nickname set to \`${nickName}\``).then((m) => m.delete({timeout: 5000}));
} }
}), }),
guilds: new NamedCommand({ guilds: new NamedCommand({
description: "Shows a list of all guilds the bot is a member of.", description: "Shows a list of all guilds the bot is a member of.",
permission: PERMISSIONS.BOT_SUPPORT, permission: PERMISSIONS.BOT_SUPPORT,
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const guildList = client.guilds.cache.array().map((e) => e.name); const guildList = client.guilds.cache.array().map((e) => e.name);
channel.send(guildList, {split: true}); send(guildList, {split: true});
} }
}), }),
activity: new NamedCommand({ activity: new NamedCommand({
description: "Set the activity of the bot.", description: "Set the activity of the bot.",
permission: PERMISSIONS.BOT_SUPPORT, permission: PERMISSIONS.BOT_SUPPORT,
usage: "<type> <string>", usage: "<type> <string>",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
client.user?.setActivity(".help", { client.user?.setActivity(".help", {
type: "LISTENING" type: "LISTENING"
}); });
channel.send("Activity set to default."); send("Activity set to default.");
}, },
any: new Command({ any: new Command({
description: `Select an activity type to set. Available levels: \`[${activities.join(", ")}]\``, description: `Select an activity type to set. Available levels: \`[${activities.join(", ")}]\``,
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const type = args[0]; const type = args[0];
if (activities.includes(type)) { if (activities.includes(type)) {
client.user?.setActivity(args.slice(1).join(" "), { client.user?.setActivity(args.slice(1).join(" "), {
type: args[0].toUpperCase() type: args[0].toUpperCase()
}); });
channel.send(`Set activity to \`${args[0].toUpperCase()}\` \`${args.slice(1).join(" ")}\`.`); send(`Set activity to \`${args[0].toUpperCase()}\` \`${args.slice(1).join(" ")}\`.`);
} else } else
channel.send( send(
`Couldn't find an activity type named \`${type}\`! The available types are \`[${activities.join( `Couldn't find an activity type named \`${type}\`! The available types are \`[${activities.join(
", " ", "
)}]\`.` )}]\`.`
@ -308,17 +306,17 @@ export default new NamedCommand({
description: "Sets up the current channel to receive system logs.", description: "Sets up the current channel to receive system logs.",
permission: PERMISSIONS.BOT_ADMIN, permission: PERMISSIONS.BOT_ADMIN,
channelType: CHANNEL_TYPE.GUILD, channelType: CHANNEL_TYPE.GUILD,
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
Config.systemLogsChannel = channel.id; Config.systemLogsChannel = channel.id;
Config.save(); Config.save();
channel.send(`Successfully set ${channel} as the system logs channel.`); send(`Successfully set ${channel} as the system logs channel.`);
}, },
channel: new Command({ channel: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const targetChannel = args[0] as TextChannel; const targetChannel = args[0] as TextChannel;
Config.systemLogsChannel = targetChannel.id; Config.systemLogsChannel = targetChannel.id;
Config.save(); Config.save();
channel.send(`Successfully set ${targetChannel} as the system logs channel.`); send(`Successfully set ${targetChannel} as the system logs channel.`);
} }
}) })
}) })

View File

@ -16,11 +16,11 @@ export default new NamedCommand({
description: "Lists all commands. If a command is specified, their arguments are listed as well.", description: "Lists all commands. If a command is specified, their arguments are listed as well.",
usage: "([command, [subcommand/type], ...])", usage: "([command, [subcommand/type], ...])",
aliases: ["h"], aliases: ["h"],
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const commands = await getCommandList(); const commands = await getCommandList();
const categoryArray = commands.keyArray(); const categoryArray = commands.keyArray();
paginate(channel.send, author.id, categoryArray.length, (page, hasMultiplePages) => { paginate(send, author.id, categoryArray.length, (page, hasMultiplePages) => {
const category = categoryArray[page]; const category = categoryArray[page];
const commandList = commands.get(category)!; const commandList = commands.get(category)!;
let output = `Legend: \`<type>\`, \`[list/of/stuff]\`, \`(optional)\`, \`(<optional type>)\`, \`([optional/list/...])\`\n`; let output = `Legend: \`<type>\`, \`[list/of/stuff]\`, \`(optional)\`, \`(<optional type>)\`, \`([optional/list/...])\`\n`;
@ -32,9 +32,9 @@ export default new NamedCommand({
}); });
}, },
any: new Command({ any: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const [result, category] = await getCommandInfo(args); const [result, category] = await getCommandInfo(args);
if (typeof result === "string") return channel.send(result); if (typeof result === "string") return send(result);
let append = ""; let append = "";
const command = result.command; const command = result.command;
const header = result.args.length > 0 ? `${result.header} ${result.args.join(" ")}` : result.header; const header = result.args.length > 0 ? `${result.header} ${result.args.join(" ")}` : result.header;
@ -66,7 +66,7 @@ export default new NamedCommand({
aliases = formattedAliases.join(", ") || "None"; aliases = formattedAliases.join(", ") || "None";
} }
return channel.send( return send(
new MessageEmbed() new MessageEmbed()
.setTitle(header) .setTitle(header)
.setDescription(command.description) .setDescription(command.description)

View File

@ -1,7 +1,7 @@
import {Command, NamedCommand} from "../core"; import {Command, NamedCommand} from "../core";
export default new NamedCommand({ export default new NamedCommand({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
// code // code
} }
}); });

View File

@ -4,19 +4,19 @@ import {MessageEmbed} from "discord.js";
export default new NamedCommand({ export default new NamedCommand({
description: "Calculates a specified math expression.", description: "Calculates a specified math expression.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
if (!args[0]) return channel.send("Please provide a calculation."); if (!args[0]) return send("Please provide a calculation.");
let resp; let resp;
try { try {
resp = math.evaluate(args.join(" ")); resp = math.evaluate(args.join(" "));
} catch (e) { } catch (e) {
return channel.send("Please provide a *valid* calculation."); return send("Please provide a *valid* calculation.");
} }
const embed = new MessageEmbed() const embed = new MessageEmbed()
.setColor(0xffffff) .setColor(0xffffff)
.setTitle("Math Calculation") .setTitle("Math Calculation")
.addField("Input", `\`\`\`js\n${args.join("")}\`\`\``) .addField("Input", `\`\`\`js\n${args.join("")}\`\`\``)
.addField("Output", `\`\`\`js\n${resp}\`\`\``); .addField("Output", `\`\`\`js\n${resp}\`\`\``);
return channel.send(embed); return send(embed);
} }
}); });

View File

@ -3,17 +3,17 @@ import {Command, NamedCommand} from "../../core";
export default new NamedCommand({ export default new NamedCommand({
description: "Renames current voice channel.", description: "Renames current voice channel.",
usage: "<name>", usage: "<name>",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const voiceChannel = message.member?.voice.channel; const voiceChannel = message.member?.voice.channel;
if (!voiceChannel) return channel.send("You are not in a voice channel."); if (!voiceChannel) return send("You are not in a voice channel.");
if (!voiceChannel.guild.me?.hasPermission("MANAGE_CHANNELS")) if (!voiceChannel.guild.me?.hasPermission("MANAGE_CHANNELS"))
return channel.send("I am lacking the required permissions to perform this action."); return send("I am lacking the required permissions to perform this action.");
if (args.length === 0) return channel.send("Please provide a new voice channel name."); if (args.length === 0) return send("Please provide a new voice channel name.");
const prevName = voiceChannel.name; const prevName = voiceChannel.name;
const newName = args.join(" "); const newName = args.join(" ");
await voiceChannel.setName(newName); await voiceChannel.setName(newName);
return await channel.send(`Changed channel name from "${prevName}" to "${newName}".`); return await send(`Changed channel name from "${prevName}" to "${newName}".`);
} }
}); });

View File

@ -8,9 +8,9 @@ export default new NamedCommand({
any: new Command({ any: new Command({
description: "The emote(s) to send.", description: "The emote(s) to send.",
usage: "<emotes...>", usage: "<emotes...>",
async run({guild, channel, message, args}) { async run({send, guild, channel, message, args}) {
const output = processEmoteQueryFormatted(args); const output = processEmoteQueryFormatted(args);
if (output.length > 0) channel.send(output); if (output.length > 0) send(output);
} }
}) })
}); });

View File

@ -8,21 +8,21 @@ import moment, {utc} from "moment";
export default new NamedCommand({ export default new NamedCommand({
description: "Command to provide all sorts of info about the current server, a user, etc.", description: "Command to provide all sorts of info about the current server, a user, etc.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.send(await getUserInfo(author, member)); send(await getUserInfo(author, member));
}, },
subcommands: { subcommands: {
avatar: new NamedCommand({ avatar: new NamedCommand({
description: "Shows your own, or another user's avatar.", description: "Shows your own, or another user's avatar.",
usage: "(<user>)", usage: "(<user>)",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.send(author.displayAvatarURL({dynamic: true, size: 2048})); send(author.displayAvatarURL({dynamic: true, size: 2048}));
}, },
id: "user", id: "user",
user: new Command({ user: new Command({
description: "Shows your own, or another user's avatar.", description: "Shows your own, or another user's avatar.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.send( send(
args[0].displayAvatarURL({ args[0].displayAvatarURL({
dynamic: true, dynamic: true,
size: 2048 size: 2048
@ -33,26 +33,26 @@ export default new NamedCommand({
any: new Command({ any: new Command({
description: "Shows another user's avatar by searching their name", description: "Shows another user's avatar by searching their name",
channelType: CHANNEL_TYPE.GUILD, channelType: CHANNEL_TYPE.GUILD,
async run({message, channel, guild, author, client, args}) { async run({send, message, channel, guild, author, client, args}) {
const name = args.join(" "); const name = args.join(" ");
const member = await getMemberByName(guild!, name); const member = await getMemberByName(guild!, name);
if (member instanceof GuildMember) { if (member instanceof GuildMember) {
channel.send( send(
member.user.displayAvatarURL({ member.user.displayAvatarURL({
dynamic: true, dynamic: true,
size: 2048 size: 2048
}) })
); );
} else { } else {
channel.send(member); send(member);
} }
} }
}) })
}), }),
bot: new NamedCommand({ bot: new NamedCommand({
description: "Displays info about the bot.", description: "Displays info about the bot.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const core = os.cpus()[0]; const core = os.cpus()[0];
const embed = new MessageEmbed() const embed = new MessageEmbed()
.setColor(guild?.me?.displayHexColor || "BLUE") .setColor(guild?.me?.displayHexColor || "BLUE")
@ -88,33 +88,33 @@ export default new NamedCommand({
size: 2048 size: 2048
}); });
if (avatarURL) embed.setThumbnail(avatarURL); if (avatarURL) embed.setThumbnail(avatarURL);
channel.send(embed); send(embed);
} }
}), }),
guild: new NamedCommand({ guild: new NamedCommand({
description: "Displays info about the current guild or another guild.", description: "Displays info about the current guild or another guild.",
usage: "(<guild name>/<guild ID>)", usage: "(<guild name>/<guild ID>)",
channelType: CHANNEL_TYPE.GUILD, channelType: CHANNEL_TYPE.GUILD,
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.send(await getGuildInfo(guild!, guild)); send(await getGuildInfo(guild!, guild));
}, },
id: "guild", id: "guild",
guild: new Command({ guild: new Command({
description: "Display info about a guild by its ID.", description: "Display info about a guild by its ID.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const targetGuild = args[0] as Guild; const targetGuild = args[0] as Guild;
channel.send(await getGuildInfo(targetGuild, guild)); send(await getGuildInfo(targetGuild, guild));
} }
}), }),
any: new Command({ any: new Command({
description: "Display info about a guild by finding its name.", description: "Display info about a guild by finding its name.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const targetGuild = getGuildByName(args.join(" ")); const targetGuild = getGuildByName(args.join(" "));
if (targetGuild instanceof Guild) { if (targetGuild instanceof Guild) {
channel.send(await getGuildInfo(targetGuild, guild)); send(await getGuildInfo(targetGuild, guild));
} else { } else {
channel.send(targetGuild); send(targetGuild);
} }
} }
}) })
@ -123,11 +123,11 @@ export default new NamedCommand({
id: "user", id: "user",
user: new Command({ user: new Command({
description: "Displays info about mentioned user.", description: "Displays info about mentioned user.",
async run({message, channel, guild, author, client, args}) { async run({send, message, channel, guild, author, client, args}) {
const user = args[0] as User; const user = args[0] as User;
// Transforms the User object into a GuildMember object of the current guild. // Transforms the User object into a GuildMember object of the current guild.
const member = guild?.members.resolve(args[0]); const member = guild?.members.resolve(args[0]);
channel.send(await getUserInfo(user, member)); send(await getUserInfo(user, member));
} }
}) })
}); });

View File

@ -2,8 +2,8 @@ import {Command, NamedCommand} from "../../core";
export default new NamedCommand({ export default new NamedCommand({
description: "Gives you the invite link.", description: "Gives you the invite link.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.send( send(
`https://discordapp.com/api/oauth2/authorize?client_id=${client.user!.id}&permissions=${ `https://discordapp.com/api/oauth2/authorize?client_id=${client.user!.id}&permissions=${
args[0] || 8 args[0] || 8
}&scope=bot` }&scope=bot`

View File

@ -1,5 +1,5 @@
import {GuildEmoji, MessageEmbed, TextChannel, DMChannel, NewsChannel, User} from "discord.js"; import {GuildEmoji, MessageEmbed, User} from "discord.js";
import {Command, NamedCommand, paginate} from "../../core"; import {Command, NamedCommand, paginate, SendFunction} from "../../core";
import {split} from "../../lib"; import {split} from "../../lib";
import vm from "vm"; import vm from "vm";
@ -8,20 +8,20 @@ const REGEX_TIMEOUT_MS = 1000;
export default new NamedCommand({ export default new NamedCommand({
description: "Lists all emotes the bot has in it's registry,", description: "Lists all emotes the bot has in it's registry,",
usage: "<regex pattern> (-flags)", usage: "<regex pattern> (-flags)",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
displayEmoteList(client.emojis.cache.array(), channel, author); displayEmoteList(client.emojis.cache.array(), send, author);
}, },
any: new Command({ any: new Command({
description: description:
"Filters emotes by via a regular expression. Flags can be added by adding a dash at the end. For example, to do a case-insensitive search, do %prefix%lsemotes somepattern -i", "Filters emotes by via a regular expression. Flags can be added by adding a dash at the end. For example, to do a case-insensitive search, do %prefix%lsemotes somepattern -i",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
// If a guild ID is provided, filter all emotes by that guild (but only if there aren't any arguments afterward) // If a guild ID is provided, filter all emotes by that guild (but only if there aren't any arguments afterward)
if (args.length === 1 && /^\d{17,}$/.test(args[0])) { if (args.length === 1 && /^\d{17,}$/.test(args[0])) {
const guildID: string = args[0]; const guildID: string = args[0];
displayEmoteList( displayEmoteList(
client.emojis.cache.filter((emote) => emote.guild.id === guildID).array(), client.emojis.cache.filter((emote) => emote.guild.id === guildID).array(),
channel, send,
author author
); );
} else { } else {
@ -57,10 +57,10 @@ export default new NamedCommand({
script.runInContext(context, {timeout: REGEX_TIMEOUT_MS}); script.runInContext(context, {timeout: REGEX_TIMEOUT_MS});
emotes = sandbox.emotes; emotes = sandbox.emotes;
emoteCollection = emoteCollection.filter((emote) => emotes.has(emote.id)); // Only allow emotes that haven't been deleted. emoteCollection = emoteCollection.filter((emote) => emotes.has(emote.id)); // Only allow emotes that haven't been deleted.
displayEmoteList(emoteCollection, channel, author); displayEmoteList(emoteCollection, send, author);
} catch (error) { } catch (error) {
if (error.code === "ERR_SCRIPT_EXECUTION_TIMEOUT") { if (error.code === "ERR_SCRIPT_EXECUTION_TIMEOUT") {
channel.send( send(
`The regular expression you entered exceeded the time limit of ${REGEX_TIMEOUT_MS} milliseconds.` `The regular expression you entered exceeded the time limit of ${REGEX_TIMEOUT_MS} milliseconds.`
); );
} else { } else {
@ -68,14 +68,14 @@ export default new NamedCommand({
} }
} }
} else { } else {
channel.send("Failed to initialize sandbox."); send("Failed to initialize sandbox.");
} }
} }
} }
}) })
}); });
async function displayEmoteList(emotes: GuildEmoji[], channel: TextChannel | DMChannel | NewsChannel, author: User) { async function displayEmoteList(emotes: GuildEmoji[], send: SendFunction, author: User) {
emotes.sort((a, b) => { emotes.sort((a, b) => {
const first = a.name.toLowerCase(); const first = a.name.toLowerCase();
const second = b.name.toLowerCase(); const second = b.name.toLowerCase();
@ -90,7 +90,7 @@ async function displayEmoteList(emotes: GuildEmoji[], channel: TextChannel | DMC
// Gather the first page (if it even exists, which it might not if there no valid emotes appear) // Gather the first page (if it even exists, which it might not if there no valid emotes appear)
if (pages > 0) { if (pages > 0) {
paginate(channel.send, author.id, pages, (page, hasMultiplePages) => { paginate(send, author.id, pages, (page, hasMultiplePages) => {
embed.setTitle(hasMultiplePages ? `**Emotes** (Page ${page + 1} of ${pages})` : "**Emotes**"); embed.setTitle(hasMultiplePages ? `**Emotes** (Page ${page + 1} of ${pages})` : "**Emotes**");
let desc = ""; let desc = "";
@ -102,6 +102,6 @@ async function displayEmoteList(emotes: GuildEmoji[], channel: TextChannel | DMC
return embed; return embed;
}); });
} else { } else {
channel.send("No valid emotes found by that query."); send("No valid emotes found by that query.");
} }
} }

View File

@ -6,7 +6,7 @@ export default new NamedCommand({
description: description:
"Reacts to the a previous message in your place. You have to react with the same emote before the bot removes that reaction.", "Reacts to the a previous message in your place. You have to react with the same emote before the bot removes that reaction.",
usage: 'react <emotes...> (<distance / message ID / "Copy ID" / "Copy Message Link">)', usage: 'react <emotes...> (<distance / message ID / "Copy ID" / "Copy Message Link">)',
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
let target: Message | undefined; let target: Message | undefined;
let distance = 1; let distance = 1;
@ -32,18 +32,18 @@ export default new NamedCommand({
try { try {
guild = await client.guilds.fetch(guildID); guild = await client.guilds.fetch(guildID);
} catch { } catch {
return channel.send(`\`${guildID}\` is an invalid guild ID!`); return send(`\`${guildID}\` is an invalid guild ID!`);
} }
} }
if (tmpChannel.id !== channelID) tmpChannel = guild.channels.cache.get(channelID); if (tmpChannel.id !== channelID) tmpChannel = guild.channels.cache.get(channelID);
if (!tmpChannel) return channel.send(`\`${channelID}\` is an invalid channel ID!`); if (!tmpChannel) return send(`\`${channelID}\` is an invalid channel ID!`);
if (message.id !== messageID) { if (message.id !== messageID) {
try { try {
target = await (tmpChannel as TextChannel).messages.fetch(messageID); target = await (tmpChannel as TextChannel).messages.fetch(messageID);
} catch { } catch {
return channel.send(`\`${messageID}\` is an invalid message ID!`); return send(`\`${messageID}\` is an invalid message ID!`);
} }
} }
@ -57,13 +57,13 @@ export default new NamedCommand({
let tmpChannel: Channel | undefined = channel; let tmpChannel: Channel | undefined = channel;
if (tmpChannel.id !== channelID) tmpChannel = guild?.channels.cache.get(channelID); if (tmpChannel.id !== channelID) tmpChannel = guild?.channels.cache.get(channelID);
if (!tmpChannel) return channel.send(`\`${channelID}\` is an invalid channel ID!`); if (!tmpChannel) return send(`\`${channelID}\` is an invalid channel ID!`);
if (message.id !== messageID) { if (message.id !== messageID) {
try { try {
target = await (tmpChannel as TextChannel).messages.fetch(messageID); target = await (tmpChannel as TextChannel).messages.fetch(messageID);
} catch { } catch {
return channel.send(`\`${messageID}\` is an invalid message ID!`); return send(`\`${messageID}\` is an invalid message ID!`);
} }
} }
@ -74,7 +74,7 @@ export default new NamedCommand({
try { try {
target = await channel.messages.fetch(last); target = await channel.messages.fetch(last);
} catch { } catch {
return channel.send(`No valid message found by the ID \`${last}\`!`); return send(`No valid message found by the ID \`${last}\`!`);
} }
args.pop(); args.pop();
@ -84,7 +84,7 @@ export default new NamedCommand({
distance = parseInt(last); distance = parseInt(last);
if (distance >= 0 && distance <= 99) args.pop(); if (distance >= 0 && distance <= 99) args.pop();
else return channel.send("Your distance must be between 0 and 99!"); else return send("Your distance must be between 0 and 99!");
} }
} }

View File

@ -6,8 +6,8 @@ export default new NamedCommand({
run: "Please provide a message for me to say!", run: "Please provide a message for me to say!",
any: new Command({ any: new Command({
description: "Message to repeat.", description: "Message to repeat.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
channel.send(`*${author} says:*\n${args.join(" ")}`); send(`*${author} says:*\n${args.join(" ")}`);
} }
}) })
}); });

View File

@ -9,7 +9,7 @@ export default new NamedCommand({
description: description:
"Scans all text channels in the current guild and returns the number of times each emoji specific to the guild has been used. Has a cooldown of 24 hours per guild.", "Scans all text channels in the current guild and returns the number of times each emoji specific to the guild has been used. Has a cooldown of 24 hours per guild.",
channelType: CHANNEL_TYPE.GUILD, channelType: CHANNEL_TYPE.GUILD,
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
// Test if the command is on cooldown. This isn't the strictest cooldown possible, because in the event that the bot crashes, the cooldown will be reset. But for all intends and purposes, it's a good enough cooldown. It's a per-server cooldown. // Test if the command is on cooldown. This isn't the strictest cooldown possible, because in the event that the bot crashes, the cooldown will be reset. But for all intends and purposes, it's a good enough cooldown. It's a per-server cooldown.
const startTime = Date.now(); const startTime = Date.now();
const cooldown = 86400000; // 24 hours const cooldown = 86400000; // 24 hours
@ -19,9 +19,7 @@ export default new NamedCommand({
// If it's been less than an hour since the command was last used, prevent it from executing. // If it's been less than an hour since the command was last used, prevent it from executing.
if (difference < cooldown) if (difference < cooldown)
return channel.send( return send(`This command requires a day to cooldown. You'll be able to activate this command ${howLong}.`);
`This command requires a day to cooldown. You'll be able to activate this command ${howLong}.`
);
else lastUsedTimestamps.set(guild!.id, startTime); else lastUsedTimestamps.set(guild!.id, startTime);
const stats: { const stats: {
@ -41,7 +39,7 @@ export default new NamedCommand({
let channelsSearched = 0; let channelsSearched = 0;
let currentChannelName = ""; let currentChannelName = "";
const totalChannels = allTextChannelsInCurrentGuild.size; const totalChannels = allTextChannelsInCurrentGuild.size;
const statusMessage = await channel.send("Gathering emotes..."); const statusMessage = await send("Gathering emotes...");
let warnings = 0; let warnings = 0;
channel.startTyping(); channel.startTyping();
@ -181,15 +179,15 @@ export default new NamedCommand({
); );
} }
return await channel.send(lines, {split: true}); return await send(lines, {split: true});
}, },
subcommands: { subcommands: {
forcereset: new NamedCommand({ forcereset: new NamedCommand({
description: "Forces the cooldown timer to reset.", description: "Forces the cooldown timer to reset.",
permission: PERMISSIONS.BOT_SUPPORT, permission: PERMISSIONS.BOT_SUPPORT,
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
lastUsedTimestamps.set(guild!.id, 0); lastUsedTimestamps.set(guild!.id, 0);
channel.send("Reset the cooldown on `scanemotes`."); send("Reset the cooldown on `scanemotes`.");
} }
}) })
} }

View File

@ -5,14 +5,14 @@ export default new NamedCommand({
description: "Shortens a given URL.", description: "Shortens a given URL.",
run: "Please provide a URL.", run: "Please provide a URL.",
any: new Command({ any: new Command({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
https.get("https://is.gd/create.php?format=simple&url=" + encodeURIComponent(args[0]), function (res) { https.get("https://is.gd/create.php?format=simple&url=" + encodeURIComponent(args[0]), function (res) {
var body = ""; var body = "";
res.on("data", function (chunk) { res.on("data", function (chunk) {
body += chunk; body += chunk;
}); });
res.on("end", function () { res.on("end", function () {
channel.send(`<${body}>`); send(`<${body}>`);
}); });
}); });
} }

View File

@ -3,7 +3,7 @@ import {streamList} from "../../modules/streamNotifications";
export default new NamedCommand({ export default new NamedCommand({
description: "Sets the description of your stream. You can embed links by writing `[some name](some link)`", description: "Sets the description of your stream. You can embed links by writing `[some name](some link)`",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const userID = author.id; const userID = author.id;
if (streamList.has(userID)) { if (streamList.has(userID)) {
@ -11,7 +11,7 @@ export default new NamedCommand({
const description = args.join(" ") || "No description set."; const description = args.join(" ") || "No description set.";
stream.description = description; stream.description = description;
stream.update(); stream.update();
channel.send(`Successfully set the stream description to:`, { send(`Successfully set the stream description to:`, {
embed: { embed: {
description, description,
color: member!.displayColor color: member!.displayColor
@ -19,7 +19,7 @@ export default new NamedCommand({
}); });
} else { } else {
// Alternatively, I could make descriptions last outside of just one stream. // Alternatively, I could make descriptions last outside of just one stream.
channel.send("You can only use this command when streaming."); send("You can only use this command when streaming.");
} }
} }
}); });

View File

@ -169,21 +169,21 @@ function getTimeEmbed(user: User) {
export default new NamedCommand({ export default new NamedCommand({
description: "Show others what time it is for you.", description: "Show others what time it is for you.",
aliases: ["tz"], aliases: ["tz"],
async run({channel, author}) { async run({send, channel, author}) {
channel.send(getTimeEmbed(author)); send(getTimeEmbed(author));
}, },
subcommands: { subcommands: {
// Welcome to callback hell. We hope you enjoy your stay here! // Welcome to callback hell. We hope you enjoy your stay here!
setup: new NamedCommand({ setup: new NamedCommand({
description: "Registers your timezone information for the bot.", description: "Registers your timezone information for the bot.",
async run({author, channel}) { async run({send, author, channel}) {
const profile = Storage.getUser(author.id); const profile = Storage.getUser(author.id);
profile.timezone = null; profile.timezone = null;
profile.daylightSavingsRegion = null; profile.daylightSavingsRegion = null;
let hour: number; let hour: number;
ask( ask(
await channel.send( await send(
"What hour (0 to 23) is it for you right now?\n*(Note: Make sure to use Discord's inline reply feature or this won't work!)*" "What hour (0 to 23) is it for you right now?\n*(Note: Make sure to use Discord's inline reply feature or this won't work!)*"
), ),
author.id, author.id,
@ -257,7 +257,7 @@ export default new NamedCommand({
// I calculate the list beforehand and check for duplicates to reduce unnecessary asking. // I calculate the list beforehand and check for duplicates to reduce unnecessary asking.
if (duplicates.includes(hour)) { if (duplicates.includes(hour)) {
const isSameDay = await askYesOrNo( const isSameDay = await askYesOrNo(
await channel.send( await send(
`Is the current day of the month the ${moment().utc().format("Do")} for you?` `Is the current day of the month the ${moment().utc().format("Do")} for you?`
), ),
author.id author.id
@ -289,13 +289,13 @@ export default new NamedCommand({
// I should note that error handling should be added sometime because await throws an exception on Promise.reject. // I should note that error handling should be added sometime because await throws an exception on Promise.reject.
const hasDST = await askYesOrNo( const hasDST = await askYesOrNo(
await channel.send("Does your timezone change based on daylight savings?"), await send("Does your timezone change based on daylight savings?"),
author.id author.id
); );
const finalize = () => { const finalize = () => {
Storage.save(); Storage.save();
channel.send( send(
"You've finished setting up your timezone! Just check to see if this looks right, and if it doesn't, run this setup again.", "You've finished setting up your timezone! Just check to see if this looks right, and if it doesn't, run this setup again.",
getTimeEmbed(author) getTimeEmbed(author)
); );
@ -313,7 +313,7 @@ export default new NamedCommand({
finalize(); finalize();
}; };
askMultipleChoice(await channel.send(DST_NOTE_SETUP), author.id, [ askMultipleChoice(await send(DST_NOTE_SETUP), author.id, [
() => finalizeDST("na"), () => finalizeDST("na"),
() => finalizeDST("eu"), () => finalizeDST("eu"),
() => finalizeDST("sh") () => finalizeDST("sh")
@ -328,9 +328,9 @@ export default new NamedCommand({
}), }),
delete: new NamedCommand({ delete: new NamedCommand({
description: "Delete your timezone information.", description: "Delete your timezone information.",
async run({channel, author}) { async run({send, channel, author}) {
prompt( prompt(
await channel.send( await send(
"Are you sure you want to delete your timezone information?\n*(This message will automatically be deleted after 10 seconds.)*" "Are you sure you want to delete your timezone information?\n*(This message will automatically be deleted after 10 seconds.)*"
), ),
author.id, author.id,
@ -345,10 +345,10 @@ export default new NamedCommand({
}), }),
utc: new NamedCommand({ utc: new NamedCommand({
description: "Displays UTC time.", description: "Displays UTC time.",
async run({channel}) { async run({send, channel}) {
const time = moment().utc(); const time = moment().utc();
channel.send({ send({
embed: { embed: {
color: TIME_EMBED_COLOR, color: TIME_EMBED_COLOR,
fields: [ fields: [
@ -377,16 +377,16 @@ export default new NamedCommand({
id: "user", id: "user",
user: new Command({ user: new Command({
description: "See what time it is for someone else.", description: "See what time it is for someone else.",
async run({channel, args}) { async run({send, channel, args}) {
channel.send(getTimeEmbed(args[0])); send(getTimeEmbed(args[0]));
} }
}), }),
any: new Command({ any: new Command({
description: "See what time it is for someone else (by their username).", description: "See what time it is for someone else (by their username).",
async run({channel, args, guild}) { async run({send, channel, args, guild}) {
const member = await getMemberByName(guild!, args.join(" ")); const member = await getMemberByName(guild!, args.join(" "));
if (member instanceof GuildMember) channel.send(getTimeEmbed(member.user)); if (member instanceof GuildMember) send(getTimeEmbed(member.user));
else channel.send(member); else send(member);
} }
}) })
}); });

View File

@ -5,7 +5,7 @@ import {MessageEmbed} from "discord.js";
export default new NamedCommand({ export default new NamedCommand({
description: "Keep and edit your personal todo list.", description: "Keep and edit your personal todo list.",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const user = Storage.getUser(author.id); const user = Storage.getUser(author.id);
const embed = new MessageEmbed().setTitle(`Todo list for ${author.tag}`).setColor("BLUE"); const embed = new MessageEmbed().setTitle(`Todo list for ${author.tag}`).setColor("BLUE");
@ -17,21 +17,21 @@ export default new NamedCommand({
); );
} }
channel.send(embed); send(embed);
}, },
subcommands: { subcommands: {
add: new NamedCommand({ add: new NamedCommand({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const user = Storage.getUser(author.id); const user = Storage.getUser(author.id);
const note = args.join(" "); const note = args.join(" ");
user.todoList[Date.now().toString()] = note; user.todoList[Date.now().toString()] = note;
console.debug(user.todoList); console.debug(user.todoList);
Storage.save(); Storage.save();
channel.send(`Successfully added \`${note}\` to your todo list.`); send(`Successfully added \`${note}\` to your todo list.`);
} }
}), }),
remove: new NamedCommand({ remove: new NamedCommand({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const user = Storage.getUser(author.id); const user = Storage.getUser(author.id);
const note = args.join(" "); const note = args.join(" ");
let isFound = false; let isFound = false;
@ -43,19 +43,19 @@ export default new NamedCommand({
delete user.todoList[timestamp]; delete user.todoList[timestamp];
Storage.save(); Storage.save();
isFound = true; isFound = true;
channel.send(`Removed \`${note}\` from your todo list.`); send(`Removed \`${note}\` from your todo list.`);
} }
} }
if (!isFound) channel.send("That item couldn't be found."); if (!isFound) send("That item couldn't be found.");
} }
}), }),
clear: new NamedCommand({ clear: new NamedCommand({
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const user = Storage.getUser(author.id); const user = Storage.getUser(author.id);
user.todoList = {}; user.todoList = {};
Storage.save(); Storage.save();
channel.send("Cleared todo list."); send("Cleared todo list.");
} }
}) })
} }

View File

@ -4,14 +4,14 @@ import translate from "translate-google";
export default new NamedCommand({ export default new NamedCommand({
description: "Translates your input.", description: "Translates your input.",
usage: "<lang ID> <input>", usage: "<lang ID> <input>",
async run({message, channel, guild, author, member, client, args}) { async run({send, message, channel, guild, author, member, client, args}) {
const lang = args[0]; const lang = args[0];
const input = args.slice(1).join(" "); const input = args.slice(1).join(" ");
translate(input, { translate(input, {
to: lang to: lang
}) })
.then((res) => { .then((res) => {
channel.send({ send({
embed: { embed: {
title: "Translation", title: "Translation",
fields: [ fields: [
@ -29,9 +29,7 @@ export default new NamedCommand({
}) })
.catch((error) => { .catch((error) => {
console.error(error); console.error(error);
channel.send( send(`${error}\nPlease use the following list: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes`);
`${error}\nPlease use the following list: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes`
);
}); });
} }
}); });