@fluxerjs/core 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,127 +1,20 @@
1
- import * as _fluxerjs_types from '@fluxerjs/types';
2
- import { APISticker, APIEmoji, APIEmbed, APIWebhook, APIWebhookUpdateRequest, APIWebhookTokenUpdateRequest, APIChannelOverwrite, APIChannel, APIChannelPartial, ChannelType, GatewayReactionEmoji, GatewayMessageReactionAddDispatchData, GatewayMessageReactionRemoveDispatchData, APIMessageAttachment, MessageType, APIMessageSticker, APIMessageReaction, APIMessageReference, APIMessageSnapshot, APIMessageCall, APIMessage, APIUserPartial, APIGuildMember, APIRole, RESTUpdateRoleBody, APIBan, GuildFeature, GuildVerificationLevel, DefaultMessageNotifications, GuildExplicitContentFilter, GuildMFALevel, APIGuild, RESTCreateRoleBody, APIGuildAuditLog, APIVanityURL, APIGuildPartial, APIInvite, GatewayPresenceUpdateData, APIProfileResponse, GatewayMessageReactionRemoveAllDispatchData, GatewayMessageReactionRemoveEmojiDispatchData, GatewayVoiceStateUpdateDispatchData, GatewayVoiceServerUpdateDispatchData, GatewayGuildEmojisUpdateDispatchData, GatewayGuildStickersUpdateDispatchData, GatewayGuildIntegrationsUpdateDispatchData, GatewayGuildScheduledEventCreateDispatchData, GatewayGuildScheduledEventUpdateDispatchData, GatewayGuildScheduledEventDeleteDispatchData, GatewayChannelPinsUpdateDispatchData, GatewayPresenceUpdateDispatchData, GatewayWebhooksUpdateDispatchData, APIInstance, GatewaySendPayload, Routes } from '@fluxerjs/types';
1
+ import { EventEmitter } from 'events';
2
+ import { REST } from '@fluxerjs/rest';
3
+ import { WebSocketManager } from '@fluxerjs/ws';
4
+ import { APIEmbed, APIUserPartial, APIRole, RESTUpdateRoleBody, APIGuildMember, APIWebhook, APIWebhookUpdateRequest, APIWebhookTokenUpdateRequest, APIBan, APIEmoji, APISticker, GuildFeature, GuildVerificationLevel, DefaultMessageNotifications, GuildExplicitContentFilter, GuildMFALevel, APIGuild, RESTCreateRoleBody, APIGuildAuditLog, APIVanityURL, GatewayReactionEmoji, GatewayMessageReactionAddDispatchData, GatewayMessageReactionRemoveDispatchData, APIMessageAttachment, MessageType, APIMessageSticker, APIMessageReaction, APIMessageReference, APIMessageSnapshot, APIMessageCall, APIMessage, APIGuildPartial, APIChannelPartial, APIInvite, APIChannelOverwrite, APIChannel, ChannelType, GatewayPresenceUpdateData, APIProfileResponse, GatewayMessageReactionRemoveAllDispatchData, GatewayMessageReactionRemoveEmojiDispatchData, APIApplicationCommandInteraction, GatewayVoiceStateUpdateDispatchData, GatewayVoiceServerUpdateDispatchData, GatewayMessageDeleteBulkDispatchData, GatewayGuildEmojisUpdateDispatchData, GatewayGuildStickersUpdateDispatchData, GatewayGuildIntegrationsUpdateDispatchData, GatewayGuildRoleCreateDispatchData, GatewayGuildRoleUpdateDispatchData, GatewayGuildRoleDeleteDispatchData, GatewayGuildScheduledEventCreateDispatchData, GatewayGuildScheduledEventUpdateDispatchData, GatewayGuildScheduledEventDeleteDispatchData, GatewayChannelPinsUpdateDispatchData, GatewayInviteDeleteDispatchData, GatewayTypingStartDispatchData, GatewayUserUpdateDispatchData, GatewayPresenceUpdateDispatchData, GatewayWebhooksUpdateDispatchData, APIInstance, GatewaySendPayload, Routes } from '@fluxerjs/types';
3
5
  export { GatewayOpcodes, MessageAttachmentFlags, Routes } from '@fluxerjs/types';
4
- import { PermissionResolvable } from '@fluxerjs/util';
5
- export { PermissionFlags, PermissionResolvable, PermissionString, PermissionsBitField, UserFlagsBitField, UserFlagsBits, UserFlagsResolvable, UserFlagsString, parsePrefixCommand, parseUserMention, resolvePermissionsToBitfield, resolveTenorToImageUrl } from '@fluxerjs/util';
6
6
  import { Collection } from '@fluxerjs/collection';
7
7
  import { EmbedBuilder } from '@fluxerjs/builders';
8
8
  export { AttachmentBuilder, EmbedBuilder, MessagePayload } from '@fluxerjs/builders';
9
- import { EventEmitter } from 'events';
10
- import { REST } from '@fluxerjs/rest';
11
- import { WebSocketManager } from '@fluxerjs/ws';
12
-
13
- /** Base class for all Fluxer structures. Provides the client reference. */
14
- declare abstract class Base {
15
- /** The client instance this structure belongs to. */
16
- abstract readonly client: Client;
17
- }
18
-
19
- /** Represents a custom sticker in a guild. */
20
- declare class GuildSticker extends Base {
21
- readonly client: Client;
22
- readonly id: string;
23
- readonly guildId: string;
24
- name: string;
25
- description: string;
26
- readonly tags: string[];
27
- readonly animated: boolean;
28
- /** @param data - API sticker from GET /guilds/{id}/stickers or guild sticker events */
29
- constructor(client: Client, data: APISticker & {
30
- guild_id?: string;
31
- }, guildId: string);
32
- /** CDN URL for this sticker image. */
33
- get url(): string;
34
- /** Delete this sticker. Requires Manage Emojis and Stickers permission. */
35
- delete(): Promise<void>;
36
- /**
37
- * Edit this sticker's name and/or description.
38
- * Requires Manage Emojis and Stickers permission.
39
- */
40
- edit(options: {
41
- name?: string;
42
- description?: string;
43
- }): Promise<GuildSticker>;
44
- }
9
+ import { PermissionResolvable } from '@fluxerjs/util';
10
+ export { PermissionFlags, PermissionResolvable, PermissionString, PermissionsBitField, UserFlagsBitField, UserFlagsBits, UserFlagsResolvable, UserFlagsString, parsePrefixCommand, parseUserMention, resolvePermissionsToBitfield, resolveTenorToImageUrl } from '@fluxerjs/util';
45
11
 
46
- /** Represents a custom emoji in a guild. */
47
- declare class GuildEmoji extends Base {
48
- readonly client: Client;
49
- readonly id: string;
50
- readonly guildId: string;
12
+ /** Resolved file data (after URL fetch). Used internally by REST layer. */
13
+ interface ResolvedMessageFile {
51
14
  name: string;
52
- readonly animated: boolean;
53
- /** @param data - API emoji from GET /guilds/{id}/emojis or guild emoji events */
54
- constructor(client: Client, data: APIEmoji & {
55
- guild_id?: string;
56
- }, guildId: string);
57
- /** CDN URL for this emoji image. */
58
- get url(): string;
59
- /** Emoji identifier for use in reactions: `name:id` */
60
- get identifier(): string;
61
- /** Delete this emoji. Requires Manage Emojis and Stickers permission. */
62
- delete(): Promise<void>;
63
- /**
64
- * Edit this emoji's name.
65
- * Requires Manage Emojis and Stickers permission.
66
- */
67
- edit(options: {
68
- name: string;
69
- }): Promise<GuildEmoji>;
70
- }
71
-
72
- /**
73
- * Manages messages for a channel. Access via channel.messages.
74
- * @example
75
- * const message = await channel.messages.fetch(messageId);
76
- * if (message) await message.edit({ content: 'Updated!' });
77
- */
78
- declare class MessageManager {
79
- private readonly client;
80
- private readonly channelId;
81
- constructor(client: Client, channelId: string);
82
- /**
83
- * Fetch a message by ID from this channel.
84
- * @param messageId - Snowflake of the message
85
- * @returns The message
86
- * @throws FluxerError with MESSAGE_NOT_FOUND if the message does not exist
87
- */
88
- fetch(messageId: string): Promise<Message>;
89
- }
90
-
91
- interface MessageCollectorOptions {
92
- /** Filter function. Return true to collect the message. */
93
- filter?: (message: Message) => boolean;
94
- /** Max duration in ms. Collector stops when time expires. */
95
- time?: number;
96
- /** Max messages to collect. Collector stops when limit reached. */
97
- max?: number;
98
- }
99
- type MessageCollectorEndReason = 'time' | 'limit' | 'user';
100
- interface MessageCollectorEvents {
101
- collect: [message: Message];
102
- end: [collected: Collection<string, Message>, reason: MessageCollectorEndReason];
103
- }
104
- /**
105
- * Collects messages in a channel. Use channel.createMessageCollector().
106
- * @example
107
- * const collector = channel.createMessageCollector({ filter: m => m.author.id === userId, time: 10000 });
108
- * collector.on('collect', m => console.log(m.content));
109
- * collector.on('end', (collected, reason) => console.log(`Stopped: ${reason}`));
110
- */
111
- declare class MessageCollector extends EventEmitter {
112
- readonly client: Client;
113
- readonly channelId: string;
114
- readonly options: Required<MessageCollectorOptions>;
115
- readonly collected: Collection<string, Message>;
116
- private _timeout;
117
- private _ended;
118
- private _listener;
119
- constructor(client: Client, channelId: string, options?: MessageCollectorOptions);
120
- stop(reason?: MessageCollectorEndReason): void;
121
- on<K extends keyof MessageCollectorEvents>(event: K, listener: (...args: MessageCollectorEvents[K]) => void): this;
122
- emit<K extends keyof MessageCollectorEvents>(event: K, ...args: MessageCollectorEvents[K]): boolean;
15
+ data: Blob | ArrayBuffer | Uint8Array | Buffer;
16
+ filename?: string;
123
17
  }
124
-
125
18
  /** File data for message attachment uploads. Use `data` for buffers or `url` to fetch from a URL. */
126
19
  type MessageFileData = {
127
20
  name: string;
@@ -144,7 +37,7 @@ interface MessageAttachmentMeta {
144
37
  /** Options for sending a message (content, embeds, files). Used by Message.send, Channel.send, ChannelManager.send.
145
38
  * EmbedBuilder instances are auto-converted to API format—no need to call .toJSON().
146
39
  */
147
- type MessageSendOptions = string | {
40
+ type MessageSendOptions = {
148
41
  content?: string;
149
42
  /** EmbedBuilder instances are auto-converted; raw APIEmbed also supported. */
150
43
  embeds?: (APIEmbed | EmbedBuilder)[];
@@ -153,320 +46,816 @@ type MessageSendOptions = string | {
153
46
  /** Attachment metadata for files (id = index). Use when files are provided. */
154
47
  attachments?: MessageAttachmentMeta[];
155
48
  };
156
-
157
- /** File data for webhook attachment uploads. Use `data` for buffers or `url` to fetch from a URL. */
158
- type WebhookFileData = MessageFileData;
159
- /** Attachment metadata for webhook file uploads (id matches FormData index). */
160
- interface WebhookAttachmentMeta {
161
- id: number;
162
- filename: string;
163
- title?: string | null;
164
- description?: string | null;
165
- /** MessageAttachmentFlags: IS_SPOILER (8), CONTAINS_EXPLICIT_MEDIA (16), IS_ANIMATED (32) */
166
- flags?: number;
167
- }
168
- /** Options for sending a message via webhook. Aligns with WebhookMessageRequest in the API. */
169
- interface WebhookSendOptions {
170
- /** Message text content (up to 2000 characters) */
49
+ /** API-ready body from MessageSendOptions (serializes EmbedBuilder, includes attachments when files present). */
50
+ interface SendBodyResult {
171
51
  content?: string;
172
- /** Embed objects. Use EmbedBuilder or APIEmbed; EmbedBuilder is serialized automatically. */
173
- embeds?: (APIEmbed | EmbedBuilder)[];
174
- /** Override the webhook's default username for this message */
175
- username?: string;
176
- /** Override the webhook's default avatar URL for this message */
177
- avatar_url?: string;
178
- /** Text-to-speech */
179
- tts?: boolean;
180
- /** File attachments. When present, uses multipart/form-data (same as channel.send). */
181
- files?: WebhookFileData[];
182
- /** Attachment metadata for files (id = index). Use when files are provided. */
183
- attachments?: WebhookAttachmentMeta[];
52
+ embeds?: APIEmbed[];
53
+ attachments?: Array<{
54
+ id: number;
55
+ filename: string;
56
+ title?: string | null;
57
+ description?: string | null;
58
+ flags?: number;
59
+ }>;
184
60
  }
185
- /**
186
- * Represents a Discord/Fluxer webhook. Supports creating, fetching, sending, and deleting.
187
- * The token is only available when the webhook was created; fetched webhooks cannot send messages.
188
- */
189
- declare class Webhook extends Base {
61
+
62
+ /** Base class for all Fluxer structures. Provides the client reference. */
63
+ declare abstract class Base {
64
+ /** The client instance this structure belongs to. */
65
+ abstract readonly client: Client;
66
+ }
67
+
68
+ /** Represents a user (or bot) on Fluxer. */
69
+ declare class User extends Base {
190
70
  readonly client: Client;
191
71
  readonly id: string;
192
- readonly guildId: string;
193
- channelId: string;
194
- name: string;
72
+ username: string;
73
+ discriminator: string;
74
+ globalName: string | null;
195
75
  avatar: string | null;
196
- /** Present only when webhook was created via createWebhook(); not returned when fetching. */
197
- readonly token: string | null;
198
- /** User who created the webhook. */
199
- readonly user: User;
200
- /** @param data - API webhook from POST /channels/{id}/webhooks (has token) or GET /webhooks/{id} (no token) */
201
- constructor(client: Client, data: APIWebhook & {
202
- token?: string | null;
203
- });
76
+ readonly bot: boolean;
77
+ /** RGB avatar color (e.g. 7577782). Null if not set. */
78
+ avatarColor: number | null;
79
+ /** Public flags bitfield. Null if not set. */
80
+ flags: number | null;
81
+ /** Whether this is an official system user. */
82
+ readonly system: boolean;
83
+ /** Banner hash (from profile, member, or invite context). Null when not available. */
84
+ banner: string | null;
85
+ /** @param data - API user from message author, GET /users/{id}, or GET /users/@me */
86
+ constructor(client: Client, data: APIUserPartial);
87
+ /** Update mutable fields from fresh API data. Used by getOrCreateUser cache. */
88
+ _patch(data: APIUserPartial): void;
204
89
  /**
205
- * Get the URL for this webhook's avatar.
206
- * Returns null if the webhook has no custom avatar.
90
+ * Get the URL for this user's avatar.
91
+ * Auto-detects animated avatars (hash starting with `a_`) and uses gif extension.
92
+ * @param options - Optional `size` and `extension` (default: png, or gif for animated)
207
93
  */
208
94
  avatarURL(options?: {
209
95
  size?: number;
210
96
  extension?: string;
211
97
  }): string | null;
212
- /** Delete this webhook. Requires bot token with Manage Webhooks permission. */
213
- delete(): Promise<void>;
214
- /**
215
- * Edit this webhook. With token: name and avatar only. Without token (bot auth): name, avatar, and channel_id.
216
- * @param options - Fields to update (name, avatar, channel_id when using bot auth)
217
- * @returns This webhook instance with updated fields
218
- */
219
- edit(options: APIWebhookUpdateRequest | APIWebhookTokenUpdateRequest): Promise<Webhook>;
98
+ /** Get the avatar URL, or the default avatar if none set (Fluxer: fluxerstatic.com). */
99
+ displayAvatarURL(options?: {
100
+ size?: number;
101
+ extension?: string;
102
+ }): string;
220
103
  /**
221
- * Send a message via this webhook. Requires the webhook token (only present when created, not when fetched).
222
- * @param options - Text content or object with content, embeds, username, avatar_url, tts, files, attachments
223
- * @param wait - If true, waits for the API and returns the created Message; otherwise returns void (204)
224
- * @throws Error if token is not available
225
- * @example
226
- * await webhook.send('Hello!');
227
- * await webhook.send({ embeds: [embed] });
228
- * await webhook.send({ content: 'File attached', files: [{ name: 'data.txt', data: buffer }] });
229
- * const msg = await webhook.send({ content: 'Hi' }, true);
104
+ * Get the URL for this user's banner.
105
+ * Returns null if the user has no banner (only available when fetched from profile/member context).
230
106
  */
231
- send(options: string | WebhookSendOptions, wait?: boolean): Promise<Message | undefined>;
107
+ bannerURL(options?: {
108
+ size?: number;
109
+ extension?: string;
110
+ }): string | null;
111
+ /** Returns a mention string (e.g. `<@123456>`). */
112
+ toString(): string;
232
113
  /**
233
- * Fetch a webhook by ID using bot auth.
234
- * @param client - The client instance
235
- * @param webhookId - The webhook ID
236
- * @returns Webhook without token (cannot send)
114
+ * Create or get a DM channel with this user.
115
+ * Returns the DM channel; use {@link DMChannel.send} to send messages.
237
116
  */
238
- static fetch(client: Client, webhookId: string): Promise<Webhook>;
117
+ createDM(): Promise<DMChannel>;
239
118
  /**
240
- * Create a Webhook instance from an ID and token (e.g. from a stored webhook URL).
241
- * @param client - The client instance
242
- * @param webhookId - The webhook ID
243
- * @param token - The webhook token (from createWebhook or stored)
244
- * @param options - Optional channelId, guildId, name for display
119
+ * Send a DM to this user.
120
+ * Convenience method that creates the DM channel and sends the message.
245
121
  */
246
- static fromToken(client: Client, webhookId: string, token: string, options?: {
247
- channelId?: string;
248
- guildId?: string;
249
- name?: string;
250
- }): Webhook;
122
+ send(options: MessageSendOptions): Promise<Message>;
251
123
  }
252
124
 
253
- /** Base class for all channel types. */
254
- declare abstract class Channel extends Base {
255
- /** Whether this channel has a send method (TextChannel, DMChannel). */
256
- isSendable(): this is TextChannel | DMChannel;
257
- /** Whether this channel is a DM or Group DM. */
258
- isDM(): boolean;
259
- /** Whether this channel is voice-based (VoiceChannel). */
260
- isVoice(): boolean;
261
- /** Create a DM channel from API data (type DM or GroupDM). */
262
- static createDM(client: Client, data: APIChannelPartial): DMChannel;
125
+ /** Represents a role in a guild. */
126
+ declare class Role extends Base {
263
127
  readonly client: Client;
264
128
  readonly id: string;
265
- type: ChannelType;
266
- /** Channel name. Guild channels and Group DMs have names; 1:1 DMs are typically null. */
267
- name: string | null;
268
- /** Channel icon hash (Group DMs). Null if none. */
269
- icon: string | null;
270
- /** ISO timestamp when the last message was pinned. Null if never pinned. */
271
- lastPinTimestamp: string | null;
272
- /** @param data - API channel from GET /channels/{id} or GET /guilds/{id}/channels */
273
- constructor(client: Client, data: APIChannelPartial);
129
+ readonly guildId: string;
130
+ name: string;
131
+ color: number;
132
+ position: number;
133
+ permissions: string;
134
+ hoist: boolean;
135
+ mentionable: boolean;
136
+ unicodeEmoji: string | null;
137
+ /** Separately sorted position for hoisted roles. Null if not set. */
138
+ hoistPosition: number | null;
139
+ /** @param client - The client instance */
140
+ /** @param data - API role from GET /guilds/{id}/roles or gateway role events */
141
+ /** @param guildId - The guild this role belongs to */
142
+ constructor(client: Client, data: APIRole, guildId: string);
143
+ /** Update mutable fields from fresh API data. Used by edit and gateway events. */
144
+ _patch(data: Partial<APIRole>): void;
145
+ /** Returns a mention string (e.g. `<@&123456>`). */
146
+ toString(): string;
274
147
  /**
275
- * Create the appropriate channel subclass from API data.
276
- * @param client - The client instance
277
- * @param data - Channel data from the API
148
+ * Check if this role has a permission. Administrator grants all permissions.
149
+ * @param permission - Permission flag, name, or resolvable
150
+ * @returns true if the role has the permission
151
+ * @example
152
+ * if (role.has(PermissionFlags.BanMembers)) { ... }
153
+ * if (role.has('ManageChannels')) { ... }
278
154
  */
279
- static from(client: Client, data: APIChannel | APIChannelPartial): GuildChannel | TextChannel | null;
155
+ has(permission: PermissionResolvable): boolean;
280
156
  /**
281
- * Create a channel from API data, including DM and GroupDM.
282
- * Used by ChannelManager.fetch() for GET /channels/{id}.
157
+ * Edit this role.
158
+ * Requires Manage Roles permission.
159
+ * @param options - Role updates (permissions accepts PermissionResolvable for convenience)
160
+ * @returns This role (updated in place)
161
+ * @example
162
+ * await role.edit({ name: 'Moderator', permissions: ['BanMembers', 'KickMembers'] });
283
163
  */
284
- static fromOrCreate(client: Client, data: APIChannel | APIChannelPartial): TextChannel | DMChannel | GuildChannel | null;
164
+ edit(options: RESTUpdateRoleBody & {
165
+ permissions?: string | PermissionResolvable;
166
+ }): Promise<Role>;
285
167
  /**
286
- * Bulk delete messages. Requires Manage Messages permission.
287
- * @param messageIds - Array of message IDs to delete (2–100)
168
+ * Delete this role.
169
+ * Requires Manage Roles permission.
288
170
  */
289
- bulkDeleteMessages(messageIds: string[]): Promise<void>;
171
+ delete(): Promise<void>;
172
+ }
173
+
174
+ /** Role ID or Role object for add/remove. */
175
+ type RoleResolvable = string | Role;
176
+ /**
177
+ * Manages a guild member's roles with add/remove/set and a cache of Role objects.
178
+ * Discord.js parity: member.roles.add(), member.roles.remove(), member.roles.set(), member.roles.cache
179
+ *
180
+ * @discordJsCompat https://discord.js.org/docs/packages/discord.js/main/GuildMemberRoleManager
181
+ * @example
182
+ * // Add a role (Discord.js style)
183
+ * await member.roles.add(roleId);
184
+ *
185
+ * @example
186
+ * // Remove a role
187
+ * await member.roles.remove(roleId);
188
+ *
189
+ * @example
190
+ * // Replace all roles
191
+ * await member.roles.set(['roleId1', 'roleId2']);
192
+ *
193
+ * @example
194
+ * // Check if member has a role
195
+ * if (member.roles.cache.has(roleId)) { ... }
196
+ */
197
+ declare class GuildMemberRoleManager {
198
+ private readonly member;
199
+ private _roleIds;
200
+ constructor(member: GuildMember, initialRoleIds?: string[]);
201
+ /** Role IDs for this member. Used by permissions; prefer cache for Role objects. */
202
+ get roleIds(): readonly string[];
203
+ /** Check if the member has a role. Discord.js parity: member.roles.cache.has(roleId) */
204
+ has(roleOrId: RoleResolvable): boolean;
205
+ /**
206
+ * Collection of Role objects for this member's roles (from guild.roles).
207
+ * Discord.js parity: member.roles.cache
208
+ * @discordJsCompat https://discord.js.org/docs/packages/discord.js/main/GuildMemberRoleManager
209
+ */
210
+ get cache(): Collection<string, Role>;
211
+ /** Resolve role ID from RoleResolvable. */
212
+ private _resolveId;
290
213
  /**
291
- * Send a typing indicator to the channel. Lasts ~10 seconds.
214
+ * Add a role to this member.
215
+ * Discord.js parity: member.roles.add(roleId)
216
+ * Requires Manage Roles permission.
217
+ * @discordJsCompat https://discord.js.org/docs/packages/discord.js/main/GuildMemberRoleManager
292
218
  */
293
- sendTyping(): Promise<void>;
294
- }
295
- declare class GuildChannel extends Channel {
296
- readonly guildId: string;
297
- name: string | null;
298
- position?: number;
299
- parentId: string | null;
300
- /** Permission overwrites for roles and members. */
301
- permissionOverwrites: APIChannelOverwrite[];
302
- constructor(client: Client, data: APIChannel);
219
+ add(roleOrId: RoleResolvable): Promise<void>;
303
220
  /**
304
- * Create a webhook in this channel.
305
- * @param options - Webhook name and optional avatar URL
306
- * @returns The webhook with token (required for send()). Requires Manage Webhooks permission.
221
+ * Remove a role from this member.
222
+ * Discord.js parity: member.roles.remove(roleId)
223
+ * Requires Manage Roles permission.
224
+ * @discordJsCompat https://discord.js.org/docs/packages/discord.js/main/GuildMemberRoleManager
307
225
  */
308
- createWebhook(options: {
309
- name: string;
310
- avatar?: string | null;
311
- }): Promise<Webhook>;
226
+ remove(roleOrId: RoleResolvable): Promise<void>;
312
227
  /**
313
- * Fetch all webhooks in this channel.
314
- * @returns Webhooks (includes token when listing from channel; can send via send())
228
+ * Replace all roles for this member. PATCH /guilds/{id}/members/{userId}
229
+ * Discord.js parity: member.roles.set(roleIds)
230
+ * Requires Manage Roles permission.
231
+ * @discordJsCompat https://discord.js.org/docs/packages/discord.js/main/GuildMemberRoleManager
315
232
  */
316
- fetchWebhooks(): Promise<Webhook[]>;
233
+ set(roleIds: string[]): Promise<void>;
317
234
  /**
318
- * Create an invite for this channel.
319
- * @param options - max_uses (0–100), max_age (0–604800 seconds), unique, temporary
320
- * Requires Create Instant Invite permission.
235
+ * Update internal role IDs from API response. Called by GuildMember.edit().
236
+ * @internal
321
237
  */
322
- createInvite(options?: {
323
- max_uses?: number;
324
- max_age?: number;
325
- unique?: boolean;
326
- temporary?: boolean;
327
- }): Promise<Invite>;
238
+ _patch(roleIds: string[]): void;
239
+ }
240
+
241
+ /** Represents a member of a guild. */
242
+ declare class GuildMember extends Base {
243
+ readonly client: Client;
244
+ readonly id: string;
245
+ readonly user: User;
246
+ readonly guild: Guild;
247
+ nick: string | null;
328
248
  /**
329
- * Fetch invites for this channel.
330
- * Requires Manage Channel permission.
249
+ * Role manager with add/remove/set and cache. Discord.js parity: member.roles.add(), member.roles.cache
250
+ * @discordJsCompat https://discord.js.org/docs/packages/discord.js/main/GuildMemberRoleManager
331
251
  */
332
- fetchInvites(): Promise<Invite[]>;
252
+ readonly roles: GuildMemberRoleManager;
253
+ readonly joinedAt: Date;
254
+ communicationDisabledUntil: Date | null;
255
+ readonly mute: boolean;
256
+ readonly deaf: boolean;
257
+ readonly avatar: string | null;
258
+ readonly banner: string | null;
259
+ readonly accentColor: number | null;
260
+ readonly profileFlags: number | null;
261
+ /** @param data - API guild member from GET /guilds/{id}/members or GET /guilds/{id}/members/{user_id} */
262
+ constructor(client: Client, data: APIGuildMember & {
263
+ guild_id?: string;
264
+ }, guild: Guild);
265
+ /** Nickname, or global name, or username. */
266
+ get displayName(): string;
333
267
  /**
334
- * Set or update a permission overwrite. PUT /channels/{id}/permissions/{overwriteId}.
335
- * @param overwriteId - Role or member ID
336
- * @param options - type (0=role, 1=member), allow, deny (permission bitfields)
268
+ * Get the guild-specific avatar URL for this member.
269
+ * Returns null if the member has no guild avatar (use displayAvatarURL for fallback).
337
270
  */
338
- editPermission(overwriteId: string, options: {
339
- type: 0 | 1;
340
- allow?: string;
341
- deny?: string;
342
- }): Promise<void>;
271
+ avatarURL(options?: {
272
+ size?: number;
273
+ extension?: string;
274
+ }): string | null;
343
275
  /**
344
- * Remove a permission overwrite. DELETE /channels/{id}/permissions/{overwriteId}.
276
+ * Get the avatar URL to display for this member.
277
+ * Uses guild-specific avatar if set, otherwise falls back to the user's avatar.
345
278
  */
346
- deletePermission(overwriteId: string): Promise<void>;
279
+ displayAvatarURL(options?: {
280
+ size?: number;
281
+ extension?: string;
282
+ }): string;
347
283
  /**
348
- * Edit this channel. PATCH /channels/{id}.
349
- * Requires Manage Channel permission.
284
+ * Get the guild-specific banner URL for this member.
285
+ * Returns null if the member has no guild banner.
350
286
  */
351
- edit(options: {
352
- name?: string | null;
353
- topic?: string | null;
354
- parent_id?: string | null;
355
- bitrate?: number | null;
356
- user_limit?: number | null;
357
- nsfw?: boolean;
358
- rate_limit_per_user?: number;
359
- rtc_region?: string | null;
360
- permission_overwrites?: Array<{
361
- id: string;
362
- type: number;
363
- allow?: string;
364
- deny?: string;
365
- }>;
366
- }): Promise<this>;
287
+ bannerURL(options?: {
288
+ size?: number;
289
+ extension?: string;
290
+ }): string | null;
367
291
  /**
368
- * Delete this channel. Requires Manage Channel permission.
369
- * @param options - silent: if true, does not send a system message (default false)
292
+ * Add a role to this member.
293
+ * Prefer member.roles.add(roleId) for Discord.js parity.
294
+ * @param roleId - The role ID to add
295
+ * Requires Manage Roles permission.
370
296
  */
371
- delete(options?: {
372
- silent?: boolean;
373
- }): Promise<void>;
374
- }
375
- declare class TextChannel extends GuildChannel {
376
- topic?: string | null;
377
- nsfw?: boolean;
378
- rateLimitPerUser?: number;
379
- lastMessageId?: string | null;
380
- constructor(client: Client, data: APIChannel);
297
+ addRole(roleId: string): Promise<void>;
381
298
  /**
382
- * Send a message to this channel.
383
- * @param options - Text content or object with content, embeds, and/or files
299
+ * Remove a role from this member.
300
+ * Prefer member.roles.remove(roleId) for Discord.js parity.
301
+ * @param roleId - The role ID to remove
302
+ * Requires Manage Roles permission.
384
303
  */
385
- send(options: MessageSendOptions): Promise<Message>;
386
- /** Message manager for this channel. Use channel.messages.fetch(messageId). */
387
- get messages(): MessageManager;
304
+ removeRole(roleId: string): Promise<void>;
388
305
  /**
389
- * Create a message collector for this channel.
390
- * Collects messages matching the filter until time expires or max is reached.
391
- * @param options - Filter, time (ms), and max count
392
- * @example
393
- * const collector = channel.createMessageCollector({ filter: m => m.author.id === userId, time: 10000 });
394
- * collector.on('collect', m => console.log(m.content));
395
- * collector.on('end', (collected, reason) => { ... });
306
+ * Edit this guild member. PATCH /guilds/{id}/members/{userId} or /members/@me for the bot.
307
+ * For @me: nick, avatar, banner, bio, pronouns, accent_color, profile_flags, mute, deaf,
308
+ * communication_disabled_until, timeout_reason, channel_id, connection_id.
309
+ * For other members: same plus roles (array of role IDs).
396
310
  */
397
- createMessageCollector(options?: MessageCollectorOptions): MessageCollector;
311
+ edit(options: {
312
+ nick?: string | null;
313
+ roles?: string[];
314
+ avatar?: string | null;
315
+ banner?: string | null;
316
+ bio?: string | null;
317
+ pronouns?: string | null;
318
+ accent_color?: number | null;
319
+ profile_flags?: number | null;
320
+ mute?: boolean;
321
+ deaf?: boolean;
322
+ communication_disabled_until?: string | null;
323
+ timeout_reason?: string | null;
324
+ channel_id?: string | null;
325
+ connection_id?: string | null;
326
+ }): Promise<this>;
398
327
  /**
399
- * Fetch pinned messages in this channel.
400
- * @returns Pinned messages
328
+ * Get the member's guild-level permissions (from roles only, no channel overwrites).
329
+ * Use this for server-wide permission checks (e.g. ban, kick, manage roles).
330
+ * @returns Object with has(permission) to check specific permissions
331
+ * @example
332
+ * const perms = member.permissions;
333
+ * if (perms.has(PermissionFlags.BanMembers)) { ... }
401
334
  */
402
- fetchPinnedMessages(): Promise<Message[]>;
335
+ get permissions(): {
336
+ has(permission: PermissionResolvable): boolean;
337
+ };
403
338
  /**
404
- * Fetch a message by ID from this channel.
405
- * @param messageId - Snowflake of the message
406
- * @returns The message, or null if not found
407
- * @deprecated Use channel.messages.fetch(messageId) instead.
339
+ * Compute the member's effective permissions in a guild channel.
340
+ * Applies role permissions and channel overwrites.
341
+ * @param channel - The guild channel to check permissions for
342
+ * @returns Object with has(permission) to check specific permissions
343
+ * @example
344
+ * const perms = member.permissionsIn(channel);
345
+ * if (perms.has(PermissionFlags.SendMessages)) { ... }
408
346
  */
409
- fetchMessage(messageId: string): Promise<Message>;
410
- }
411
- declare class CategoryChannel extends GuildChannel {
347
+ permissionsIn(channel: GuildChannel): {
348
+ has(permission: PermissionResolvable): boolean;
349
+ };
350
+ private _computeBasePermissions;
412
351
  }
413
- declare class VoiceChannel extends GuildChannel {
414
- bitrate?: number | null;
415
- userLimit?: number | null;
416
- rtcRegion?: string | null;
417
- constructor(client: Client, data: APIChannel);
352
+
353
+ /**
354
+ * Manages guild members with a Collection-like API.
355
+ * Extends Collection so you can use .get(), .set(), .filter(), etc.
356
+ * Provides guild.members.me for Discord.js parity.
357
+ *
358
+ * @discordJsCompat https://discord.js.org/docs/packages/discord.js/main/GuildMemberManager
359
+ */
360
+ declare class GuildMemberManager extends Collection<string, GuildMember> {
361
+ private readonly guild;
362
+ constructor(guild: Guild);
363
+ /**
364
+ * Get a guild member from cache or fetch from the API if not present.
365
+ * Convenience helper to avoid repeating `guild.members.get(userId) ?? (await guild.fetchMember(userId))`.
366
+ * @param userId - Snowflake of the user
367
+ * @returns The guild member
368
+ * @throws FluxerError with MEMBER_NOT_FOUND if user is not in the guild (404)
369
+ * @example
370
+ * const member = await guild.members.resolve(userId);
371
+ * console.log(member.displayName);
372
+ */
373
+ resolve(userId: string): Promise<GuildMember>;
374
+ /**
375
+ * The current bot user as a GuildMember in this guild.
376
+ * Returns null if the bot's member is not cached or client.user is null.
377
+ * Use fetchMe() to load the bot's member when not cached.
378
+ *
379
+ * @discordJsCompat https://discord.js.org/docs/packages/discord.js/main/GuildMemberManager
380
+ * @example
381
+ * const perms = guild.members.me?.permissions;
382
+ * if (perms?.has(PermissionFlags.BanMembers)) { ... }
383
+ */
384
+ get me(): GuildMember | null;
385
+ /**
386
+ * Fetch the current bot user as a GuildMember in this guild.
387
+ * Caches the result in guild.members.
388
+ *
389
+ * @throws Error if client.user is null (client not ready)
390
+ * @example
391
+ * const me = await guild.members.fetchMe();
392
+ * console.log(me.displayName);
393
+ */
394
+ fetchMe(): Promise<GuildMember>;
395
+ /**
396
+ * Fetch guild members with pagination. GET /guilds/{id}/members.
397
+ * @param options - limit (1-1000), after (user ID for pagination)
398
+ * @returns Array of GuildMember objects (cached in guild.members)
399
+ */
400
+ fetch(options?: {
401
+ limit?: number;
402
+ after?: string;
403
+ }): Promise<GuildMember[]>;
418
404
  }
419
- declare class LinkChannel extends GuildChannel {
420
- url?: string | null;
421
- constructor(client: Client, data: APIChannel);
405
+
406
+ /** File data for webhook attachment uploads. Use `data` for buffers or `url` to fetch from a URL. */
407
+ type WebhookFileData = MessageFileData;
408
+ /** Attachment metadata for webhook file uploads (id matches FormData index). */
409
+ interface WebhookAttachmentMeta {
410
+ id: number;
411
+ filename: string;
412
+ title?: string | null;
413
+ description?: string | null;
414
+ /** MessageAttachmentFlags: IS_SPOILER (8), CONTAINS_EXPLICIT_MEDIA (16), IS_ANIMATED (32) */
415
+ flags?: number;
422
416
  }
423
- /** DM channel (direct message between bot and a user). */
424
- declare class DMChannel extends Channel {
425
- lastMessageId?: string | null;
426
- /** Group DM creator ID. Null for 1:1 DMs. */
427
- ownerId: string | null;
428
- /** Group DM recipients as User objects. Empty for 1:1 DMs. */
429
- recipients: User[];
430
- /** Group DM member display names (userId -> nickname). */
431
- nicks: Record<string, string>;
432
- constructor(client: Client, data: APIChannelPartial & Partial<APIChannel>);
417
+ /** Options for sending a message via webhook. Aligns with WebhookMessageRequest in the API. */
418
+ interface WebhookSendOptions {
419
+ /** Message text content (up to 2000 characters) */
420
+ content?: string;
421
+ /** Embed objects. Use EmbedBuilder or APIEmbed; EmbedBuilder is serialized automatically. */
422
+ embeds?: (APIEmbed | EmbedBuilder)[];
423
+ /** Override the webhook's default username for this message */
424
+ username?: string;
425
+ /** Override the webhook's default avatar URL for this message */
426
+ avatar_url?: string;
427
+ /** Text-to-speech */
428
+ tts?: boolean;
429
+ /** File attachments. When present, uses multipart/form-data (same as channel.send). */
430
+ files?: WebhookFileData[];
431
+ /** Attachment metadata for files (id = index). Use when files are provided. */
432
+ attachments?: WebhookAttachmentMeta[];
433
+ }
434
+ /**
435
+ * Represents a Discord/Fluxer webhook. Supports creating, fetching, sending, and deleting.
436
+ * The token is only available when the webhook was created; fetched webhooks cannot send messages.
437
+ */
438
+ declare class Webhook extends Base {
439
+ readonly client: Client;
440
+ readonly id: string;
441
+ readonly guildId: string;
442
+ channelId: string;
443
+ name: string;
444
+ avatar: string | null;
445
+ /** Present only when webhook was created via createWebhook(); not returned when fetching. */
446
+ readonly token: string | null;
447
+ /** User who created the webhook. */
448
+ readonly user: User;
449
+ /** @param data - API webhook from POST /channels/{id}/webhooks (has token) or GET /webhooks/{id} (no token) */
450
+ constructor(client: Client, data: APIWebhook & {
451
+ token?: string | null;
452
+ });
433
453
  /**
434
- * Send a message to this DM channel.
435
- * @param options - Text content or object with content, embeds, and/or files
454
+ * Get the URL for this webhook's avatar.
455
+ * Returns null if the webhook has no custom avatar.
436
456
  */
437
- send(options: MessageSendOptions): Promise<Message>;
438
- /** Message manager for this channel. Use channel.messages.fetch(messageId). */
439
- get messages(): MessageManager;
457
+ avatarURL(options?: {
458
+ size?: number;
459
+ extension?: string;
460
+ }): string | null;
461
+ /** Delete this webhook. Requires bot token with Manage Webhooks permission. */
462
+ delete(): Promise<void>;
440
463
  /**
441
- * Create a message collector for this DM channel.
442
- * @param options - Filter, time (ms), and max count
464
+ * Edit this webhook. With token: name and avatar only. Without token (bot auth): name, avatar, and channel_id.
465
+ * @param options - Fields to update (name, avatar, channel_id when using bot auth)
466
+ * @returns This webhook instance with updated fields
443
467
  */
444
- createMessageCollector(options?: MessageCollectorOptions): MessageCollector;
468
+ edit(options: APIWebhookUpdateRequest | APIWebhookTokenUpdateRequest): Promise<Webhook>;
469
+ /**
470
+ * Send a message via this webhook. Requires the webhook token (only present when created, not when fetched).
471
+ * @param options - Text content or object with content, embeds, username, avatar_url, tts, files, attachments
472
+ * @param wait - If true, waits for the API and returns the created Message; otherwise returns void (204)
473
+ * @throws Error if token is not available
474
+ * @example
475
+ * await webhook.send('Hello!');
476
+ * await webhook.send({ embeds: [embed] });
477
+ * await webhook.send({ content: 'File attached', files: [{ name: 'data.txt', data: buffer }] });
478
+ * const msg = await webhook.send({ content: 'Hi' }, true);
479
+ */
480
+ send(options: string | WebhookSendOptions, wait?: boolean): Promise<Message | undefined>;
481
+ /**
482
+ * Fetch a webhook by ID using bot auth.
483
+ * @param client - The client instance
484
+ * @param webhookId - The webhook ID
485
+ * @returns Webhook without token (cannot send)
486
+ */
487
+ static fetch(client: Client, webhookId: string): Promise<Webhook>;
488
+ /**
489
+ * Create a Webhook instance from an ID and token (e.g. from a stored webhook URL).
490
+ * @param client - The client instance
491
+ * @param webhookId - The webhook ID
492
+ * @param token - The webhook token (from createWebhook or stored)
493
+ * @param options - Optional channelId, guildId, name for display
494
+ */
495
+ static fromToken(client: Client, webhookId: string, token: string, options?: {
496
+ channelId?: string;
497
+ guildId?: string;
498
+ name?: string;
499
+ }): Webhook;
500
+ }
501
+
502
+ /** Represents a ban in a guild. */
503
+ declare class GuildBan extends Base {
504
+ readonly client: Client;
505
+ readonly guildId: string;
506
+ readonly user: User;
507
+ readonly reason: string | null;
508
+ /** ISO timestamp when a temporary ban expires. Null for permanent bans. */
509
+ readonly expiresAt: string | null;
510
+ /** @param data - API ban from GET /guilds/{id}/bans or gateway GUILD_BAN_ADD */
511
+ constructor(client: Client, data: APIBan & {
512
+ guild_id?: string;
513
+ }, guildId: string);
514
+ /**
515
+ * Remove this ban (unban the user).
516
+ * Requires Ban Members permission.
517
+ */
518
+ unban(): Promise<void>;
519
+ }
520
+
521
+ /** Represents a custom emoji in a guild. */
522
+ declare class GuildEmoji extends Base {
523
+ readonly client: Client;
524
+ readonly id: string;
525
+ readonly guildId: string;
526
+ name: string;
527
+ readonly animated: boolean;
528
+ /** @param data - API emoji from GET /guilds/{id}/emojis or guild emoji events */
529
+ constructor(client: Client, data: APIEmoji & {
530
+ guild_id?: string;
531
+ }, guildId: string);
532
+ /** CDN URL for this emoji image. */
533
+ get url(): string;
534
+ /** Emoji identifier for use in reactions: `name:id` */
535
+ get identifier(): string;
536
+ /** Delete this emoji. Requires Manage Emojis and Stickers permission. */
537
+ delete(): Promise<void>;
538
+ /**
539
+ * Edit this emoji's name.
540
+ * Requires Manage Emojis and Stickers permission.
541
+ */
542
+ edit(options: {
543
+ name: string;
544
+ }): Promise<GuildEmoji>;
545
+ }
546
+
547
+ /** Represents a custom sticker in a guild. */
548
+ declare class GuildSticker extends Base {
549
+ readonly client: Client;
550
+ readonly id: string;
551
+ readonly guildId: string;
552
+ name: string;
553
+ description: string;
554
+ readonly tags: string[];
555
+ readonly animated: boolean;
556
+ /** @param data - API sticker from GET /guilds/{id}/stickers or guild sticker events */
557
+ constructor(client: Client, data: APISticker & {
558
+ guild_id?: string;
559
+ }, guildId: string);
560
+ /** CDN URL for this sticker image. */
561
+ get url(): string;
562
+ /** Delete this sticker. Requires Manage Emojis and Stickers permission. */
563
+ delete(): Promise<void>;
564
+ /**
565
+ * Edit this sticker's name and/or description.
566
+ * Requires Manage Emojis and Stickers permission.
567
+ */
568
+ edit(options: {
569
+ name?: string;
570
+ description?: string;
571
+ }): Promise<GuildSticker>;
572
+ }
573
+
574
+ /** Represents a Fluxer guild (server). */
575
+ declare class Guild extends Base {
576
+ readonly client: Client;
577
+ readonly id: string;
578
+ name: string;
579
+ icon: string | null;
580
+ banner: string | null;
581
+ readonly ownerId: string;
582
+ /** Invite splash image hash. Null if none. */
583
+ splash: string | null;
584
+ /** Custom vanity URL code (e.g. fluxer.gg/code). Null if none. */
585
+ vanityURLCode: string | null;
586
+ /** Enabled guild features. */
587
+ features: GuildFeature[];
588
+ verificationLevel: GuildVerificationLevel;
589
+ defaultMessageNotifications: DefaultMessageNotifications;
590
+ explicitContentFilter: GuildExplicitContentFilter;
591
+ /** AFK voice channel ID. Null if none. */
592
+ afkChannelId: string | null;
593
+ /** AFK timeout in seconds. */
594
+ afkTimeout: number;
595
+ /** System messages channel ID. Null if none. */
596
+ systemChannelId: string | null;
597
+ /** Rules/guidelines channel ID. Null if none. */
598
+ rulesChannelId: string | null;
599
+ nsfwLevel: number;
600
+ mfaLevel: GuildMFALevel;
601
+ /** Banner image width. Optional. */
602
+ bannerWidth?: number | null;
603
+ /** Banner image height. Optional. */
604
+ bannerHeight?: number | null;
605
+ /** Splash image width. Optional. */
606
+ splashWidth?: number | null;
607
+ /** Splash image height. Optional. */
608
+ splashHeight?: number | null;
609
+ members: GuildMemberManager;
610
+ channels: Collection<string, GuildChannel>;
611
+ roles: Collection<string, Role>;
612
+ emojis: Collection<string, GuildEmoji>;
613
+ /** @param data - API guild from GET /guilds/{id} or gateway GUILD_CREATE */
614
+ constructor(client: Client, data: APIGuild & {
615
+ roles?: APIRole[];
616
+ ownerId?: string;
617
+ });
618
+ /** Get the guild icon URL, or null if no icon. */
619
+ iconURL(options?: {
620
+ size?: number;
621
+ }): string | null;
622
+ /** Get the guild banner URL, or null if no banner. */
623
+ bannerURL(options?: {
624
+ size?: number;
625
+ }): string | null;
626
+ /** Get the guild splash (invite background) URL, or null if no splash. */
627
+ splashURL(options?: {
628
+ size?: number;
629
+ }): string | null;
630
+ /**
631
+ * Add a role to a member by user ID. Does not require fetching the member first.
632
+ * @param userId - The user ID of the member
633
+ * @param roleId - The role ID to add (or use guild.resolveRoleId for mention/name resolution)
634
+ * Requires Manage Roles permission.
635
+ */
636
+ addRoleToMember(userId: string, roleId: string): Promise<void>;
637
+ /**
638
+ * Remove a role from a member by user ID. Does not require fetching the member first.
639
+ * @param userId - The user ID of the member
640
+ * @param roleId - The role ID to remove
641
+ * Requires Manage Roles permission.
642
+ */
643
+ removeRoleFromMember(userId: string, roleId: string): Promise<void>;
644
+ /**
645
+ * Create a role in this guild.
646
+ * Requires Manage Roles permission.
647
+ * @param options - Role data (permissions accepts PermissionResolvable for convenience)
648
+ * @returns The created role
649
+ * @example
650
+ * const role = await guild.createRole({ name: 'Mod', permissions: ['KickMembers', 'BanMembers'] });
651
+ */
652
+ createRole(options: RESTCreateRoleBody & {
653
+ permissions?: string | PermissionResolvable;
654
+ }): Promise<Role>;
655
+ /**
656
+ * Fetch all roles in this guild.
657
+ * @returns Array of Role objects (cached in guild.roles)
658
+ */
659
+ fetchRoles(): Promise<Role[]>;
660
+ /**
661
+ * Fetch a role by ID.
662
+ * @param roleId - The role ID to fetch
663
+ * @returns The role
664
+ * @throws FluxerError with ROLE_NOT_FOUND if role does not exist (404)
665
+ */
666
+ fetchRole(roleId: string): Promise<Role>;
667
+ /**
668
+ * Resolve a role ID from an argument (role mention, raw ID, or name).
669
+ * Fetches guild roles if name is provided.
670
+ * @param arg - Role mention (@role), role ID, or role name
671
+ * @returns The role ID, or null if not found
672
+ */
673
+ resolveRoleId(arg: string): Promise<string | null>;
674
+ /**
675
+ * Ban a user from this guild.
676
+ * @param userId - The user ID to ban
677
+ * @param options - Optional reason, delete_message_days (0–7), and ban_duration_seconds (temporary ban).
678
+ * ban_duration_seconds: 0 = permanent, or use 3600, 43200, 86400, 259200, 432000, 604800, 1209600, 2592000.
679
+ * Requires Ban Members permission.
680
+ */
681
+ ban(userId: string, options?: {
682
+ reason?: string;
683
+ delete_message_days?: number;
684
+ ban_duration_seconds?: number;
685
+ }): Promise<void>;
686
+ /**
687
+ * Fetch guild bans. Requires Ban Members permission.
688
+ * @returns List of GuildBan objects
689
+ */
690
+ fetchBans(): Promise<GuildBan[]>;
691
+ /**
692
+ * Remove a ban (unban a user).
693
+ * @param userId - The user ID to unban
694
+ * Requires Ban Members permission.
695
+ */
696
+ unban(userId: string): Promise<void>;
697
+ /**
698
+ * Kick a member from this guild.
699
+ * @param userId - The user ID to kick
700
+ * Requires Kick Members permission.
701
+ */
702
+ kick(userId: string): Promise<void>;
703
+ /**
704
+ * Fetch a guild member by user ID.
705
+ * @param userId - The user ID of the member to fetch
706
+ * @returns The guild member
707
+ * @throws FluxerError with MEMBER_NOT_FOUND if user is not in the guild (404)
708
+ * @throws FluxerError with cause for permission denied (403) or other REST errors
709
+ */
710
+ fetchMember(userId: string): Promise<GuildMember>;
711
+ /**
712
+ * Fetch guild audit logs. Requires View Audit Log permission.
713
+ * @param options - Optional limit, before, after, user_id, action_type for filtering
714
+ */
715
+ fetchAuditLogs(options?: {
716
+ limit?: number;
717
+ before?: string;
718
+ after?: string;
719
+ userId?: string;
720
+ actionType?: number;
721
+ }): Promise<APIGuildAuditLog>;
722
+ /** Fetch all webhooks in this guild. Returned webhooks do not include the token (cannot send). */
723
+ fetchWebhooks(): Promise<Webhook[]>;
724
+ /**
725
+ * Create a channel in this guild.
726
+ * @param data - Channel data: type (0=text, 2=voice, 4=category, 5=link), name, and optional parent_id, topic, bitrate, user_limit, nsfw, permission_overwrites
727
+ * Requires Manage Channels permission.
728
+ */
729
+ createChannel(data: {
730
+ type: 0 | 2 | 4 | 5;
731
+ name: string;
732
+ parent_id?: string | null;
733
+ topic?: string | null;
734
+ bitrate?: number | null;
735
+ user_limit?: number | null;
736
+ nsfw?: boolean;
737
+ permission_overwrites?: Array<{
738
+ id: string;
739
+ type: number;
740
+ allow: string;
741
+ deny: string;
742
+ }>;
743
+ }): Promise<GuildChannel>;
744
+ /**
745
+ * Fetch all channels in this guild.
746
+ * @returns Array of GuildChannel objects (cached in guild.channels and client.channels)
747
+ */
748
+ fetchChannels(): Promise<GuildChannel[]>;
749
+ /**
750
+ * Edit this guild. PATCH /guilds/{id}.
751
+ * Requires guild owner or Administrator.
752
+ */
753
+ edit(options: {
754
+ name?: string;
755
+ icon?: string | null;
756
+ system_channel_id?: string | null;
757
+ system_channel_flags?: number;
758
+ afk_channel_id?: string | null;
759
+ afk_timeout?: number;
760
+ default_message_notifications?: DefaultMessageNotifications;
761
+ verification_level?: GuildVerificationLevel;
762
+ mfa_level?: GuildMFALevel;
763
+ explicit_content_filter?: GuildExplicitContentFilter;
764
+ banner?: string | null;
765
+ splash?: string | null;
766
+ embed_splash?: string | null;
767
+ splash_card_alignment?: string;
768
+ features?: GuildFeature[];
769
+ }): Promise<this>;
770
+ /**
771
+ * Delete this guild. POST /guilds/{id}/delete.
772
+ * Must be the guild owner.
773
+ */
774
+ delete(): Promise<void>;
775
+ /**
776
+ * Fetch vanity URL for this guild. GET /guilds/{id}/vanity-url.
777
+ * Requires Manage Guild permission.
778
+ */
779
+ fetchVanityURL(): Promise<APIVanityURL>;
780
+ /**
781
+ * Transfer guild ownership to another user. POST /guilds/{id}/transfer-ownership.
782
+ * Must be the guild owner.
783
+ */
784
+ transferOwnership(newOwnerId: string, password?: string): Promise<void>;
785
+ /**
786
+ * Set text channel flexible names feature. PATCH /guilds/{id}/text-channel-flexible-names.
787
+ */
788
+ setTextChannelFlexibleNames(enabled: boolean): Promise<this>;
789
+ /**
790
+ * Set detached banner feature. PATCH /guilds/{id}/detached-banner.
791
+ */
792
+ setDetachedBanner(enabled: boolean): Promise<this>;
793
+ /**
794
+ * Set disallow unclaimed accounts. PATCH /guilds/{id}/disallow-unclaimed-accounts.
795
+ */
796
+ setDisallowUnclaimedAccounts(enabled: boolean): Promise<this>;
797
+ /**
798
+ * Update role positions. PATCH /guilds/{id}/roles.
799
+ * @param updates - Array of { id, position? }
800
+ */
801
+ setRolePositions(updates: Array<{
802
+ id: string;
803
+ position?: number;
804
+ }>): Promise<APIRole[]>;
805
+ /**
806
+ * Update role hoist positions. PATCH /guilds/{id}/roles/hoist-positions.
807
+ */
808
+ setRoleHoistPositions(updates: Array<{
809
+ id: string;
810
+ hoist_position?: number;
811
+ }>): Promise<APIRole[]>;
812
+ /**
813
+ * Reset role hoist positions. DELETE /guilds/{id}/roles/hoist-positions.
814
+ */
815
+ resetRoleHoistPositions(): Promise<APIRole[]>;
816
+ /**
817
+ * Update channel positions.
818
+ * @param updates - Array of { id, position?, parent_id?, lock_permissions? }
819
+ * Requires Manage Channels permission.
820
+ */
821
+ setChannelPositions(updates: Array<{
822
+ id: string;
823
+ position?: number;
824
+ parent_id?: string | null;
825
+ lock_permissions?: boolean;
826
+ }>): Promise<void>;
445
827
  /**
446
- * Fetch pinned messages in this DM channel.
447
- * @returns Pinned messages
828
+ * Fetch all emojis in this guild.
829
+ * @returns Array of GuildEmoji objects (cached in guild.emojis)
448
830
  */
449
- fetchPinnedMessages(): Promise<Message[]>;
831
+ fetchEmojis(): Promise<GuildEmoji[]>;
450
832
  /**
451
- * Fetch a message by ID from this DM channel.
452
- * @param messageId - Snowflake of the message
453
- * @returns The message, or null if not found
454
- * @deprecated Use channel.messages.fetch(messageId) instead.
833
+ * Fetch a single emoji by ID.
834
+ * @param emojiId - The emoji ID to fetch
835
+ * @returns The guild emoji
836
+ * @throws FluxerError if emoji not found (404)
455
837
  */
456
- fetchMessage(messageId: string): Promise<Message>;
838
+ fetchEmoji(emojiId: string): Promise<GuildEmoji>;
457
839
  /**
458
- * Add a recipient to this Group DM. Requires Group DM (type GroupDM).
459
- * PUT /channels/{id}/recipients/{userId}.
840
+ * Bulk create emojis. POST /guilds/{id}/emojis/bulk.
841
+ * @param emojis - Array of { name, image } (base64), 1-50 emojis
842
+ * @returns Array of created GuildEmoji objects
460
843
  */
461
- addRecipient(userId: string): Promise<void>;
844
+ createEmojisBulk(emojis: Array<{
845
+ name: string;
846
+ image: string;
847
+ }>): Promise<GuildEmoji[]>;
462
848
  /**
463
- * Remove a recipient from this Group DM. Requires Group DM (type GroupDM).
464
- * DELETE /channels/{id}/recipients/{userId}.
465
- * @param options - silent: if true, does not send a system message (default false)
849
+ * Bulk create stickers. POST /guilds/{id}/stickers/bulk.
850
+ * @param stickers - Array of { name, image, description?, tags? }, 1-50 stickers
851
+ * @returns Array of created GuildSticker objects
466
852
  */
467
- removeRecipient(userId: string, options?: {
468
- silent?: boolean;
469
- }): Promise<void>;
853
+ createStickersBulk(stickers: Array<{
854
+ name: string;
855
+ image: string;
856
+ description?: string;
857
+ tags?: string[];
858
+ }>): Promise<GuildSticker[]>;
470
859
  }
471
860
 
472
861
  /** Represents a reaction added to or removed from a message. */
@@ -537,6 +926,12 @@ interface MessageEditOptions {
537
926
  /** New embeds (replaces existing) */
538
927
  embeds?: (APIEmbed | EmbedBuilder)[];
539
928
  }
929
+ type MessagePayload = {
930
+ files?: ResolvedMessageFile[];
931
+ body: SendBodyResult & {
932
+ referenced_message?: APIMessageReference;
933
+ };
934
+ };
540
935
 
541
936
  /** Represents a message in a channel. */
542
937
  declare class Message extends Base {
@@ -569,743 +964,477 @@ declare class Message extends Base {
569
964
  readonly mentionRoles: string[];
570
965
  /** Client-side nonce for acknowledgment. Null if not provided. */
571
966
  readonly nonce: string | null;
572
- /** Channel where this message was sent. Resolved from cache; null if not cached (e.g. DM channel not in cache). */
573
- get channel(): Channel | null;
574
- /** Guild where this message was sent. Resolved from cache; null for DMs or if not cached. */
575
- get guild(): Guild | null;
576
- /**
577
- * Resolve the channel (from cache or API). Use when you need the channel and it may not be cached.
578
- * @returns The channel
579
- * @throws FluxerError with CHANNEL_NOT_FOUND if the channel does not exist
580
- */
581
- resolveChannel(): Promise<Channel>;
582
- /**
583
- * Resolve the guild (from cache or API). Returns null for DMs.
584
- * @returns The guild, or null if this is a DM or guild not found
585
- */
586
- resolveGuild(): Promise<Guild | null>;
587
- /** @param data - API message from POST/PATCH /channels/{id}/messages or gateway MESSAGE_CREATE */
588
- constructor(client: Client, data: APIMessage);
589
- /**
590
- * Send a message to this channel without replying. Use when you want a standalone message.
591
- * @param options - Text content or object with content, embeds, and/or files
592
- * @example
593
- * await message.send('Pong!');
594
- * await message.send({ embeds: [embed] }); // EmbedBuilder auto-converted
595
- * await message.send({ content: 'File', files: [{ name: 'data.txt', data }] });
596
- */
597
- send(options: MessageSendOptions): Promise<Message>;
598
- /**
599
- * Send a message to a specific channel. Use for logging, forwarding, or sending to another channel in the guild.
600
- * @param channelId - Snowflake of the target channel (e.g. log channel ID)
601
- * @param options - Text content or object with content and/or embeds
602
- * @example
603
- * await message.sendTo(logChannelId, 'User ' + message.author.username + ' said: ' + message.content);
604
- * await message.sendTo(announceChannelId, { embeds: [embed] });
605
- */
606
- sendTo(channelId: string, options: MessageSendOptions): Promise<Message>;
607
- /**
608
- * Reply to this message (shows as a reply in the client).
609
- * @param options - Text content or object with content, embeds, and/or files
610
- * @example
611
- * await message.reply('Pong!');
612
- * await message.reply({ embeds: [embed] });
613
- */
614
- reply(options: MessageSendOptions): Promise<Message>;
615
- /**
616
- * Edit this message. Only the author (or admins) can edit.
617
- * @param options - New content and/or embeds
618
- */
619
- edit(options: MessageEditOptions): Promise<Message>;
620
- /**
621
- * Create a reaction collector for this message.
622
- * Collects reactions matching the filter until time expires or max is reached.
623
- * @param options - Filter, time (ms), and max count
624
- * @example
625
- * const collector = message.createReactionCollector({ filter: (r, u) => u.id === userId, time: 10000 });
626
- * collector.on('collect', (reaction, user) => console.log(user.username, 'reacted with', reaction.emoji.name));
627
- * collector.on('end', (collected, reason) => { ... });
628
- */
629
- createReactionCollector(options?: ReactionCollectorOptions): ReactionCollector;
630
- /**
631
- * Re-fetch this message from the API to get the latest content, embeds, reactions, etc.
632
- * Use when you have a stale Message (e.g. from an old event or cache) and need fresh data.
633
- * @returns The updated message
634
- * @throws FluxerError with MESSAGE_NOT_FOUND if the message was deleted or does not exist
635
- * @example
636
- * const updated = await message.fetch();
637
- * console.log('Latest content:', updated.content);
638
- */
639
- fetch(): Promise<Message>;
640
- /** Delete this message. */
641
- delete(): Promise<void>;
642
- /**
643
- * Delete a specific attachment from this message.
644
- * DELETE /channels/{id}/messages/{id}/attachments/{attachmentId}.
645
- */
646
- deleteAttachment(attachmentId: string): Promise<void>;
647
- /** Pin this message to the channel. Requires Manage Messages permission. */
648
- pin(): Promise<void>;
649
- /** Unpin this message from the channel. Requires Manage Messages permission. */
650
- unpin(): Promise<void>;
651
- /**
652
- * Format emoji for reaction API: unicode string or "name:id" for custom.
653
- * For string resolution (e.g. :name:), use client.resolveEmoji; Message methods resolve automatically when guildId is available.
654
- */
655
- private static formatEmoji;
656
- private resolveEmojiForReaction;
657
- /**
658
- * Add a reaction to this message (as the bot).
659
- * @param emoji - Unicode emoji, custom `{ name, id }`, `:name:`, `name:id`, or `<:name:id>`
660
- */
661
- react(emoji: string | {
662
- name: string;
663
- id?: string;
664
- animated?: boolean;
665
- }): Promise<void>;
666
- /**
667
- * Remove the bot's reaction, or a specific user's reaction if userId is provided.
668
- * @param emoji - Unicode emoji, custom `{ name, id }`, `:name:`, `name:id`, or `<:name:id>`
669
- * @param userId - If provided, removes that user's reaction (requires moderator permissions)
670
- */
671
- removeReaction(emoji: string | {
672
- name: string;
673
- id?: string;
674
- animated?: boolean;
675
- }, userId?: string): Promise<void>;
676
- /**
677
- * Remove all reactions from this message.
678
- * Requires moderator permissions.
679
- */
680
- removeAllReactions(): Promise<void>;
681
- /**
682
- * Remove all reactions of a specific emoji from this message.
683
- * @param emoji - Unicode emoji, custom `{ name, id }`, `:name:`, `name:id`, or `<:name:id>`. Requires moderator permissions.
684
- */
685
- removeReactionEmoji(emoji: string | {
686
- name: string;
687
- id?: string;
688
- animated?: boolean;
689
- }): Promise<void>;
690
- /**
691
- * Fetch users who reacted with the given emoji.
692
- * @param emoji - Unicode emoji or custom `{ name, id }`
693
- * @param options - limit (1–100), after (user ID for pagination)
694
- * @returns Array of User objects
695
- */
696
- fetchReactionUsers(emoji: string | {
697
- name: string;
698
- id?: string;
699
- animated?: boolean;
700
- }, options?: {
701
- limit?: number;
702
- after?: string;
703
- }): Promise<User[]>;
704
- }
705
-
706
- /** Represents a user (or bot) on Fluxer. */
707
- declare class User extends Base {
708
- readonly client: Client;
709
- readonly id: string;
710
- username: string;
711
- discriminator: string;
712
- globalName: string | null;
713
- avatar: string | null;
714
- readonly bot: boolean;
715
- /** RGB avatar color (e.g. 7577782). Null if not set. */
716
- avatarColor: number | null;
717
- /** Public flags bitfield. Null if not set. */
718
- flags: number | null;
719
- /** Whether this is an official system user. */
720
- readonly system: boolean;
721
- /** Banner hash (from profile, member, or invite context). Null when not available. */
722
- banner: string | null;
723
- /** @param data - API user from message author, GET /users/{id}, or GET /users/@me */
724
- constructor(client: Client, data: APIUserPartial);
725
- /** Update mutable fields from fresh API data. Used by getOrCreateUser cache. */
726
- _patch(data: APIUserPartial): void;
727
- /**
728
- * Get the URL for this user's avatar.
729
- * Auto-detects animated avatars (hash starting with `a_`) and uses gif extension.
730
- * @param options - Optional `size` and `extension` (default: png, or gif for animated)
731
- */
732
- avatarURL(options?: {
733
- size?: number;
734
- extension?: string;
735
- }): string | null;
736
- /** Get the avatar URL, or the default avatar if none set (Fluxer: fluxerstatic.com). */
737
- displayAvatarURL(options?: {
738
- size?: number;
739
- extension?: string;
740
- }): string;
741
- /**
742
- * Get the URL for this user's banner.
743
- * Returns null if the user has no banner (only available when fetched from profile/member context).
744
- */
745
- bannerURL(options?: {
746
- size?: number;
747
- extension?: string;
748
- }): string | null;
749
- /** Returns a mention string (e.g. `<@123456>`). */
750
- toString(): string;
751
- /**
752
- * Create or get a DM channel with this user.
753
- * Returns the DM channel; use {@link DMChannel.send} to send messages.
754
- */
755
- createDM(): Promise<DMChannel>;
756
- /**
757
- * Send a DM to this user.
758
- * Convenience method that creates the DM channel and sends the message.
759
- */
760
- send(options: MessageSendOptions): Promise<Message>;
761
- }
762
-
763
- /** Represents a member of a guild. */
764
- declare class GuildMember extends Base {
765
- readonly client: Client;
766
- readonly id: string;
767
- readonly user: User;
768
- readonly guild: Guild;
769
- nick: string | null;
770
- readonly roles: string[];
771
- readonly joinedAt: Date;
772
- communicationDisabledUntil: Date | null;
773
- readonly mute: boolean;
774
- readonly deaf: boolean;
775
- readonly avatar: string | null;
776
- readonly banner: string | null;
777
- readonly accentColor: number | null;
778
- readonly profileFlags: number | null;
779
- /** @param data - API guild member from GET /guilds/{id}/members or GET /guilds/{id}/members/{user_id} */
780
- constructor(client: Client, data: APIGuildMember & {
781
- guild_id?: string;
782
- }, guild: Guild);
783
- /** Nickname, or global name, or username. */
784
- get displayName(): string;
785
- /**
786
- * Get the guild-specific avatar URL for this member.
787
- * Returns null if the member has no guild avatar (use displayAvatarURL for fallback).
788
- */
789
- avatarURL(options?: {
790
- size?: number;
791
- extension?: string;
792
- }): string | null;
793
967
  /**
794
- * Get the avatar URL to display for this member.
795
- * Uses guild-specific avatar if set, otherwise falls back to the user's avatar.
968
+ * Channel where this message was sent. Resolved from cache; null if not cached.
969
+ * Messages can only exist in text-based channels (text, DM, announcement), so this always has send() when non-null.
796
970
  */
797
- displayAvatarURL(options?: {
798
- size?: number;
799
- extension?: string;
800
- }): string;
971
+ get channel(): (TextChannel | DMChannel | GuildChannel) | null;
972
+ /** Guild where this message was sent. Resolved from cache; null for DMs or if not cached. */
973
+ get guild(): Guild | null;
801
974
  /**
802
- * Get the guild-specific banner URL for this member.
803
- * Returns null if the member has no guild banner.
975
+ * Resolve the channel (from cache or API). Use when you need the channel and it may not be cached.
976
+ * @returns The channel
977
+ * @throws FluxerError with CHANNEL_NOT_FOUND if the channel does not exist
804
978
  */
805
- bannerURL(options?: {
806
- size?: number;
807
- extension?: string;
808
- }): string | null;
979
+ resolveChannel(): Promise<Channel>;
809
980
  /**
810
- * Add a role to this member.
811
- * @param roleId - The role ID to add
812
- * Requires Manage Roles permission.
981
+ * Resolve the guild (from cache or API). Returns null for DMs.
982
+ * @returns The guild, or null if this is a DM or guild not found
813
983
  */
814
- addRole(roleId: string): Promise<void>;
984
+ resolveGuild(): Promise<Guild | null>;
985
+ /** @param data - API message from POST/PATCH /channels/{id}/messages or gateway MESSAGE_CREATE */
986
+ constructor(client: Client, data: APIMessage);
815
987
  /**
816
- * Remove a role from this member.
817
- * @param roleId - The role ID to remove
818
- * Requires Manage Roles permission.
988
+ * Send a message to this channel without replying. Use when you want a standalone message.
989
+ * @param options - Text content or object with content, embeds, and/or files
990
+ * @example
991
+ * await message.send('Pong!');
992
+ * await message.send({ embeds: [embed] }); // EmbedBuilder auto-converted
993
+ * await message.send({ content: 'File', files: [{ name: 'data.txt', data }] });
819
994
  */
820
- removeRole(roleId: string): Promise<void>;
995
+ send(options: string | MessageSendOptions): Promise<Message>;
821
996
  /**
822
- * Edit this guild member. PATCH /guilds/{id}/members/{userId} or /members/@me for the bot.
823
- * For @me: nick, avatar, banner, bio, pronouns, accent_color, profile_flags, mute, deaf,
824
- * communication_disabled_until, timeout_reason, channel_id, connection_id.
825
- * For other members: same plus roles (array of role IDs).
997
+ * Send a message to a specific channel. Use for logging, forwarding, or sending to another channel in the guild.
998
+ * @param channelId - Snowflake of the target channel (e.g. log channel ID)
999
+ * @param options - Text content or object with content and/or embeds
1000
+ * @example
1001
+ * await message.sendTo(logChannelId, 'User ' + message.author.username + ' said: ' + message.content);
1002
+ * await message.sendTo(announceChannelId, { embeds: [embed] });
826
1003
  */
827
- edit(options: {
828
- nick?: string | null;
829
- roles?: string[];
830
- avatar?: string | null;
831
- banner?: string | null;
832
- bio?: string | null;
833
- pronouns?: string | null;
834
- accent_color?: number | null;
835
- profile_flags?: number | null;
836
- mute?: boolean;
837
- deaf?: boolean;
838
- communication_disabled_until?: string | null;
839
- timeout_reason?: string | null;
840
- channel_id?: string | null;
841
- connection_id?: string | null;
842
- }): Promise<this>;
1004
+ sendTo(channelId: string, options: MessageSendOptions): Promise<Message>;
843
1005
  /**
844
- * Get the member's guild-level permissions (from roles only, no channel overwrites).
845
- * Use this for server-wide permission checks (e.g. ban, kick, manage roles).
846
- * @returns Object with has(permission) to check specific permissions
1006
+ * Reply to this message (shows as a reply in the client).
1007
+ * @param options - Text content or object with content, embeds, and/or files
847
1008
  * @example
848
- * const perms = member.permissions;
849
- * if (perms.has(PermissionFlags.BanMembers)) { ... }
1009
+ * await message.reply('Pong!');
1010
+ * await message.reply({ embeds: [embed] });
850
1011
  */
851
- get permissions(): {
852
- has(permission: PermissionResolvable): boolean;
853
- };
1012
+ reply(options: string | MessageSendOptions): Promise<Message>;
1013
+ /** Exposed for testing purposes, use Message.reply() or send() for normal use */
1014
+ static _createMessageBody(content: string | MessageSendOptions, referenced_message?: {
1015
+ channel_id: string;
1016
+ message_id: string;
1017
+ guild_id?: string;
1018
+ }): Promise<MessagePayload>;
1019
+ _send(payload: MessagePayload): Promise<Message>;
854
1020
  /**
855
- * Compute the member's effective permissions in a guild channel.
856
- * Applies role permissions and channel overwrites.
857
- * @param channel - The guild channel to check permissions for
858
- * @returns Object with has(permission) to check specific permissions
859
- * @example
860
- * const perms = member.permissionsIn(channel);
861
- * if (perms.has(PermissionFlags.SendMessages)) { ... }
1021
+ * Edit this message. Only the author (or admins) can edit.
1022
+ * @param options - New content and/or embeds
862
1023
  */
863
- permissionsIn(channel: GuildChannel): {
864
- has(permission: PermissionResolvable): boolean;
865
- };
866
- private _computeBasePermissions;
867
- }
868
-
869
- /**
870
- * Manages guild members with a Collection-like API.
871
- * Extends Collection so you can use .get(), .set(), .filter(), etc.
872
- * Provides guild.members.me for Discord.js parity.
873
- */
874
- declare class GuildMemberManager extends Collection<string, GuildMember> {
875
- private readonly guild;
876
- constructor(guild: Guild);
1024
+ edit(options: MessageEditOptions): Promise<Message>;
877
1025
  /**
878
- * Get a guild member from cache or fetch from the API if not present.
879
- * Convenience helper to avoid repeating `guild.members.get(userId) ?? (await guild.fetchMember(userId))`.
880
- * @param userId - Snowflake of the user
881
- * @returns The guild member
882
- * @throws FluxerError with MEMBER_NOT_FOUND if user is not in the guild (404)
1026
+ * Create a reaction collector for this message.
1027
+ * Collects reactions matching the filter until time expires or max is reached.
1028
+ * @param options - Filter, time (ms), and max count
883
1029
  * @example
884
- * const member = await guild.members.resolve(userId);
885
- * console.log(member.displayName);
1030
+ * const collector = message.createReactionCollector({ filter: (r, u) => u.id === userId, time: 10000 });
1031
+ * collector.on('collect', (reaction, user) => console.log(user.username, 'reacted with', reaction.emoji.name));
1032
+ * collector.on('end', (collected, reason) => { ... });
886
1033
  */
887
- resolve(userId: string): Promise<GuildMember>;
1034
+ createReactionCollector(options?: ReactionCollectorOptions): ReactionCollector;
888
1035
  /**
889
- * The current bot user as a GuildMember in this guild.
890
- * Returns null if the bot's member is not cached or client.user is null.
891
- * Use fetchMe() to load the bot's member when not cached.
892
- *
1036
+ * Re-fetch this message from the API to get the latest content, embeds, reactions, etc.
1037
+ * Use when you have a stale Message (e.g. from an old event or cache) and need fresh data.
1038
+ * @returns The updated message
1039
+ * @throws FluxerError with MESSAGE_NOT_FOUND if the message was deleted or does not exist
893
1040
  * @example
894
- * const perms = guild.members.me?.permissions;
895
- * if (perms?.has(PermissionFlags.BanMembers)) { ... }
1041
+ * const updated = await message.fetch();
1042
+ * console.log('Latest content:', updated.content);
896
1043
  */
897
- get me(): GuildMember | null;
1044
+ fetch(): Promise<Message>;
1045
+ /** Delete this message. */
1046
+ delete(): Promise<void>;
898
1047
  /**
899
- * Fetch the current bot user as a GuildMember in this guild.
900
- * Caches the result in guild.members.
901
- *
902
- * @throws Error if client.user is null (client not ready)
903
- * @example
904
- * const me = await guild.members.fetchMe();
905
- * console.log(me.displayName);
1048
+ * Delete a specific attachment from this message.
1049
+ * DELETE /channels/{id}/messages/{id}/attachments/{attachmentId}.
906
1050
  */
907
- fetchMe(): Promise<GuildMember>;
1051
+ deleteAttachment(attachmentId: string): Promise<void>;
1052
+ /** Pin this message to the channel. Requires Manage Messages permission. */
1053
+ pin(): Promise<void>;
1054
+ /** Unpin this message from the channel. Requires Manage Messages permission. */
1055
+ unpin(): Promise<void>;
908
1056
  /**
909
- * Fetch guild members with pagination. GET /guilds/{id}/members.
910
- * @param options - limit (1-1000), after (user ID for pagination)
911
- * @returns Array of GuildMember objects (cached in guild.members)
1057
+ * Format emoji for reaction API: unicode string or "name:id" for custom.
1058
+ * For string resolution (e.g. :name:), use client.resolveEmoji; Message methods resolve automatically when guildId is available.
912
1059
  */
913
- fetch(options?: {
914
- limit?: number;
915
- after?: string;
916
- }): Promise<GuildMember[]>;
917
- }
918
-
919
- /** Represents a role in a guild. */
920
- declare class Role extends Base {
921
- readonly client: Client;
922
- readonly id: string;
923
- readonly guildId: string;
924
- name: string;
925
- color: number;
926
- position: number;
927
- permissions: string;
928
- hoist: boolean;
929
- mentionable: boolean;
930
- unicodeEmoji: string | null;
931
- /** Separately sorted position for hoisted roles. Null if not set. */
932
- hoistPosition: number | null;
933
- /** @param client - The client instance */
934
- /** @param data - API role from GET /guilds/{id}/roles or gateway role events */
935
- /** @param guildId - The guild this role belongs to */
936
- constructor(client: Client, data: APIRole, guildId: string);
937
- /** Update mutable fields from fresh API data. Used by edit and gateway events. */
938
- _patch(data: Partial<APIRole>): void;
939
- /** Returns a mention string (e.g. `<@&123456>`). */
940
- toString(): string;
1060
+ private static formatEmoji;
1061
+ private resolveEmojiForReaction;
941
1062
  /**
942
- * Check if this role has a permission. Administrator grants all permissions.
943
- * @param permission - Permission flag, name, or resolvable
944
- * @returns true if the role has the permission
945
- * @example
946
- * if (role.has(PermissionFlags.BanMembers)) { ... }
947
- * if (role.has('ManageChannels')) { ... }
1063
+ * Add a reaction to this message (as the bot).
1064
+ * @param emoji - Unicode emoji, custom `{ name, id }`, `:name:`, `name:id`, or `<:name:id>`
948
1065
  */
949
- has(permission: PermissionResolvable): boolean;
1066
+ react(emoji: string | {
1067
+ name: string;
1068
+ id?: string;
1069
+ animated?: boolean;
1070
+ }): Promise<void>;
950
1071
  /**
951
- * Edit this role.
952
- * Requires Manage Roles permission.
953
- * @param options - Role updates (permissions accepts PermissionResolvable for convenience)
954
- * @returns This role (updated in place)
955
- * @example
956
- * await role.edit({ name: 'Moderator', permissions: ['BanMembers', 'KickMembers'] });
1072
+ * Remove the bot's reaction, or a specific user's reaction if userId is provided.
1073
+ * @param emoji - Unicode emoji, custom `{ name, id }`, `:name:`, `name:id`, or `<:name:id>`
1074
+ * @param userId - If provided, removes that user's reaction (requires moderator permissions)
957
1075
  */
958
- edit(options: RESTUpdateRoleBody & {
959
- permissions?: string | PermissionResolvable;
960
- }): Promise<Role>;
1076
+ removeReaction(emoji: string | {
1077
+ name: string;
1078
+ id?: string;
1079
+ animated?: boolean;
1080
+ }, userId?: string): Promise<void>;
961
1081
  /**
962
- * Delete this role.
963
- * Requires Manage Roles permission.
1082
+ * Remove all reactions from this message.
1083
+ * Requires moderator permissions.
1084
+ */
1085
+ removeAllReactions(): Promise<void>;
1086
+ /**
1087
+ * Remove all reactions of a specific emoji from this message.
1088
+ * @param emoji - Unicode emoji, custom `{ name, id }`, `:name:`, `name:id`, or `<:name:id>`. Requires moderator permissions.
1089
+ */
1090
+ removeReactionEmoji(emoji: string | {
1091
+ name: string;
1092
+ id?: string;
1093
+ animated?: boolean;
1094
+ }): Promise<void>;
1095
+ /**
1096
+ * Fetch users who reacted with the given emoji.
1097
+ * @param emoji - Unicode emoji or custom `{ name, id }`
1098
+ * @param options - limit (1–100), after (user ID for pagination)
1099
+ * @returns Array of User objects
1100
+ */
1101
+ fetchReactionUsers(emoji: string | {
1102
+ name: string;
1103
+ id?: string;
1104
+ animated?: boolean;
1105
+ }, options?: {
1106
+ limit?: number;
1107
+ after?: string;
1108
+ }): Promise<User[]>;
1109
+ }
1110
+
1111
+ /**
1112
+ * Manages messages for a channel. Access via channel.messages.
1113
+ * @example
1114
+ * const message = await channel.messages.fetch(messageId);
1115
+ * if (message) await message.edit({ content: 'Updated!' });
1116
+ */
1117
+ declare class MessageManager {
1118
+ private readonly client;
1119
+ private readonly channelId;
1120
+ constructor(client: Client, channelId: string);
1121
+ /**
1122
+ * Fetch a message by ID from this channel.
1123
+ * @param messageId - Snowflake of the message
1124
+ * @returns The message
1125
+ * @throws FluxerError with MESSAGE_NOT_FOUND if the message does not exist
964
1126
  */
965
- delete(): Promise<void>;
1127
+ fetch(messageId: string): Promise<Message>;
966
1128
  }
967
1129
 
968
- /** Represents a ban in a guild. */
969
- declare class GuildBan extends Base {
1130
+ interface MessageCollectorOptions {
1131
+ /** Filter function. Return true to collect the message. */
1132
+ filter?: (message: Message) => boolean;
1133
+ /** Max duration in ms. Collector stops when time expires. */
1134
+ time?: number;
1135
+ /** Max messages to collect. Collector stops when limit reached. */
1136
+ max?: number;
1137
+ }
1138
+ type MessageCollectorEndReason = 'time' | 'limit' | 'user';
1139
+ interface MessageCollectorEvents {
1140
+ collect: [message: Message];
1141
+ end: [collected: Collection<string, Message>, reason: MessageCollectorEndReason];
1142
+ }
1143
+ /**
1144
+ * Collects messages in a channel. Use channel.createMessageCollector().
1145
+ * @example
1146
+ * const collector = channel.createMessageCollector({ filter: m => m.author.id === userId, time: 10000 });
1147
+ * collector.on('collect', m => console.log(m.content));
1148
+ * collector.on('end', (collected, reason) => console.log(`Stopped: ${reason}`));
1149
+ */
1150
+ declare class MessageCollector extends EventEmitter {
970
1151
  readonly client: Client;
971
- readonly guildId: string;
972
- readonly user: User;
973
- readonly reason: string | null;
974
- /** ISO timestamp when a temporary ban expires. Null for permanent bans. */
1152
+ readonly channelId: string;
1153
+ readonly options: Required<MessageCollectorOptions>;
1154
+ readonly collected: Collection<string, Message>;
1155
+ private _timeout;
1156
+ private _ended;
1157
+ private _listener;
1158
+ constructor(client: Client, channelId: string, options?: MessageCollectorOptions);
1159
+ stop(reason?: MessageCollectorEndReason): void;
1160
+ on<K extends keyof MessageCollectorEvents>(event: K, listener: (...args: MessageCollectorEvents[K]) => void): this;
1161
+ emit<K extends keyof MessageCollectorEvents>(event: K, ...args: MessageCollectorEvents[K]): boolean;
1162
+ }
1163
+
1164
+ /** Represents an invite to a guild or channel. */
1165
+ declare class Invite extends Base {
1166
+ readonly client: Client;
1167
+ readonly code: string;
1168
+ readonly type: number;
1169
+ readonly guild: APIGuildPartial;
1170
+ readonly channel: APIChannelPartial;
1171
+ readonly inviter: User | null;
1172
+ readonly memberCount: number | null;
1173
+ readonly presenceCount: number | null;
975
1174
  readonly expiresAt: string | null;
976
- /** @param data - API ban from GET /guilds/{id}/bans or gateway GUILD_BAN_ADD */
977
- constructor(client: Client, data: APIBan & {
978
- guild_id?: string;
979
- }, guildId: string);
1175
+ readonly temporary: boolean | null;
1176
+ readonly createdAt: string | null;
1177
+ readonly uses: number | null;
1178
+ readonly maxUses: number | null;
1179
+ readonly maxAge: number | null;
1180
+ /** @param data - API invite from GET /invites/{code}, channel/guild invite list, or gateway INVITE_CREATE */
1181
+ constructor(client: Client, data: APIInvite);
1182
+ /** Full invite URL (https://fluxer.gg/{code} or instance-specific). */
1183
+ get url(): string;
980
1184
  /**
981
- * Remove this ban (unban the user).
982
- * Requires Ban Members permission.
1185
+ * Resolve the guild from cache if available.
1186
+ * @returns The guild, or null if not cached
983
1187
  */
984
- unban(): Promise<void>;
1188
+ getGuild(): Guild | null;
1189
+ /**
1190
+ * Delete this invite.
1191
+ * Requires Manage Guild or Create Instant Invite permission.
1192
+ */
1193
+ delete(): Promise<void>;
985
1194
  }
986
1195
 
987
- /** Represents a Fluxer guild (server). */
988
- declare class Guild extends Base {
1196
+ /** Base class for all channel types. */
1197
+ declare abstract class Channel extends Base {
1198
+ /** Whether this channel has a send method (TextChannel, DMChannel). */
1199
+ isTextBased(): this is TextChannel | DMChannel;
1200
+ /** Whether this channel is a DM or Group DM. */
1201
+ isDM(): this is DMChannel;
1202
+ /** Whether this channel is voice-based (VoiceChannel). */
1203
+ isVoice(): this is VoiceChannel;
1204
+ isLink(): this is LinkChannel;
1205
+ /** Create a DM channel from API data (type DM or GroupDM). */
1206
+ static createDM(client: Client, data: APIChannelPartial): DMChannel;
989
1207
  readonly client: Client;
990
1208
  readonly id: string;
991
- name: string;
1209
+ type: ChannelType;
1210
+ /** Channel name. Guild channels and Group DMs have names; 1:1 DMs are typically null. */
1211
+ name: string | null;
1212
+ /** Channel icon hash (Group DMs). Null if none. */
992
1213
  icon: string | null;
993
- banner: string | null;
994
- readonly ownerId: string;
995
- /** Invite splash image hash. Null if none. */
996
- splash: string | null;
997
- /** Custom vanity URL code (e.g. fluxer.gg/code). Null if none. */
998
- vanityURLCode: string | null;
999
- /** Enabled guild features. */
1000
- features: GuildFeature[];
1001
- verificationLevel: GuildVerificationLevel;
1002
- defaultMessageNotifications: DefaultMessageNotifications;
1003
- explicitContentFilter: GuildExplicitContentFilter;
1004
- /** AFK voice channel ID. Null if none. */
1005
- afkChannelId: string | null;
1006
- /** AFK timeout in seconds. */
1007
- afkTimeout: number;
1008
- /** System messages channel ID. Null if none. */
1009
- systemChannelId: string | null;
1010
- /** Rules/guidelines channel ID. Null if none. */
1011
- rulesChannelId: string | null;
1012
- nsfwLevel: number;
1013
- mfaLevel: GuildMFALevel;
1014
- /** Banner image width. Optional. */
1015
- bannerWidth?: number | null;
1016
- /** Banner image height. Optional. */
1017
- bannerHeight?: number | null;
1018
- /** Splash image width. Optional. */
1019
- splashWidth?: number | null;
1020
- /** Splash image height. Optional. */
1021
- splashHeight?: number | null;
1022
- members: GuildMemberManager;
1023
- channels: Collection<string, GuildChannel>;
1024
- roles: Collection<string, Role>;
1025
- /** @param data - API guild from GET /guilds/{id} or gateway GUILD_CREATE */
1026
- constructor(client: Client, data: APIGuild & {
1027
- roles?: APIRole[];
1028
- ownerId?: string;
1029
- });
1030
- /** Get the guild icon URL, or null if no icon. */
1031
- iconURL(options?: {
1032
- size?: number;
1033
- }): string | null;
1034
- /** Get the guild banner URL, or null if no banner. */
1035
- bannerURL(options?: {
1036
- size?: number;
1037
- }): string | null;
1038
- /** Get the guild splash (invite background) URL, or null if no splash. */
1039
- splashURL(options?: {
1040
- size?: number;
1041
- }): string | null;
1214
+ /** ISO timestamp when the last message was pinned. Null if never pinned. */
1215
+ lastPinTimestamp: string | null;
1216
+ /** @param data - API channel from GET /channels/{id} or GET /guilds/{id}/channels */
1217
+ constructor(client: Client, data: APIChannelPartial);
1042
1218
  /**
1043
- * Add a role to a member by user ID. Does not require fetching the member first.
1044
- * @param userId - The user ID of the member
1045
- * @param roleId - The role ID to add (or use guild.resolveRoleId for mention/name resolution)
1046
- * Requires Manage Roles permission.
1219
+ * Create the appropriate channel subclass from API data.
1220
+ * @param client - The client instance
1221
+ * @param data - Channel data from the API
1047
1222
  */
1048
- addRoleToMember(userId: string, roleId: string): Promise<void>;
1223
+ static from(client: Client, data: APIChannel | APIChannelPartial): GuildChannel | TextChannel | null;
1049
1224
  /**
1050
- * Remove a role from a member by user ID. Does not require fetching the member first.
1051
- * @param userId - The user ID of the member
1052
- * @param roleId - The role ID to remove
1053
- * Requires Manage Roles permission.
1225
+ * Create a channel from API data, including DM and GroupDM.
1226
+ * Used by ChannelManager.fetch() for GET /channels/{id}.
1054
1227
  */
1055
- removeRoleFromMember(userId: string, roleId: string): Promise<void>;
1228
+ static fromOrCreate(client: Client, data: APIChannel | APIChannelPartial): TextChannel | DMChannel | GuildChannel | null;
1056
1229
  /**
1057
- * Create a role in this guild.
1058
- * Requires Manage Roles permission.
1059
- * @param options - Role data (permissions accepts PermissionResolvable for convenience)
1060
- * @returns The created role
1061
- * @example
1062
- * const role = await guild.createRole({ name: 'Mod', permissions: ['KickMembers', 'BanMembers'] });
1230
+ * Bulk delete messages. Requires Manage Messages permission.
1231
+ * @param messageIds - Array of message IDs to delete (2–100)
1063
1232
  */
1064
- createRole(options: RESTCreateRoleBody & {
1065
- permissions?: string | PermissionResolvable;
1066
- }): Promise<Role>;
1233
+ bulkDeleteMessages(messageIds: string[]): Promise<void>;
1067
1234
  /**
1068
- * Fetch all roles in this guild.
1069
- * @returns Array of Role objects (cached in guild.roles)
1235
+ * Send a typing indicator to the channel. Lasts ~10 seconds.
1070
1236
  */
1071
- fetchRoles(): Promise<Role[]>;
1237
+ sendTyping(): Promise<void>;
1072
1238
  /**
1073
- * Fetch a role by ID.
1074
- * @param roleId - The role ID to fetch
1075
- * @returns The role
1076
- * @throws FluxerError with ROLE_NOT_FOUND if role does not exist (404)
1239
+ * Whether the bot can send messages in this channel.
1240
+ * For DMs: always true (when the channel exists).
1241
+ * For guild channels: checks ViewChannel and SendMessages permissions via guild.members.me.
1077
1242
  */
1078
- fetchRole(roleId: string): Promise<Role>;
1243
+ canSendMessage(): boolean;
1244
+ }
1245
+ declare class GuildChannel extends Channel {
1246
+ readonly guildId: string;
1247
+ name: string | null;
1248
+ position?: number;
1249
+ parentId: string | null;
1250
+ /** Permission overwrites for roles and members. */
1251
+ permissionOverwrites: APIChannelOverwrite[];
1252
+ constructor(client: Client, data: APIChannel);
1079
1253
  /**
1080
- * Resolve a role ID from an argument (role mention, raw ID, or name).
1081
- * Fetches guild roles if name is provided.
1082
- * @param arg - Role mention (@role), role ID, or role name
1083
- * @returns The role ID, or null if not found
1254
+ * Create a webhook in this channel.
1255
+ * @param options - Webhook name and optional avatar URL
1256
+ * @returns The webhook with token (required for send()). Requires Manage Webhooks permission.
1084
1257
  */
1085
- resolveRoleId(arg: string): Promise<string | null>;
1258
+ createWebhook(options: {
1259
+ name: string;
1260
+ avatar?: string | null;
1261
+ }): Promise<Webhook>;
1086
1262
  /**
1087
- * Ban a user from this guild.
1088
- * @param userId - The user ID to ban
1089
- * @param options - Optional reason, delete_message_days (0–7), and ban_duration_seconds (temporary ban).
1090
- * ban_duration_seconds: 0 = permanent, or use 3600, 43200, 86400, 259200, 432000, 604800, 1209600, 2592000.
1091
- * Requires Ban Members permission.
1263
+ * Fetch all webhooks in this channel.
1264
+ * @returns Webhooks (includes token when listing from channel; can send via send())
1092
1265
  */
1093
- ban(userId: string, options?: {
1094
- reason?: string;
1095
- delete_message_days?: number;
1096
- ban_duration_seconds?: number;
1097
- }): Promise<void>;
1266
+ fetchWebhooks(): Promise<Webhook[]>;
1098
1267
  /**
1099
- * Fetch guild bans. Requires Ban Members permission.
1100
- * @returns List of GuildBan objects
1268
+ * Create an invite for this channel.
1269
+ * @param options - max_uses (0–100), max_age (0–604800 seconds), unique, temporary
1270
+ * Requires Create Instant Invite permission.
1101
1271
  */
1102
- fetchBans(): Promise<GuildBan[]>;
1272
+ createInvite(options?: {
1273
+ max_uses?: number;
1274
+ max_age?: number;
1275
+ unique?: boolean;
1276
+ temporary?: boolean;
1277
+ }): Promise<Invite>;
1103
1278
  /**
1104
- * Remove a ban (unban a user).
1105
- * @param userId - The user ID to unban
1106
- * Requires Ban Members permission.
1279
+ * Fetch invites for this channel.
1280
+ * Requires Manage Channel permission.
1107
1281
  */
1108
- unban(userId: string): Promise<void>;
1282
+ fetchInvites(): Promise<Invite[]>;
1109
1283
  /**
1110
- * Kick a member from this guild.
1111
- * @param userId - The user ID to kick
1112
- * Requires Kick Members permission.
1284
+ * Set or update a permission overwrite. PUT /channels/{id}/permissions/{overwriteId}.
1285
+ * @param overwriteId - Role or member ID
1286
+ * @param options - type (0=role, 1=member), allow, deny (permission bitfields)
1113
1287
  */
1114
- kick(userId: string): Promise<void>;
1288
+ editPermission(overwriteId: string, options: {
1289
+ type: 0 | 1;
1290
+ allow?: string;
1291
+ deny?: string;
1292
+ }): Promise<void>;
1115
1293
  /**
1116
- * Fetch a guild member by user ID.
1117
- * @param userId - The user ID of the member to fetch
1118
- * @returns The guild member
1119
- * @throws FluxerError with MEMBER_NOT_FOUND if user is not in the guild (404)
1120
- * @throws FluxerError with cause for permission denied (403) or other REST errors
1294
+ * Whether the bot can send messages in this channel.
1295
+ * Checks ViewChannel and SendMessages via guild.members.me permissions.
1296
+ * Returns false if guild or bot member not cached.
1297
+ */
1298
+ canSendMessage(): boolean;
1299
+ /**
1300
+ * Send a message to this guild channel.
1301
+ * Works for text and announcement channels. Voice/category/link channels will fail at the API.
1121
1302
  */
1122
- fetchMember(userId: string): Promise<GuildMember>;
1303
+ send(options: MessageSendOptions): Promise<Message>;
1123
1304
  /**
1124
- * Fetch guild audit logs. Requires View Audit Log permission.
1125
- * @param options - Optional limit, before, after, user_id, action_type for filtering
1305
+ * Remove a permission overwrite. DELETE /channels/{id}/permissions/{overwriteId}.
1126
1306
  */
1127
- fetchAuditLogs(options?: {
1128
- limit?: number;
1129
- before?: string;
1130
- after?: string;
1131
- userId?: string;
1132
- actionType?: number;
1133
- }): Promise<APIGuildAuditLog>;
1134
- /** Fetch all webhooks in this guild. Returned webhooks do not include the token (cannot send). */
1135
- fetchWebhooks(): Promise<Webhook[]>;
1307
+ deletePermission(overwriteId: string): Promise<void>;
1136
1308
  /**
1137
- * Create a channel in this guild.
1138
- * @param data - Channel data: type (0=text, 2=voice, 4=category, 5=link), name, and optional parent_id, topic, bitrate, user_limit, nsfw, permission_overwrites
1139
- * Requires Manage Channels permission.
1309
+ * Edit this channel. PATCH /channels/{id}.
1310
+ * Requires Manage Channel permission.
1140
1311
  */
1141
- createChannel(data: {
1142
- type: 0 | 2 | 4 | 5;
1143
- name: string;
1144
- parent_id?: string | null;
1312
+ edit(options: {
1313
+ name?: string | null;
1145
1314
  topic?: string | null;
1315
+ parent_id?: string | null;
1146
1316
  bitrate?: number | null;
1147
1317
  user_limit?: number | null;
1148
1318
  nsfw?: boolean;
1319
+ rate_limit_per_user?: number;
1320
+ rtc_region?: string | null;
1149
1321
  permission_overwrites?: Array<{
1150
1322
  id: string;
1151
1323
  type: number;
1152
- allow: string;
1153
- deny: string;
1324
+ allow?: string;
1325
+ deny?: string;
1154
1326
  }>;
1155
- }): Promise<GuildChannel>;
1156
- /**
1157
- * Fetch all channels in this guild.
1158
- * @returns Array of GuildChannel objects (cached in guild.channels and client.channels)
1159
- */
1160
- fetchChannels(): Promise<GuildChannel[]>;
1161
- /**
1162
- * Edit this guild. PATCH /guilds/{id}.
1163
- * Requires guild owner or Administrator.
1164
- */
1165
- edit(options: {
1166
- name?: string;
1167
- icon?: string | null;
1168
- system_channel_id?: string | null;
1169
- system_channel_flags?: number;
1170
- afk_channel_id?: string | null;
1171
- afk_timeout?: number;
1172
- default_message_notifications?: DefaultMessageNotifications;
1173
- verification_level?: GuildVerificationLevel;
1174
- mfa_level?: GuildMFALevel;
1175
- explicit_content_filter?: GuildExplicitContentFilter;
1176
- banner?: string | null;
1177
- splash?: string | null;
1178
- embed_splash?: string | null;
1179
- splash_card_alignment?: string;
1180
- features?: GuildFeature[];
1181
1327
  }): Promise<this>;
1182
1328
  /**
1183
- * Delete this guild. POST /guilds/{id}/delete.
1184
- * Must be the guild owner.
1185
- */
1186
- delete(): Promise<void>;
1187
- /**
1188
- * Fetch vanity URL for this guild. GET /guilds/{id}/vanity-url.
1189
- * Requires Manage Guild permission.
1190
- */
1191
- fetchVanityURL(): Promise<APIVanityURL>;
1192
- /**
1193
- * Transfer guild ownership to another user. POST /guilds/{id}/transfer-ownership.
1194
- * Must be the guild owner.
1195
- */
1196
- transferOwnership(newOwnerId: string, password?: string): Promise<void>;
1197
- /**
1198
- * Set text channel flexible names feature. PATCH /guilds/{id}/text-channel-flexible-names.
1329
+ * Delete this channel. Requires Manage Channel permission.
1330
+ * @param options - silent: if true, does not send a system message (default false)
1199
1331
  */
1200
- setTextChannelFlexibleNames(enabled: boolean): Promise<this>;
1332
+ delete(options?: {
1333
+ silent?: boolean;
1334
+ }): Promise<void>;
1335
+ }
1336
+ declare class TextChannel extends GuildChannel {
1337
+ topic?: string | null;
1338
+ nsfw?: boolean;
1339
+ rateLimitPerUser?: number;
1340
+ lastMessageId?: string | null;
1341
+ constructor(client: Client, data: APIChannel);
1201
1342
  /**
1202
- * Set detached banner feature. PATCH /guilds/{id}/detached-banner.
1343
+ * Send a message to this channel.
1344
+ * @param options - Text content or object with content, embeds, and/or files
1203
1345
  */
1204
- setDetachedBanner(enabled: boolean): Promise<this>;
1346
+ send(options: MessageSendOptions): Promise<Message>;
1347
+ /** Message manager for this channel. Use channel.messages.fetch(messageId). */
1348
+ get messages(): MessageManager;
1205
1349
  /**
1206
- * Set disallow unclaimed accounts. PATCH /guilds/{id}/disallow-unclaimed-accounts.
1350
+ * Create a message collector for this channel.
1351
+ * Collects messages matching the filter until time expires or max is reached.
1352
+ * @param options - Filter, time (ms), and max count
1353
+ * @example
1354
+ * const collector = channel.createMessageCollector({ filter: m => m.author.id === userId, time: 10000 });
1355
+ * collector.on('collect', m => console.log(m.content));
1356
+ * collector.on('end', (collected, reason) => { ... });
1207
1357
  */
1208
- setDisallowUnclaimedAccounts(enabled: boolean): Promise<this>;
1358
+ createMessageCollector(options?: MessageCollectorOptions): MessageCollector;
1209
1359
  /**
1210
- * Update role positions. PATCH /guilds/{id}/roles.
1211
- * @param updates - Array of { id, position? }
1360
+ * Fetch pinned messages in this channel.
1361
+ * @returns Pinned messages
1212
1362
  */
1213
- setRolePositions(updates: Array<{
1214
- id: string;
1215
- position?: number;
1216
- }>): Promise<APIRole[]>;
1363
+ fetchPinnedMessages(): Promise<Message[]>;
1217
1364
  /**
1218
- * Update role hoist positions. PATCH /guilds/{id}/roles/hoist-positions.
1365
+ * Fetch a message by ID from this channel.
1366
+ * @param messageId - Snowflake of the message
1367
+ * @returns The message, or null if not found
1368
+ * @deprecated Use channel.messages.fetch(messageId) instead.
1219
1369
  */
1220
- setRoleHoistPositions(updates: Array<{
1221
- id: string;
1222
- hoist_position?: number;
1223
- }>): Promise<APIRole[]>;
1370
+ fetchMessage(messageId: string): Promise<Message>;
1371
+ }
1372
+ declare class CategoryChannel extends GuildChannel {
1373
+ }
1374
+ declare class VoiceChannel extends GuildChannel {
1375
+ bitrate?: number | null;
1376
+ userLimit?: number | null;
1377
+ rtcRegion?: string | null;
1378
+ constructor(client: Client, data: APIChannel);
1379
+ }
1380
+ declare class LinkChannel extends GuildChannel {
1381
+ url: string | null;
1382
+ constructor(client: Client, data: APIChannel);
1383
+ }
1384
+ /** DM channel (direct message between bot and a user). */
1385
+ declare class DMChannel extends Channel {
1386
+ lastMessageId?: string | null;
1387
+ /** Group DM creator ID. Null for 1:1 DMs. */
1388
+ ownerId: string | null;
1389
+ /** Group DM recipients as User objects. Empty for 1:1 DMs. */
1390
+ recipients: User[];
1391
+ /** Group DM member display names (userId -> nickname). */
1392
+ nicks: Record<string, string>;
1393
+ constructor(client: Client, data: APIChannelPartial & Partial<APIChannel>);
1224
1394
  /**
1225
- * Reset role hoist positions. DELETE /guilds/{id}/roles/hoist-positions.
1395
+ * Send a message to this DM channel.
1396
+ * @param options - Text content or object with content, embeds, and/or files
1226
1397
  */
1227
- resetRoleHoistPositions(): Promise<APIRole[]>;
1398
+ send(options: MessageSendOptions): Promise<Message>;
1399
+ /** Message manager for this channel. Use channel.messages.fetch(messageId). */
1400
+ get messages(): MessageManager;
1228
1401
  /**
1229
- * Update channel positions.
1230
- * @param updates - Array of { id, position?, parent_id?, lock_permissions? }
1231
- * Requires Manage Channels permission.
1402
+ * Create a message collector for this DM channel.
1403
+ * @param options - Filter, time (ms), and max count
1232
1404
  */
1233
- setChannelPositions(updates: Array<{
1234
- id: string;
1235
- position?: number;
1236
- parent_id?: string | null;
1237
- lock_permissions?: boolean;
1238
- }>): Promise<void>;
1405
+ createMessageCollector(options?: MessageCollectorOptions): MessageCollector;
1239
1406
  /**
1240
- * Bulk create emojis. POST /guilds/{id}/emojis/bulk.
1241
- * @param emojis - Array of { name, image } (base64), 1-50 emojis
1242
- * @returns Array of created GuildEmoji objects
1407
+ * Fetch pinned messages in this DM channel.
1408
+ * @returns Pinned messages
1243
1409
  */
1244
- createEmojisBulk(emojis: Array<{
1245
- name: string;
1246
- image: string;
1247
- }>): Promise<GuildEmoji[]>;
1410
+ fetchPinnedMessages(): Promise<Message[]>;
1248
1411
  /**
1249
- * Bulk create stickers. POST /guilds/{id}/stickers/bulk.
1250
- * @param stickers - Array of { name, image, description?, tags? }, 1-50 stickers
1251
- * @returns Array of created GuildSticker objects
1412
+ * Fetch a message by ID from this DM channel.
1413
+ * @param messageId - Snowflake of the message
1414
+ * @returns The message, or null if not found
1415
+ * @deprecated Use channel.messages.fetch(messageId) instead.
1252
1416
  */
1253
- createStickersBulk(stickers: Array<{
1254
- name: string;
1255
- image: string;
1256
- description?: string;
1257
- tags?: string[];
1258
- }>): Promise<GuildSticker[]>;
1259
- }
1260
-
1261
- /** Represents an invite to a guild or channel. */
1262
- declare class Invite extends Base {
1263
- readonly client: Client;
1264
- readonly code: string;
1265
- readonly type: number;
1266
- readonly guild: APIGuildPartial;
1267
- readonly channel: APIChannelPartial;
1268
- readonly inviter: User | null;
1269
- readonly memberCount: number | null;
1270
- readonly presenceCount: number | null;
1271
- readonly expiresAt: string | null;
1272
- readonly temporary: boolean | null;
1273
- readonly createdAt: string | null;
1274
- readonly uses: number | null;
1275
- readonly maxUses: number | null;
1276
- readonly maxAge: number | null;
1277
- /** @param data - API invite from GET /invites/{code}, channel/guild invite list, or gateway INVITE_CREATE */
1278
- constructor(client: Client, data: APIInvite);
1279
- /** Full invite URL (https://fluxer.gg/{code} or instance-specific). */
1280
- get url(): string;
1417
+ fetchMessage(messageId: string): Promise<Message>;
1281
1418
  /**
1282
- * Resolve the guild from cache if available.
1283
- * @returns The guild, or null if not cached
1419
+ * Add a recipient to this Group DM. Requires Group DM (type GroupDM).
1420
+ * PUT /channels/{id}/recipients/{userId}.
1284
1421
  */
1285
- getGuild(): Guild | null;
1422
+ addRecipient(userId: string): Promise<void>;
1286
1423
  /**
1287
- * Delete this invite.
1288
- * Requires Manage Guild or Create Instant Invite permission.
1424
+ * Remove a recipient from this Group DM. Requires Group DM (type GroupDM).
1425
+ * DELETE /channels/{id}/recipients/{userId}.
1426
+ * @param options - silent: if true, does not send a system message (default false)
1289
1427
  */
1290
- delete(): Promise<void>;
1291
- }
1292
-
1293
- /** Minimal message data for MessageDelete when the full message is not available. */
1294
- interface PartialMessage {
1295
- id: string;
1296
- channelId: string;
1297
- channel?: Channel | null;
1298
- /** Message content, when provided by the gateway (e.g. Fluxer). */
1299
- content?: string | null;
1300
- /** Author user ID, when provided by the gateway (e.g. Fluxer). */
1301
- authorId?: string | null;
1428
+ removeRecipient(userId: string, options?: {
1429
+ silent?: boolean;
1430
+ }): Promise<void>;
1302
1431
  }
1303
1432
 
1304
1433
  /**
1305
1434
  * Manages channels with fetch and send.
1306
1435
  * Extends Collection so you can use .get(), .set(), .filter(), etc.
1307
1436
  */
1308
- declare class ChannelManager extends Collection<string, Channel> {
1437
+ declare class ChannelManager extends Collection<string, Channel | GuildChannel> {
1309
1438
  private readonly client;
1310
1439
  private readonly maxSize;
1311
1440
  constructor(client: Client);
@@ -1318,7 +1447,7 @@ declare class ChannelManager extends Collection<string, Channel> {
1318
1447
  * @throws FluxerError with CHANNEL_NOT_FOUND if the channel does not exist
1319
1448
  * @example
1320
1449
  * const channel = await client.channels.resolve(message.channelId);
1321
- * if (channel?.isSendable()) await channel.send('Hello!');
1450
+ * if (channel?.isTextBased()) await channel.send('Hello!');
1322
1451
  */
1323
1452
  resolve(channelId: string): Promise<Channel>;
1324
1453
  /**
@@ -1328,7 +1457,7 @@ declare class ChannelManager extends Collection<string, Channel> {
1328
1457
  * @throws FluxerError with CHANNEL_NOT_FOUND if the channel does not exist
1329
1458
  * @example
1330
1459
  * const channel = await client.channels.fetch(channelId);
1331
- * if (channel?.isSendable()) await channel.send('Hello!');
1460
+ * if (channel?.isTextBased()) await channel.send('Hello!');
1332
1461
  */
1333
1462
  fetch(channelId: string): Promise<Channel>;
1334
1463
  /**
@@ -1409,6 +1538,8 @@ interface ClientOptions {
1409
1538
  intents?: number;
1410
1539
  /** Suppress the warning when intents are set (Fluxer does not support intents yet). */
1411
1540
  suppressIntentWarning?: boolean;
1541
+ /** When true, delay the Ready event until all guilds from READY (including unavailable) have been received via GUILD_CREATE. Default: false. */
1542
+ waitForGuilds?: boolean;
1412
1543
  /** Cache size limits (channels, guilds, users). When exceeded, oldest entries are evicted. Omit or 0 = unbounded. */
1413
1544
  cache?: CacheSizeLimits;
1414
1545
  /** Initial presence (status, custom_status, etc.) sent on identify. Can also update via PresenceUpdate after connect. */
@@ -1543,6 +1674,17 @@ declare class UsersManager extends Collection<string, User> {
1543
1674
  }): Promise<FetchedUserWithProfile>;
1544
1675
  }
1545
1676
 
1677
+ /** Minimal message data for MessageDelete when the full message is not available. */
1678
+ interface PartialMessage {
1679
+ id: string;
1680
+ channelId: string;
1681
+ channel?: Channel | null;
1682
+ /** Message content, when provided by the gateway (e.g. Fluxer). */
1683
+ content?: string | null;
1684
+ /** Author user ID, when provided by the gateway (e.g. Fluxer). */
1685
+ authorId?: string | null;
1686
+ }
1687
+
1546
1688
  /**
1547
1689
  * Callback parameter types for client events. Use with client.on(Events.X, handler).
1548
1690
  * @see Events
@@ -1550,10 +1692,7 @@ declare class UsersManager extends Collection<string, User> {
1550
1692
  interface ClientEvents {
1551
1693
  [Events.Ready]: [];
1552
1694
  [Events.MessageCreate]: [message: Message];
1553
- [Events.MessageUpdate]: [
1554
- oldMessage: Message | null,
1555
- newMessage: Message
1556
- ];
1695
+ [Events.MessageUpdate]: [oldMessage: Message | null, newMessage: Message];
1557
1696
  [Events.MessageDelete]: [message: PartialMessage];
1558
1697
  [Events.MessageReactionAdd]: [
1559
1698
  reaction: MessageReaction,
@@ -1573,9 +1712,7 @@ interface ClientEvents {
1573
1712
  ];
1574
1713
  [Events.MessageReactionRemoveAll]: [data: GatewayMessageReactionRemoveAllDispatchData];
1575
1714
  [Events.MessageReactionRemoveEmoji]: [data: GatewayMessageReactionRemoveEmojiDispatchData];
1576
- [Events.InteractionCreate]: [
1577
- interaction: _fluxerjs_types.APIApplicationCommandInteraction
1578
- ];
1715
+ [Events.InteractionCreate]: [interaction: APIApplicationCommandInteraction];
1579
1716
  [Events.GuildCreate]: [guild: Guild];
1580
1717
  [Events.GuildUpdate]: [oldGuild: Guild, newGuild: Guild];
1581
1718
  [Events.GuildDelete]: [guild: Guild];
@@ -1583,10 +1720,7 @@ interface ClientEvents {
1583
1720
  [Events.ChannelUpdate]: [oldChannel: Channel, newChannel: Channel];
1584
1721
  [Events.ChannelDelete]: [channel: Channel];
1585
1722
  [Events.GuildMemberAdd]: [member: GuildMember];
1586
- [Events.GuildMemberUpdate]: [
1587
- oldMember: GuildMember,
1588
- newMember: GuildMember
1589
- ];
1723
+ [Events.GuildMemberUpdate]: [oldMember: GuildMember, newMember: GuildMember];
1590
1724
  [Events.GuildMemberRemove]: [member: GuildMember];
1591
1725
  [Events.VoiceStateUpdate]: [data: GatewayVoiceStateUpdateDispatchData];
1592
1726
  [Events.VoiceServerUpdate]: [data: GatewayVoiceServerUpdateDispatchData];
@@ -1599,25 +1733,23 @@ interface ClientEvents {
1599
1733
  }>;
1600
1734
  }
1601
1735
  ];
1602
- [Events.MessageDeleteBulk]: [
1603
- data: _fluxerjs_types.GatewayMessageDeleteBulkDispatchData
1604
- ];
1736
+ [Events.MessageDeleteBulk]: [data: GatewayMessageDeleteBulkDispatchData];
1605
1737
  [Events.GuildBanAdd]: [ban: GuildBan];
1606
1738
  [Events.GuildBanRemove]: [ban: GuildBan];
1607
1739
  [Events.GuildEmojisUpdate]: [data: GatewayGuildEmojisUpdateDispatchData];
1608
1740
  [Events.GuildStickersUpdate]: [data: GatewayGuildStickersUpdateDispatchData];
1609
1741
  [Events.GuildIntegrationsUpdate]: [data: GatewayGuildIntegrationsUpdateDispatchData];
1610
- [Events.GuildRoleCreate]: [data: _fluxerjs_types.GatewayGuildRoleCreateDispatchData];
1611
- [Events.GuildRoleUpdate]: [data: _fluxerjs_types.GatewayGuildRoleUpdateDispatchData];
1612
- [Events.GuildRoleDelete]: [data: _fluxerjs_types.GatewayGuildRoleDeleteDispatchData];
1742
+ [Events.GuildRoleCreate]: [data: GatewayGuildRoleCreateDispatchData];
1743
+ [Events.GuildRoleUpdate]: [data: GatewayGuildRoleUpdateDispatchData];
1744
+ [Events.GuildRoleDelete]: [data: GatewayGuildRoleDeleteDispatchData];
1613
1745
  [Events.GuildScheduledEventCreate]: [data: GatewayGuildScheduledEventCreateDispatchData];
1614
1746
  [Events.GuildScheduledEventUpdate]: [data: GatewayGuildScheduledEventUpdateDispatchData];
1615
1747
  [Events.GuildScheduledEventDelete]: [data: GatewayGuildScheduledEventDeleteDispatchData];
1616
1748
  [Events.ChannelPinsUpdate]: [data: GatewayChannelPinsUpdateDispatchData];
1617
1749
  [Events.InviteCreate]: [invite: Invite];
1618
- [Events.InviteDelete]: [data: _fluxerjs_types.GatewayInviteDeleteDispatchData];
1619
- [Events.TypingStart]: [data: _fluxerjs_types.GatewayTypingStartDispatchData];
1620
- [Events.UserUpdate]: [data: _fluxerjs_types.GatewayUserUpdateDispatchData];
1750
+ [Events.InviteDelete]: [data: GatewayInviteDeleteDispatchData];
1751
+ [Events.TypingStart]: [data: GatewayTypingStartDispatchData];
1752
+ [Events.UserUpdate]: [data: GatewayUserUpdateDispatchData];
1621
1753
  [Events.PresenceUpdate]: [data: GatewayPresenceUpdateDispatchData];
1622
1754
  [Events.WebhooksUpdate]: [data: GatewayWebhooksUpdateDispatchData];
1623
1755
  [Events.Resumed]: [];
@@ -1642,6 +1774,8 @@ declare class Client extends EventEmitter {
1642
1774
  /** Timestamp when the client became ready. Null until READY is received. */
1643
1775
  readyAt: Date | null;
1644
1776
  private _ws;
1777
+ /** When waitForGuilds, set of guild IDs we're waiting for GUILD_CREATE on. Null when not waiting. */
1778
+ _pendingGuildIds: Set<string> | null;
1645
1779
  /** @param options - Token, REST config, WebSocket, presence, etc. */
1646
1780
  constructor(options?: ClientOptions);
1647
1781
  /**
@@ -1685,9 +1819,9 @@ declare class Client extends EventEmitter {
1685
1819
  * Send a message to any channel by ID. Shorthand for client.channels.send().
1686
1820
  * Works even when the channel is not cached.
1687
1821
  */
1688
- sendToChannel(channelId: string, payload: string | {
1822
+ sendToChannel(channelId: string, content: string | {
1689
1823
  content?: string;
1690
- embeds?: _fluxerjs_types.APIEmbed[];
1824
+ embeds?: APIEmbed[];
1691
1825
  }): Promise<Message>;
1692
1826
  /**
1693
1827
  * Get or create a User from API data. Caches in client.users.
@@ -1708,6 +1842,16 @@ declare class Client extends EventEmitter {
1708
1842
  * @param token - Bot token (e.g. from FLUXER_BOT_TOKEN)
1709
1843
  */
1710
1844
  login(token: string): Promise<string>;
1845
+ /**
1846
+ * Called when all guilds have been received (or immediately if not waiting).
1847
+ * Sets readyAt, emits Ready, clears pending state.
1848
+ */
1849
+ _finalizeReady(): void;
1850
+ /**
1851
+ * Called by GUILD_CREATE handler when waitForGuilds is enabled.
1852
+ * Removes guild from pending set; when empty, finalizes ready.
1853
+ */
1854
+ _onGuildReceived(guildId: string): void;
1711
1855
  /** Disconnect from the gateway and clear cached data. */
1712
1856
  destroy(): Promise<void>;
1713
1857
  /** Returns true if the client has received Ready and `user` is set. */
@@ -1743,6 +1887,7 @@ declare const ErrorCodes: {
1743
1887
  readonly MemberNotFound: "MEMBER_NOT_FOUND";
1744
1888
  readonly RoleNotFound: "ROLE_NOT_FOUND";
1745
1889
  readonly EmojiNotInGuild: "EMOJI_NOT_IN_GUILD";
1890
+ readonly EmojiNotFound: "EMOJI_NOT_FOUND";
1746
1891
  };
1747
1892
 
1748
1893
  /** User Content CDN (avatars, icons, banners, emojis, attachments). */
@@ -1812,4 +1957,4 @@ declare function cdnMemberBannerURL(guildId: string, userId: string, bannerHash:
1812
1957
  */
1813
1958
  declare function cdnDefaultAvatarURL(userIdOrIndex: string | number): string;
1814
1959
 
1815
- export { Base, CDN_URL, CategoryChannel, type CdnUrlOptions, Channel, ChannelManager, Client, type ClientEventMethods, type ClientEvents, ClientUser, type CollectedReaction, DMChannel, ErrorCodes, Events, type FetchedUserWithProfile, FluxerError, type FluxerErrorOptions, Guild, GuildBan, GuildChannel, GuildEmoji, GuildMember, GuildMemberManager, GuildSticker, Invite, LinkChannel, Message, MessageCollector, type MessageCollectorEndReason, type MessageCollectorOptions, type MessageEditOptions, MessageManager, MessageReaction, type MessageSendOptions, type PartialMessage, ReactionCollector, type ReactionCollectorEndReason, type ReactionCollectorOptions, Role, STATIC_CDN_URL, TextChannel, User, UsersManager, VoiceChannel, Webhook, type WebhookSendOptions, cdnAvatarURL, cdnBannerURL, cdnDefaultAvatarURL, cdnDisplayAvatarURL, cdnMemberAvatarURL, cdnMemberBannerURL };
1960
+ export { Base, CDN_URL, CategoryChannel, type CdnUrlOptions, Channel, ChannelManager, Client, type ClientEventMethods, type ClientEvents, ClientUser, type CollectedReaction, DMChannel, ErrorCodes, Events, type FetchedUserWithProfile, FluxerError, type FluxerErrorOptions, Guild, GuildBan, GuildChannel, GuildEmoji, GuildMember, GuildMemberManager, GuildMemberRoleManager, GuildSticker, Invite, LinkChannel, Message, MessageCollector, type MessageCollectorEndReason, type MessageCollectorOptions, type MessageEditOptions, MessageManager, MessageReaction, type MessageSendOptions, type PartialMessage, ReactionCollector, type ReactionCollectorEndReason, type ReactionCollectorOptions, Role, type RoleResolvable, STATIC_CDN_URL, TextChannel, User, UsersManager, VoiceChannel, Webhook, type WebhookSendOptions, cdnAvatarURL, cdnBannerURL, cdnDefaultAvatarURL, cdnDisplayAvatarURL, cdnMemberAvatarURL, cdnMemberBannerURL };