diff options
author | sowgro <tpoke.ferrari@gmail.com> | 2023-09-02 19:12:47 -0400 |
---|---|---|
committer | sowgro <tpoke.ferrari@gmail.com> | 2023-09-02 19:12:47 -0400 |
commit | e4450c8417624b71d779cb4f41692538f9165e10 (patch) | |
tree | b70826542223ecdf8a7a259f61b0a1abb8a217d8 /node_modules/discord.js/src/structures/MessagePayload.js | |
download | sowbot3-e4450c8417624b71d779cb4f41692538f9165e10.tar.gz sowbot3-e4450c8417624b71d779cb4f41692538f9165e10.tar.bz2 sowbot3-e4450c8417624b71d779cb4f41692538f9165e10.zip |
first commit
Diffstat (limited to 'node_modules/discord.js/src/structures/MessagePayload.js')
-rw-r--r-- | node_modules/discord.js/src/structures/MessagePayload.js | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/node_modules/discord.js/src/structures/MessagePayload.js b/node_modules/discord.js/src/structures/MessagePayload.js new file mode 100644 index 0000000..e237309 --- /dev/null +++ b/node_modules/discord.js/src/structures/MessagePayload.js @@ -0,0 +1,299 @@ +'use strict'; + +const { Buffer } = require('node:buffer'); +const { lazy, isJSONEncodable } = require('@discordjs/util'); +const { MessageFlags } = require('discord-api-types/v10'); +const ActionRowBuilder = require('./ActionRowBuilder'); +const { DiscordjsRangeError, ErrorCodes } = require('../errors'); +const DataResolver = require('../util/DataResolver'); +const MessageFlagsBitField = require('../util/MessageFlagsBitField'); +const { basename, verifyString } = require('../util/Util'); + +const getBaseInteraction = lazy(() => require('./BaseInteraction')); + +/** + * Represents a message to be sent to the API. + */ +class MessagePayload { + /** + * @param {MessageTarget} target The target for this message to be sent to + * @param {MessagePayloadOption} options The payload of this message + */ + constructor(target, options) { + /** + * The target for this message to be sent to + * @type {MessageTarget} + */ + this.target = target; + + /** + * The payload of this message. + * @type {MessagePayloadOption} + */ + this.options = options; + + /** + * Body sendable to the API + * @type {?APIMessage} + */ + this.body = null; + + /** + * Files sendable to the API + * @type {?RawFile[]} + */ + this.files = null; + } + + /** + * Whether or not the target is a {@link Webhook} or a {@link WebhookClient} + * @type {boolean} + * @readonly + */ + get isWebhook() { + const Webhook = require('./Webhook'); + const WebhookClient = require('../client/WebhookClient'); + return this.target instanceof Webhook || this.target instanceof WebhookClient; + } + + /** + * Whether or not the target is a {@link User} + * @type {boolean} + * @readonly + */ + get isUser() { + const User = require('./User'); + const { GuildMember } = require('./GuildMember'); + return this.target instanceof User || this.target instanceof GuildMember; + } + + /** + * Whether or not the target is a {@link Message} + * @type {boolean} + * @readonly + */ + get isMessage() { + const { Message } = require('./Message'); + return this.target instanceof Message; + } + + /** + * Whether or not the target is a {@link MessageManager} + * @type {boolean} + * @readonly + */ + get isMessageManager() { + const MessageManager = require('../managers/MessageManager'); + return this.target instanceof MessageManager; + } + + /** + * Whether or not the target is an {@link BaseInteraction} or an {@link InteractionWebhook} + * @type {boolean} + * @readonly + */ + get isInteraction() { + const BaseInteraction = getBaseInteraction(); + const InteractionWebhook = require('./InteractionWebhook'); + return this.target instanceof BaseInteraction || this.target instanceof InteractionWebhook; + } + + /** + * Makes the content of this message. + * @returns {?string} + */ + makeContent() { + let content; + if (this.options.content === null) { + content = ''; + } else if (this.options.content !== undefined) { + content = verifyString(this.options.content, DiscordjsRangeError, ErrorCodes.MessageContentType, true); + } + + return content; + } + + /** + * Resolves the body. + * @returns {MessagePayload} + */ + resolveBody() { + if (this.body) return this; + const isInteraction = this.isInteraction; + const isWebhook = this.isWebhook; + + const content = this.makeContent(); + const tts = Boolean(this.options.tts); + + let nonce; + if (this.options.nonce !== undefined) { + nonce = this.options.nonce; + if (typeof nonce === 'number' ? !Number.isInteger(nonce) : typeof nonce !== 'string') { + throw new DiscordjsRangeError(ErrorCodes.MessageNonceType); + } + } + + const components = this.options.components?.map(c => (isJSONEncodable(c) ? c : new ActionRowBuilder(c)).toJSON()); + + let username; + let avatarURL; + let threadName; + if (isWebhook) { + username = this.options.username ?? this.target.name; + if (this.options.avatarURL) avatarURL = this.options.avatarURL; + if (this.options.threadName) threadName = this.options.threadName; + } + + let flags; + if ( + this.options.flags !== undefined || + (this.isMessage && this.options.reply === undefined) || + this.isMessageManager + ) { + flags = + // eslint-disable-next-line eqeqeq + this.options.flags != null + ? new MessageFlagsBitField(this.options.flags).bitfield + : this.target.flags?.bitfield; + } + + if (isInteraction && this.options.ephemeral) { + flags |= MessageFlags.Ephemeral; + } + + let allowedMentions = + this.options.allowedMentions === undefined + ? this.target.client.options.allowedMentions + : this.options.allowedMentions; + + if (allowedMentions?.repliedUser !== undefined) { + allowedMentions = { ...allowedMentions, replied_user: allowedMentions.repliedUser }; + delete allowedMentions.repliedUser; + } + + let message_reference; + if (typeof this.options.reply === 'object') { + const reference = this.options.reply.messageReference; + const message_id = this.isMessage ? reference.id ?? reference : this.target.messages.resolveId(reference); + if (message_id) { + message_reference = { + message_id, + fail_if_not_exists: this.options.reply.failIfNotExists ?? this.target.client.options.failIfNotExists, + }; + } + } + + const attachments = this.options.files?.map((file, index) => ({ + id: index.toString(), + description: file.description, + })); + if (Array.isArray(this.options.attachments)) { + this.options.attachments.push(...(attachments ?? [])); + } else { + this.options.attachments = attachments; + } + + this.body = { + content, + tts, + nonce, + embeds: this.options.embeds?.map(embed => + isJSONEncodable(embed) ? embed.toJSON() : this.target.client.options.jsonTransformer(embed), + ), + components, + username, + avatar_url: avatarURL, + allowed_mentions: content === undefined && message_reference === undefined ? undefined : allowedMentions, + flags, + message_reference, + attachments: this.options.attachments, + sticker_ids: this.options.stickers?.map(sticker => sticker.id ?? sticker), + thread_name: threadName, + }; + return this; + } + + /** + * Resolves files. + * @returns {Promise<MessagePayload>} + */ + async resolveFiles() { + if (this.files) return this; + + this.files = await Promise.all(this.options.files?.map(file => this.constructor.resolveFile(file)) ?? []); + return this; + } + + /** + * Resolves a single file into an object sendable to the API. + * @param {AttachmentPayload|BufferResolvable|Stream} fileLike Something that could be resolved to a file + * @returns {Promise<RawFile>} + */ + static async resolveFile(fileLike) { + let attachment; + let name; + + const findName = thing => { + if (typeof thing === 'string') { + return basename(thing); + } + + if (thing.path) { + return basename(thing.path); + } + + return 'file.jpg'; + }; + + const ownAttachment = + typeof fileLike === 'string' || fileLike instanceof Buffer || typeof fileLike.pipe === 'function'; + if (ownAttachment) { + attachment = fileLike; + name = findName(attachment); + } else { + attachment = fileLike.attachment; + name = fileLike.name ?? findName(attachment); + } + + const { data, contentType } = await DataResolver.resolveFile(attachment); + return { data, name, contentType }; + } + + /** + * Creates a {@link MessagePayload} from user-level arguments. + * @param {MessageTarget} target Target to send to + * @param {string|MessagePayloadOption} options Options or content to use + * @param {MessagePayloadOption} [extra={}] Extra options to add onto specified options + * @returns {MessagePayload} + */ + static create(target, options, extra = {}) { + return new this( + target, + typeof options !== 'object' || options === null ? { content: options, ...extra } : { ...options, ...extra }, + ); + } +} + +module.exports = MessagePayload; + +/** + * A target for a message. + * @typedef {TextBasedChannels|User|GuildMember|Webhook|WebhookClient|BaseInteraction|InteractionWebhook| + * Message|MessageManager} MessageTarget + */ + +/** + * A possible payload option. + * @typedef {MessageCreateOptions|MessageEditOptions|WebhookMessageCreateOptions|WebhookMessageEditOptions| + * InteractionReplyOptions|InteractionUpdateOptions} MessagePayloadOption + */ + +/** + * @external APIMessage + * @see {@link https://discord.com/developers/docs/resources/channel#message-object} + */ + +/** + * @external RawFile + * @see {@link https://discord.js.org/docs/packages/rest/stable/RawFile:Interface} + */ |