Fix
- Message Send and Edit (Using REST, not patch Axios) - Send Attachment Fix
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "discord.js-selfbot-v13",
 | 
			
		||||
  "version": "0.2.4",
 | 
			
		||||
  "version": "0.3.0",
 | 
			
		||||
  "description": "A unofficial discord.js fork for creating selfbots [Based on discord.js v13]",
 | 
			
		||||
  "main": "./src/index.js",
 | 
			
		||||
  "types": "./typings/index.d.ts",
 | 
			
		||||
 
 | 
			
		||||
@@ -9,49 +9,6 @@ const MessagePayload = require('../structures/MessagePayload');
 | 
			
		||||
const Util = require('../util/Util');
 | 
			
		||||
const DiscordAPIError = require('../rest/DiscordAPIError');
 | 
			
		||||
 | 
			
		||||
const _edit = (client, channelID, messageID, data, files) => {
 | 
			
		||||
	return new Promise((resolve, reject) => {
 | 
			
		||||
		require('axios')({
 | 
			
		||||
			method: 'patch',
 | 
			
		||||
			url: `${client.options.http.api}/v${client.options.http.version}/channels/${channelID}/messages/${messageID}`,
 | 
			
		||||
			headers: {
 | 
			
		||||
				authorization: client.token,
 | 
			
		||||
				Accept: '*/*',
 | 
			
		||||
				'Accept-Language': 'en-US,en;q=0.9',
 | 
			
		||||
				'Cache-Control': 'no-cache',
 | 
			
		||||
				Pragma: 'no-cache',
 | 
			
		||||
				Referer: 'https://discord.com/channels/@me',
 | 
			
		||||
				'Sec-Ch-Ua': '" Not A;Brand";v="99" "',
 | 
			
		||||
				'Sec-Ch-Ua-Mobile': '?0',
 | 
			
		||||
				'Sec-Ch-Ua-Platform': '"iOS"',
 | 
			
		||||
				'Sec-Fetch-Dest': 'empty',
 | 
			
		||||
				'Sec-Fetch-Mode': 'cors',
 | 
			
		||||
				'Sec-Fetch-Site': 'same-origin',
 | 
			
		||||
				'X-Debug-Options': 'bugReporterEnabled',
 | 
			
		||||
				'X-Discord-Locale': 'en-US',
 | 
			
		||||
				Origin: 'https://discord.com',
 | 
			
		||||
			},
 | 
			
		||||
			data,
 | 
			
		||||
			files,
 | 
			
		||||
		})
 | 
			
		||||
			.then((res) => resolve(res.data))
 | 
			
		||||
			.catch((err) => {
 | 
			
		||||
				err.request.options = {
 | 
			
		||||
					data,
 | 
			
		||||
					files,
 | 
			
		||||
				};
 | 
			
		||||
				return reject(
 | 
			
		||||
					new DiscordAPIError(
 | 
			
		||||
						err.response.data,
 | 
			
		||||
						err.response.status,
 | 
			
		||||
						err.request,
 | 
			
		||||
					),
 | 
			
		||||
				);
 | 
			
		||||
			});
 | 
			
		||||
	});
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Manages API methods for Messages and holds their cache.
 | 
			
		||||
 * @extends {CachedManager}
 | 
			
		||||
@@ -174,8 +131,7 @@ class MessageManager extends CachedManager {
 | 
			
		||||
    )
 | 
			
		||||
      .resolveBody()
 | 
			
		||||
      .resolveFiles();
 | 
			
		||||
    // const d = await this.client.api.channels(this.channel.id).messages(messageId).patch({ body, files });
 | 
			
		||||
    const d = await _edit(this.client, this.channel.id, messageId, body, files);
 | 
			
		||||
    const d = await this.client.api.channels(this.channel.id).messages(messageId).patch({ body, files });
 | 
			
		||||
    const existing = this.cache.get(messageId);
 | 
			
		||||
    if (existing) {
 | 
			
		||||
      const clone = existing._clone();
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
 | 
			
		||||
const https = require('node:https');
 | 
			
		||||
const { setTimeout } = require('node:timers');
 | 
			
		||||
const FormData = require('form-data');
 | 
			
		||||
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
 | 
			
		||||
const { UserAgent } = require('../util/Constants');
 | 
			
		||||
 | 
			
		||||
@@ -47,23 +46,32 @@ class APIRequest {
 | 
			
		||||
 | 
			
		||||
    let body;
 | 
			
		||||
    if (this.options.files?.length) {
 | 
			
		||||
      body = new FormData();
 | 
			
		||||
      for (const [index, file] of this.options.files.entries()) {
 | 
			
		||||
        if (file?.file) body.append(file.key ?? `files[${index}]`, file.file, file.name);
 | 
			
		||||
      }
 | 
			
		||||
      if (typeof this.options.data !== 'undefined') {
 | 
			
		||||
        if (this.options.dontUsePayloadJSON) {
 | 
			
		||||
          for (const [key, value] of Object.entries(this.options.data)) body.append(key, value);
 | 
			
		||||
        } else {
 | 
			
		||||
          body.append('payload_json', JSON.stringify(this.options.data));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      headers = Object.assign(headers, body.getHeaders());
 | 
			
		||||
      // eslint-disable-next-line eqeqeq
 | 
			
		||||
    } else if (this.options.data != null) {
 | 
			
		||||
      body = JSON.stringify(this.options.data);
 | 
			
		||||
      headers['Content-Type'] = 'application/json';
 | 
			
		||||
    }
 | 
			
		||||
			body = new FormData();
 | 
			
		||||
			for (const [index, file] of this.options.files.entries()) {
 | 
			
		||||
				if (file?.file)
 | 
			
		||||
					body.append(file.key ?? `files[${index}]`, file.file, file.name);
 | 
			
		||||
			}
 | 
			
		||||
			if (
 | 
			
		||||
				typeof this.options.data !== 'undefined' ||
 | 
			
		||||
				typeof this.options.body !== 'undefined'
 | 
			
		||||
			) {
 | 
			
		||||
				if (this.options.dontUsePayloadJSON) {
 | 
			
		||||
					for (const [key, value] of Object.entries(this.options.data || this.options.body)) {
 | 
			
		||||
						body.append(key, value);
 | 
			
		||||
          }
 | 
			
		||||
				} else {
 | 
			
		||||
					body.append('payload_json', JSON.stringify(this.options.data || this.options.body));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			headers = Object.assign(headers, body.getHeaders());
 | 
			
		||||
			// eslint-disable-next-line eqeqeq
 | 
			
		||||
		} else if (this.options.data != null) {
 | 
			
		||||
			body = JSON.stringify(this.options.data);
 | 
			
		||||
			headers['Content-Type'] = 'application/json';
 | 
			
		||||
		} else if (this.options.body != null) {
 | 
			
		||||
			body = JSON.stringify(this.options.body);
 | 
			
		||||
			headers['Content-Type'] = 'application/json';
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    const controller = new AbortController();
 | 
			
		||||
    const timeout = setTimeout(() => controller.abort(), this.client.options.restRequestTimeout).unref();
 | 
			
		||||
 
 | 
			
		||||
@@ -12,186 +12,204 @@ const Util = require('../util/Util');
 | 
			
		||||
 * Represents a message to be sent to the API.
 | 
			
		||||
 */
 | 
			
		||||
class MessagePayload {
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {MessageTarget} target The target for this message to be sent to
 | 
			
		||||
   * @param {MessageOptions|WebhookMessageOptions} options Options passed in from send
 | 
			
		||||
   */
 | 
			
		||||
  constructor(target, options) {
 | 
			
		||||
    /**
 | 
			
		||||
     * The target for this message to be sent to
 | 
			
		||||
     * @type {MessageTarget}
 | 
			
		||||
     */
 | 
			
		||||
    this.target = target;
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param {MessageTarget} target The target for this message to be sent to
 | 
			
		||||
	 * @param {MessageOptions|WebhookMessageOptions} options Options passed in from send
 | 
			
		||||
	 */
 | 
			
		||||
	constructor(target, options) {
 | 
			
		||||
		/**
 | 
			
		||||
		 * The target for this message to be sent to
 | 
			
		||||
		 * @type {MessageTarget}
 | 
			
		||||
		 */
 | 
			
		||||
		this.target = target;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Options passed in from send
 | 
			
		||||
     * @type {MessageOptions|WebhookMessageOptions}
 | 
			
		||||
     */
 | 
			
		||||
    this.options = options;
 | 
			
		||||
		/**
 | 
			
		||||
		 * Options passed in from send
 | 
			
		||||
		 * @type {MessageOptions|WebhookMessageOptions}
 | 
			
		||||
		 */
 | 
			
		||||
		this.options = options;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Body sendable to the API
 | 
			
		||||
     * @type {?APIMessage}
 | 
			
		||||
     */
 | 
			
		||||
    this.body = null;
 | 
			
		||||
		/**
 | 
			
		||||
		 * Body sendable to the API
 | 
			
		||||
		 * @type {?APIMessage}
 | 
			
		||||
		 */
 | 
			
		||||
		this.body = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Files sendable to the API
 | 
			
		||||
     * @type {?RawFile[]}
 | 
			
		||||
     */
 | 
			
		||||
    this.files = 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 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 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 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 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 Interaction} or an {@link InteractionWebhook}
 | 
			
		||||
   * @type {boolean}
 | 
			
		||||
   * @readonly
 | 
			
		||||
   */
 | 
			
		||||
  get isInteraction() {
 | 
			
		||||
    const Interaction = require('./Interaction');
 | 
			
		||||
    const InteractionWebhook = require('./InteractionWebhook');
 | 
			
		||||
    return this.target instanceof Interaction || this.target instanceof InteractionWebhook;
 | 
			
		||||
  }
 | 
			
		||||
	/**
 | 
			
		||||
	 * Whether or not the target is an {@link Interaction} or an {@link InteractionWebhook}
 | 
			
		||||
	 * @type {boolean}
 | 
			
		||||
	 * @readonly
 | 
			
		||||
	 */
 | 
			
		||||
	get isInteraction() {
 | 
			
		||||
		const Interaction = require('./Interaction');
 | 
			
		||||
		const InteractionWebhook = require('./InteractionWebhook');
 | 
			
		||||
		return (
 | 
			
		||||
			this.target instanceof Interaction ||
 | 
			
		||||
			this.target instanceof InteractionWebhook
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Makes the content of this message.
 | 
			
		||||
   * @returns {?string}
 | 
			
		||||
   */
 | 
			
		||||
  makeContent() {
 | 
			
		||||
    let content;
 | 
			
		||||
    if (this.options.content === null) {
 | 
			
		||||
      content = '';
 | 
			
		||||
    } else if (typeof this.options.content !== 'undefined') {
 | 
			
		||||
      content = Util.verifyString(this.options.content, RangeError, 'MESSAGE_CONTENT_TYPE', false);
 | 
			
		||||
    }
 | 
			
		||||
	/**
 | 
			
		||||
	 * Makes the content of this message.
 | 
			
		||||
	 * @returns {?string}
 | 
			
		||||
	 */
 | 
			
		||||
	makeContent() {
 | 
			
		||||
		let content;
 | 
			
		||||
		if (this.options.content === null) {
 | 
			
		||||
			content = '';
 | 
			
		||||
		} else if (typeof this.options.content !== 'undefined') {
 | 
			
		||||
			content = Util.verifyString(
 | 
			
		||||
				this.options.content,
 | 
			
		||||
				RangeError,
 | 
			
		||||
				'MESSAGE_CONTENT_TYPE',
 | 
			
		||||
				false,
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    return content;
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * Resolves the body.
 | 
			
		||||
   * @returns {MessagePayload}
 | 
			
		||||
   */
 | 
			
		||||
  resolveBody() {
 | 
			
		||||
    if (this.data) return this;
 | 
			
		||||
    const isInteraction = this.isInteraction;
 | 
			
		||||
    const isWebhook = this.isWebhook;
 | 
			
		||||
		return content;
 | 
			
		||||
	}
 | 
			
		||||
	/**
 | 
			
		||||
	 * Resolves the body.
 | 
			
		||||
	 * @returns {MessagePayload}
 | 
			
		||||
	 */
 | 
			
		||||
	resolveBody() {
 | 
			
		||||
		if (this.data) return this;
 | 
			
		||||
		const isInteraction = this.isInteraction;
 | 
			
		||||
		const isWebhook = this.isWebhook;
 | 
			
		||||
 | 
			
		||||
    const content = this.makeContent();
 | 
			
		||||
    const tts = Boolean(this.options.tts);
 | 
			
		||||
		const content = this.makeContent();
 | 
			
		||||
		const tts = Boolean(this.options.tts);
 | 
			
		||||
 | 
			
		||||
    let nonce;
 | 
			
		||||
    if (typeof this.options.nonce !== 'undefined') {
 | 
			
		||||
      nonce = this.options.nonce;
 | 
			
		||||
      // eslint-disable-next-line max-len
 | 
			
		||||
      if (typeof nonce === 'number' ? !Number.isInteger(nonce) : typeof nonce !== 'string') {
 | 
			
		||||
        throw new RangeError('MESSAGE_NONCE_TYPE');
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
		let nonce;
 | 
			
		||||
		if (typeof this.options.nonce !== 'undefined') {
 | 
			
		||||
			nonce = this.options.nonce;
 | 
			
		||||
			// eslint-disable-next-line max-len
 | 
			
		||||
			if (
 | 
			
		||||
				typeof nonce === 'number'
 | 
			
		||||
					? !Number.isInteger(nonce)
 | 
			
		||||
					: typeof nonce !== 'string'
 | 
			
		||||
			) {
 | 
			
		||||
				throw new RangeError('MESSAGE_NONCE_TYPE');
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    const components = this.options.components?.map((c) =>
 | 
			
		||||
		const components = this.options.components?.map((c) =>
 | 
			
		||||
			BaseMessageComponent.create(c).toJSON(),
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
    let username;
 | 
			
		||||
    let avatarURL;
 | 
			
		||||
    if (isWebhook) {
 | 
			
		||||
      username = this.options.username ?? this.target.name;
 | 
			
		||||
      if (this.options.avatarURL) avatarURL = this.options.avatarURL;
 | 
			
		||||
    }
 | 
			
		||||
		let username;
 | 
			
		||||
		let avatarURL;
 | 
			
		||||
		if (isWebhook) {
 | 
			
		||||
			username = this.options.username ?? this.target.name;
 | 
			
		||||
			if (this.options.avatarURL) avatarURL = this.options.avatarURL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    let flags;
 | 
			
		||||
    if (
 | 
			
		||||
      typeof this.options.flags !== 'undefined' ||
 | 
			
		||||
      (this.isMessage && typeof 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;
 | 
			
		||||
    }
 | 
			
		||||
		let flags;
 | 
			
		||||
		if (
 | 
			
		||||
			typeof this.options.flags !== 'undefined' ||
 | 
			
		||||
			(this.isMessage && typeof 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;
 | 
			
		||||
    }
 | 
			
		||||
		if (isInteraction && this.options.ephemeral) {
 | 
			
		||||
			flags |= MessageFlags.Ephemeral;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    let allowedMentions =
 | 
			
		||||
      typeof this.options.allowedMentions === 'undefined'
 | 
			
		||||
        ? this.target.client.options.allowedMentions
 | 
			
		||||
        : this.options.allowedMentions;
 | 
			
		||||
		let allowedMentions =
 | 
			
		||||
			typeof this.options.allowedMentions === 'undefined'
 | 
			
		||||
				? this.target.client.options.allowedMentions
 | 
			
		||||
				: this.options.allowedMentions;
 | 
			
		||||
 | 
			
		||||
    if (allowedMentions) {
 | 
			
		||||
      allowedMentions = Util.cloneObject(allowedMentions);
 | 
			
		||||
      allowedMentions.replied_user = allowedMentions.repliedUser;
 | 
			
		||||
      delete allowedMentions.repliedUser;
 | 
			
		||||
    }
 | 
			
		||||
		if (allowedMentions) {
 | 
			
		||||
			allowedMentions = Util.cloneObject(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,
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
		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;
 | 
			
		||||
    }
 | 
			
		||||
		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 = {
 | 
			
		||||
		this.body = {
 | 
			
		||||
			content,
 | 
			
		||||
			tts,
 | 
			
		||||
			nonce,
 | 
			
		||||
@@ -213,68 +231,74 @@ class MessagePayload {
 | 
			
		||||
				(sticker) => sticker.id ?? sticker,
 | 
			
		||||
			),
 | 
			
		||||
		};
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Resolves files.
 | 
			
		||||
   * @returns {Promise<MessagePayload>}
 | 
			
		||||
   */
 | 
			
		||||
  async resolveFiles() {
 | 
			
		||||
    if (this.files) 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;
 | 
			
		||||
  }
 | 
			
		||||
		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 {BufferResolvable|Stream|FileOptions|MessageAttachment} fileLike Something that could be resolved to a file
 | 
			
		||||
   * @returns {Promise<RawFile>}
 | 
			
		||||
   */
 | 
			
		||||
  static async resolveFile(fileLike) {
 | 
			
		||||
    let attachment;
 | 
			
		||||
    let name;
 | 
			
		||||
	/**
 | 
			
		||||
	 * Resolves a single file into an object sendable to the API.
 | 
			
		||||
	 * @param {BufferResolvable|Stream|FileOptions|MessageAttachment} 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 Util.basename(thing);
 | 
			
		||||
      }
 | 
			
		||||
		const findName = (thing) => {
 | 
			
		||||
			if (typeof thing === 'string') {
 | 
			
		||||
				return Util.basename(thing);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
      if (thing.path) {
 | 
			
		||||
        return Util.basename(thing.path);
 | 
			
		||||
      }
 | 
			
		||||
			if (thing.path) {
 | 
			
		||||
				return Util.basename(thing.path);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
      return 'file.jpg';
 | 
			
		||||
    };
 | 
			
		||||
			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 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 = await DataResolver.resolveFile(attachment);
 | 
			
		||||
    return { data, name };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Creates a {@link MessagePayload} from user-level arguments.
 | 
			
		||||
   * @param {MessageTarget} target Target to send to
 | 
			
		||||
   * @param {string|MessageOptions|WebhookMessageOptions} options Options or content to use
 | 
			
		||||
   * @param {MessageOptions|WebhookMessageOptions} [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 },
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
		const resource = await DataResolver.resolveFile(attachment);
 | 
			
		||||
		return { attachment, name, file: resource };
 | 
			
		||||
	}
 | 
			
		||||
	/**
 | 
			
		||||
	 * Creates a {@link MessagePayload} from user-level arguments.
 | 
			
		||||
	 * @param {MessageTarget} target Target to send to
 | 
			
		||||
	 * @param {string|MessageOptions|WebhookMessageOptions} options Options or content to use
 | 
			
		||||
	 * @param {MessageOptions|WebhookMessageOptions} [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;
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,5 +1,5 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
const FormData = require('form-data');
 | 
			
		||||
const { Collection } = require('@discordjs/collection');
 | 
			
		||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
 | 
			
		||||
const { InteractionType, Routes } = require('discord-api-types/v9');
 | 
			
		||||
@@ -9,47 +9,6 @@ const MessageCollector = require('../MessageCollector');
 | 
			
		||||
const MessagePayload = require('../MessagePayload');
 | 
			
		||||
const DiscordAPIError = require('../../rest/DiscordAPIError');
 | 
			
		||||
 | 
			
		||||
const _send = (client, channelID, data, files) => {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
		require('axios')({
 | 
			
		||||
			method: 'post',
 | 
			
		||||
			url: `${client.options.http.api}/v${client.options.http.version}/channels/${channelID}/messages`,
 | 
			
		||||
			headers: {
 | 
			
		||||
				authorization: client.token,
 | 
			
		||||
				Accept: '*/*',
 | 
			
		||||
				'Accept-Language': 'en-US,en;q=0.9',
 | 
			
		||||
				'Cache-Control': 'no-cache',
 | 
			
		||||
				Pragma: 'no-cache',
 | 
			
		||||
				Referer: 'https://discord.com/channels/@me',
 | 
			
		||||
				'Sec-Ch-Ua': '" Not A;Brand";v="99" "',
 | 
			
		||||
				'Sec-Ch-Ua-Mobile': '?0',
 | 
			
		||||
				'Sec-Ch-Ua-Platform': '"iOS"',
 | 
			
		||||
				'Sec-Fetch-Dest': 'empty',
 | 
			
		||||
				'Sec-Fetch-Mode': 'cors',
 | 
			
		||||
				'Sec-Fetch-Site': 'same-origin',
 | 
			
		||||
				'X-Debug-Options': 'bugReporterEnabled',
 | 
			
		||||
				'X-Discord-Locale': 'en-US',
 | 
			
		||||
				Origin: 'https://discord.com',
 | 
			
		||||
			},
 | 
			
		||||
			data,
 | 
			
		||||
			files,
 | 
			
		||||
		})
 | 
			
		||||
			.then((res) => resolve(res.data))
 | 
			
		||||
			.catch((err) => {
 | 
			
		||||
        err.request.options = {
 | 
			
		||||
          data,
 | 
			
		||||
          files,
 | 
			
		||||
        };
 | 
			
		||||
        return reject(
 | 
			
		||||
					new DiscordAPIError(
 | 
			
		||||
						err.response.data,
 | 
			
		||||
						err.response.status,
 | 
			
		||||
						err.request,
 | 
			
		||||
					),
 | 
			
		||||
				);
 | 
			
		||||
      });
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
 * Interface for classes that have text-channel-like features.
 | 
			
		||||
 * @interface
 | 
			
		||||
@@ -215,8 +174,8 @@ class TextBasedChannel {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const { body, files } = await messagePayload.resolveFiles();
 | 
			
		||||
		// const d = await this.client.api.channels[this.id].messages.post({ body, files });
 | 
			
		||||
		const d = await _send(this.client, this.id, body, files);
 | 
			
		||||
		console.log(body)
 | 
			
		||||
		const d = await this.client.api.channels[this.id].messages.post({ body, files });
 | 
			
		||||
		return this.messages.cache.get(d.id) ?? this.messages._add(d);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -109,7 +109,7 @@ class Options extends null {
 | 
			
		||||
					// 'Accept-Encoding': 'gzip, deflate, br',
 | 
			
		||||
					'Accept-Language': 'en-US,en;q=0.9',
 | 
			
		||||
					'Cache-Control': 'no-cache',
 | 
			
		||||
          'Content-Type': 'application/json',
 | 
			
		||||
          // 'Content-Type': 'application/json',
 | 
			
		||||
					Pragma: 'no-cache',
 | 
			
		||||
					Referer: 'https://discord.com/channels/@me',
 | 
			
		||||
					'Sec-Ch-Ua': '" Not A;Brand";v="99" "',
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user