Skip to content

Commit

Permalink
feat: message forwards
Browse files Browse the repository at this point in the history
  • Loading branch information
imnaiyar committed Jan 29, 2025
1 parent 92aea94 commit b274e25
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 3 deletions.
16 changes: 16 additions & 0 deletions packages/discord.js/src/structures/Message.js
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,22 @@ class Message extends Base {
return this.channel.send(data);
}

/**
* Forwards this message
*
* @param {TextChannelResolvable} channel The channel to forward this message to.
* @returns {Promise<Message>}
*/
forward(channel) {
const resolvedChannel = this.client.channels.resolve(channel);
return resolvedChannel.send({
forward: {
messageId: this.id,
channelId: this.channelId,
},
});
}

/**
* Options for starting a thread on a message.
* @typedef {Object} StartThreadOptions
Expand Down
16 changes: 15 additions & 1 deletion packages/discord.js/src/structures/MessagePayload.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const { Buffer } = require('node:buffer');
const { lazy, isJSONEncodable } = require('@discordjs/util');
const { DiscordSnowflake } = require('@sapphire/snowflake');
const { MessageFlags } = require('discord-api-types/v10');
const { MessageFlags, MessageReferenceType } = require('discord-api-types/v10');
const ActionRowBuilder = require('./ActionRowBuilder');
const { DiscordjsError, DiscordjsRangeError, ErrorCodes } = require('../errors');
const { resolveFile } = require('../util/DataResolver');
Expand Down Expand Up @@ -199,6 +199,20 @@ class MessagePayload {
}
}

if (typeof this.options.forward === 'object') {
const reference = this.options.forward.messageId;
const channel_id = reference.channelId ?? this.target.client.channels.resolveId(this.options.forward.channelId);
const message_id = this.isMessage ? (reference.id ?? reference) : this.target.messages.resolveId(reference);
if (message_id) {
if (!channel_id) throw new DiscordjsError(ErrorCodes.InvalidType, 'channel', 'TextChannelResolvable');
message_reference = {
type: MessageReferenceType.Forward,
message_id,
channel_id,
};
}
}

const attachments = this.options.files?.map((file, index) => ({
id: index.toString(),
description: file.description,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,17 @@ class TextBasedChannel {
* <info>Only `MessageFlags.SuppressEmbeds` and `MessageFlags.SuppressNotifications` can be set.</info>
*/

/**
* @typedef {Object} ForwardOptions
* @property {MessageResolvable} messageId The message to forward to
* @property {TextChannelResolvable} [channelId] The channel of the originating message
*/

/**
* The options for sending a message.
* @typedef {BaseMessageCreateOptions} MessageCreateOptions
* @property {ReplyOptions} [reply] The options for replying to a message
* @property {ForwardOptions} [forward] The options for forwarding a message
*/

/**
Expand Down
22 changes: 20 additions & 2 deletions packages/discord.js/typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2310,6 +2310,7 @@ export class Message<InGuild extends boolean = boolean> extends Base {
public reply(
options: string | MessagePayload | MessageReplyOptions,
): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
public forward(channel: TextChannelResolvable): Promise<Message>;
public resolveComponent(customId: string): MessageActionRowComponent | null;
public startThread(options: StartThreadOptions): Promise<PublicThreadChannel<false>>;
public suppressEmbeds(suppress?: boolean): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
Expand Down Expand Up @@ -6742,6 +6743,7 @@ export interface MessageCreateOptions extends BaseMessageOptionsWithPoll {
nonce?: string | number;
enforceNonce?: boolean;
reply?: ReplyOptions;
forward?: ForwardOptions;
stickers?: readonly StickerResolvable[];
flags?:
| BitFieldResolvable<
Expand Down Expand Up @@ -6994,7 +6996,22 @@ export interface ReplyOptions {
failIfNotExists?: boolean;
}

export interface MessageReplyOptions extends Omit<MessageCreateOptions, 'reply'> {
export interface BaseForwardOptions {
messageId: MessageResolvable;
channelId?: TextChannelResolvable;
}

export interface ForwardOptionsWithMandaatoryChannel extends BaseForwardOptions {
channelId: TextChannelResolvable;
}

export interface ForwardOptionsWithOptionalChannel extends BaseForwardOptions {
messageId: Exclude<MessageResolvable, Snowflake>;
}

export type ForwardOptions = ForwardOptionsWithMandaatoryChannel | ForwardOptionsWithOptionalChannel;

export interface MessageReplyOptions extends Omit<MessageCreateOptions, 'reply' | 'forward'> {
failIfNotExists?: boolean;
}

Expand Down Expand Up @@ -7273,7 +7290,8 @@ export interface WebhookFetchMessageOptions {
threadId?: Snowflake;
}

export interface WebhookMessageCreateOptions extends Omit<MessageCreateOptions, 'nonce' | 'reply' | 'stickers'> {
export interface WebhookMessageCreateOptions
extends Omit<MessageCreateOptions, 'nonce' | 'reply' | 'stickers' | 'forward'> {
username?: string;
avatarURL?: string;
threadId?: Snowflake;
Expand Down

0 comments on commit b274e25

Please sign in to comment.