Added more library functions to command handler
This commit is contained in:
parent
bd67f3b8cc
commit
54ce28d8d4
|
@ -1,9 +1,10 @@
|
||||||
import {Command, NamedCommand, callMemberByUsername} from "../../core";
|
import {Command, NamedCommand, getMemberByName} from "../../core";
|
||||||
import {isAuthorized, getMoneyEmbed} from "./modules/eco-utils";
|
import {isAuthorized, getMoneyEmbed} from "./modules/eco-utils";
|
||||||
import {DailyCommand, PayCommand, GuildCommand, LeaderboardCommand} from "./modules/eco-core";
|
import {DailyCommand, PayCommand, GuildCommand, LeaderboardCommand} from "./modules/eco-core";
|
||||||
import {BuyCommand, ShopCommand} from "./modules/eco-shop";
|
import {BuyCommand, ShopCommand} from "./modules/eco-shop";
|
||||||
import {MondayCommand, AwardCommand} from "./modules/eco-extras";
|
import {MondayCommand, AwardCommand} from "./modules/eco-extras";
|
||||||
import {BetCommand} from "./modules/eco-bet";
|
import {BetCommand} from "./modules/eco-bet";
|
||||||
|
import {GuildMember} from "discord.js";
|
||||||
|
|
||||||
export default new NamedCommand({
|
export default new NamedCommand({
|
||||||
description: "Economy command for Monika.",
|
description: "Economy command for Monika.",
|
||||||
|
@ -35,10 +36,11 @@ export default new NamedCommand({
|
||||||
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({guild, channel, args, message}) {
|
||||||
if (isAuthorized(guild, channel))
|
if (isAuthorized(guild, channel)) {
|
||||||
callMemberByUsername(message, args.join(" "), (member) => {
|
const member = await getMemberByName(guild!, args.join(" "));
|
||||||
channel.send(getMoneyEmbed(member.user));
|
if (member instanceof GuildMember) channel.send(getMoneyEmbed(member.user));
|
||||||
});
|
else channel.send(member);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {User} from "discord.js";
|
import {User, GuildMember} from "discord.js";
|
||||||
import {Command, NamedCommand, getMemberByUsername, CHANNEL_TYPE} from "../../core";
|
import {Command, NamedCommand, getMemberByName, CHANNEL_TYPE} from "../../core";
|
||||||
|
|
||||||
// Quotes must be used here or the numbers will change
|
// Quotes must be used here or the numbers will change
|
||||||
const registry: {[id: string]: string} = {
|
const registry: {[id: string]: string} = {
|
||||||
|
@ -69,12 +69,10 @@ export default new NamedCommand({
|
||||||
channelType: CHANNEL_TYPE.GUILD,
|
channelType: CHANNEL_TYPE.GUILD,
|
||||||
async run({message, channel, guild, author, client, args}) {
|
async run({message, channel, guild, author, client, args}) {
|
||||||
const query = args.join(" ") as string;
|
const query = args.join(" ") as string;
|
||||||
const member = await getMemberByUsername(guild!, query);
|
const member = await getMemberByName(guild!, query);
|
||||||
|
|
||||||
if (member && member.id in registry) {
|
if (member instanceof GuildMember) {
|
||||||
const id = member.id;
|
if (member.id in registry) {
|
||||||
|
|
||||||
if (id in registry) {
|
|
||||||
channel.send(`\`${member.nickname ?? member.user.username}\` - ${registry[member.id]}`);
|
channel.send(`\`${member.nickname ?? member.user.username}\` - ${registry[member.id]}`);
|
||||||
} else {
|
} else {
|
||||||
channel.send(
|
channel.send(
|
||||||
|
@ -82,7 +80,7 @@ export default new NamedCommand({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
channel.send(`Couldn't find a user by the name of \`${query}\`!`);
|
channel.send(member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {MessageEmbed, version as djsversion, Guild, User, GuildMember} from "discord.js";
|
import {MessageEmbed, version as djsversion, Guild, User, GuildMember} from "discord.js";
|
||||||
import ms from "ms";
|
import ms from "ms";
|
||||||
import os from "os";
|
import os from "os";
|
||||||
import {Command, NamedCommand, getMemberByUsername, CHANNEL_TYPE} from "../../core";
|
import {Command, NamedCommand, getMemberByName, CHANNEL_TYPE} from "../../core";
|
||||||
import {formatBytes, trimArray} from "../../lib";
|
import {formatBytes, trimArray} from "../../lib";
|
||||||
import {verificationLevels, filterLevels, regions} from "../../defs/info";
|
import {verificationLevels, filterLevels, regions} from "../../defs/info";
|
||||||
import moment, {utc} from "moment";
|
import moment, {utc} from "moment";
|
||||||
|
@ -35,9 +35,9 @@ export default new NamedCommand({
|
||||||
channelType: CHANNEL_TYPE.GUILD,
|
channelType: CHANNEL_TYPE.GUILD,
|
||||||
async run({message, channel, guild, author, client, args}) {
|
async run({message, channel, guild, author, client, args}) {
|
||||||
const name = args.join(" ");
|
const name = args.join(" ");
|
||||||
const member = await getMemberByUsername(guild!, name);
|
const member = await getMemberByName(guild!, name);
|
||||||
|
|
||||||
if (member) {
|
if (member instanceof GuildMember) {
|
||||||
channel.send(
|
channel.send(
|
||||||
member.user.displayAvatarURL({
|
member.user.displayAvatarURL({
|
||||||
dynamic: true,
|
dynamic: true,
|
||||||
|
@ -45,7 +45,7 @@ export default new NamedCommand({
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
channel.send(`No user found by the name \`${name}\`!`);
|
channel.send(member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {Command, NamedCommand, ask, askYesOrNo, askMultipleChoice, prompt, callMemberByUsername} from "../../core";
|
import {Command, NamedCommand, ask, askYesOrNo, askMultipleChoice, prompt, getMemberByName} from "../../core";
|
||||||
import {Storage} from "../../structures";
|
import {Storage} from "../../structures";
|
||||||
import {User} from "discord.js";
|
import {User, GuildMember} from "discord.js";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
|
||||||
const DATE_FORMAT = "D MMMM YYYY";
|
const DATE_FORMAT = "D MMMM YYYY";
|
||||||
|
@ -383,10 +383,10 @@ export default new NamedCommand({
|
||||||
}),
|
}),
|
||||||
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, message}) {
|
async run({channel, args, guild}) {
|
||||||
callMemberByUsername(message, args.join(" "), (member) => {
|
const member = await getMemberByName(guild!, args.join(" "));
|
||||||
channel.send(getTimeEmbed(member.user));
|
if (member instanceof GuildMember) channel.send(getTimeEmbed(member.user));
|
||||||
});
|
else channel.send(member);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,9 +8,10 @@ import {
|
||||||
Guild,
|
Guild,
|
||||||
User,
|
User,
|
||||||
GuildMember,
|
GuildMember,
|
||||||
GuildChannel
|
GuildChannel,
|
||||||
|
Channel
|
||||||
} from "discord.js";
|
} from "discord.js";
|
||||||
import {SingleMessageOptions} from "./libd";
|
import {getChannelByID, getMessageByID, getUserByID, SingleMessageOptions} from "./libd";
|
||||||
import {hasPermission, getPermissionLevel, getPermissionName} from "./permissions";
|
import {hasPermission, getPermissionLevel, getPermissionName} from "./permissions";
|
||||||
import {getPrefix} from "./interface";
|
import {getPrefix} from "./interface";
|
||||||
import {parseVars, requireAllCasesHandledFor} from "../lib";
|
import {parseVars, requireAllCasesHandledFor} from "../lib";
|
||||||
|
@ -338,17 +339,20 @@ export class Command {
|
||||||
return this.subcommands.get(param)!.execute(args, menu, metadata);
|
return this.subcommands.get(param)!.execute(args, menu, metadata);
|
||||||
} else if (this.channel && patterns.channel.test(param)) {
|
} else if (this.channel && patterns.channel.test(param)) {
|
||||||
const id = patterns.channel.exec(param)![1];
|
const id = patterns.channel.exec(param)![1];
|
||||||
const channel = menu.client.channels.cache.get(id);
|
const channel = await getChannelByID(id);
|
||||||
|
|
||||||
// Users can only enter in this format for text channels, so this restricts it to that.
|
if (channel instanceof Channel) {
|
||||||
if (channel instanceof TextChannel) {
|
if (channel instanceof TextChannel || channel instanceof DMChannel) {
|
||||||
metadata.symbolicArgs.push("<channel>");
|
metadata.symbolicArgs.push("<channel>");
|
||||||
menu.args.push(channel);
|
menu.args.push(channel);
|
||||||
return this.channel.execute(args, menu, metadata);
|
return this.channel.execute(args, menu, metadata);
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
content: `\`${id}\` is not a valid text channel!`
|
||||||
|
};
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return {
|
return channel;
|
||||||
content: `\`${id}\` is not a valid text channel!`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
} else if (this.role && patterns.role.test(param)) {
|
} else if (this.role && patterns.role.test(param)) {
|
||||||
const id = patterns.role.exec(param)![1];
|
const id = patterns.role.exec(param)![1];
|
||||||
|
@ -397,34 +401,25 @@ export class Command {
|
||||||
messageID = result[2];
|
messageID = result[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
const channel = menu.client.channels.cache.get(channelID);
|
const message = await getMessageByID(channelID, messageID);
|
||||||
|
|
||||||
if (channel instanceof TextChannel || channel instanceof DMChannel) {
|
if (message instanceof Message) {
|
||||||
try {
|
metadata.symbolicArgs.push("<message>");
|
||||||
metadata.symbolicArgs.push("<message>");
|
menu.args.push(message);
|
||||||
menu.args.push(await channel.messages.fetch(messageID));
|
return this.message.execute(args, menu, metadata);
|
||||||
return this.message.execute(args, menu, metadata);
|
|
||||||
} catch {
|
|
||||||
return {
|
|
||||||
content: `\`${messageID}\` isn't a valid message of channel ${channel}!`
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return {
|
return message;
|
||||||
content: `\`${channelID}\` is not a valid text channel!`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
} else if (this.user && patterns.user.test(param)) {
|
} else if (this.user && patterns.user.test(param)) {
|
||||||
const id = patterns.user.exec(param)![1];
|
const id = patterns.user.exec(param)![1];
|
||||||
|
const user = await getUserByID(id);
|
||||||
|
|
||||||
try {
|
if (user instanceof User) {
|
||||||
metadata.symbolicArgs.push("<user>");
|
metadata.symbolicArgs.push("<user>");
|
||||||
menu.args.push(await menu.client.users.fetch(id));
|
menu.args.push(user);
|
||||||
return this.user.execute(args, menu, metadata);
|
return this.user.execute(args, menu, metadata);
|
||||||
} catch {
|
} else {
|
||||||
return {
|
return user;
|
||||||
content: `No user found by the ID \`${id}\`!`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
} else if (this.id && this.idType && patterns.id.test(param)) {
|
} else if (this.id && this.idType && patterns.id.test(param)) {
|
||||||
metadata.symbolicArgs.push("<id>");
|
metadata.symbolicArgs.push("<id>");
|
||||||
|
@ -434,16 +429,20 @@ export class Command {
|
||||||
// Because this part is pretty much a whole bunch of copy pastes.
|
// Because this part is pretty much a whole bunch of copy pastes.
|
||||||
switch (this.idType) {
|
switch (this.idType) {
|
||||||
case "channel":
|
case "channel":
|
||||||
const channel = menu.client.channels.cache.get(id);
|
const channel = await getChannelByID(id);
|
||||||
|
|
||||||
// Users can only enter in this format for text channels, so this restricts it to that.
|
if (channel instanceof Channel) {
|
||||||
if (channel instanceof TextChannel) {
|
if (channel instanceof TextChannel || channel instanceof DMChannel) {
|
||||||
menu.args.push(channel);
|
metadata.symbolicArgs.push("<channel>");
|
||||||
return this.id.execute(args, menu, metadata);
|
menu.args.push(channel);
|
||||||
|
return this.id.execute(args, menu, metadata);
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
content: `\`${id}\` is not a valid text channel!`
|
||||||
|
};
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return {
|
return channel;
|
||||||
content: `\`${id}\` isn't a valid text channel!`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
case "role":
|
case "role":
|
||||||
if (!menu.guild) {
|
if (!menu.guild) {
|
||||||
|
@ -474,22 +473,22 @@ export class Command {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
case "message":
|
case "message":
|
||||||
try {
|
const message = await getMessageByID(menu.channel, id);
|
||||||
menu.args.push(await menu.channel.messages.fetch(id));
|
|
||||||
|
if (message instanceof Message) {
|
||||||
|
menu.args.push(message);
|
||||||
return this.id.execute(args, menu, metadata);
|
return this.id.execute(args, menu, metadata);
|
||||||
} catch {
|
} else {
|
||||||
return {
|
return message;
|
||||||
content: `\`${id}\` isn't a valid message of channel ${menu.channel}!`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
case "user":
|
case "user":
|
||||||
try {
|
const user = await getUserByID(id);
|
||||||
menu.args.push(await menu.client.users.fetch(id));
|
|
||||||
|
if (user instanceof User) {
|
||||||
|
menu.args.push(user);
|
||||||
return this.id.execute(args, menu, metadata);
|
return this.id.execute(args, menu, metadata);
|
||||||
} catch {
|
} else {
|
||||||
return {
|
return user;
|
||||||
content: `No user found by the ID \`${id}\`!`
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
requireAllCasesHandledFor(this.idType);
|
requireAllCasesHandledFor(this.idType);
|
||||||
|
|
|
@ -2,16 +2,6 @@
|
||||||
export {Command, NamedCommand, CHANNEL_TYPE} from "./command";
|
export {Command, NamedCommand, CHANNEL_TYPE} from "./command";
|
||||||
export {addInterceptRule} from "./handler";
|
export {addInterceptRule} from "./handler";
|
||||||
export {launch} from "./interface";
|
export {launch} from "./interface";
|
||||||
export {
|
export * from "./libd";
|
||||||
SingleMessageOptions,
|
|
||||||
botHasPermission,
|
|
||||||
paginate,
|
|
||||||
prompt,
|
|
||||||
ask,
|
|
||||||
askYesOrNo,
|
|
||||||
askMultipleChoice,
|
|
||||||
getMemberByUsername,
|
|
||||||
callMemberByUsername
|
|
||||||
} from "./libd";
|
|
||||||
export {getCommandList, getCommandInfo} from "./loader";
|
export {getCommandList, getCommandInfo} from "./loader";
|
||||||
export {hasPermission, getPermissionLevel, getPermissionName} from "./permissions";
|
export {hasPermission, getPermissionLevel, getPermissionName} from "./permissions";
|
||||||
|
|
|
@ -25,11 +25,13 @@ interface LaunchSettings {
|
||||||
// Additionally, each method would return the object so multiple methods could be chained, such as OnionCore.setPermissions(...).setPrefixResolver(...).launch(client).
|
// Additionally, each method would return the object so multiple methods could be chained, such as OnionCore.setPermissions(...).setPrefixResolver(...).launch(client).
|
||||||
// I decided to not do this because creating a class then having a bunch of boilerplate around it just wouldn't really be worth it.
|
// I decided to not do this because creating a class then having a bunch of boilerplate around it just wouldn't really be worth it.
|
||||||
// commandsDirectory requires an absolute path to work, so use __dirname.
|
// commandsDirectory requires an absolute path to work, so use __dirname.
|
||||||
export async function launch(client: Client, commandsDirectory: string, settings?: LaunchSettings) {
|
export async function launch(newClient: Client, commandsDirectory: string, settings?: LaunchSettings) {
|
||||||
// Core Launch Parameters //
|
// Core Launch Parameters //
|
||||||
|
client.destroy(); // Release any resources/connections being used by the placeholder client.
|
||||||
|
client = newClient;
|
||||||
loadableCommands = loadCommands(commandsDirectory);
|
loadableCommands = loadCommands(commandsDirectory);
|
||||||
attachMessageHandlerToClient(client);
|
attachMessageHandlerToClient(newClient);
|
||||||
attachEventListenersToClient(client);
|
attachEventListenersToClient(newClient);
|
||||||
|
|
||||||
// Additional Configuration //
|
// Additional Configuration //
|
||||||
if (settings?.permissionLevels) {
|
if (settings?.permissionLevels) {
|
||||||
|
@ -42,6 +44,7 @@ export async function launch(client: Client, commandsDirectory: string, settings
|
||||||
|
|
||||||
// Placeholder until properly loaded by the user.
|
// Placeholder until properly loaded by the user.
|
||||||
export let loadableCommands = (async () => new Collection<string, NamedCommand>())();
|
export let loadableCommands = (async () => new Collection<string, NamedCommand>())();
|
||||||
|
export let client = new Client();
|
||||||
export let permissionLevels: PermissionLevel[] = [
|
export let permissionLevels: PermissionLevel[] = [
|
||||||
{
|
{
|
||||||
name: "User",
|
name: "User",
|
||||||
|
|
179
src/core/libd.ts
179
src/core/libd.ts
|
@ -7,9 +7,13 @@ import {
|
||||||
TextChannel,
|
TextChannel,
|
||||||
DMChannel,
|
DMChannel,
|
||||||
NewsChannel,
|
NewsChannel,
|
||||||
MessageOptions
|
MessageOptions,
|
||||||
|
Channel,
|
||||||
|
GuildChannel,
|
||||||
|
User
|
||||||
} from "discord.js";
|
} from "discord.js";
|
||||||
import {unreactEventListeners, replyEventListeners} from "./eventListeners";
|
import {unreactEventListeners, replyEventListeners} from "./eventListeners";
|
||||||
|
import {client} from "./interface";
|
||||||
|
|
||||||
export type SingleMessageOptions = MessageOptions & {split?: false};
|
export type SingleMessageOptions = MessageOptions & {split?: false};
|
||||||
|
|
||||||
|
@ -20,16 +24,19 @@ export function botHasPermission(guild: Guild | null, permission: number): boole
|
||||||
return !!guild?.me?.hasPermission(permission);
|
return !!guild?.me?.hasPermission(permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The SoonTM Section //
|
||||||
// Maybe promisify this section to reduce the potential for creating callback hell? Especially if multiple questions in a row are being asked.
|
// Maybe promisify this section to reduce the potential for creating callback hell? Especially if multiple questions in a row are being asked.
|
||||||
|
// It's probably a good idea to modularize the base reaction handler so there's less copy pasted code.
|
||||||
// Pagination function that allows for customization via a callback.
|
// Maybe also make a reaction handler that listens for when reactions are added and removed.
|
||||||
// Define your own pages outside the function because this only manages the actual turning of pages.
|
// The reaction handler would also run an async function to react in order (parallel to the reaction handler).
|
||||||
|
|
||||||
const FIVE_BACKWARDS_EMOJI = "⏪";
|
const FIVE_BACKWARDS_EMOJI = "⏪";
|
||||||
const BACKWARDS_EMOJI = "⬅️";
|
const BACKWARDS_EMOJI = "⬅️";
|
||||||
const FORWARDS_EMOJI = "➡️";
|
const FORWARDS_EMOJI = "➡️";
|
||||||
const FIVE_FORWARDS_EMOJI = "⏩";
|
const FIVE_FORWARDS_EMOJI = "⏩";
|
||||||
|
|
||||||
|
// Pagination function that allows for customization via a callback.
|
||||||
|
// Define your own pages outside the function because this only manages the actual turning of pages.
|
||||||
/**
|
/**
|
||||||
* Takes a message and some additional parameters and makes a reaction page with it. All the pagination logic is taken care of but nothing more, the page index is returned and you have to send a callback to do something with it.
|
* Takes a message and some additional parameters and makes a reaction page with it. All the pagination logic is taken care of but nothing more, the page index is returned and you have to send a callback to do something with it.
|
||||||
*/
|
*/
|
||||||
|
@ -251,44 +258,132 @@ export async function askMultipleChoice(
|
||||||
if (!isDeleted) message.delete();
|
if (!isDeleted) message.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a user by their username. Gets the first one then rolls with it.
|
|
||||||
*/
|
|
||||||
export async function getMemberByUsername(guild: Guild, username: string) {
|
|
||||||
return (
|
|
||||||
await guild.members.fetch({
|
|
||||||
query: username,
|
|
||||||
limit: 1
|
|
||||||
})
|
|
||||||
).first();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenience function to handle cases where someone isn't found by a username automatically.
|
|
||||||
*/
|
|
||||||
export async function callMemberByUsername(
|
|
||||||
message: Message,
|
|
||||||
username: string,
|
|
||||||
onSuccess: (member: GuildMember) => void
|
|
||||||
) {
|
|
||||||
const guild = message.guild;
|
|
||||||
const send = message.channel.send;
|
|
||||||
|
|
||||||
if (guild) {
|
|
||||||
const member = await getMemberByUsername(guild, username);
|
|
||||||
|
|
||||||
if (member) onSuccess(member);
|
|
||||||
else send(`Couldn't find a user by the name of \`${username}\`!`);
|
|
||||||
} else send("You must execute this command in a server!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// TO DO Section //
|
|
||||||
|
|
||||||
// getGuildByID() - checks for guild.available (boolean)
|
|
||||||
// getGuildByName()
|
|
||||||
// findMemberByNickname() - gets a member by their nickname or their username
|
|
||||||
// findUserByUsername()
|
|
||||||
|
|
||||||
// For "get x by y" methods:
|
// For "get x by y" methods:
|
||||||
// Caching: All guilds, channels, and roles are fully cached, while the caches for messages, users, and members aren't complete.
|
// Caching: All guilds, channels, and roles are fully cached, while the caches for messages, users, and members aren't complete.
|
||||||
// It's more reliable to get users/members by fetching their IDs. fetch() will searching through the cache anyway.
|
// It's more reliable to get users/members by fetching their IDs. fetch() will searching through the cache anyway.
|
||||||
|
// For guilds, do an extra check to make sure there isn't an outage (guild.available).
|
||||||
|
|
||||||
|
export function getGuildByID(id: string): Guild | SingleMessageOptions {
|
||||||
|
const guild = client.guilds.cache.get(id);
|
||||||
|
|
||||||
|
if (guild) {
|
||||||
|
if (guild.available) return guild;
|
||||||
|
else return {content: `The guild \`${guild.name}\` (ID: \`${id}\`) is unavailable due to an outage.`};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
content: `No guild found by the ID of \`${id}\`!`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGuildByName(name: string): Guild | SingleMessageOptions {
|
||||||
|
const query = name.toLowerCase();
|
||||||
|
const guild = client.guilds.cache.find((guild) => guild.name.toLowerCase().includes(query));
|
||||||
|
|
||||||
|
if (guild) {
|
||||||
|
if (guild.available) return guild;
|
||||||
|
else return {content: `The guild \`${guild.name}\` (ID: \`${guild.id}\`) is unavailable due to an outage.`};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
content: `No guild found by the name of \`${name}\`!`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getChannelByID(id: string): Promise<Channel | SingleMessageOptions> {
|
||||||
|
try {
|
||||||
|
return await client.channels.fetch(id);
|
||||||
|
} catch {
|
||||||
|
return {content: `No channel found by the ID of \`${id}\`!`};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only go through the cached channels (non-DM channels). Plus, searching DM channels by name wouldn't really make sense, nor do they have names to search anyway.
|
||||||
|
export function getChannelByName(name: string): GuildChannel | SingleMessageOptions {
|
||||||
|
const query = name.toLowerCase();
|
||||||
|
const channel = client.channels.cache.find(
|
||||||
|
(channel) => channel instanceof GuildChannel && channel.name.toLowerCase().includes(query)
|
||||||
|
) as GuildChannel | undefined;
|
||||||
|
if (channel) return channel;
|
||||||
|
else return {content: `No channel found by the name of \`${name}\`!`};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getMessageByID(
|
||||||
|
channel: TextChannel | DMChannel | NewsChannel | string,
|
||||||
|
id: string
|
||||||
|
): Promise<Message | SingleMessageOptions> {
|
||||||
|
if (typeof channel === "string") {
|
||||||
|
const targetChannel = await getChannelByID(channel);
|
||||||
|
if (targetChannel instanceof TextChannel || targetChannel instanceof DMChannel) channel = targetChannel;
|
||||||
|
else if (targetChannel instanceof Channel) return {content: `\`${id}\` isn't a valid text-based channel!`};
|
||||||
|
else return targetChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await channel.messages.fetch(id);
|
||||||
|
} catch {
|
||||||
|
return {content: `\`${id}\` isn't a valid message of the channel ${channel}!`};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getUserByID(id: string): Promise<User | SingleMessageOptions> {
|
||||||
|
try {
|
||||||
|
return await client.users.fetch(id);
|
||||||
|
} catch {
|
||||||
|
return {content: `No user found by the ID of \`${id}\`!`};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also check tags (if provided) to narrow down users.
|
||||||
|
export function getUserByName(name: string): User | SingleMessageOptions {
|
||||||
|
let query = name.toLowerCase();
|
||||||
|
const tagMatch = /^(.+?)#(\d{4})$/.exec(name);
|
||||||
|
let tag: string | null = null;
|
||||||
|
|
||||||
|
if (tagMatch) {
|
||||||
|
query = tagMatch[1].toLowerCase();
|
||||||
|
tag = tagMatch[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = client.users.cache.find((user) => {
|
||||||
|
const hasUsernameMatch = user.username.toLowerCase().includes(query);
|
||||||
|
if (tag) return hasUsernameMatch && user.discriminator === tag;
|
||||||
|
else return hasUsernameMatch;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (user) return user;
|
||||||
|
else return {content: `No user found by the name of \`${name}\`!`};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getMemberByID(guild: Guild, id: string): Promise<GuildMember | SingleMessageOptions> {
|
||||||
|
try {
|
||||||
|
return await guild.members.fetch(id);
|
||||||
|
} catch {
|
||||||
|
return {content: `No member found by the ID of \`${id}\`!`};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// First checks if a member can be found by that nickname, then check if a member can be found by that username.
|
||||||
|
export async function getMemberByName(guild: Guild, name: string): Promise<GuildMember | SingleMessageOptions> {
|
||||||
|
const member = (
|
||||||
|
await guild.members.fetch({
|
||||||
|
query: name,
|
||||||
|
limit: 1
|
||||||
|
})
|
||||||
|
).first();
|
||||||
|
|
||||||
|
// Search by username if no member is found, then resolve the user into a member if possible.
|
||||||
|
if (member) {
|
||||||
|
return member;
|
||||||
|
} else {
|
||||||
|
const user = getUserByName(name);
|
||||||
|
|
||||||
|
if (user instanceof User) {
|
||||||
|
const member = guild.members.resolve(user);
|
||||||
|
if (member) return member;
|
||||||
|
else return {content: `The user \`${user.tag}\` isn't in this guild!`};
|
||||||
|
} else {
|
||||||
|
return {content: `No member found by the name of \`${name}\`!`};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue