Comprehensive message functionality including creation, editing, deletion, embeds, attachments, reactions, and content formatting for Discord communication.
Represents a Discord message with full content and metadata.
/**
* Represents a Discord message
* @extends Base
*/
class Message extends Base {
readonly id: Snowflake;
readonly channelId: Snowflake;
readonly channel: TextBasedChannel;
readonly guildId: Snowflake | null;
readonly guild: Guild | null;
readonly author: User;
readonly member: GuildMember | null;
readonly content: string;
readonly cleanContent: string;
readonly createdAt: Date;
readonly editedAt: Date | null;
readonly editedTimestamp: number | null;
readonly tts: boolean;
readonly nonce: string | number | null;
readonly system: boolean;
readonly pinned: boolean;
readonly webhookId: Snowflake | null;
readonly flags: Readonly<MessageFlagsBitField>;
readonly reference: MessageReference | null;
readonly interaction: MessageInteraction | null;
readonly thread: ThreadChannel | null;
// Content components
readonly embeds: Embed[];
readonly attachments: Collection<Snowflake, Attachment>;
readonly components: ActionRow<MessageActionRowComponent>[];
readonly mentions: MessageMentions;
readonly reactions: ReactionManager;
readonly poll: Poll | null;
// Message operations
reply(options: string | MessageReplyOptions): Promise<Message>;
edit(options: string | MessageEditOptions): Promise<Message>;
delete(): Promise<Message>;
crosspost(): Promise<Message>;
fetch(force?: boolean): Promise<Message>;
pin(reason?: string): Promise<Message>;
unpin(reason?: string): Promise<Message>;
react(emoji: EmojiIdentifierResolvable): Promise<MessageReaction>;
// Utility methods
fetchReference(): Promise<Message>;
fetchWebhook(): Promise<Webhook>;
suppressEmbeds(suppress?: boolean): Promise<Message>;
resolveComponent(customId: string): MessageActionRowComponent | null;
// Thread operations
startThread(options: StartThreadOptions): Promise<ThreadChannel>;
// URL generation
readonly url: string;
toString(): string;
// Content checks
readonly partial: boolean;
readonly deletable: boolean;
readonly editable: boolean;
readonly crosspostable: boolean;
readonly pinnable: boolean;
}
interface MessageReplyOptions extends BaseMessageOptions {
allowedMentions?: MessageMentionOptions;
failIfNotExists?: boolean;
}
interface MessageEditOptions extends Omit<BaseMessageOptions, 'reply'> {
attachments?: JSONEncodable<AttachmentPayload>[];
}
interface BaseMessageOptions {
content?: string;
embeds?: (EmbedBuilder | Embed | APIEmbed)[];
files?: (AttachmentBuilder | Attachment | FileOptions | BufferResolvable | Stream | string)[];
components?: (ActionRowBuilder<MessageActionRowComponentBuilder> | ActionRowData<MessageActionRowComponentData> | APIActionRowComponent<APIMessageActionRowComponent>)[];
allowedMentions?: MessageMentionOptions;
flags?: BitFieldResolvable<MessageFlagsString, number>;
tts?: boolean;
nonce?: string | number;
enforceNonce?: boolean;
}Usage Examples:
// Reply to a message
await message.reply('Hello! This is a reply.');
// Reply with embed
await message.reply({
content: 'Here is some information:',
embeds: [
new EmbedBuilder()
.setTitle('Important Info')
.setDescription('This is important.')
.setColor(Colors.Blue)
]
});
// Edit a message
await message.edit({
content: 'Updated content',
embeds: [new EmbedBuilder().setTitle('Updated Title')]
});
// React to a message
await message.react('๐');
await message.react('<:custom_emoji:123456789012345678>');
// Start a thread from message
const thread = await message.startThread({
name: 'Discussion Thread',
autoArchiveDuration: ThreadAutoArchiveDuration.OneHour
});Rich embedded content for messages with customizable layouts and formatting.
/**
* Builder for creating Discord embeds
*/
class EmbedBuilder {
constructor(data?: APIEmbed);
// Content methods
setTitle(title: string | null): this;
setDescription(description: string | null): this;
setURL(url: string | null): this;
setColor(color: ColorResolvable | null): this;
setTimestamp(timestamp?: DateResolvable | null): this;
// Author section
setAuthor(options: EmbedAuthorOptions | null): this;
// Footer section
setFooter(options: EmbedFooterOptions | null): this;
// Image and thumbnail
setImage(url: string | null): this;
setThumbnail(url: string | null): this;
// Fields
addFields(...fields: APIEmbedField[]): this;
setFields(...fields: APIEmbedField[]): this;
spliceFields(index: number, deleteCount: number, ...fields: APIEmbedField[]): this;
// Utility methods
toJSON(): APIEmbed;
static from(other: APIEmbed | EmbedBuilder): EmbedBuilder;
}
interface EmbedAuthorOptions {
name: string;
url?: string;
iconURL?: string;
}
interface EmbedFooterOptions {
text: string;
iconURL?: string;
}
interface APIEmbedField {
name: string;
value: string;
inline?: boolean;
}
/**
* Represents a Discord embed
*/
class Embed {
readonly title: string | null;
readonly description: string | null;
readonly url: string | null;
readonly color: number | null;
readonly timestamp: string | null;
readonly fields: EmbedField[];
readonly thumbnail: EmbedThumbnail | null;
readonly image: EmbedImage | null;
readonly video: EmbedVideo | null;
readonly author: EmbedAuthor | null;
readonly provider: EmbedProvider | null;
readonly footer: EmbedFooter | null;
readonly length: number;
readonly hexColor: string | null;
toJSON(): APIEmbed;
equals(embed: Embed | APIEmbed): boolean;
}Usage Examples:
// Basic embed
const embed = new EmbedBuilder()
.setTitle('Server Information')
.setDescription('Welcome to our Discord server!')
.setColor(Colors.Blue)
.setTimestamp();
// Complex embed with all components
const detailedEmbed = new EmbedBuilder()
.setTitle('User Profile')
.setDescription('Detailed user information')
.setColor(0x00AE86)
.setAuthor({
name: 'Discord Bot',
iconURL: 'https://example.com/bot-avatar.png',
url: 'https://example.com'
})
.setThumbnail('https://example.com/user-avatar.png')
.setImage('https://example.com/banner.png')
.addFields(
{ name: 'Username', value: 'JohnDoe#1234', inline: true },
{ name: 'Joined', value: '<t:1609459200:F>', inline: true },
{ name: 'Roles', value: 'Member, Contributor', inline: true }
)
.setFooter({
text: 'Powered by Discord.js',
iconURL: 'https://example.com/footer-icon.png'
})
.setTimestamp();
await channel.send({ embeds: [detailedEmbed] });File attachment handling for messages including images, documents, and media.
/**
* Builder for creating message attachments
*/
class AttachmentBuilder {
constructor(attachment: BufferResolvable | Stream, data?: AttachmentData);
setName(name: string): this;
setDescription(description: string): this;
setSpoiler(spoiler?: boolean): this;
readonly attachment: BufferResolvable | Stream;
readonly name: string | null;
readonly description: string | null;
readonly spoiler: boolean;
toJSON(): unknown;
static from(other: JSONEncodable<AttachmentPayload>): AttachmentBuilder;
}
interface AttachmentData {
name?: string;
description?: string;
}
/**
* Represents a Discord attachment
*/
class Attachment {
readonly id: Snowflake;
readonly attachment: string;
readonly name: string | null;
readonly description: string | null;
readonly contentType: string | null;
readonly size: number;
readonly url: string;
readonly proxyURL: string;
readonly height: number | null;
readonly width: number | null;
readonly ephemeral: boolean;
readonly duration: number | null;
readonly waveform: string | null;
readonly flags: Readonly<AttachmentFlagsBitField>;
readonly spoiler: boolean;
toJSON(): unknown;
}Usage Examples:
import { readFileSync } from 'fs';
// Send file attachment
const attachment = new AttachmentBuilder('./image.png')
.setName('cool-image.png')
.setDescription('A cool image to share');
await channel.send({
content: 'Check out this image!',
files: [attachment]
});
// Send multiple files
await channel.send({
files: [
'./document.pdf',
new AttachmentBuilder(readFileSync('./data.json'))
.setName('server-data.json'),
{
attachment: 'https://example.com/remote-image.png',
name: 'remote-image.png'
}
]
});
// Spoiler attachment
const spoilerImage = new AttachmentBuilder('./spoiler.png')
.setName('spoiler.png')
.setSpoiler(true);
await channel.send({
content: 'Spoiler image below:',
files: [spoilerImage]
});Reaction management for messages including adding, removing, and monitoring reactions.
/**
* Represents a message reaction
*/
class MessageReaction {
readonly message: Message;
readonly emoji: GuildEmoji | ReactionEmoji;
readonly count: number;
readonly me: boolean;
readonly users: ReactionUserManager;
readonly partial: boolean;
// Reaction management
remove(): Promise<MessageReaction>;
fetch(): Promise<MessageReaction>;
toJSON(): unknown;
}
/**
* Represents a reaction emoji
*/
class ReactionEmoji extends Emoji {
readonly reaction: MessageReaction;
toJSON(): unknown;
}
/**
* Manages users who reacted to a message
*/
class ReactionUserManager extends CachedManager<Snowflake, User, UserResolvable> {
readonly reaction: MessageReaction;
remove(user?: UserResolvable): Promise<MessageReaction>;
}
/**
* Manages reactions on a message
*/
class ReactionManager extends CachedManager<string | Snowflake, MessageReaction, MessageReactionResolvable> {
readonly message: Message;
removeAll(): Promise<Message>;
resolve(reaction: MessageReactionResolvable): MessageReaction | null;
resolveId(reaction: MessageReactionResolvable): Snowflake | string | null;
}Parsing and handling of mentions in message content.
/**
* Handles mentions in messages
*/
class MessageMentions {
readonly message: Message;
readonly users: Collection<Snowflake, User>;
readonly members: Collection<Snowflake, GuildMember> | null;
readonly channels: Collection<Snowflake, GuildChannel>;
readonly roles: Collection<Snowflake, Role>;
readonly everyone: boolean;
readonly repliedUser: User | null;
readonly parsedUsers: Collection<Snowflake, User>;
// Static methods for creating mentions
static channelMention(channel: Snowflake): string;
static roleMention(role: Snowflake): string;
static userMention(user: Snowflake): string;
static memberNicknameMention(memberId: Snowflake): string;
toJSON(): unknown;
// Mention patterns
static readonly ChannelsPattern: RegExp;
static readonly RolesPattern: RegExp;
static readonly UsersPattern: RegExp;
static readonly EveryonePattern: RegExp;
}
interface MessageMentionOptions {
parse?: MessageMentionTypes[];
users?: UserResolvable[];
roles?: RoleResolvable[];
repliedUser?: boolean;
}
type MessageMentionTypes = 'roles' | 'users' | 'everyone';Integration between messages and interactive components.
/**
* Message payload for sending/editing messages
*/
class MessagePayload {
constructor(target: MessageTarget, options: MessageOptions);
readonly target: MessageTarget;
readonly options: MessageOptions;
readonly data: RawMessagePayloadData | null;
readonly files: RawFile[] | null;
static create(target: MessageTarget, options: MessageOptions, extra?: MessagePayloadOption): MessagePayload;
makeRequest(): Promise<RawMessagePayloadData>;
resolveData(): this;
resolveFiles(): Promise<this>;
}
interface MessageOptions extends BaseMessageOptions {
reply?: ReplyOptions;
stickers?: StickerResolvable[];
poll?: PollData;
}
interface ReplyOptions {
messageReference: MessageResolvable;
failIfNotExists?: boolean;
}Different channel types support different message features.
/**
* Base interface for channels that support text
*/
interface TextBasedChannel {
send(options: string | MessagePayload | MessageCreateOptions): Promise<Message>;
bulkDelete(messages: Collection<Snowflake, Message> | readonly MessageResolvable[] | number, filterOld?: boolean): Promise<Collection<Snowflake, (Message | undefined)>>;
sendTyping(): Promise<void>;
createMessageCollector(options?: MessageCollectorOptions): MessageCollector;
awaitMessages(options?: AwaitMessagesOptions): Promise<Collection<Snowflake, Message>>;
}
/**
* Thread channel for organized discussions
*/
class ThreadChannel extends BaseChannel {
readonly guildId: Snowflake;
readonly guild: Guild;
readonly parent: ForumChannel | TextChannel | NewsChannel | null;
readonly ownerId: Snowflake | null;
readonly members: ThreadMemberManager;
readonly messageCount: number | null;
readonly memberCount: number | null;
readonly rateLimitPerUser: number | null;
readonly archived: boolean | null;
readonly archiveTimestamp: Date | null;
readonly autoArchiveDuration: ThreadAutoArchiveDuration | null;
readonly locked: boolean | null;
readonly invitable: boolean | null;
readonly totalMessageSent: number | null;
readonly appliedTags: Snowflake[];
// Thread management
setArchived(archived?: boolean, reason?: string): Promise<ThreadChannel>;
setAutoArchiveDuration(autoArchiveDuration: ThreadAutoArchiveDuration, reason?: string): Promise<ThreadChannel>;
setInvitable(invitable?: boolean, reason?: string): Promise<ThreadChannel>;
setLocked(locked?: boolean, reason?: string): Promise<ThreadChannel>;
setName(name: string, reason?: string): Promise<ThreadChannel>;
setAppliedTags(appliedTags: readonly Snowflake[], reason?: string): Promise<ThreadChannel>;
// Member management
join(): Promise<ThreadChannel>;
leave(): Promise<ThreadChannel>;
}Usage Examples:
// Send messages to different channel types
await textChannel.send('Hello in text channel!');
await dmChannel.send('Hello in DM!');
await threadChannel.send('Hello in thread!');
// Bulk delete messages
const messages = await channel.messages.fetch({ limit: 100 });
await channel.bulkDelete(messages.filter(msg => msg.author.bot));
// Send typing indicator
await channel.sendTyping();
// Complex message with all features
await channel.send({
content: 'Check out this comprehensive message!',
embeds: [
new EmbedBuilder()
.setTitle('Title')
.setDescription('Description')
.setColor(Colors.Green)
],
files: [
new AttachmentBuilder('./image.png').setName('example.png')
],
components: [
new ActionRowBuilder<ButtonBuilder>()
.addComponents(
new ButtonBuilder()
.setCustomId('button_id')
.setLabel('Click Me')
.setStyle(ButtonStyle.Primary)
)
],
allowedMentions: {
parse: ['users'],
users: ['123456789012345678']
}
});