A powerful Node.js library for interacting with the Discord API, enabling developers to create Discord bots and applications with full API coverage
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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']
}
});Install with Tessl CLI
npx tessl i tessl/npm-discord-js