@sapphire/framework
Version:
Discord bot framework built for advanced and amazing bots.
1 lines • 7.19 kB
Source Map (JSON)
{"version":3,"sources":["../../../../src/lib/resolvers/message.ts"],"names":[],"mappings":"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","file":"message.mjs","sourcesContent":["import { ChannelMessageRegex, MessageLinkRegex, SnowflakeRegex } from '@sapphire/discord-utilities';\nimport {\n\tisAnyInteraction,\n\tisGuildBasedChannel,\n\tisNewsChannel,\n\tisStageChannel,\n\tisTextBasedChannel,\n\tisTextChannel,\n\ttype AnyInteraction,\n\ttype GuildBasedChannelTypes,\n\ttype TextBasedChannelTypes\n} from '@sapphire/discord.js-utilities';\nimport { container } from '@sapphire/pieces';\nimport { Result } from '@sapphire/result';\nimport type { Awaitable } from '@sapphire/utilities';\nimport { PermissionFlagsBits, type Message, type Snowflake, type User } from 'discord.js';\nimport { Identifiers } from '../errors/Identifiers';\n\n/**\n * Options to resolve a message from a string, given a certain context.\n */\nexport interface MessageResolverOptions {\n\t/**\n\t * Channel to resolve the message in.\n\t * @default message.channel\n\t */\n\tchannel?: TextBasedChannelTypes;\n\t/**\n\t * Base {@link Message} or {@link AnyInteraction} to resolve the message from (e.g. pick the channel if not given).\n\t */\n\tmessageOrInteraction: Message | AnyInteraction;\n\t/**\n\t * Whether to scan the entire guild cache for the message.\n\t * If channel is given with this option, this option is ignored.\n\t * @default false\n\t */\n\tscan?: boolean;\n}\n\nexport async function resolveMessage(parameter: string, options: MessageResolverOptions): Promise<Result<Message, Identifiers.ArgumentMessageError>> {\n\tconst message =\n\t\t(await resolveById(parameter, options)) ??\n\t\t(await resolveByLink(parameter, options)) ??\n\t\t(await resolveByChannelAndMessage(parameter, options));\n\n\tif (message) {\n\t\treturn Result.ok(message);\n\t}\n\n\treturn Result.err(Identifiers.ArgumentMessageError);\n}\n\nfunction resolveById(parameter: string, options: MessageResolverOptions): Awaitable<Message | null> {\n\tif (!SnowflakeRegex.test(parameter) || isStageChannel(options.messageOrInteraction.channel)) {\n\t\treturn null;\n\t}\n\n\tif (options.channel && !isStageChannel(options.channel)) {\n\t\treturn options.channel.messages.fetch(parameter as Snowflake);\n\t}\n\n\tif (options.scan && isGuildBasedChannel(options.messageOrInteraction.channel)) {\n\t\tfor (const channel of options.messageOrInteraction.channel.guild.channels.cache.values()) {\n\t\t\tif (!isTextBasedChannel(channel) || isStageChannel(channel)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst message = channel.messages.cache.get(parameter);\n\t\t\tif (message) {\n\t\t\t\treturn message;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn options.messageOrInteraction.channel?.messages.fetch(parameter as Snowflake) ?? null;\n}\n\nasync function resolveByLink(parameter: string, options: MessageResolverOptions): Promise<Message | null> {\n\tif (!options.messageOrInteraction.guild) {\n\t\treturn null;\n\t}\n\n\tconst matches = MessageLinkRegex.exec(parameter);\n\tif (!matches) {\n\t\treturn null;\n\t}\n\n\tconst [, guildId, channelId, messageId] = matches;\n\n\tconst guild = container.client.guilds.cache.get(guildId as Snowflake);\n\tif (guild !== options.messageOrInteraction.guild) {\n\t\treturn null;\n\t}\n\n\treturn getMessageFromChannel(\n\t\tchannelId,\n\t\tmessageId,\n\t\tisAnyInteraction(options.messageOrInteraction) ? options.messageOrInteraction.user : options.messageOrInteraction.author\n\t);\n}\n\nasync function resolveByChannelAndMessage(parameter: string, options: MessageResolverOptions): Promise<Message | null> {\n\tconst result = ChannelMessageRegex.exec(parameter)?.groups;\n\n\tif (!result) {\n\t\treturn null;\n\t}\n\n\treturn getMessageFromChannel(\n\t\tresult.channelId,\n\t\tresult.messageId,\n\t\tisAnyInteraction(options.messageOrInteraction) ? options.messageOrInteraction.user : options.messageOrInteraction.author\n\t);\n}\n\nasync function getMessageFromChannel(channelId: Snowflake, messageId: Snowflake, originalAuthor: User): Promise<Message | null> {\n\tconst channel = container.client.channels.cache.get(channelId) as GuildBasedChannelTypes;\n\tif (!channel) {\n\t\treturn null;\n\t}\n\n\tif (!(isNewsChannel(channel) || isTextChannel(channel))) {\n\t\treturn null;\n\t}\n\n\tif (!channel.viewable) {\n\t\treturn null;\n\t}\n\n\tif (!channel.permissionsFor(originalAuthor)?.has(PermissionFlagsBits.ViewChannel)) {\n\t\treturn null;\n\t}\n\n\treturn channel.messages.fetch(messageId);\n}\n"]}