novaapp-sdk 1.4.0 → 1.4.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/bin/nova.mjs +23 -0
- package/dist/chunk-53M2BTB5.mjs +26 -0
- package/dist/chunk-LMORGVJR.mjs +124 -0
- package/dist/cli/index.d.mts +6 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.js +871 -0
- package/dist/cli/index.mjs +716 -0
- package/dist/client-DbKa6yJo.d.mts +4244 -0
- package/dist/client-DbKa6yJo.d.ts +4244 -0
- package/dist/devtools/index.d.mts +94 -0
- package/dist/devtools/index.d.ts +94 -0
- package/dist/devtools/index.js +160 -0
- package/dist/devtools/index.mjs +7 -0
- package/dist/index.d.mts +6802 -2834
- package/dist/index.d.ts +6802 -2834
- package/dist/index.js +11200 -1342
- package/dist/index.mjs +11109 -1342
- package/dist/testing/index.d.mts +689 -0
- package/dist/testing/index.d.ts +689 -0
- package/dist/testing/index.js +849 -0
- package/dist/testing/index.mjs +820 -0
- package/package.json +17 -3
|
@@ -0,0 +1,4244 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Lightweight HTTP client for the Nova Bot API.
|
|
5
|
+
* Uses the native fetch API (Node 18+).
|
|
6
|
+
*/
|
|
7
|
+
declare class HttpClient {
|
|
8
|
+
readonly baseUrl: string;
|
|
9
|
+
private readonly token;
|
|
10
|
+
constructor(baseUrl: string, token: string);
|
|
11
|
+
private request;
|
|
12
|
+
get<T>(path: string): Promise<T>;
|
|
13
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
14
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
15
|
+
delete<T>(path: string): Promise<T>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface BotUser {
|
|
19
|
+
id: string;
|
|
20
|
+
username: string;
|
|
21
|
+
displayName: string;
|
|
22
|
+
avatar: string | null;
|
|
23
|
+
isBot: true;
|
|
24
|
+
}
|
|
25
|
+
interface BotApplication {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
/** Convenience: same as botUser.username */
|
|
29
|
+
username: string;
|
|
30
|
+
/** Convenience: same as botUser.displayName */
|
|
31
|
+
displayName: string;
|
|
32
|
+
description: string | null;
|
|
33
|
+
avatar: string | null;
|
|
34
|
+
category: string | null;
|
|
35
|
+
isPublic: boolean;
|
|
36
|
+
isVerified: boolean;
|
|
37
|
+
callbackUrl: string | null;
|
|
38
|
+
createdAt: string;
|
|
39
|
+
botUser: BotUser;
|
|
40
|
+
scopes: string[];
|
|
41
|
+
}
|
|
42
|
+
interface NovaServer {
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
icon: string | null;
|
|
46
|
+
description: string | null;
|
|
47
|
+
memberCount: number;
|
|
48
|
+
channelCount: number;
|
|
49
|
+
joinedAt: string;
|
|
50
|
+
}
|
|
51
|
+
interface Member {
|
|
52
|
+
role: 'OWNER' | 'ADMIN' | 'MEMBER';
|
|
53
|
+
joinedAt: string;
|
|
54
|
+
user: {
|
|
55
|
+
id: string;
|
|
56
|
+
username: string;
|
|
57
|
+
displayName: string;
|
|
58
|
+
avatar: string | null;
|
|
59
|
+
status: 'ONLINE' | 'IDLE' | 'DND' | 'OFFLINE';
|
|
60
|
+
isBot: boolean;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
type ChannelType = 'TEXT' | 'VOICE' | 'ANNOUNCEMENT' | 'FORUM' | 'STAGE';
|
|
64
|
+
interface Channel {
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
type: ChannelType;
|
|
68
|
+
serverId: string | null;
|
|
69
|
+
topic: string | null;
|
|
70
|
+
position: number;
|
|
71
|
+
/** Slow-mode interval in seconds. `0` means disabled. */
|
|
72
|
+
slowMode: number;
|
|
73
|
+
createdAt: string;
|
|
74
|
+
}
|
|
75
|
+
interface Role {
|
|
76
|
+
id: string;
|
|
77
|
+
name: string;
|
|
78
|
+
color: string | null;
|
|
79
|
+
position: number;
|
|
80
|
+
serverId: string;
|
|
81
|
+
hoist: boolean;
|
|
82
|
+
permissions: Record<string, boolean>;
|
|
83
|
+
createdAt: string;
|
|
84
|
+
}
|
|
85
|
+
interface BanEntry {
|
|
86
|
+
userId: string;
|
|
87
|
+
username: string;
|
|
88
|
+
displayName: string;
|
|
89
|
+
avatar: string | null;
|
|
90
|
+
reason: string | null;
|
|
91
|
+
bannedAt: string;
|
|
92
|
+
moderatorId: string | null;
|
|
93
|
+
}
|
|
94
|
+
interface Invite {
|
|
95
|
+
code: string;
|
|
96
|
+
serverId: string;
|
|
97
|
+
creatorId: string;
|
|
98
|
+
uses: number;
|
|
99
|
+
maxUses: number | null;
|
|
100
|
+
expiresAt: string | null;
|
|
101
|
+
createdAt: string;
|
|
102
|
+
}
|
|
103
|
+
/** A message with all reaction data fetched. */
|
|
104
|
+
interface ReactionDetail {
|
|
105
|
+
emoji: string;
|
|
106
|
+
count: number;
|
|
107
|
+
users: Array<{
|
|
108
|
+
id: string;
|
|
109
|
+
username: string;
|
|
110
|
+
displayName: string;
|
|
111
|
+
avatar: string | null;
|
|
112
|
+
}>;
|
|
113
|
+
}
|
|
114
|
+
/** Bot status that can be set via `client.setStatus()`. */
|
|
115
|
+
type BotStatus = 'ONLINE' | 'IDLE' | 'DND' | 'OFFLINE';
|
|
116
|
+
interface Attachment {
|
|
117
|
+
id: string;
|
|
118
|
+
url: string;
|
|
119
|
+
filename: string;
|
|
120
|
+
mimeType: string;
|
|
121
|
+
size: number;
|
|
122
|
+
}
|
|
123
|
+
interface Reaction {
|
|
124
|
+
emoji: string;
|
|
125
|
+
count: number;
|
|
126
|
+
userIds: string[];
|
|
127
|
+
}
|
|
128
|
+
interface EmbedField {
|
|
129
|
+
name: string;
|
|
130
|
+
value: string;
|
|
131
|
+
inline?: boolean;
|
|
132
|
+
}
|
|
133
|
+
interface Embed {
|
|
134
|
+
title?: string;
|
|
135
|
+
description?: string;
|
|
136
|
+
/** Makes the title a clickable link. */
|
|
137
|
+
url?: string;
|
|
138
|
+
/** Hex colour string — e.g. `'#5865F2'`. */
|
|
139
|
+
color?: string;
|
|
140
|
+
thumbnail?: string;
|
|
141
|
+
image?: string;
|
|
142
|
+
footer?: string;
|
|
143
|
+
fields?: EmbedField[];
|
|
144
|
+
timestamp?: string;
|
|
145
|
+
author?: {
|
|
146
|
+
name: string;
|
|
147
|
+
iconUrl?: string;
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
interface MessageComponent {
|
|
151
|
+
type: 'button' | 'select';
|
|
152
|
+
customId?: string;
|
|
153
|
+
label?: string;
|
|
154
|
+
style?: 'primary' | 'secondary' | 'success' | 'danger' | 'link';
|
|
155
|
+
emoji?: string;
|
|
156
|
+
url?: string;
|
|
157
|
+
placeholder?: string;
|
|
158
|
+
options?: Array<{
|
|
159
|
+
label: string;
|
|
160
|
+
value: string;
|
|
161
|
+
description?: string;
|
|
162
|
+
}>;
|
|
163
|
+
minValues?: number;
|
|
164
|
+
maxValues?: number;
|
|
165
|
+
disabled?: boolean;
|
|
166
|
+
}
|
|
167
|
+
interface Message {
|
|
168
|
+
id: string;
|
|
169
|
+
content: string;
|
|
170
|
+
channelId: string;
|
|
171
|
+
author: BotUser | {
|
|
172
|
+
id: string;
|
|
173
|
+
username: string;
|
|
174
|
+
displayName: string;
|
|
175
|
+
avatar: string | null;
|
|
176
|
+
isBot: boolean;
|
|
177
|
+
};
|
|
178
|
+
embed?: Embed | null;
|
|
179
|
+
components?: MessageComponent[] | null;
|
|
180
|
+
replyToId?: string | null;
|
|
181
|
+
attachments: Attachment[];
|
|
182
|
+
reactions: Reaction[];
|
|
183
|
+
createdAt: string;
|
|
184
|
+
editedAt?: string | null;
|
|
185
|
+
deletedAt?: string | null;
|
|
186
|
+
}
|
|
187
|
+
type InteractionType = 'SLASH_COMMAND' | 'BUTTON_CLICK' | 'SELECT_MENU' | 'MODAL_SUBMIT' | 'AUTOCOMPLETE' | 'CONTEXT_MENU' | 'PREFIX_COMMAND';
|
|
188
|
+
interface Interaction {
|
|
189
|
+
id: string;
|
|
190
|
+
type: InteractionType;
|
|
191
|
+
commandName?: string | null;
|
|
192
|
+
customId?: string | null;
|
|
193
|
+
data?: unknown;
|
|
194
|
+
/** For SELECT_MENU interactions — the chosen option values. */
|
|
195
|
+
values?: string[];
|
|
196
|
+
/** For MODAL_SUBMIT interactions — field customId → submitted value. */
|
|
197
|
+
modalData?: Record<string, string>;
|
|
198
|
+
/**
|
|
199
|
+
* For AUTOCOMPLETE interactions — the option being completed and the
|
|
200
|
+
* partial string the user has typed so far.
|
|
201
|
+
*/
|
|
202
|
+
autocomplete?: {
|
|
203
|
+
name: string;
|
|
204
|
+
value: string;
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* For CONTEXT_MENU interactions — the ID of the message or user that was
|
|
208
|
+
* right-clicked.
|
|
209
|
+
*/
|
|
210
|
+
contextTargetId?: string | null;
|
|
211
|
+
userId: string;
|
|
212
|
+
channelId: string;
|
|
213
|
+
serverId?: string | null;
|
|
214
|
+
triggerMsgId?: string | null;
|
|
215
|
+
createdAt: string;
|
|
216
|
+
}
|
|
217
|
+
/** A single text input field inside a bot modal. */
|
|
218
|
+
interface BotModalField {
|
|
219
|
+
/** Unique field ID — returned as key in `modalData` on MODAL_SUBMIT. */
|
|
220
|
+
customId: string;
|
|
221
|
+
/** Label displayed above the input. */
|
|
222
|
+
label: string;
|
|
223
|
+
/** `'short'` = single-line input, `'paragraph'` = multi-line textarea. */
|
|
224
|
+
type: 'short' | 'paragraph';
|
|
225
|
+
placeholder?: string;
|
|
226
|
+
required?: boolean;
|
|
227
|
+
minLength?: number;
|
|
228
|
+
maxLength?: number;
|
|
229
|
+
/** Optional pre-filled default value. */
|
|
230
|
+
value?: string;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Pass this as `modal` inside `client.interactions.respond()` to open a
|
|
234
|
+
* modal dialog on the user's client instead of sending a message.
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* await client.interactions.respond(interaction.id, {
|
|
238
|
+
* modal: {
|
|
239
|
+
* title: 'Submit a report',
|
|
240
|
+
* customId: 'report_modal',
|
|
241
|
+
* fields: [
|
|
242
|
+
* { customId: 'reason', label: 'Reason', type: 'paragraph', required: true },
|
|
243
|
+
* ],
|
|
244
|
+
* },
|
|
245
|
+
* })
|
|
246
|
+
*/
|
|
247
|
+
interface BotModalDefinition {
|
|
248
|
+
/** Title shown at the top of the modal dialog. */
|
|
249
|
+
title: string;
|
|
250
|
+
/** Custom ID passed back with the MODAL_SUBMIT interaction. */
|
|
251
|
+
customId: string;
|
|
252
|
+
fields: BotModalField[];
|
|
253
|
+
}
|
|
254
|
+
interface SlashCommandOption {
|
|
255
|
+
name: string;
|
|
256
|
+
description: string;
|
|
257
|
+
type: 'STRING' | 'INTEGER' | 'NUMBER' | 'BOOLEAN' | 'USER' | 'CHANNEL' | 'ROLE' | 'ATTACHMENT';
|
|
258
|
+
required?: boolean;
|
|
259
|
+
/** Whether to enable autocomplete for this option. Mutually exclusive with `choices`. */
|
|
260
|
+
autocomplete?: boolean;
|
|
261
|
+
choices?: Array<{
|
|
262
|
+
name: string;
|
|
263
|
+
value: string | number;
|
|
264
|
+
}>;
|
|
265
|
+
/** Minimum value (for INTEGER / NUMBER types). */
|
|
266
|
+
minValue?: number;
|
|
267
|
+
/** Maximum value (for INTEGER / NUMBER types). */
|
|
268
|
+
maxValue?: number;
|
|
269
|
+
/** Minimum length (for STRING type). */
|
|
270
|
+
minLength?: number;
|
|
271
|
+
/** Maximum length (for STRING type). */
|
|
272
|
+
maxLength?: number;
|
|
273
|
+
}
|
|
274
|
+
interface SlashCommandDefinition {
|
|
275
|
+
name: string;
|
|
276
|
+
description: string;
|
|
277
|
+
options?: SlashCommandOption[];
|
|
278
|
+
}
|
|
279
|
+
interface PrefixCommandDefinition {
|
|
280
|
+
prefix: string;
|
|
281
|
+
name: string;
|
|
282
|
+
description: string;
|
|
283
|
+
options?: SlashCommandOption[];
|
|
284
|
+
guildId?: string | null;
|
|
285
|
+
}
|
|
286
|
+
interface ContextCommandDefinition {
|
|
287
|
+
name: string;
|
|
288
|
+
target: 'MESSAGE' | 'USER';
|
|
289
|
+
guildId?: string | null;
|
|
290
|
+
}
|
|
291
|
+
interface RegisteredSlashCommand {
|
|
292
|
+
id: string;
|
|
293
|
+
name: string;
|
|
294
|
+
description: string;
|
|
295
|
+
options: SlashCommandOption[];
|
|
296
|
+
guildId: string | null;
|
|
297
|
+
enabled: boolean;
|
|
298
|
+
createdAt: string;
|
|
299
|
+
}
|
|
300
|
+
interface RegisteredPrefixCommand {
|
|
301
|
+
id: string;
|
|
302
|
+
prefix: string;
|
|
303
|
+
name: string;
|
|
304
|
+
description: string;
|
|
305
|
+
options: SlashCommandOption[];
|
|
306
|
+
guildId: string | null;
|
|
307
|
+
enabled: boolean;
|
|
308
|
+
createdAt: string;
|
|
309
|
+
}
|
|
310
|
+
interface RegisteredContextCommand {
|
|
311
|
+
id: string;
|
|
312
|
+
name: string;
|
|
313
|
+
target: 'MESSAGE' | 'USER';
|
|
314
|
+
guildId: string | null;
|
|
315
|
+
enabled: boolean;
|
|
316
|
+
createdAt: string;
|
|
317
|
+
}
|
|
318
|
+
type BotEventType = 'message.created' | 'message.edited' | 'message.deleted' | 'message.reaction_added' | 'message.reaction_removed' | 'message.pinned' | 'user.joined_server' | 'user.left_server' | 'user.updated_profile' | 'user.banned' | 'user.unbanned' | 'user.role_added' | 'user.role_removed' | 'user.started_typing' | 'user.voice_joined' | 'user.voice_left' | 'interaction.slash_command' | 'interaction.button_click' | 'interaction.select_menu' | 'interaction.modal_submit' | 'interaction.autocomplete' | 'server.updated' | 'channel.created' | 'channel.deleted' | 'channel.updated' | 'role.created' | 'role.updated' | 'role.deleted' | 'invite.created' | 'invite.deleted' | 'forum.post.created' | 'event.created' | 'event.updated' | 'event.deleted' | 'category.created' | 'category.updated' | 'category.deleted' | 'member.warned' | 'messages.bulk_deleted';
|
|
319
|
+
interface BotEvent<T = unknown> {
|
|
320
|
+
type: BotEventType;
|
|
321
|
+
data: T;
|
|
322
|
+
timestamp: string;
|
|
323
|
+
}
|
|
324
|
+
interface SendMessageOptions {
|
|
325
|
+
content?: string;
|
|
326
|
+
embed?: Embed;
|
|
327
|
+
components?: MessageComponent[];
|
|
328
|
+
replyToId?: string;
|
|
329
|
+
}
|
|
330
|
+
interface EditMessageOptions {
|
|
331
|
+
content?: string;
|
|
332
|
+
embed?: Embed;
|
|
333
|
+
components?: MessageComponent[];
|
|
334
|
+
}
|
|
335
|
+
interface RespondInteractionOptions {
|
|
336
|
+
content?: string;
|
|
337
|
+
embed?: Embed;
|
|
338
|
+
components?: MessageComponent[];
|
|
339
|
+
ephemeral?: boolean;
|
|
340
|
+
/**
|
|
341
|
+
* Open a modal dialog on the user's client instead of sending a message.
|
|
342
|
+
* When set, all other fields are ignored.
|
|
343
|
+
*/
|
|
344
|
+
modal?: BotModalDefinition;
|
|
345
|
+
}
|
|
346
|
+
interface FetchMessagesOptions {
|
|
347
|
+
limit?: number;
|
|
348
|
+
before?: string;
|
|
349
|
+
}
|
|
350
|
+
interface FetchMembersOptions {
|
|
351
|
+
limit?: number;
|
|
352
|
+
/** Return members whose role matches this value. */
|
|
353
|
+
role?: 'OWNER' | 'ADMIN' | 'MEMBER';
|
|
354
|
+
/** Filter by partial username (case-insensitive). */
|
|
355
|
+
search?: string;
|
|
356
|
+
}
|
|
357
|
+
interface PollInteractionsOptions {
|
|
358
|
+
limit?: number;
|
|
359
|
+
since?: string;
|
|
360
|
+
}
|
|
361
|
+
interface CreateChannelOptions {
|
|
362
|
+
name: string;
|
|
363
|
+
type?: ChannelType;
|
|
364
|
+
topic?: string;
|
|
365
|
+
position?: number;
|
|
366
|
+
slowMode?: number;
|
|
367
|
+
}
|
|
368
|
+
interface EditChannelOptions {
|
|
369
|
+
name?: string;
|
|
370
|
+
topic?: string;
|
|
371
|
+
position?: number;
|
|
372
|
+
slowMode?: number;
|
|
373
|
+
}
|
|
374
|
+
interface FetchChannelsOptions {
|
|
375
|
+
type?: ChannelType;
|
|
376
|
+
}
|
|
377
|
+
/** A raw permission record stored for a specific scope (server, role, or channel). */
|
|
378
|
+
interface BotPermissionRecord {
|
|
379
|
+
id: string;
|
|
380
|
+
botId: string;
|
|
381
|
+
serverId: string;
|
|
382
|
+
/** `null` means this record is server-wide (not channel-scoped). */
|
|
383
|
+
channelId: string | null;
|
|
384
|
+
/** `null` means this record applies to all roles. */
|
|
385
|
+
roleId: string | null;
|
|
386
|
+
/** Key-value map of permission name → granted flag. */
|
|
387
|
+
permissions: Record<string, boolean>;
|
|
388
|
+
createdAt: string;
|
|
389
|
+
updatedAt: string;
|
|
390
|
+
}
|
|
391
|
+
/** Response from `client.permissions.get()`. */
|
|
392
|
+
interface PermissionsResult {
|
|
393
|
+
/**
|
|
394
|
+
* Merged, effective permissions for the requested scope.
|
|
395
|
+
* Merging order (highest wins): channel > role > server-wide.
|
|
396
|
+
*/
|
|
397
|
+
permissions: Record<string, boolean>;
|
|
398
|
+
/** All raw permission records matching the query scope. */
|
|
399
|
+
records: BotPermissionRecord[];
|
|
400
|
+
}
|
|
401
|
+
/** Options accepted by `client.permissions.get()`. */
|
|
402
|
+
interface PermissionsQueryOptions {
|
|
403
|
+
/** The server to query permissions for (required). */
|
|
404
|
+
serverId: string;
|
|
405
|
+
/** Narrow the scope to a specific channel. */
|
|
406
|
+
channelId?: string;
|
|
407
|
+
/** Narrow the scope to a specific role. */
|
|
408
|
+
roleId?: string;
|
|
409
|
+
}
|
|
410
|
+
/** A direct message sent between the bot and a user. */
|
|
411
|
+
interface DirectMessage {
|
|
412
|
+
id: string;
|
|
413
|
+
content: string;
|
|
414
|
+
/** The sender's user ID. */
|
|
415
|
+
fromId: string;
|
|
416
|
+
/** The recipient's user ID. */
|
|
417
|
+
toId: string;
|
|
418
|
+
editedAt: string | null;
|
|
419
|
+
createdAt: string;
|
|
420
|
+
}
|
|
421
|
+
/** Snapshot of a user's voice channel presence. */
|
|
422
|
+
interface VoiceState {
|
|
423
|
+
userId: string;
|
|
424
|
+
channelId: string;
|
|
425
|
+
serverId: string;
|
|
426
|
+
/** Whether the user's microphone is muted. */
|
|
427
|
+
muted: boolean;
|
|
428
|
+
/** Whether the user's audio output is deafened. */
|
|
429
|
+
deafened: boolean;
|
|
430
|
+
/** ISO timestamp when the user joined the voice channel. */
|
|
431
|
+
joinedAt: string;
|
|
432
|
+
}
|
|
433
|
+
interface RoleCreateOptions {
|
|
434
|
+
name: string;
|
|
435
|
+
color?: string;
|
|
436
|
+
hoist?: boolean;
|
|
437
|
+
/**
|
|
438
|
+
* Permission flags to grant for this role.
|
|
439
|
+
* Any key not set retains its default value from the server.
|
|
440
|
+
*/
|
|
441
|
+
permissions?: Partial<{
|
|
442
|
+
manageServer: boolean;
|
|
443
|
+
manageChannels: boolean;
|
|
444
|
+
manageRoles: boolean;
|
|
445
|
+
viewAuditLog: boolean;
|
|
446
|
+
createInvites: boolean;
|
|
447
|
+
manageWebhooks: boolean;
|
|
448
|
+
kickMembers: boolean;
|
|
449
|
+
banMembers: boolean;
|
|
450
|
+
timeoutMembers: boolean;
|
|
451
|
+
changeNickname: boolean;
|
|
452
|
+
manageNicknames: boolean;
|
|
453
|
+
muteMembers: boolean;
|
|
454
|
+
deafenMembers: boolean;
|
|
455
|
+
moveMembers: boolean;
|
|
456
|
+
sendMessages: boolean;
|
|
457
|
+
manageMessages: boolean;
|
|
458
|
+
embedLinks: boolean;
|
|
459
|
+
attachFiles: boolean;
|
|
460
|
+
addReactions: boolean;
|
|
461
|
+
mentionEveryone: boolean;
|
|
462
|
+
readMessageHistory: boolean;
|
|
463
|
+
}>;
|
|
464
|
+
}
|
|
465
|
+
type RoleEditOptions = Partial<RoleCreateOptions>;
|
|
466
|
+
interface InviteCreateOptions {
|
|
467
|
+
/** Maximum number of times the invite can be used. `null` = unlimited. */
|
|
468
|
+
maxUses?: number | null;
|
|
469
|
+
/** ISO timestamp when the invite expires. `null` = never expires. */
|
|
470
|
+
expiresAt?: string | null;
|
|
471
|
+
}
|
|
472
|
+
interface Webhook {
|
|
473
|
+
id: string;
|
|
474
|
+
serverId: string;
|
|
475
|
+
channelId: string;
|
|
476
|
+
name: string;
|
|
477
|
+
/** A secret token used to post messages via this webhook. */
|
|
478
|
+
token: string;
|
|
479
|
+
createdAt: string;
|
|
480
|
+
}
|
|
481
|
+
interface WebhookCreateOptions {
|
|
482
|
+
/** Display name shown when the webhook posts a message. */
|
|
483
|
+
name: string;
|
|
484
|
+
}
|
|
485
|
+
interface WebhookEditOptions {
|
|
486
|
+
/** New display name for the webhook. */
|
|
487
|
+
name?: string;
|
|
488
|
+
/** Move the webhook to a different text channel. */
|
|
489
|
+
channelId?: string;
|
|
490
|
+
}
|
|
491
|
+
interface ExecuteWebhookOptions {
|
|
492
|
+
content?: string;
|
|
493
|
+
embed?: Embed;
|
|
494
|
+
/** Override the default display name for this execution. */
|
|
495
|
+
username?: string;
|
|
496
|
+
}
|
|
497
|
+
type AuditLogAction = 'member.kicked' | 'member.banned' | 'member.unbanned' | 'member.role_added' | 'member.role_removed' | 'message.deleted' | 'message.pinned' | 'message.unpinned' | 'channel.created' | 'channel.updated' | 'channel.deleted' | 'role.created' | 'role.updated' | 'role.deleted' | 'invite.created' | 'invite.deleted' | 'webhook.created' | 'webhook.updated' | 'webhook.deleted' | 'server.updated' | string;
|
|
498
|
+
interface AuditLogEntry {
|
|
499
|
+
id: string;
|
|
500
|
+
serverId: string;
|
|
501
|
+
action: AuditLogAction;
|
|
502
|
+
/** The user who performed the action. */
|
|
503
|
+
actorId: string;
|
|
504
|
+
actorName: string;
|
|
505
|
+
/** The entity affected (user, channel, role, etc.). */
|
|
506
|
+
targetId: string | null;
|
|
507
|
+
targetName: string | null;
|
|
508
|
+
/** Extra context (old/new values, reason, etc.). */
|
|
509
|
+
metadata: Record<string, unknown> | null;
|
|
510
|
+
createdAt: string;
|
|
511
|
+
}
|
|
512
|
+
interface FetchAuditLogsOptions {
|
|
513
|
+
limit?: number;
|
|
514
|
+
/** Only return entries for a specific action type. */
|
|
515
|
+
action?: AuditLogAction;
|
|
516
|
+
/** Only return entries targeting a specific user ID. */
|
|
517
|
+
userId?: string;
|
|
518
|
+
before?: string;
|
|
519
|
+
}
|
|
520
|
+
interface ServerUpdateOptions {
|
|
521
|
+
name?: string;
|
|
522
|
+
description?: string;
|
|
523
|
+
icon?: string | null;
|
|
524
|
+
}
|
|
525
|
+
/** Extended member object returned when fetching a single member by user ID. */
|
|
526
|
+
interface SingleMember extends Member {
|
|
527
|
+
/** The custom role assigned to this member, if any. */
|
|
528
|
+
customRole: Role | null;
|
|
529
|
+
}
|
|
530
|
+
interface NovaClientOptions {
|
|
531
|
+
/** Your bot token — starts with "nova_bot_" */
|
|
532
|
+
token: string;
|
|
533
|
+
/**
|
|
534
|
+
* Base URL of the Nova server.
|
|
535
|
+
* @default "https://novachatapp.com"
|
|
536
|
+
*/
|
|
537
|
+
baseUrl?: string;
|
|
538
|
+
}
|
|
539
|
+
interface ChannelCategory {
|
|
540
|
+
id: string;
|
|
541
|
+
serverId: string;
|
|
542
|
+
name: string;
|
|
543
|
+
position: number;
|
|
544
|
+
createdAt: string;
|
|
545
|
+
}
|
|
546
|
+
interface CreateCategoryOptions {
|
|
547
|
+
name: string;
|
|
548
|
+
position?: number;
|
|
549
|
+
}
|
|
550
|
+
interface EditCategoryOptions {
|
|
551
|
+
name?: string;
|
|
552
|
+
position?: number;
|
|
553
|
+
}
|
|
554
|
+
interface ForumPost {
|
|
555
|
+
id: string;
|
|
556
|
+
channelId: string;
|
|
557
|
+
authorId: string;
|
|
558
|
+
title: string;
|
|
559
|
+
body: string;
|
|
560
|
+
tags: string[];
|
|
561
|
+
pinned: boolean;
|
|
562
|
+
closed: boolean;
|
|
563
|
+
upvoteCount: number;
|
|
564
|
+
replyCount: number;
|
|
565
|
+
author: {
|
|
566
|
+
id: string;
|
|
567
|
+
username: string;
|
|
568
|
+
displayName: string;
|
|
569
|
+
avatar: string | null;
|
|
570
|
+
};
|
|
571
|
+
createdAt: string;
|
|
572
|
+
updatedAt: string;
|
|
573
|
+
}
|
|
574
|
+
interface CreateForumPostOptions {
|
|
575
|
+
title: string;
|
|
576
|
+
body: string;
|
|
577
|
+
tags?: string[];
|
|
578
|
+
}
|
|
579
|
+
interface EditForumPostOptions {
|
|
580
|
+
title?: string;
|
|
581
|
+
body?: string;
|
|
582
|
+
tags?: string[];
|
|
583
|
+
pinned?: boolean;
|
|
584
|
+
closed?: boolean;
|
|
585
|
+
}
|
|
586
|
+
interface FetchForumPostsOptions {
|
|
587
|
+
limit?: number;
|
|
588
|
+
before?: string;
|
|
589
|
+
}
|
|
590
|
+
interface ServerEvent {
|
|
591
|
+
id: string;
|
|
592
|
+
serverId: string;
|
|
593
|
+
channelId: string | null;
|
|
594
|
+
createdById: string;
|
|
595
|
+
title: string;
|
|
596
|
+
description: string | null;
|
|
597
|
+
imageUrl: string | null;
|
|
598
|
+
location: string | null;
|
|
599
|
+
startAt: string;
|
|
600
|
+
endAt: string | null;
|
|
601
|
+
attendeeCount?: number;
|
|
602
|
+
createdAt: string;
|
|
603
|
+
}
|
|
604
|
+
interface ServerEventAttendee {
|
|
605
|
+
eventId: string;
|
|
606
|
+
userId: string;
|
|
607
|
+
status: 'GOING' | 'MAYBE' | 'NOT_GOING';
|
|
608
|
+
user: {
|
|
609
|
+
id: string;
|
|
610
|
+
username: string;
|
|
611
|
+
displayName: string;
|
|
612
|
+
avatar: string | null;
|
|
613
|
+
};
|
|
614
|
+
createdAt: string;
|
|
615
|
+
}
|
|
616
|
+
interface CreateEventOptions {
|
|
617
|
+
title: string;
|
|
618
|
+
description?: string;
|
|
619
|
+
imageUrl?: string;
|
|
620
|
+
location?: string;
|
|
621
|
+
startAt: string;
|
|
622
|
+
endAt?: string;
|
|
623
|
+
channelId?: string;
|
|
624
|
+
}
|
|
625
|
+
interface EditEventOptions {
|
|
626
|
+
title?: string;
|
|
627
|
+
description?: string;
|
|
628
|
+
imageUrl?: string;
|
|
629
|
+
location?: string;
|
|
630
|
+
startAt?: string;
|
|
631
|
+
endAt?: string | null;
|
|
632
|
+
}
|
|
633
|
+
interface FetchEventsOptions {
|
|
634
|
+
limit?: number;
|
|
635
|
+
/** Only return events starting from now. */
|
|
636
|
+
upcoming?: boolean;
|
|
637
|
+
}
|
|
638
|
+
interface MemberXPData {
|
|
639
|
+
userId: string;
|
|
640
|
+
xp: number;
|
|
641
|
+
level: number;
|
|
642
|
+
joinedAt?: string;
|
|
643
|
+
}
|
|
644
|
+
interface LeaderboardEntry extends MemberXPData {
|
|
645
|
+
rank: number;
|
|
646
|
+
user: {
|
|
647
|
+
id: string;
|
|
648
|
+
username: string;
|
|
649
|
+
displayName: string;
|
|
650
|
+
avatar: string | null;
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
interface Warning {
|
|
654
|
+
id: string;
|
|
655
|
+
serverId: string;
|
|
656
|
+
userId: string;
|
|
657
|
+
moderatorId: string;
|
|
658
|
+
reason: string;
|
|
659
|
+
createdAt: string;
|
|
660
|
+
}
|
|
661
|
+
interface FetchWarningsOptions {
|
|
662
|
+
userId?: string;
|
|
663
|
+
}
|
|
664
|
+
type AutoModRuleType = 'BLOCKED_WORD' | 'BLOCKED_LINK';
|
|
665
|
+
interface AutoModRule {
|
|
666
|
+
id: string;
|
|
667
|
+
serverId: string;
|
|
668
|
+
type: AutoModRuleType;
|
|
669
|
+
value: string;
|
|
670
|
+
enabled: boolean;
|
|
671
|
+
createdAt: string;
|
|
672
|
+
}
|
|
673
|
+
interface CreateAutoModRuleOptions {
|
|
674
|
+
type: AutoModRuleType;
|
|
675
|
+
value: string;
|
|
676
|
+
enabled?: boolean;
|
|
677
|
+
}
|
|
678
|
+
interface EditAutoModRuleOptions {
|
|
679
|
+
value?: string;
|
|
680
|
+
enabled?: boolean;
|
|
681
|
+
}
|
|
682
|
+
interface UserProfile {
|
|
683
|
+
id: string;
|
|
684
|
+
username: string;
|
|
685
|
+
displayName: string;
|
|
686
|
+
avatar: string | null;
|
|
687
|
+
status: 'ONLINE' | 'IDLE' | 'DND' | 'OFFLINE';
|
|
688
|
+
bio: string | null;
|
|
689
|
+
isBot: boolean;
|
|
690
|
+
createdAt: string;
|
|
691
|
+
}
|
|
692
|
+
interface SoundboardClip {
|
|
693
|
+
id: string;
|
|
694
|
+
serverId: string;
|
|
695
|
+
name: string;
|
|
696
|
+
fileUrl: string;
|
|
697
|
+
duration: number;
|
|
698
|
+
uploadedById: string;
|
|
699
|
+
createdAt: string;
|
|
700
|
+
}
|
|
701
|
+
interface ServerStats {
|
|
702
|
+
serverId: string;
|
|
703
|
+
memberCount: number;
|
|
704
|
+
channelCount: number;
|
|
705
|
+
roleCount: number;
|
|
706
|
+
onlineCount: number;
|
|
707
|
+
messageCount: number;
|
|
708
|
+
}
|
|
709
|
+
interface BulkDeleteResult {
|
|
710
|
+
deleted: number;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
declare class MessagesAPI {
|
|
714
|
+
private readonly http;
|
|
715
|
+
constructor(http: HttpClient);
|
|
716
|
+
/**
|
|
717
|
+
* Send a message to a channel.
|
|
718
|
+
*
|
|
719
|
+
* @example
|
|
720
|
+
* await client.messages.send('channel-id', { content: 'Hello!' })
|
|
721
|
+
* await client.messages.send('channel-id', {
|
|
722
|
+
* embed: { title: 'Report', description: 'Everything is fine.' }
|
|
723
|
+
* })
|
|
724
|
+
*/
|
|
725
|
+
send(channelId: string, options: SendMessageOptions): Promise<Message>;
|
|
726
|
+
/**
|
|
727
|
+
* Edit a message previously sent by this bot.
|
|
728
|
+
*/
|
|
729
|
+
edit(messageId: string, options: EditMessageOptions): Promise<Message>;
|
|
730
|
+
/**
|
|
731
|
+
* Delete a message previously sent by this bot.
|
|
732
|
+
*/
|
|
733
|
+
delete(messageId: string): Promise<{
|
|
734
|
+
ok: true;
|
|
735
|
+
}>;
|
|
736
|
+
/**
|
|
737
|
+
* Fetch recent messages from a channel.
|
|
738
|
+
*/
|
|
739
|
+
fetch(channelId: string, options?: FetchMessagesOptions): Promise<Message[]>;
|
|
740
|
+
/**
|
|
741
|
+
* Send a typing indicator in a channel (appears for ~5 seconds).
|
|
742
|
+
*/
|
|
743
|
+
typing(channelId: string): Promise<{
|
|
744
|
+
ok: true;
|
|
745
|
+
}>;
|
|
746
|
+
/**
|
|
747
|
+
* Fetch a single message by ID.
|
|
748
|
+
*
|
|
749
|
+
* @example
|
|
750
|
+
* const msg = await client.messages.fetchOne('message-id')
|
|
751
|
+
*/
|
|
752
|
+
fetchOne(messageId: string): Promise<Message>;
|
|
753
|
+
/**
|
|
754
|
+
* Pin a message in its channel.
|
|
755
|
+
* The bot must have the `messages.manage` scope.
|
|
756
|
+
*
|
|
757
|
+
* @example
|
|
758
|
+
* await client.messages.pin('message-id')
|
|
759
|
+
*/
|
|
760
|
+
pin(messageId: string): Promise<{
|
|
761
|
+
ok: true;
|
|
762
|
+
}>;
|
|
763
|
+
/**
|
|
764
|
+
* Unpin a message.
|
|
765
|
+
*
|
|
766
|
+
* @example
|
|
767
|
+
* await client.messages.unpin('message-id')
|
|
768
|
+
*/
|
|
769
|
+
unpin(messageId: string): Promise<{
|
|
770
|
+
ok: true;
|
|
771
|
+
}>;
|
|
772
|
+
/**
|
|
773
|
+
* Fetch all pinned messages in a channel.
|
|
774
|
+
*
|
|
775
|
+
* @example
|
|
776
|
+
* const pins = await client.messages.fetchPinned('channel-id')
|
|
777
|
+
*/
|
|
778
|
+
fetchPinned(channelId: string): Promise<Message[]>;
|
|
779
|
+
/**
|
|
780
|
+
* Add a reaction to a message.
|
|
781
|
+
*
|
|
782
|
+
* @example
|
|
783
|
+
* await client.messages.addReaction('message-id', '👍')
|
|
784
|
+
*/
|
|
785
|
+
addReaction(messageId: string, emoji: string): Promise<{
|
|
786
|
+
ok: true;
|
|
787
|
+
}>;
|
|
788
|
+
/**
|
|
789
|
+
* Remove the bot's reaction from a message.
|
|
790
|
+
*
|
|
791
|
+
* @example
|
|
792
|
+
* await client.messages.removeReaction('message-id', '👍')
|
|
793
|
+
*/
|
|
794
|
+
removeReaction(messageId: string, emoji: string): Promise<{
|
|
795
|
+
ok: true;
|
|
796
|
+
}>;
|
|
797
|
+
/**
|
|
798
|
+
* Fetch all reactions on a message.
|
|
799
|
+
*
|
|
800
|
+
* @example
|
|
801
|
+
* const reactions = await client.messages.fetchReactions('message-id')
|
|
802
|
+
*/
|
|
803
|
+
fetchReactions(messageId: string): Promise<ReactionDetail[]>;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
declare class CommandsAPI {
|
|
807
|
+
private readonly http;
|
|
808
|
+
constructor(http: HttpClient);
|
|
809
|
+
/**
|
|
810
|
+
* Register (or fully replace) slash commands.
|
|
811
|
+
* Pass `guildId` to register guild-specific commands; omit for global.
|
|
812
|
+
*
|
|
813
|
+
* @example
|
|
814
|
+
* await client.commands.setSlash([
|
|
815
|
+
* { name: 'ping', description: 'Responds with pong!' },
|
|
816
|
+
* { name: 'ban', description: 'Ban a user', options: [
|
|
817
|
+
* { name: 'user', description: 'User to ban', type: 'USER', required: true }
|
|
818
|
+
* ]}
|
|
819
|
+
* ])
|
|
820
|
+
*/
|
|
821
|
+
setSlash(commands: SlashCommandDefinition[], guildId?: string): Promise<{
|
|
822
|
+
registered: number;
|
|
823
|
+
}>;
|
|
824
|
+
/**
|
|
825
|
+
* Fetch all registered slash commands.
|
|
826
|
+
*/
|
|
827
|
+
getSlash(guildId?: string): Promise<RegisteredSlashCommand[]>;
|
|
828
|
+
/**
|
|
829
|
+
* Delete a slash command by name.
|
|
830
|
+
*/
|
|
831
|
+
deleteSlash(name: string): Promise<{
|
|
832
|
+
ok: true;
|
|
833
|
+
}>;
|
|
834
|
+
/**
|
|
835
|
+
* Register (or fully replace) prefix commands.
|
|
836
|
+
*
|
|
837
|
+
* @example
|
|
838
|
+
* await client.commands.setPrefix([
|
|
839
|
+
* { prefix: '!', name: 'help', description: 'Show help' },
|
|
840
|
+
* { prefix: '!', name: 'kick', description: 'Kick a user' },
|
|
841
|
+
* ])
|
|
842
|
+
*/
|
|
843
|
+
setPrefix(commands: PrefixCommandDefinition[]): Promise<{
|
|
844
|
+
created: number;
|
|
845
|
+
}>;
|
|
846
|
+
/**
|
|
847
|
+
* Fetch all registered prefix commands.
|
|
848
|
+
*/
|
|
849
|
+
getPrefix(): Promise<RegisteredPrefixCommand[]>;
|
|
850
|
+
/**
|
|
851
|
+
* Delete a prefix command.
|
|
852
|
+
*/
|
|
853
|
+
deletePrefix(prefix: string, name: string): Promise<{
|
|
854
|
+
ok: true;
|
|
855
|
+
}>;
|
|
856
|
+
/**
|
|
857
|
+
* Register (or fully replace) context menu commands.
|
|
858
|
+
*
|
|
859
|
+
* @example
|
|
860
|
+
* await client.commands.setContext([
|
|
861
|
+
* { name: 'Report message', target: 'MESSAGE' },
|
|
862
|
+
* { name: 'View profile', target: 'USER' },
|
|
863
|
+
* ])
|
|
864
|
+
*/
|
|
865
|
+
setContext(commands: ContextCommandDefinition[]): Promise<{
|
|
866
|
+
created: number;
|
|
867
|
+
}>;
|
|
868
|
+
/**
|
|
869
|
+
* Fetch all registered context menu commands.
|
|
870
|
+
*/
|
|
871
|
+
getContext(): Promise<RegisteredContextCommand[]>;
|
|
872
|
+
/**
|
|
873
|
+
* Delete a context menu command by name.
|
|
874
|
+
*/
|
|
875
|
+
deleteContext(name: string): Promise<{
|
|
876
|
+
ok: true;
|
|
877
|
+
}>;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
declare class MembersAPI {
|
|
881
|
+
private readonly http;
|
|
882
|
+
constructor(http: HttpClient);
|
|
883
|
+
/**
|
|
884
|
+
* Fetch members of a server the bot is in.
|
|
885
|
+
* Supports filtering by role and searching by username/displayName.
|
|
886
|
+
*
|
|
887
|
+
* @example
|
|
888
|
+
* const members = await client.members.list('server-id', { limit: 50 })
|
|
889
|
+
* const admins = await client.members.list('server-id', { role: 'ADMIN' })
|
|
890
|
+
* const found = await client.members.list('server-id', { search: 'john' })
|
|
891
|
+
*/
|
|
892
|
+
list(serverId: string, options?: FetchMembersOptions): Promise<Member[]>;
|
|
893
|
+
/**
|
|
894
|
+
* Fetch a single member from a server by their user ID.
|
|
895
|
+
* Returns the member's custom role if assigned.
|
|
896
|
+
* Requires the `members.read` scope.
|
|
897
|
+
*
|
|
898
|
+
* @example
|
|
899
|
+
* const member = await client.members.fetch('server-id', 'user-id')
|
|
900
|
+
* console.log(member.customRole?.name ?? 'No custom role')
|
|
901
|
+
*/
|
|
902
|
+
fetch(serverId: string, userId: string): Promise<SingleMember>;
|
|
903
|
+
/**
|
|
904
|
+
* Kick a member from a server.
|
|
905
|
+
* Bots cannot kick owners or admins (403 will be thrown).
|
|
906
|
+
*
|
|
907
|
+
* @example
|
|
908
|
+
* await client.members.kick('server-id', 'user-id')
|
|
909
|
+
*/
|
|
910
|
+
kick(serverId: string, userId: string): Promise<{
|
|
911
|
+
ok: true;
|
|
912
|
+
}>;
|
|
913
|
+
/**
|
|
914
|
+
* Ban a member from a server.
|
|
915
|
+
* Bots cannot ban owners or admins (403 will be thrown).
|
|
916
|
+
*
|
|
917
|
+
* @example
|
|
918
|
+
* await client.members.ban('server-id', 'user-id', 'Spamming')
|
|
919
|
+
*/
|
|
920
|
+
ban(serverId: string, userId: string, reason?: string): Promise<{
|
|
921
|
+
ok: true;
|
|
922
|
+
}>;
|
|
923
|
+
/**
|
|
924
|
+
* Unban a previously banned user.
|
|
925
|
+
* Requires the `members.ban` scope.
|
|
926
|
+
*
|
|
927
|
+
* @example
|
|
928
|
+
* await client.members.unban('server-id', 'user-id')
|
|
929
|
+
*/
|
|
930
|
+
unban(serverId: string, userId: string): Promise<{
|
|
931
|
+
ok: true;
|
|
932
|
+
}>;
|
|
933
|
+
/**
|
|
934
|
+
* Fetch the ban list for a server.
|
|
935
|
+
* Requires the `members.ban` scope.
|
|
936
|
+
*
|
|
937
|
+
* @example
|
|
938
|
+
* const bans = await client.members.listBans('server-id')
|
|
939
|
+
* for (const ban of bans) {
|
|
940
|
+
* console.log(`${ban.username} — ${ban.reason ?? 'No reason'}`)
|
|
941
|
+
* }
|
|
942
|
+
*/
|
|
943
|
+
listBans(serverId: string): Promise<BanEntry[]>;
|
|
944
|
+
/**
|
|
945
|
+
* Send a direct message to a user (DM).
|
|
946
|
+
* Requires the `messages.write` scope.
|
|
947
|
+
*
|
|
948
|
+
* @example
|
|
949
|
+
* await client.members.dm('user-id', { content: 'Hello!' })
|
|
950
|
+
* await client.members.dm('user-id', 'Hello from the bot!')
|
|
951
|
+
*/
|
|
952
|
+
dm(userId: string, options: string | Omit<SendMessageOptions, 'replyToId'>): Promise<Message>;
|
|
953
|
+
/**
|
|
954
|
+
* Add a role to a member.
|
|
955
|
+
* Requires the `members.roles` scope.
|
|
956
|
+
*
|
|
957
|
+
* @example
|
|
958
|
+
* await client.members.addRole('server-id', 'user-id', 'role-id')
|
|
959
|
+
*/
|
|
960
|
+
addRole(serverId: string, userId: string, roleId: string): Promise<{
|
|
961
|
+
ok: true;
|
|
962
|
+
}>;
|
|
963
|
+
/**
|
|
964
|
+
* Remove a role from a member.
|
|
965
|
+
* Requires the `members.roles` scope.
|
|
966
|
+
*
|
|
967
|
+
* @example
|
|
968
|
+
* await client.members.removeRole('server-id', 'user-id', 'role-id')
|
|
969
|
+
*/
|
|
970
|
+
removeRole(serverId: string, userId: string, roleId: string): Promise<{
|
|
971
|
+
ok: true;
|
|
972
|
+
}>;
|
|
973
|
+
/**
|
|
974
|
+
* Issue a warning to a member.
|
|
975
|
+
* Requires the `members.moderate` scope.
|
|
976
|
+
*
|
|
977
|
+
* @example
|
|
978
|
+
* await client.members.warn('server-id', 'user-id', 'Spamming')
|
|
979
|
+
*/
|
|
980
|
+
warn(serverId: string, userId: string, reason: string): Promise<Warning>;
|
|
981
|
+
/**
|
|
982
|
+
* Fetch warnings for a server (or optionally a specific user).
|
|
983
|
+
* Requires the `members.moderate` scope.
|
|
984
|
+
*
|
|
985
|
+
* @example
|
|
986
|
+
* const all = await client.members.fetchWarnings('server-id')
|
|
987
|
+
* const userWarnings = await client.members.fetchWarnings('server-id', { userId: 'user-id' })
|
|
988
|
+
*/
|
|
989
|
+
fetchWarnings(serverId: string, options?: FetchWarningsOptions): Promise<Warning[]>;
|
|
990
|
+
/**
|
|
991
|
+
* Remove a warning by its ID.
|
|
992
|
+
* Requires the `members.moderate` scope.
|
|
993
|
+
*
|
|
994
|
+
* @example
|
|
995
|
+
* await client.members.removeWarning('warning-id')
|
|
996
|
+
*/
|
|
997
|
+
removeWarning(warningId: string): Promise<{
|
|
998
|
+
ok: true;
|
|
999
|
+
}>;
|
|
1000
|
+
/**
|
|
1001
|
+
* Get a member's XP and level.
|
|
1002
|
+
* Requires the `members.read` scope.
|
|
1003
|
+
*
|
|
1004
|
+
* @example
|
|
1005
|
+
* const xpData = await client.members.getXP('server-id', 'user-id')
|
|
1006
|
+
* console.log(`Level ${xpData.level} — ${xpData.xp} XP`)
|
|
1007
|
+
*/
|
|
1008
|
+
getXP(serverId: string, userId: string): Promise<MemberXPData>;
|
|
1009
|
+
/**
|
|
1010
|
+
* Set or add XP to a member.
|
|
1011
|
+
* Requires the `members.manage` scope.
|
|
1012
|
+
*
|
|
1013
|
+
* @example
|
|
1014
|
+
* // Add 50 XP
|
|
1015
|
+
* await client.members.setXP('server-id', 'user-id', { add: 50 })
|
|
1016
|
+
* // Set XP to a specific value
|
|
1017
|
+
* await client.members.setXP('server-id', 'user-id', { xp: 1000 })
|
|
1018
|
+
*/
|
|
1019
|
+
setXP(serverId: string, userId: string, options: {
|
|
1020
|
+
xp?: number;
|
|
1021
|
+
add?: number;
|
|
1022
|
+
}): Promise<MemberXPData>;
|
|
1023
|
+
/**
|
|
1024
|
+
* Get the XP leaderboard for a server.
|
|
1025
|
+
* Requires the `members.read` scope.
|
|
1026
|
+
*
|
|
1027
|
+
* @example
|
|
1028
|
+
* const top10 = await client.members.leaderboard('server-id', 10)
|
|
1029
|
+
*/
|
|
1030
|
+
leaderboard(serverId: string, limit?: number): Promise<LeaderboardEntry[]>;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
declare class ServersAPI {
|
|
1034
|
+
private readonly http;
|
|
1035
|
+
constructor(http: HttpClient);
|
|
1036
|
+
/**
|
|
1037
|
+
* Fetch all servers the bot is currently a member of.
|
|
1038
|
+
*
|
|
1039
|
+
* @example
|
|
1040
|
+
* const servers = await client.servers.list()
|
|
1041
|
+
* console.log(`Bot is in ${servers.length} servers`)
|
|
1042
|
+
*/
|
|
1043
|
+
list(): Promise<NovaServer[]>;
|
|
1044
|
+
/**
|
|
1045
|
+
* Fetch a single server by ID.
|
|
1046
|
+
* The bot must be a member of the server.
|
|
1047
|
+
*
|
|
1048
|
+
* @example
|
|
1049
|
+
* const server = await client.servers.fetch('server-id')
|
|
1050
|
+
* console.log(`${server.name} — ${server.memberCount} members`)
|
|
1051
|
+
*/
|
|
1052
|
+
fetch(serverId: string): Promise<NovaServer>;
|
|
1053
|
+
/**
|
|
1054
|
+
* Update a server's name, description, or icon.
|
|
1055
|
+
* Requires the `server.manage` scope.
|
|
1056
|
+
*
|
|
1057
|
+
* @example
|
|
1058
|
+
* await client.servers.update('server-id', { name: 'Better Name', description: 'A great place!' })
|
|
1059
|
+
*/
|
|
1060
|
+
update(serverId: string, options: ServerUpdateOptions): Promise<NovaServer>;
|
|
1061
|
+
/**
|
|
1062
|
+
* Fetch all roles in a server.
|
|
1063
|
+
* Results are sorted by position (lowest first).
|
|
1064
|
+
*
|
|
1065
|
+
* @example
|
|
1066
|
+
* const roles = await client.servers.listRoles('server-id')
|
|
1067
|
+
* const adminRole = roles.find(r => r.name === 'Admin')
|
|
1068
|
+
*/
|
|
1069
|
+
listRoles(serverId: string): Promise<Role[]>;
|
|
1070
|
+
/**
|
|
1071
|
+
* Fetch all channel categories in a server.
|
|
1072
|
+
*
|
|
1073
|
+
* @example
|
|
1074
|
+
* const categories = await client.servers.listCategories('server-id')
|
|
1075
|
+
*/
|
|
1076
|
+
listCategories(serverId: string): Promise<ChannelCategory[]>;
|
|
1077
|
+
/**
|
|
1078
|
+
* Get server statistics (member count, message count, etc.).
|
|
1079
|
+
*
|
|
1080
|
+
* @example
|
|
1081
|
+
* const stats = await client.servers.getStats('server-id')
|
|
1082
|
+
* console.log(`${stats.onlineCount} online / ${stats.memberCount} total`)
|
|
1083
|
+
*/
|
|
1084
|
+
getStats(serverId: string): Promise<ServerStats>;
|
|
1085
|
+
/**
|
|
1086
|
+
* Fetch all soundboard clips uploaded to a server.
|
|
1087
|
+
*
|
|
1088
|
+
* @example
|
|
1089
|
+
* const clips = await client.servers.listSoundboard('server-id')
|
|
1090
|
+
*/
|
|
1091
|
+
listSoundboard(serverId: string): Promise<SoundboardClip[]>;
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
declare class InteractionsAPI {
|
|
1095
|
+
private readonly http;
|
|
1096
|
+
private readonly emitter;
|
|
1097
|
+
constructor(http: HttpClient, emitter: EventEmitter);
|
|
1098
|
+
/**
|
|
1099
|
+
* Acknowledge an interaction without sending a visible response.
|
|
1100
|
+
* Shows a loading state to the user. You must follow up with `respond()`.
|
|
1101
|
+
*
|
|
1102
|
+
* @example
|
|
1103
|
+
* client.on('interactionCreate', async (interaction) => {
|
|
1104
|
+
* await client.interactions.ack(interaction.id)
|
|
1105
|
+
* // ... do work ...
|
|
1106
|
+
* await client.interactions.respond(interaction.id, { content: 'Done!' })
|
|
1107
|
+
* })
|
|
1108
|
+
*/
|
|
1109
|
+
ack(interactionId: string): Promise<{
|
|
1110
|
+
ok: true;
|
|
1111
|
+
}>;
|
|
1112
|
+
/**
|
|
1113
|
+
* Respond to an interaction with a message.
|
|
1114
|
+
* Set `ephemeral: true` to only show the response to the triggering user.
|
|
1115
|
+
*
|
|
1116
|
+
* @example
|
|
1117
|
+
* await client.interactions.respond(interaction.id, {
|
|
1118
|
+
* content: 'Pong!',
|
|
1119
|
+
* ephemeral: true,
|
|
1120
|
+
* })
|
|
1121
|
+
*/
|
|
1122
|
+
respond(interactionId: string, options: RespondInteractionOptions): Promise<Message | {
|
|
1123
|
+
ok: true;
|
|
1124
|
+
ephemeral: true;
|
|
1125
|
+
}>;
|
|
1126
|
+
/**
|
|
1127
|
+
* Respond to an autocomplete interaction with a list of suggested choices.
|
|
1128
|
+
* The gateway fires `AUTOCOMPLETE` interactions when a user is typing in
|
|
1129
|
+
* an option that has `autocomplete: true`. Call this within ~3 seconds.
|
|
1130
|
+
*
|
|
1131
|
+
* @example
|
|
1132
|
+
* client.autocomplete('search', async (interaction) => {
|
|
1133
|
+
* const query = interaction.autocomplete?.value ?? ''
|
|
1134
|
+
* const results = await db.search(query)
|
|
1135
|
+
* await client.interactions.autocomplete(interaction.id,
|
|
1136
|
+
* results.map(r => ({ name: r.title, value: r.id }))
|
|
1137
|
+
* )
|
|
1138
|
+
* })
|
|
1139
|
+
*/
|
|
1140
|
+
autocomplete(interactionId: string, choices: Array<{
|
|
1141
|
+
name: string;
|
|
1142
|
+
value: string | number;
|
|
1143
|
+
}>): Promise<{
|
|
1144
|
+
ok: true;
|
|
1145
|
+
}>;
|
|
1146
|
+
/**
|
|
1147
|
+
* Poll for pending (unacknowledged) interactions.
|
|
1148
|
+
* Useful when not using the WebSocket gateway.
|
|
1149
|
+
*
|
|
1150
|
+
* @example
|
|
1151
|
+
* const pending = await client.interactions.poll({ limit: 20 })
|
|
1152
|
+
* for (const i of pending) {
|
|
1153
|
+
* await client.interactions.respond(i.id, { content: 'Got it!' })
|
|
1154
|
+
* }
|
|
1155
|
+
*/
|
|
1156
|
+
poll(options?: PollInteractionsOptions): Promise<Interaction[]>;
|
|
1157
|
+
/**
|
|
1158
|
+
* Open a modal for the user who triggered an interaction and await their submission.
|
|
1159
|
+
*
|
|
1160
|
+
* Internally this:
|
|
1161
|
+
* 1. Calls `respond(interactionId, { modal })` to push the modal to the client UI.
|
|
1162
|
+
* 2. Listens for the next `interactionCreate` event whose type is `MODAL_SUBMIT`
|
|
1163
|
+
* and whose `customId` matches your modal's `customId`.
|
|
1164
|
+
* 3. Resolves with the submitted `Interaction` (containing `modalData`), or `null`
|
|
1165
|
+
* if the user closes the modal without submitting within the timeout.
|
|
1166
|
+
*
|
|
1167
|
+
* @param interactionId - ID of the triggering interaction.
|
|
1168
|
+
* @param modal - Modal definition (title, customId, fields).
|
|
1169
|
+
* @param options.timeout - Max milliseconds to wait (default: 300 000 = 5 min).
|
|
1170
|
+
*
|
|
1171
|
+
* @example
|
|
1172
|
+
* client.on('interactionCreate', async (interaction) => {
|
|
1173
|
+
* if (interaction.commandName === 'report') {
|
|
1174
|
+
* const submitted = await client.interactions.awaitModal(interaction.id, {
|
|
1175
|
+
* title: 'Submit a report',
|
|
1176
|
+
* customId: 'report_modal',
|
|
1177
|
+
* fields: [
|
|
1178
|
+
* { customId: 'reason', label: 'Reason', type: 'paragraph', required: true, maxLength: 500 },
|
|
1179
|
+
* ],
|
|
1180
|
+
* })
|
|
1181
|
+
*
|
|
1182
|
+
* if (!submitted) {
|
|
1183
|
+
* // User dismissed the modal or timed out — nothing to do
|
|
1184
|
+
* return
|
|
1185
|
+
* }
|
|
1186
|
+
*
|
|
1187
|
+
* const reason = submitted.modalData?.reason
|
|
1188
|
+
* await client.interactions.respond(submitted.id, {
|
|
1189
|
+
* content: `Report received: ${reason}`,
|
|
1190
|
+
* ephemeral: true,
|
|
1191
|
+
* })
|
|
1192
|
+
* }
|
|
1193
|
+
* })
|
|
1194
|
+
*/
|
|
1195
|
+
awaitModal(interactionId: string, modal: BotModalDefinition, options?: {
|
|
1196
|
+
timeout?: number;
|
|
1197
|
+
}): Promise<Interaction | null>;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
declare class PermissionsAPI {
|
|
1201
|
+
private readonly http;
|
|
1202
|
+
constructor(http: HttpClient);
|
|
1203
|
+
/**
|
|
1204
|
+
* Fetch the bot's effective permissions for a given scope.
|
|
1205
|
+
*
|
|
1206
|
+
* Permissions are merged in priority order:
|
|
1207
|
+
* 1. Server-wide base permissions
|
|
1208
|
+
* 2. Role override (if `roleId` provided)
|
|
1209
|
+
* 3. Channel override (if `channelId` provided, highest priority)
|
|
1210
|
+
*
|
|
1211
|
+
* `serverId` is required. `channelId` and `roleId` are optional filters.
|
|
1212
|
+
*
|
|
1213
|
+
* @example
|
|
1214
|
+
* // Effective server-wide permissions
|
|
1215
|
+
* const { permissions } = await client.permissions.get({
|
|
1216
|
+
* serverId: 'server-id',
|
|
1217
|
+
* })
|
|
1218
|
+
* console.log(permissions) // { kick_members: true, ban_members: false, ... }
|
|
1219
|
+
*
|
|
1220
|
+
* @example
|
|
1221
|
+
* // Scoped to a specific channel
|
|
1222
|
+
* const { permissions } = await client.permissions.get({
|
|
1223
|
+
* serverId: 'server-id',
|
|
1224
|
+
* channelId: 'channel-id',
|
|
1225
|
+
* })
|
|
1226
|
+
*
|
|
1227
|
+
* @example
|
|
1228
|
+
* // Scoped to a specific role
|
|
1229
|
+
* const { permissions } = await client.permissions.get({
|
|
1230
|
+
* serverId: 'server-id',
|
|
1231
|
+
* roleId: 'role-id',
|
|
1232
|
+
* })
|
|
1233
|
+
*/
|
|
1234
|
+
get(options: PermissionsQueryOptions): Promise<PermissionsResult>;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
declare class ChannelsAPI {
|
|
1238
|
+
private readonly http;
|
|
1239
|
+
constructor(http: HttpClient);
|
|
1240
|
+
/**
|
|
1241
|
+
* Fetch all channels in a server the bot is a member of.
|
|
1242
|
+
*
|
|
1243
|
+
* @example
|
|
1244
|
+
* const channels = await client.channels.list('server-id')
|
|
1245
|
+
* const textChannels = channels.filter(c => c.type === 'TEXT')
|
|
1246
|
+
*/
|
|
1247
|
+
list(serverId: string): Promise<Channel[]>;
|
|
1248
|
+
/**
|
|
1249
|
+
* Fetch a single channel by ID.
|
|
1250
|
+
*
|
|
1251
|
+
* @example
|
|
1252
|
+
* const channel = await client.channels.fetch('channel-id')
|
|
1253
|
+
* console.log(channel.name, channel.type)
|
|
1254
|
+
*/
|
|
1255
|
+
fetch(channelId: string): Promise<Channel>;
|
|
1256
|
+
/**
|
|
1257
|
+
* Create a new channel in a server.
|
|
1258
|
+
* Requires the `channels.manage` scope.
|
|
1259
|
+
*
|
|
1260
|
+
* @example
|
|
1261
|
+
* const channel = await client.channels.create('server-id', {
|
|
1262
|
+
* name: 'announcements',
|
|
1263
|
+
* type: 'ANNOUNCEMENT',
|
|
1264
|
+
* topic: 'Official announcements only',
|
|
1265
|
+
* })
|
|
1266
|
+
*/
|
|
1267
|
+
create(serverId: string, options: CreateChannelOptions): Promise<Channel>;
|
|
1268
|
+
/**
|
|
1269
|
+
* Edit an existing channel.
|
|
1270
|
+
* Requires the `channels.manage` scope.
|
|
1271
|
+
*
|
|
1272
|
+
* @example
|
|
1273
|
+
* await client.channels.edit('channel-id', { topic: 'New topic!' })
|
|
1274
|
+
*/
|
|
1275
|
+
edit(channelId: string, options: EditChannelOptions): Promise<Channel>;
|
|
1276
|
+
/**
|
|
1277
|
+
* Delete a channel.
|
|
1278
|
+
* Requires the `channels.manage` scope.
|
|
1279
|
+
*
|
|
1280
|
+
* @example
|
|
1281
|
+
* await client.channels.delete('channel-id')
|
|
1282
|
+
*/
|
|
1283
|
+
delete(channelId: string): Promise<{
|
|
1284
|
+
ok: true;
|
|
1285
|
+
}>;
|
|
1286
|
+
/**
|
|
1287
|
+
* Fetch messages from a channel.
|
|
1288
|
+
*
|
|
1289
|
+
* @example
|
|
1290
|
+
* const messages = await client.channels.fetchMessages('channel-id', { limit: 50 })
|
|
1291
|
+
*/
|
|
1292
|
+
fetchMessages(channelId: string, options?: FetchMessagesOptions): Promise<Message[]>;
|
|
1293
|
+
/**
|
|
1294
|
+
* Fetch all pinned messages in a channel.
|
|
1295
|
+
*
|
|
1296
|
+
* @example
|
|
1297
|
+
* const pins = await client.channels.fetchPins('channel-id')
|
|
1298
|
+
*/
|
|
1299
|
+
fetchPins(channelId: string): Promise<Message[]>;
|
|
1300
|
+
/**
|
|
1301
|
+
* Send a typing indicator in a channel.
|
|
1302
|
+
* Displayed to users for ~5 seconds.
|
|
1303
|
+
*
|
|
1304
|
+
* @example
|
|
1305
|
+
* await client.channels.startTyping('channel-id')
|
|
1306
|
+
*/
|
|
1307
|
+
startTyping(channelId: string): Promise<{
|
|
1308
|
+
ok: true;
|
|
1309
|
+
}>;
|
|
1310
|
+
/**
|
|
1311
|
+
* Bulk delete up to 100 messages from a channel at once.
|
|
1312
|
+
* Requires the `messages.manage` scope.
|
|
1313
|
+
* Soft-deletes all specified messages in a single operation.
|
|
1314
|
+
*
|
|
1315
|
+
* @example
|
|
1316
|
+
* const result = await client.channels.bulkDelete('channel-id', ['msg1', 'msg2', 'msg3'])
|
|
1317
|
+
* console.log(`Deleted ${result.deleted} messages`)
|
|
1318
|
+
*/
|
|
1319
|
+
bulkDelete(channelId: string, messageIds: string[]): Promise<BulkDeleteResult>;
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
declare class ReactionsAPI {
|
|
1323
|
+
private readonly http;
|
|
1324
|
+
constructor(http: HttpClient);
|
|
1325
|
+
/**
|
|
1326
|
+
* Add a reaction to a message.
|
|
1327
|
+
* Use a plain emoji character or a custom emoji ID.
|
|
1328
|
+
*
|
|
1329
|
+
* @example
|
|
1330
|
+
* await client.reactions.add('message-id', '👍')
|
|
1331
|
+
* await client.reactions.add('message-id', '🎉')
|
|
1332
|
+
*/
|
|
1333
|
+
add(messageId: string, emoji: string): Promise<{
|
|
1334
|
+
ok: true;
|
|
1335
|
+
}>;
|
|
1336
|
+
/**
|
|
1337
|
+
* Remove the bot's reaction from a message.
|
|
1338
|
+
*
|
|
1339
|
+
* @example
|
|
1340
|
+
* await client.reactions.remove('message-id', '👍')
|
|
1341
|
+
*/
|
|
1342
|
+
remove(messageId: string, emoji: string): Promise<{
|
|
1343
|
+
ok: true;
|
|
1344
|
+
}>;
|
|
1345
|
+
/**
|
|
1346
|
+
* Remove all reactions from a message.
|
|
1347
|
+
* Requires the `messages.manage` scope.
|
|
1348
|
+
*
|
|
1349
|
+
* @example
|
|
1350
|
+
* await client.reactions.removeAll('message-id')
|
|
1351
|
+
*/
|
|
1352
|
+
removeAll(messageId: string): Promise<{
|
|
1353
|
+
ok: true;
|
|
1354
|
+
}>;
|
|
1355
|
+
/**
|
|
1356
|
+
* Remove all reactions of a specific emoji from a message.
|
|
1357
|
+
* Requires the `messages.manage` scope.
|
|
1358
|
+
*
|
|
1359
|
+
* @example
|
|
1360
|
+
* await client.reactions.removeEmoji('message-id', '👍')
|
|
1361
|
+
*/
|
|
1362
|
+
removeEmoji(messageId: string, emoji: string): Promise<{
|
|
1363
|
+
ok: true;
|
|
1364
|
+
}>;
|
|
1365
|
+
/**
|
|
1366
|
+
* Fetch all reactions on a message, broken down by emoji.
|
|
1367
|
+
*
|
|
1368
|
+
* @example
|
|
1369
|
+
* const reactions = await client.reactions.fetch('message-id')
|
|
1370
|
+
* for (const r of reactions) {
|
|
1371
|
+
* console.log(`${r.emoji} — ${r.count} reactions from ${r.users.map(u => u.username).join(', ')}`)
|
|
1372
|
+
* }
|
|
1373
|
+
*/
|
|
1374
|
+
fetch(messageId: string): Promise<ReactionDetail[]>;
|
|
1375
|
+
/**
|
|
1376
|
+
* Fetch reactions for a specific emoji on a message.
|
|
1377
|
+
*
|
|
1378
|
+
* @example
|
|
1379
|
+
* const detail = await client.reactions.fetchEmoji('message-id', '👍')
|
|
1380
|
+
* console.log(`${detail.count} thumbs ups`)
|
|
1381
|
+
*/
|
|
1382
|
+
fetchEmoji(messageId: string, emoji: string): Promise<ReactionDetail>;
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
declare class RolesAPI {
|
|
1386
|
+
private readonly http;
|
|
1387
|
+
constructor(http: HttpClient);
|
|
1388
|
+
/**
|
|
1389
|
+
* List all custom roles in a server, sorted by position.
|
|
1390
|
+
*
|
|
1391
|
+
* @example
|
|
1392
|
+
* const roles = await client.roles.list('server-id')
|
|
1393
|
+
* const adminRole = roles.find(r => r.name === 'Admin')
|
|
1394
|
+
*/
|
|
1395
|
+
list(serverId: string): Promise<Role[]>;
|
|
1396
|
+
/**
|
|
1397
|
+
* Create a new custom role in a server.
|
|
1398
|
+
* Requires the `roles.manage` scope.
|
|
1399
|
+
*
|
|
1400
|
+
* @example
|
|
1401
|
+
* const role = await client.roles.create('server-id', {
|
|
1402
|
+
* name: 'Verified',
|
|
1403
|
+
* color: '#00d4ff',
|
|
1404
|
+
* hoist: true,
|
|
1405
|
+
* permissions: { sendMessages: true, addReactions: true },
|
|
1406
|
+
* })
|
|
1407
|
+
*/
|
|
1408
|
+
create(serverId: string, options: RoleCreateOptions): Promise<Role>;
|
|
1409
|
+
/**
|
|
1410
|
+
* Edit an existing role.
|
|
1411
|
+
* Requires the `roles.manage` scope.
|
|
1412
|
+
*
|
|
1413
|
+
* @example
|
|
1414
|
+
* await client.roles.edit('role-id', { color: '#ff0000', name: 'Danger' })
|
|
1415
|
+
*/
|
|
1416
|
+
edit(roleId: string, options: RoleEditOptions): Promise<Role>;
|
|
1417
|
+
/**
|
|
1418
|
+
* Delete a custom role from a server.
|
|
1419
|
+
* Any member currently assigned this role will have it removed automatically.
|
|
1420
|
+
* Requires the `roles.manage` scope.
|
|
1421
|
+
*
|
|
1422
|
+
* @example
|
|
1423
|
+
* await client.roles.delete('role-id')
|
|
1424
|
+
*/
|
|
1425
|
+
delete(roleId: string): Promise<{
|
|
1426
|
+
ok: true;
|
|
1427
|
+
}>;
|
|
1428
|
+
/**
|
|
1429
|
+
* Assign a custom role to a server member.
|
|
1430
|
+
* Requires the `members.roles` scope.
|
|
1431
|
+
*
|
|
1432
|
+
* @example
|
|
1433
|
+
* await client.roles.assign('server-id', 'user-id', 'role-id')
|
|
1434
|
+
*/
|
|
1435
|
+
assign(serverId: string, userId: string, roleId: string): Promise<{
|
|
1436
|
+
ok: true;
|
|
1437
|
+
}>;
|
|
1438
|
+
/**
|
|
1439
|
+
* Remove a custom role from a server member.
|
|
1440
|
+
* Requires the `members.roles` scope.
|
|
1441
|
+
*
|
|
1442
|
+
* @example
|
|
1443
|
+
* await client.roles.remove('server-id', 'user-id', 'role-id')
|
|
1444
|
+
*/
|
|
1445
|
+
remove(serverId: string, userId: string, roleId: string): Promise<{
|
|
1446
|
+
ok: true;
|
|
1447
|
+
}>;
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
declare class InvitesAPI {
|
|
1451
|
+
private readonly http;
|
|
1452
|
+
constructor(http: HttpClient);
|
|
1453
|
+
/**
|
|
1454
|
+
* List all active invites for a server.
|
|
1455
|
+
*
|
|
1456
|
+
* @example
|
|
1457
|
+
* const invites = await client.invites.list('server-id')
|
|
1458
|
+
* console.log(`${invites.length} active invites`)
|
|
1459
|
+
*/
|
|
1460
|
+
list(serverId: string): Promise<Invite[]>;
|
|
1461
|
+
/**
|
|
1462
|
+
* Create a new invite for a server.
|
|
1463
|
+
* Requires the `invites.manage` scope.
|
|
1464
|
+
*
|
|
1465
|
+
* @example
|
|
1466
|
+
* // A one-time invite that expires in 24 hours
|
|
1467
|
+
* const invite = await client.invites.create('server-id', {
|
|
1468
|
+
* maxUses: 1,
|
|
1469
|
+
* expiresAt: new Date(Date.now() + 86_400_000).toISOString(),
|
|
1470
|
+
* })
|
|
1471
|
+
* console.log(`https://novachatapp.com/invite/${invite.code}`)
|
|
1472
|
+
*/
|
|
1473
|
+
create(serverId: string, options?: InviteCreateOptions): Promise<Invite>;
|
|
1474
|
+
/**
|
|
1475
|
+
* Fetch a single invite by its code.
|
|
1476
|
+
*
|
|
1477
|
+
* @example
|
|
1478
|
+
* const invite = await client.invites.fetch('abc123')
|
|
1479
|
+
* console.log(`${invite.uses} / ${invite.maxUses ?? '∞'} uses`)
|
|
1480
|
+
*/
|
|
1481
|
+
fetch(code: string): Promise<Invite>;
|
|
1482
|
+
/**
|
|
1483
|
+
* Revoke (delete) an invite.
|
|
1484
|
+
* Requires the `invites.manage` scope.
|
|
1485
|
+
*
|
|
1486
|
+
* @example
|
|
1487
|
+
* await client.invites.revoke('abc123')
|
|
1488
|
+
*/
|
|
1489
|
+
revoke(code: string): Promise<{
|
|
1490
|
+
ok: true;
|
|
1491
|
+
}>;
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
declare class WebhooksAPI {
|
|
1495
|
+
private readonly http;
|
|
1496
|
+
constructor(http: HttpClient);
|
|
1497
|
+
/**
|
|
1498
|
+
* List all webhooks in a channel.
|
|
1499
|
+
* Requires the `webhooks.manage` scope.
|
|
1500
|
+
*
|
|
1501
|
+
* @example
|
|
1502
|
+
* const webhooks = await client.webhooks.list('channel-id')
|
|
1503
|
+
*/
|
|
1504
|
+
list(channelId: string): Promise<Webhook[]>;
|
|
1505
|
+
/**
|
|
1506
|
+
* Create a webhook in a channel.
|
|
1507
|
+
* Requires the `webhooks.manage` scope.
|
|
1508
|
+
*
|
|
1509
|
+
* @example
|
|
1510
|
+
* const webhook = await client.webhooks.create('channel-id', { name: 'Announcements' })
|
|
1511
|
+
* console.log('Token:', webhook.token)
|
|
1512
|
+
*/
|
|
1513
|
+
create(channelId: string, options: WebhookCreateOptions): Promise<Webhook>;
|
|
1514
|
+
/**
|
|
1515
|
+
* Fetch a webhook by its ID.
|
|
1516
|
+
* Requires the `webhooks.manage` scope.
|
|
1517
|
+
*
|
|
1518
|
+
* @example
|
|
1519
|
+
* const webhook = await client.webhooks.fetch('webhook-id')
|
|
1520
|
+
*/
|
|
1521
|
+
fetch(webhookId: string): Promise<Webhook>;
|
|
1522
|
+
/**
|
|
1523
|
+
* Edit a webhook's name and/or target channel.
|
|
1524
|
+
* Requires the `webhooks.manage` scope.
|
|
1525
|
+
*
|
|
1526
|
+
* @example
|
|
1527
|
+
* await client.webhooks.edit('webhook-id', { name: 'New Name', channelId: 'other-channel' })
|
|
1528
|
+
*/
|
|
1529
|
+
edit(webhookId: string, options: WebhookEditOptions): Promise<Webhook>;
|
|
1530
|
+
/**
|
|
1531
|
+
* Delete a webhook.
|
|
1532
|
+
* Requires the `webhooks.manage` scope.
|
|
1533
|
+
*
|
|
1534
|
+
* @example
|
|
1535
|
+
* await client.webhooks.delete('webhook-id')
|
|
1536
|
+
*/
|
|
1537
|
+
delete(webhookId: string): Promise<{
|
|
1538
|
+
ok: true;
|
|
1539
|
+
}>;
|
|
1540
|
+
/**
|
|
1541
|
+
* Execute a webhook — post a message to the webhook's channel.
|
|
1542
|
+
* Does not require any extra scope (uses the webhook data already owned by
|
|
1543
|
+
* this bot application).
|
|
1544
|
+
*
|
|
1545
|
+
* @example
|
|
1546
|
+
* await client.webhooks.execute('webhook-id', {
|
|
1547
|
+
* content: '🚀 Deployment successful!',
|
|
1548
|
+
* username: 'Deploy Bot',
|
|
1549
|
+
* })
|
|
1550
|
+
*/
|
|
1551
|
+
execute(webhookId: string, options: ExecuteWebhookOptions): Promise<Message>;
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
declare class AuditLogAPI {
|
|
1555
|
+
private readonly http;
|
|
1556
|
+
constructor(http: HttpClient);
|
|
1557
|
+
/**
|
|
1558
|
+
* Fetch the audit log for a server.
|
|
1559
|
+
* Requires the `audit-log.read` scope.
|
|
1560
|
+
*
|
|
1561
|
+
* You can filter by action type, actor user ID, and paginate backwards
|
|
1562
|
+
* using the `before` cursor (an ISO timestamp).
|
|
1563
|
+
*
|
|
1564
|
+
* @example
|
|
1565
|
+
* // Most recent 50 entries
|
|
1566
|
+
* const entries = await client.auditLog.fetch('server-id')
|
|
1567
|
+
*
|
|
1568
|
+
* // Only kick and ban actions
|
|
1569
|
+
* const modActions = await client.auditLog.fetch('server-id', {
|
|
1570
|
+
* action: 'member.banned',
|
|
1571
|
+
* limit: 20,
|
|
1572
|
+
* })
|
|
1573
|
+
*
|
|
1574
|
+
* // All actions performed by a specific user
|
|
1575
|
+
* const byUser = await client.auditLog.fetch('server-id', { userId: 'user-id' })
|
|
1576
|
+
*/
|
|
1577
|
+
fetch(serverId: string, options?: FetchAuditLogsOptions): Promise<AuditLogEntry[]>;
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
declare class ForumAPI {
|
|
1581
|
+
private readonly http;
|
|
1582
|
+
constructor(http: HttpClient);
|
|
1583
|
+
/**
|
|
1584
|
+
* List forum posts in a FORUM channel.
|
|
1585
|
+
*
|
|
1586
|
+
* @example
|
|
1587
|
+
* const posts = await client.forum.list('channel-id')
|
|
1588
|
+
*/
|
|
1589
|
+
list(channelId: string, options?: FetchForumPostsOptions): Promise<ForumPost[]>;
|
|
1590
|
+
/**
|
|
1591
|
+
* Create a forum post in a FORUM channel.
|
|
1592
|
+
*
|
|
1593
|
+
* @example
|
|
1594
|
+
* const post = await client.forum.create('channel-id', {
|
|
1595
|
+
* title: 'Ideas thread',
|
|
1596
|
+
* body: 'Post your ideas here!',
|
|
1597
|
+
* tags: ['idea', 'discussion'],
|
|
1598
|
+
* })
|
|
1599
|
+
*/
|
|
1600
|
+
create(channelId: string, options: CreateForumPostOptions): Promise<ForumPost>;
|
|
1601
|
+
/**
|
|
1602
|
+
* Edit a forum post.
|
|
1603
|
+
* The bot must be the author of the post.
|
|
1604
|
+
*
|
|
1605
|
+
* @example
|
|
1606
|
+
* await client.forum.edit('post-id', { closed: true })
|
|
1607
|
+
*/
|
|
1608
|
+
edit(postId: string, options: EditForumPostOptions): Promise<ForumPost>;
|
|
1609
|
+
/**
|
|
1610
|
+
* Delete a forum post.
|
|
1611
|
+
* The bot must be the author of the post.
|
|
1612
|
+
*
|
|
1613
|
+
* @example
|
|
1614
|
+
* await client.forum.delete('post-id')
|
|
1615
|
+
*/
|
|
1616
|
+
delete(postId: string): Promise<void>;
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
declare class EventsAPI {
|
|
1620
|
+
private readonly http;
|
|
1621
|
+
constructor(http: HttpClient);
|
|
1622
|
+
/**
|
|
1623
|
+
* List server events.
|
|
1624
|
+
*
|
|
1625
|
+
* @example
|
|
1626
|
+
* const events = await client.events.list('server-id', { upcoming: true })
|
|
1627
|
+
*/
|
|
1628
|
+
list(serverId: string, options?: FetchEventsOptions): Promise<ServerEvent[]>;
|
|
1629
|
+
/**
|
|
1630
|
+
* Fetch a single server event by ID.
|
|
1631
|
+
* Returns full attendee list.
|
|
1632
|
+
*
|
|
1633
|
+
* @example
|
|
1634
|
+
* const event = await client.events.fetch('event-id')
|
|
1635
|
+
*/
|
|
1636
|
+
fetch(eventId: string): Promise<ServerEvent & {
|
|
1637
|
+
attendees: ServerEventAttendee[];
|
|
1638
|
+
}>;
|
|
1639
|
+
/**
|
|
1640
|
+
* Create a server event.
|
|
1641
|
+
*
|
|
1642
|
+
* @example
|
|
1643
|
+
* const event = await client.events.create('server-id', {
|
|
1644
|
+
* title: 'Game Night',
|
|
1645
|
+
* description: 'Friday fun!',
|
|
1646
|
+
* startAt: new Date(Date.now() + 86400_000).toISOString(),
|
|
1647
|
+
* })
|
|
1648
|
+
*/
|
|
1649
|
+
create(serverId: string, options: CreateEventOptions): Promise<ServerEvent>;
|
|
1650
|
+
/**
|
|
1651
|
+
* Edit a server event.
|
|
1652
|
+
*
|
|
1653
|
+
* @example
|
|
1654
|
+
* await client.events.edit('event-id', { title: 'Game Night v2' })
|
|
1655
|
+
*/
|
|
1656
|
+
edit(eventId: string, options: EditEventOptions): Promise<ServerEvent>;
|
|
1657
|
+
/**
|
|
1658
|
+
* Delete a server event.
|
|
1659
|
+
*
|
|
1660
|
+
* @example
|
|
1661
|
+
* await client.events.delete('event-id')
|
|
1662
|
+
*/
|
|
1663
|
+
delete(eventId: string): Promise<void>;
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
declare class CategoriesAPI {
|
|
1667
|
+
private readonly http;
|
|
1668
|
+
constructor(http: HttpClient);
|
|
1669
|
+
/**
|
|
1670
|
+
* List all channel categories in a server, ordered by position.
|
|
1671
|
+
*
|
|
1672
|
+
* @example
|
|
1673
|
+
* const cats = await client.categories.list('server-id')
|
|
1674
|
+
*/
|
|
1675
|
+
list(serverId: string): Promise<ChannelCategory[]>;
|
|
1676
|
+
/**
|
|
1677
|
+
* Create a new channel category.
|
|
1678
|
+
*
|
|
1679
|
+
* @example
|
|
1680
|
+
* const cat = await client.categories.create('server-id', { name: 'General', position: 0 })
|
|
1681
|
+
*/
|
|
1682
|
+
create(serverId: string, options: CreateCategoryOptions): Promise<ChannelCategory>;
|
|
1683
|
+
/**
|
|
1684
|
+
* Edit an existing channel category.
|
|
1685
|
+
*
|
|
1686
|
+
* @example
|
|
1687
|
+
* await client.categories.edit('cat-id', { name: 'Renamed' })
|
|
1688
|
+
*/
|
|
1689
|
+
edit(categoryId: string, options: EditCategoryOptions): Promise<ChannelCategory>;
|
|
1690
|
+
/**
|
|
1691
|
+
* Delete a channel category.
|
|
1692
|
+
*
|
|
1693
|
+
* @example
|
|
1694
|
+
* await client.categories.delete('cat-id')
|
|
1695
|
+
*/
|
|
1696
|
+
delete(categoryId: string): Promise<void>;
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
declare class AutoModAPI {
|
|
1700
|
+
private readonly http;
|
|
1701
|
+
constructor(http: HttpClient);
|
|
1702
|
+
/**
|
|
1703
|
+
* List all automod rules for a server.
|
|
1704
|
+
*
|
|
1705
|
+
* @example
|
|
1706
|
+
* const rules = await client.automod.list('server-id')
|
|
1707
|
+
*/
|
|
1708
|
+
list(serverId: string): Promise<AutoModRule[]>;
|
|
1709
|
+
/**
|
|
1710
|
+
* Create a new automod rule.
|
|
1711
|
+
*
|
|
1712
|
+
* @example
|
|
1713
|
+
* await client.automod.create('server-id', { type: 'BLOCKED_WORD', value: 'badword' })
|
|
1714
|
+
* await client.automod.create('server-id', { type: 'BLOCKED_LINK', value: 'example.com' })
|
|
1715
|
+
*/
|
|
1716
|
+
create(serverId: string, options: CreateAutoModRuleOptions): Promise<AutoModRule>;
|
|
1717
|
+
/**
|
|
1718
|
+
* Enable / disable a rule or update the blocked value.
|
|
1719
|
+
*
|
|
1720
|
+
* @example
|
|
1721
|
+
* await client.automod.edit('rule-id', { enabled: false })
|
|
1722
|
+
*/
|
|
1723
|
+
edit(ruleId: string, options: EditAutoModRuleOptions): Promise<AutoModRule>;
|
|
1724
|
+
/**
|
|
1725
|
+
* Delete an automod rule.
|
|
1726
|
+
*
|
|
1727
|
+
* @example
|
|
1728
|
+
* await client.automod.delete('rule-id')
|
|
1729
|
+
*/
|
|
1730
|
+
delete(ruleId: string): Promise<void>;
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
declare class UsersAPI {
|
|
1734
|
+
private readonly http;
|
|
1735
|
+
constructor(http: HttpClient);
|
|
1736
|
+
/**
|
|
1737
|
+
* Fetch a user's public profile by ID.
|
|
1738
|
+
*
|
|
1739
|
+
* @example
|
|
1740
|
+
* const user = await client.users.fetch('user-id')
|
|
1741
|
+
* console.log(user.displayName)
|
|
1742
|
+
*/
|
|
1743
|
+
fetch(userId: string): Promise<UserProfile>;
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
type TextInputStyle = 'short' | 'paragraph';
|
|
1747
|
+
/**
|
|
1748
|
+
* Fluent builder for a single text-input field inside a modal.
|
|
1749
|
+
*
|
|
1750
|
+
* @example
|
|
1751
|
+
* new TextInputBuilder()
|
|
1752
|
+
* .setCustomId('reason')
|
|
1753
|
+
* .setLabel('Reason')
|
|
1754
|
+
* .setStyle('paragraph')
|
|
1755
|
+
* .setPlaceholder('Describe the issue in detail…')
|
|
1756
|
+
* .setRequired(true)
|
|
1757
|
+
* .setMaxLength(1000)
|
|
1758
|
+
*/
|
|
1759
|
+
declare class TextInputBuilder {
|
|
1760
|
+
private _data;
|
|
1761
|
+
/** Unique ID for this field — the key in `interaction.modalData` on submit. */
|
|
1762
|
+
setCustomId(customId: string): this;
|
|
1763
|
+
/** Label shown above the input inside the modal. */
|
|
1764
|
+
setLabel(label: string): this;
|
|
1765
|
+
/**
|
|
1766
|
+
* Input style:
|
|
1767
|
+
* - `'short'` — single-line text input
|
|
1768
|
+
* - `'paragraph'` — multi-line textarea
|
|
1769
|
+
*/
|
|
1770
|
+
setStyle(style: TextInputStyle): this;
|
|
1771
|
+
/** Greyed-out hint text shown when the field is empty. */
|
|
1772
|
+
setPlaceholder(placeholder: string): this;
|
|
1773
|
+
/** Whether the user must fill in this field before submitting. */
|
|
1774
|
+
setRequired(required?: boolean): this;
|
|
1775
|
+
/** Minimum number of characters required. */
|
|
1776
|
+
setMinLength(min: number): this;
|
|
1777
|
+
/** Maximum number of characters allowed. */
|
|
1778
|
+
setMaxLength(max: number): this;
|
|
1779
|
+
/** Pre-filled default value. */
|
|
1780
|
+
setValue(value: string): this;
|
|
1781
|
+
toJSON(): BotModalField;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
type FieldLike = TextInputBuilder | BotModalField;
|
|
1785
|
+
/**
|
|
1786
|
+
* Fluent builder for bot modal dialogs.
|
|
1787
|
+
*
|
|
1788
|
+
* @example
|
|
1789
|
+
* const modal = new ModalBuilder()
|
|
1790
|
+
* .setTitle('Submit a report')
|
|
1791
|
+
* .setCustomId('report_modal')
|
|
1792
|
+
* .addField(
|
|
1793
|
+
* new TextInputBuilder()
|
|
1794
|
+
* .setCustomId('reason')
|
|
1795
|
+
* .setLabel('Reason')
|
|
1796
|
+
* .setStyle('paragraph')
|
|
1797
|
+
* .setRequired(true)
|
|
1798
|
+
* .setMaxLength(1000)
|
|
1799
|
+
* )
|
|
1800
|
+
* .addField(
|
|
1801
|
+
* new TextInputBuilder()
|
|
1802
|
+
* .setCustomId('proof')
|
|
1803
|
+
* .setLabel('Evidence (optional URL)')
|
|
1804
|
+
* .setStyle('short')
|
|
1805
|
+
* )
|
|
1806
|
+
*
|
|
1807
|
+
* const submitted = await interaction.openModal(modal)
|
|
1808
|
+
* if (submitted) {
|
|
1809
|
+
* const reason = submitted.modalData.reason
|
|
1810
|
+
* }
|
|
1811
|
+
*/
|
|
1812
|
+
declare class ModalBuilder {
|
|
1813
|
+
private _title;
|
|
1814
|
+
private _customId;
|
|
1815
|
+
private readonly _fields;
|
|
1816
|
+
/** Title shown at the top of the modal dialog. */
|
|
1817
|
+
setTitle(title: string): this;
|
|
1818
|
+
/** Custom ID passed back with the `MODAL_SUBMIT` interaction. */
|
|
1819
|
+
setCustomId(customId: string): this;
|
|
1820
|
+
/** Add a single text-input field. */
|
|
1821
|
+
addField(field: FieldLike): this;
|
|
1822
|
+
/** Add multiple fields at once. */
|
|
1823
|
+
addFields(...fields: FieldLike[]): this;
|
|
1824
|
+
toJSON(): BotModalDefinition;
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
/**
|
|
1828
|
+
* Typed accessor for slash- and prefix-command options.
|
|
1829
|
+
* Available via `interaction.options`.
|
|
1830
|
+
*
|
|
1831
|
+
* @example
|
|
1832
|
+
* client.command('ban', async (interaction) => {
|
|
1833
|
+
* const userId = interaction.options.getString('user', true)
|
|
1834
|
+
* const reason = interaction.options.getString('reason') ?? 'No reason given'
|
|
1835
|
+
* })
|
|
1836
|
+
*/
|
|
1837
|
+
declare class InteractionOptions {
|
|
1838
|
+
private readonly _map;
|
|
1839
|
+
constructor(data: unknown);
|
|
1840
|
+
/** Whether this option was supplied by the user. */
|
|
1841
|
+
has(name: string): boolean;
|
|
1842
|
+
/** @overload Required — never returns `null`. */
|
|
1843
|
+
getString(name: string, required: true): string;
|
|
1844
|
+
/** @overload Optional — returns `null` when not supplied. */
|
|
1845
|
+
getString(name: string, required?: false): string | null;
|
|
1846
|
+
/** @overload Required — never returns `null`. */
|
|
1847
|
+
getInteger(name: string, required: true): number;
|
|
1848
|
+
/** @overload Optional — returns `null` when not supplied. */
|
|
1849
|
+
getInteger(name: string, required?: false): number | null;
|
|
1850
|
+
/** @overload Required — never returns `null`. */
|
|
1851
|
+
getNumber(name: string, required: true): number;
|
|
1852
|
+
/** @overload Optional — returns `null` when not supplied. */
|
|
1853
|
+
getNumber(name: string, required?: false): number | null;
|
|
1854
|
+
/** Returns `true` or `false`, or `null` if not supplied. */
|
|
1855
|
+
getBoolean(name: string): boolean | null;
|
|
1856
|
+
/**
|
|
1857
|
+
* Returns the mentioned **user ID** string (type `USER` option).
|
|
1858
|
+
* @overload Required.
|
|
1859
|
+
*/
|
|
1860
|
+
getUser(name: string, required: true): string;
|
|
1861
|
+
getUser(name: string, required?: false): string | null;
|
|
1862
|
+
/**
|
|
1863
|
+
* Returns the mentioned **channel ID** string (type `CHANNEL` option).
|
|
1864
|
+
* @overload Required.
|
|
1865
|
+
*/
|
|
1866
|
+
getChannel(name: string, required: true): string;
|
|
1867
|
+
getChannel(name: string, required?: false): string | null;
|
|
1868
|
+
/**
|
|
1869
|
+
* Returns the mentioned **role ID** string (type `ROLE` option).
|
|
1870
|
+
* @overload Required.
|
|
1871
|
+
*/
|
|
1872
|
+
getRole(name: string, required: true): string;
|
|
1873
|
+
getRole(name: string, required?: false): string | null;
|
|
1874
|
+
}
|
|
1875
|
+
/**
|
|
1876
|
+
* Rich wrapper around a raw bot interaction.
|
|
1877
|
+
* Returned by `interactionCreate`, `client.command()`, `client.button()`, `client.selectMenu()`.
|
|
1878
|
+
*
|
|
1879
|
+
* @example
|
|
1880
|
+
* client.on('interactionCreate', async (interaction) => {
|
|
1881
|
+
* if (interaction.isSlashCommand() && interaction.commandName === 'ping') {
|
|
1882
|
+
* await interaction.reply('Pong! 🏓')
|
|
1883
|
+
* }
|
|
1884
|
+
* })
|
|
1885
|
+
*
|
|
1886
|
+
* // Or use built-in routing:
|
|
1887
|
+
* client.command('ping', async (interaction) => {
|
|
1888
|
+
* await interaction.reply('Pong! 🏓')
|
|
1889
|
+
* })
|
|
1890
|
+
*/
|
|
1891
|
+
declare class NovaInteraction {
|
|
1892
|
+
private readonly _raw;
|
|
1893
|
+
private readonly _api;
|
|
1894
|
+
/** Unique interaction ID. */
|
|
1895
|
+
readonly id: string;
|
|
1896
|
+
/** Interaction type. Use type guards (`.isSlashCommand()` etc.) for narrowing. */
|
|
1897
|
+
readonly type: InteractionType;
|
|
1898
|
+
/** Command name — set for `SLASH_COMMAND` and `PREFIX_COMMAND` interactions. */
|
|
1899
|
+
readonly commandName: string | null;
|
|
1900
|
+
/** Component custom ID — set for `BUTTON_CLICK`, `SELECT_MENU`, and `MODAL_SUBMIT` interactions. */
|
|
1901
|
+
readonly customId: string | null;
|
|
1902
|
+
/** ID of the user who triggered this interaction. */
|
|
1903
|
+
readonly userId: string;
|
|
1904
|
+
/** ID of the channel where this interaction occurred. */
|
|
1905
|
+
readonly channelId: string;
|
|
1906
|
+
/** ID of the server where this interaction occurred (`null` in DMs). */
|
|
1907
|
+
readonly serverId: string | null;
|
|
1908
|
+
/** ID of the message that contained the button/select component (if any). */
|
|
1909
|
+
readonly triggerMsgId: string | null;
|
|
1910
|
+
/** Selected option values for `SELECT_MENU` interactions. */
|
|
1911
|
+
readonly values: string[];
|
|
1912
|
+
/**
|
|
1913
|
+
* Field values submitted in a `MODAL_SUBMIT` interaction.
|
|
1914
|
+
* Keys are the `customId`s of the `TextInputBuilder` fields.
|
|
1915
|
+
*
|
|
1916
|
+
* @example
|
|
1917
|
+
* const reason = interaction.modalData.reason
|
|
1918
|
+
*/
|
|
1919
|
+
readonly modalData: Record<string, string>;
|
|
1920
|
+
/** ISO timestamp of when the interaction was created. */
|
|
1921
|
+
readonly createdAt: string;
|
|
1922
|
+
/**
|
|
1923
|
+
* Typed accessor for slash/prefix command options.
|
|
1924
|
+
*
|
|
1925
|
+
* @example
|
|
1926
|
+
* const userId = interaction.options.getUser('user', true)
|
|
1927
|
+
* const reason = interaction.options.getString('reason') ?? 'No reason given'
|
|
1928
|
+
*/
|
|
1929
|
+
readonly options: InteractionOptions;
|
|
1930
|
+
constructor(_raw: Interaction, _api: InteractionsAPI);
|
|
1931
|
+
/**
|
|
1932
|
+
* For `AUTOCOMPLETE` interactions — the option being completed.
|
|
1933
|
+
* Contains `name` (option name) and `value` (partial text typed so far).
|
|
1934
|
+
* `null` for all other interaction types.
|
|
1935
|
+
*
|
|
1936
|
+
* @example
|
|
1937
|
+
* client.autocomplete('search', async (interaction) => {
|
|
1938
|
+
* const query = interaction.autocomplete?.value ?? ''
|
|
1939
|
+
* await interaction.respondAutocomplete([{ name: query, value: query }])
|
|
1940
|
+
* })
|
|
1941
|
+
*/
|
|
1942
|
+
get autocomplete(): {
|
|
1943
|
+
name: string;
|
|
1944
|
+
value: string;
|
|
1945
|
+
} | null;
|
|
1946
|
+
/** `true` when triggered by a `/slash` command. */
|
|
1947
|
+
isSlashCommand(): boolean;
|
|
1948
|
+
/** `true` when triggered by a `!prefix` command. */
|
|
1949
|
+
isPrefixCommand(): boolean;
|
|
1950
|
+
/** `true` for both slash and prefix commands. */
|
|
1951
|
+
isCommand(): boolean;
|
|
1952
|
+
/** `true` when a button component was clicked. */
|
|
1953
|
+
isButton(): boolean;
|
|
1954
|
+
/** `true` when a select-menu option was chosen. */
|
|
1955
|
+
isSelectMenu(): boolean;
|
|
1956
|
+
/** `true` when the user submitted a modal form. */
|
|
1957
|
+
isModalSubmit(): boolean;
|
|
1958
|
+
/** `true` during autocomplete suggestion requests. */
|
|
1959
|
+
isAutocomplete(): boolean;
|
|
1960
|
+
/**
|
|
1961
|
+
* Send autocomplete suggestions back to the user.
|
|
1962
|
+
* Call this inside a `client.autocomplete()` handler.
|
|
1963
|
+
* Up to 25 choices are shown; each needs a `name` (displayed) and `value` (submitted).
|
|
1964
|
+
*
|
|
1965
|
+
* @example
|
|
1966
|
+
* client.autocomplete('color', async (interaction) => {
|
|
1967
|
+
* const query = interaction.autocomplete?.value ?? ''
|
|
1968
|
+
* const colors = ['red', 'green', 'blue'].filter(c => c.startsWith(query))
|
|
1969
|
+
* await interaction.respondAutocomplete(colors.map(c => ({ name: c, value: c })))
|
|
1970
|
+
* })
|
|
1971
|
+
*/
|
|
1972
|
+
respondAutocomplete(choices: Array<{
|
|
1973
|
+
name: string;
|
|
1974
|
+
value: string | number;
|
|
1975
|
+
}>): Promise<{
|
|
1976
|
+
ok: true;
|
|
1977
|
+
}>;
|
|
1978
|
+
/** `true` when triggered via a context-menu command. */
|
|
1979
|
+
isContextMenu(): boolean;
|
|
1980
|
+
/**
|
|
1981
|
+
* Respond with a message.
|
|
1982
|
+
* Accepts a plain string or a full options object.
|
|
1983
|
+
*
|
|
1984
|
+
* @example
|
|
1985
|
+
* await interaction.reply('Pong! 🏓')
|
|
1986
|
+
* await interaction.reply({ content: 'Done!', ephemeral: true })
|
|
1987
|
+
* await interaction.reply({ embed: new EmbedBuilder().setTitle('Stats').toJSON() })
|
|
1988
|
+
*/
|
|
1989
|
+
reply(options: RespondInteractionOptions | string): Promise<Message | {
|
|
1990
|
+
ok: true;
|
|
1991
|
+
ephemeral: true;
|
|
1992
|
+
}>;
|
|
1993
|
+
/**
|
|
1994
|
+
* Respond with a message **only visible to the user** who triggered the interaction.
|
|
1995
|
+
*
|
|
1996
|
+
* @example
|
|
1997
|
+
* await interaction.replyEphemeral('Only you can see this!')
|
|
1998
|
+
*/
|
|
1999
|
+
replyEphemeral(options: string | Omit<RespondInteractionOptions, 'ephemeral'>): Promise<{
|
|
2000
|
+
ok: true;
|
|
2001
|
+
ephemeral: true;
|
|
2002
|
+
}>;
|
|
2003
|
+
/**
|
|
2004
|
+
* Acknowledge the interaction without sending a response yet.
|
|
2005
|
+
* Shows a loading indicator to the user.
|
|
2006
|
+
* Follow up with `interaction.editReply()` when you're done.
|
|
2007
|
+
*
|
|
2008
|
+
* @example
|
|
2009
|
+
* await interaction.defer()
|
|
2010
|
+
* const data = await fetchSomeSlow()
|
|
2011
|
+
* await interaction.editReply({ content: `Result: ${data}` })
|
|
2012
|
+
*/
|
|
2013
|
+
defer(): Promise<{
|
|
2014
|
+
ok: true;
|
|
2015
|
+
}>;
|
|
2016
|
+
/**
|
|
2017
|
+
* Edit the previous reply (e.g. after `defer()`).
|
|
2018
|
+
*
|
|
2019
|
+
* @example
|
|
2020
|
+
* await interaction.defer()
|
|
2021
|
+
* await interaction.editReply(`Done — processed ${count} items.`)
|
|
2022
|
+
*/
|
|
2023
|
+
editReply(options: RespondInteractionOptions | string): Promise<Message | {
|
|
2024
|
+
ok: true;
|
|
2025
|
+
ephemeral: true;
|
|
2026
|
+
}>;
|
|
2027
|
+
/**
|
|
2028
|
+
* Open a **modal dialog** and return the user's submission as a new `NovaInteraction`.
|
|
2029
|
+
* Returns `null` if the user closes the modal or the timeout expires (default: 5 min).
|
|
2030
|
+
*
|
|
2031
|
+
* **This is the recommended way to open modals.**
|
|
2032
|
+
*
|
|
2033
|
+
* @example
|
|
2034
|
+
* const submitted = await interaction.openModal(
|
|
2035
|
+
* new ModalBuilder()
|
|
2036
|
+
* .setTitle('Submit a report')
|
|
2037
|
+
* .setCustomId('report_modal')
|
|
2038
|
+
* .addField(
|
|
2039
|
+
* new TextInputBuilder()
|
|
2040
|
+
* .setCustomId('reason')
|
|
2041
|
+
* .setLabel('Reason')
|
|
2042
|
+
* .setStyle('paragraph')
|
|
2043
|
+
* .setRequired(true)
|
|
2044
|
+
* )
|
|
2045
|
+
* )
|
|
2046
|
+
*
|
|
2047
|
+
* if (!submitted) return // user dismissed or timed out
|
|
2048
|
+
*
|
|
2049
|
+
* const reason = submitted.modalData.reason
|
|
2050
|
+
* await submitted.replyEphemeral(`Report received: ${reason}`)
|
|
2051
|
+
*/
|
|
2052
|
+
openModal(modal: ModalBuilder | BotModalDefinition, options?: {
|
|
2053
|
+
timeout?: number;
|
|
2054
|
+
}): Promise<NovaInteraction | null>;
|
|
2055
|
+
/** Returns the raw interaction data from the gateway. */
|
|
2056
|
+
toJSON(): Interaction;
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
/**
|
|
2060
|
+
* A rich wrapper around a raw `Message` with convenience methods.
|
|
2061
|
+
*
|
|
2062
|
+
* Returned by `client.on('messageCreate', ...)` and from message fetch calls.
|
|
2063
|
+
*
|
|
2064
|
+
* @example
|
|
2065
|
+
* client.on('messageCreate', async (msg) => {
|
|
2066
|
+
* if (msg.content.toLowerCase() === '!ping') {
|
|
2067
|
+
* await msg.reply('Pong! 🏓')
|
|
2068
|
+
* await msg.react('🏓')
|
|
2069
|
+
* }
|
|
2070
|
+
* })
|
|
2071
|
+
*/
|
|
2072
|
+
declare class NovaMessage {
|
|
2073
|
+
/** The raw message ID. */
|
|
2074
|
+
readonly id: string;
|
|
2075
|
+
/** The message text content. */
|
|
2076
|
+
readonly content: string;
|
|
2077
|
+
/** The channel this message was sent in. */
|
|
2078
|
+
readonly channelId: string;
|
|
2079
|
+
/** The author of the message. */
|
|
2080
|
+
readonly author: Message['author'];
|
|
2081
|
+
/** Embed attached to this message, if any. */
|
|
2082
|
+
readonly embed: Embed | null;
|
|
2083
|
+
/** Interactive components (buttons, selects) attached to this message. */
|
|
2084
|
+
readonly components: MessageComponent[];
|
|
2085
|
+
/** The message this is replying to, if any. */
|
|
2086
|
+
readonly replyToId: string | null;
|
|
2087
|
+
/** Uploaded file attachments. */
|
|
2088
|
+
readonly attachments: Attachment[];
|
|
2089
|
+
/** Reactions on this message. */
|
|
2090
|
+
readonly reactions: Reaction[];
|
|
2091
|
+
/** When the message was sent. */
|
|
2092
|
+
readonly createdAt: Date;
|
|
2093
|
+
/** When the message was last edited, or `null`. */
|
|
2094
|
+
readonly editedAt: Date | null;
|
|
2095
|
+
private readonly _messages;
|
|
2096
|
+
private readonly _reactions;
|
|
2097
|
+
constructor(raw: Message, messages: MessagesAPI, reactions: ReactionsAPI);
|
|
2098
|
+
/** Returns true if the message was sent by a bot. */
|
|
2099
|
+
isFromBot(): boolean;
|
|
2100
|
+
/** Returns true if the message has an embed. */
|
|
2101
|
+
hasEmbed(): boolean;
|
|
2102
|
+
/** Returns true if the message has interactive components. */
|
|
2103
|
+
hasComponents(): boolean;
|
|
2104
|
+
/** Returns true if the message has been edited. */
|
|
2105
|
+
isEdited(): boolean;
|
|
2106
|
+
/**
|
|
2107
|
+
* Add a reaction to this message.
|
|
2108
|
+
*
|
|
2109
|
+
* @example
|
|
2110
|
+
* await msg.react('👍')
|
|
2111
|
+
* await msg.react('🎉')
|
|
2112
|
+
*/
|
|
2113
|
+
react(emoji: string): Promise<{
|
|
2114
|
+
ok: true;
|
|
2115
|
+
}>;
|
|
2116
|
+
/**
|
|
2117
|
+
* Remove the bot's reaction from this message.
|
|
2118
|
+
*
|
|
2119
|
+
* @example
|
|
2120
|
+
* await msg.removeReaction('👍')
|
|
2121
|
+
*/
|
|
2122
|
+
removeReaction(emoji: string): Promise<{
|
|
2123
|
+
ok: true;
|
|
2124
|
+
}>;
|
|
2125
|
+
/**
|
|
2126
|
+
* Reply to this message.
|
|
2127
|
+
*
|
|
2128
|
+
* @example
|
|
2129
|
+
* await msg.reply('Got it!')
|
|
2130
|
+
* await msg.reply({ embed: new EmbedBuilder().setTitle('Result').toJSON() })
|
|
2131
|
+
*/
|
|
2132
|
+
reply(options: string | Omit<SendMessageOptions, 'replyToId'>): Promise<NovaMessage>;
|
|
2133
|
+
/**
|
|
2134
|
+
* Edit this message.
|
|
2135
|
+
* Only works if the bot is the author.
|
|
2136
|
+
*
|
|
2137
|
+
* @example
|
|
2138
|
+
* await msg.edit('Updated content')
|
|
2139
|
+
* await msg.edit({ content: 'Updated', embed: { title: 'New embed' } })
|
|
2140
|
+
*/
|
|
2141
|
+
edit(options: string | EditMessageOptions): Promise<NovaMessage>;
|
|
2142
|
+
/**
|
|
2143
|
+
* Delete this message.
|
|
2144
|
+
* Only works if the bot is the author.
|
|
2145
|
+
*
|
|
2146
|
+
* @example
|
|
2147
|
+
* await msg.delete()
|
|
2148
|
+
*/
|
|
2149
|
+
delete(): Promise<{
|
|
2150
|
+
ok: true;
|
|
2151
|
+
}>;
|
|
2152
|
+
/**
|
|
2153
|
+
* Pin this message in its channel.
|
|
2154
|
+
*
|
|
2155
|
+
* @example
|
|
2156
|
+
* await msg.pin()
|
|
2157
|
+
*/
|
|
2158
|
+
pin(): Promise<{
|
|
2159
|
+
ok: true;
|
|
2160
|
+
}>;
|
|
2161
|
+
/**
|
|
2162
|
+
* Unpin this message.
|
|
2163
|
+
*
|
|
2164
|
+
* @example
|
|
2165
|
+
* await msg.unpin()
|
|
2166
|
+
*/
|
|
2167
|
+
unpin(): Promise<{
|
|
2168
|
+
ok: true;
|
|
2169
|
+
}>;
|
|
2170
|
+
/**
|
|
2171
|
+
* Re-fetch the latest version of this message from the server.
|
|
2172
|
+
*
|
|
2173
|
+
* @example
|
|
2174
|
+
* const fresh = await msg.fetch()
|
|
2175
|
+
*/
|
|
2176
|
+
fetch(): Promise<NovaMessage>;
|
|
2177
|
+
/**
|
|
2178
|
+
* Forward this message's content (and embed if present) to another channel.
|
|
2179
|
+
* Creates a new message in the target channel.
|
|
2180
|
+
*
|
|
2181
|
+
* @example
|
|
2182
|
+
* const forwarded = await msg.forward('target-channel-id')
|
|
2183
|
+
* console.log('Forwarded to:', forwarded.channelId)
|
|
2184
|
+
*/
|
|
2185
|
+
forward(channelId: string): Promise<NovaMessage>;
|
|
2186
|
+
/**
|
|
2187
|
+
* Fetch detailed reaction data for a specific emoji on this message.
|
|
2188
|
+
* Returns the users who reacted with that emoji.
|
|
2189
|
+
*
|
|
2190
|
+
* @example
|
|
2191
|
+
* const reactors = await msg.fetchReactionDetails('👍')
|
|
2192
|
+
* for (const r of reactors) console.log(r.username, 'reacted 👍')
|
|
2193
|
+
*/
|
|
2194
|
+
fetchReactionDetails(emoji: string): ReturnType<ReactionsAPI['fetchEmoji']>;
|
|
2195
|
+
/**
|
|
2196
|
+
* Remove **all** reactions from this message.
|
|
2197
|
+
* Requires the `messages.manage` scope.
|
|
2198
|
+
*
|
|
2199
|
+
* @example
|
|
2200
|
+
* await msg.clearAllReactions()
|
|
2201
|
+
*/
|
|
2202
|
+
clearAllReactions(): Promise<{
|
|
2203
|
+
ok: true;
|
|
2204
|
+
}>;
|
|
2205
|
+
/**
|
|
2206
|
+
* Remove all reactions for a specific emoji from this message.
|
|
2207
|
+
* Requires the `messages.manage` scope.
|
|
2208
|
+
*
|
|
2209
|
+
* @example
|
|
2210
|
+
* await msg.clearReactionsFor('👍')
|
|
2211
|
+
*/
|
|
2212
|
+
clearReactionsFor(emoji: string): Promise<{
|
|
2213
|
+
ok: true;
|
|
2214
|
+
}>;
|
|
2215
|
+
/**
|
|
2216
|
+
* Fetch a breakdown of all reactions on this message, grouped by emoji.
|
|
2217
|
+
*
|
|
2218
|
+
* @example
|
|
2219
|
+
* const details = await msg.fetchAllReactions()
|
|
2220
|
+
* for (const d of details) console.log(`${d.emoji} — ${d.count}`)
|
|
2221
|
+
*/
|
|
2222
|
+
fetchAllReactions(): ReturnType<ReactionsAPI['fetch']>;
|
|
2223
|
+
/**
|
|
2224
|
+
* Get a URL to this message (deep link).
|
|
2225
|
+
*/
|
|
2226
|
+
get url(): string;
|
|
2227
|
+
/**
|
|
2228
|
+
* Return the raw message object.
|
|
2229
|
+
*/
|
|
2230
|
+
toJSON(): Message;
|
|
2231
|
+
toString(): string;
|
|
2232
|
+
}
|
|
2233
|
+
|
|
2234
|
+
/**
|
|
2235
|
+
* A rich wrapper around a raw `Channel` with convenience methods.
|
|
2236
|
+
*
|
|
2237
|
+
* Returned by `client.fetchChannel()` and `client.fetchChannels()`.
|
|
2238
|
+
*
|
|
2239
|
+
* @example
|
|
2240
|
+
* const channel = await client.fetchChannel('channel-id')
|
|
2241
|
+
*
|
|
2242
|
+
* await channel.send('Hello from the bot!')
|
|
2243
|
+
* await channel.edit({ topic: 'New topic' })
|
|
2244
|
+
* const messages = await channel.fetchMessages({ limit: 20 })
|
|
2245
|
+
*/
|
|
2246
|
+
declare class NovaChannel {
|
|
2247
|
+
/** The channel's unique ID. */
|
|
2248
|
+
readonly id: string;
|
|
2249
|
+
/** The channel's name (without #). */
|
|
2250
|
+
readonly name: string;
|
|
2251
|
+
/** The channel type — `'TEXT'`, `'VOICE'`, `'ANNOUNCEMENT'`, `'FORUM'`, or `'STAGE'`. */
|
|
2252
|
+
readonly type: ChannelType;
|
|
2253
|
+
/** The ID of the server this channel belongs to. */
|
|
2254
|
+
readonly serverId: string | null;
|
|
2255
|
+
/** Optional topic / description text. */
|
|
2256
|
+
readonly topic: string | null;
|
|
2257
|
+
/** Sorting position (lower = higher in the list). */
|
|
2258
|
+
readonly position: number;
|
|
2259
|
+
/** Slow-mode interval in seconds (`0` = disabled). */
|
|
2260
|
+
readonly slowMode: number;
|
|
2261
|
+
/** When the channel was created. */
|
|
2262
|
+
readonly createdAt: Date;
|
|
2263
|
+
private readonly _channels;
|
|
2264
|
+
private readonly _messages;
|
|
2265
|
+
private readonly _webhooks;
|
|
2266
|
+
private readonly _forum;
|
|
2267
|
+
constructor(raw: Channel, channels: ChannelsAPI, messages: MessagesAPI, webhooks?: WebhooksAPI, forum?: ForumAPI);
|
|
2268
|
+
/** `true` for text channels. */
|
|
2269
|
+
isText(): boolean;
|
|
2270
|
+
/** `true` for voice channels. */
|
|
2271
|
+
isVoice(): boolean;
|
|
2272
|
+
/** `true` for announcement channels. */
|
|
2273
|
+
isAnnouncement(): boolean;
|
|
2274
|
+
/** `true` for forum channels. */
|
|
2275
|
+
isForum(): boolean;
|
|
2276
|
+
/** `true` for stage channels. */
|
|
2277
|
+
isStage(): boolean;
|
|
2278
|
+
/** `true` if slow-mode is enabled on this channel. */
|
|
2279
|
+
hasSlowMode(): boolean;
|
|
2280
|
+
/**
|
|
2281
|
+
* Send a message to this channel.
|
|
2282
|
+
* Accepts a plain string or a full options object.
|
|
2283
|
+
*
|
|
2284
|
+
* @example
|
|
2285
|
+
* await channel.send('Hello!')
|
|
2286
|
+
* await channel.send({ content: 'Hi', embed: { title: 'Stats' } })
|
|
2287
|
+
*/
|
|
2288
|
+
send(options: string | SendMessageOptions): Promise<Message>;
|
|
2289
|
+
/**
|
|
2290
|
+
* Fetch recent messages from this channel.
|
|
2291
|
+
*
|
|
2292
|
+
* @example
|
|
2293
|
+
* const messages = await channel.fetchMessages({ limit: 50 })
|
|
2294
|
+
*/
|
|
2295
|
+
fetchMessages(options?: FetchMessagesOptions): Promise<Message[]>;
|
|
2296
|
+
/**
|
|
2297
|
+
* Fetch all pinned messages in this channel.
|
|
2298
|
+
*
|
|
2299
|
+
* @example
|
|
2300
|
+
* const pins = await channel.fetchPins()
|
|
2301
|
+
*/
|
|
2302
|
+
fetchPins(): Promise<Message[]>;
|
|
2303
|
+
/**
|
|
2304
|
+
* Start a typing indicator (shows "Bot is typing…" for ~5 seconds).
|
|
2305
|
+
*
|
|
2306
|
+
* @example
|
|
2307
|
+
* await channel.startTyping()
|
|
2308
|
+
*/
|
|
2309
|
+
startTyping(): Promise<{
|
|
2310
|
+
ok: true;
|
|
2311
|
+
}>;
|
|
2312
|
+
/**
|
|
2313
|
+
* Edit this channel's properties.
|
|
2314
|
+
* Requires the `channels.manage` scope.
|
|
2315
|
+
*
|
|
2316
|
+
* @example
|
|
2317
|
+
* await channel.edit({ name: 'general-2', topic: 'The second general channel' })
|
|
2318
|
+
*/
|
|
2319
|
+
edit(options: EditChannelOptions): Promise<NovaChannel>;
|
|
2320
|
+
/**
|
|
2321
|
+
* Delete this channel.
|
|
2322
|
+
* Requires the `channels.manage` scope.
|
|
2323
|
+
*
|
|
2324
|
+
* @example
|
|
2325
|
+
* await channel.delete()
|
|
2326
|
+
*/
|
|
2327
|
+
delete(): Promise<{
|
|
2328
|
+
ok: true;
|
|
2329
|
+
}>;
|
|
2330
|
+
/**
|
|
2331
|
+
* Bulk-delete multiple messages in this channel (max 100 at once).
|
|
2332
|
+
* Requires the `messages.manage` scope.
|
|
2333
|
+
*
|
|
2334
|
+
* @example
|
|
2335
|
+
* const ids = messages.map(m => m.id)
|
|
2336
|
+
* const result = await channel.bulkDelete(ids)
|
|
2337
|
+
* console.log(`Deleted ${result.deleted} messages`)
|
|
2338
|
+
*/
|
|
2339
|
+
bulkDelete(messageIds: string[]): Promise<BulkDeleteResult>;
|
|
2340
|
+
/**
|
|
2341
|
+
* Create a webhook in this channel.
|
|
2342
|
+
* Requires the `webhooks.manage` scope.
|
|
2343
|
+
*
|
|
2344
|
+
* @example
|
|
2345
|
+
* const wh = await channel.createWebhook({ name: 'Notifications' })
|
|
2346
|
+
* console.log('Token:', wh.token)
|
|
2347
|
+
*/
|
|
2348
|
+
createWebhook(options: WebhookCreateOptions): Promise<Webhook>;
|
|
2349
|
+
/**
|
|
2350
|
+
* Fetch all webhooks in this channel.
|
|
2351
|
+
* Requires the `webhooks.manage` scope.
|
|
2352
|
+
*
|
|
2353
|
+
* @example
|
|
2354
|
+
* const webhooks = await channel.fetchWebhooks()
|
|
2355
|
+
*/
|
|
2356
|
+
fetchWebhooks(): Promise<Webhook[]>;
|
|
2357
|
+
/**
|
|
2358
|
+
* Create a new post in this FORUM channel.
|
|
2359
|
+
* Requires the `channels.write` scope.
|
|
2360
|
+
*
|
|
2361
|
+
* @example
|
|
2362
|
+
* const post = await channel.createForumPost({
|
|
2363
|
+
* title: 'Announcement',
|
|
2364
|
+
* content: 'Welcome everyone!',
|
|
2365
|
+
* })
|
|
2366
|
+
*/
|
|
2367
|
+
createForumPost(options: CreateForumPostOptions): Promise<ForumPost>;
|
|
2368
|
+
/**
|
|
2369
|
+
* Fetch posts from this FORUM channel.
|
|
2370
|
+
*
|
|
2371
|
+
* @example
|
|
2372
|
+
* const posts = await channel.fetchForumPosts({ limit: 20 })
|
|
2373
|
+
*/
|
|
2374
|
+
fetchForumPosts(options?: FetchForumPostsOptions): Promise<ForumPost[]>;
|
|
2375
|
+
/**
|
|
2376
|
+
* Returns the channel as a mention-style string: `#name`.
|
|
2377
|
+
*/
|
|
2378
|
+
toString(): string;
|
|
2379
|
+
/** Returns the raw channel data. */
|
|
2380
|
+
toJSON(): Channel;
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
/**
|
|
2384
|
+
* A rich wrapper around a raw `Member` with convenience methods.
|
|
2385
|
+
*
|
|
2386
|
+
* Returned by `client.fetchMember()` and `client.fetchMembers()`.
|
|
2387
|
+
*
|
|
2388
|
+
* @example
|
|
2389
|
+
* const member = await client.fetchMember('server-id', 'user-id')
|
|
2390
|
+
*
|
|
2391
|
+
* if (member.isAdmin()) {
|
|
2392
|
+
* await member.dm('You have admin access.')
|
|
2393
|
+
* } else {
|
|
2394
|
+
* await member.kick()
|
|
2395
|
+
* }
|
|
2396
|
+
*/
|
|
2397
|
+
declare class NovaMember {
|
|
2398
|
+
/** The user's unique ID. */
|
|
2399
|
+
readonly userId: string;
|
|
2400
|
+
/** The server this membership belongs to. */
|
|
2401
|
+
readonly serverId: string;
|
|
2402
|
+
/** The user's username (login handle). */
|
|
2403
|
+
readonly username: string;
|
|
2404
|
+
/** The user's display name. */
|
|
2405
|
+
readonly displayName: string;
|
|
2406
|
+
/** URL of the user's avatar, or `null`. */
|
|
2407
|
+
readonly avatar: string | null;
|
|
2408
|
+
/** The member's server role — `'OWNER'`, `'ADMIN'`, or `'MEMBER'`. */
|
|
2409
|
+
readonly role: 'OWNER' | 'ADMIN' | 'MEMBER';
|
|
2410
|
+
/** The user's current presence status. */
|
|
2411
|
+
readonly status: 'ONLINE' | 'IDLE' | 'DND' | 'OFFLINE';
|
|
2412
|
+
/** `true` if this member is a bot account. */
|
|
2413
|
+
readonly isBot: boolean;
|
|
2414
|
+
/** When this user joined the server. */
|
|
2415
|
+
readonly joinedAt: Date;
|
|
2416
|
+
private readonly _members;
|
|
2417
|
+
constructor(raw: Member, serverId: string, members: MembersAPI);
|
|
2418
|
+
/** `true` if this member is the server owner. */
|
|
2419
|
+
isOwner(): boolean;
|
|
2420
|
+
/** `true` if this member is an admin or the server owner. */
|
|
2421
|
+
isAdmin(): boolean;
|
|
2422
|
+
/** `true` if this member is a regular (non-privileged) member. */
|
|
2423
|
+
isRegularMember(): boolean;
|
|
2424
|
+
/** `true` if the user is currently online. */
|
|
2425
|
+
isOnline(): boolean;
|
|
2426
|
+
/** `true` if the user is idle / away. */
|
|
2427
|
+
isIdle(): boolean;
|
|
2428
|
+
/** `true` if the user is set to Do Not Disturb. */
|
|
2429
|
+
isDND(): boolean;
|
|
2430
|
+
/** `true` if the user appears offline. */
|
|
2431
|
+
isOffline(): boolean;
|
|
2432
|
+
/**
|
|
2433
|
+
* Kick this member from the server.
|
|
2434
|
+
* Bots cannot kick owners or admins (throws 403).
|
|
2435
|
+
*
|
|
2436
|
+
* @example
|
|
2437
|
+
* await member.kick()
|
|
2438
|
+
*/
|
|
2439
|
+
kick(): Promise<{
|
|
2440
|
+
ok: true;
|
|
2441
|
+
}>;
|
|
2442
|
+
/**
|
|
2443
|
+
* Ban this member from the server with an optional reason.
|
|
2444
|
+
* Bots cannot ban owners or admins (throws 403).
|
|
2445
|
+
*
|
|
2446
|
+
* @example
|
|
2447
|
+
* await member.ban('Repeated rule violations')
|
|
2448
|
+
*/
|
|
2449
|
+
ban(reason?: string): Promise<{
|
|
2450
|
+
ok: true;
|
|
2451
|
+
}>;
|
|
2452
|
+
/**
|
|
2453
|
+
* Send this user a direct message.
|
|
2454
|
+
* Requires the `messages.write` scope.
|
|
2455
|
+
*
|
|
2456
|
+
* @example
|
|
2457
|
+
* await member.dm('Welcome to the server!')
|
|
2458
|
+
* await member.dm({ content: 'Hello', embed: { title: 'Rules' } })
|
|
2459
|
+
*/
|
|
2460
|
+
dm(options: string | Omit<SendMessageOptions, 'replyToId'>): Promise<Message>;
|
|
2461
|
+
/**
|
|
2462
|
+
* Assign a custom role to this member.
|
|
2463
|
+
* Requires the `members.roles` scope.
|
|
2464
|
+
*
|
|
2465
|
+
* @example
|
|
2466
|
+
* await member.addRole('role-id')
|
|
2467
|
+
*/
|
|
2468
|
+
addRole(roleId: string): Promise<{
|
|
2469
|
+
ok: true;
|
|
2470
|
+
}>;
|
|
2471
|
+
/**
|
|
2472
|
+
* Remove a custom role from this member.
|
|
2473
|
+
* Requires the `members.roles` scope.
|
|
2474
|
+
*
|
|
2475
|
+
* @example
|
|
2476
|
+
* await member.removeRole('role-id')
|
|
2477
|
+
*/
|
|
2478
|
+
removeRole(roleId: string): Promise<{
|
|
2479
|
+
ok: true;
|
|
2480
|
+
}>;
|
|
2481
|
+
/**
|
|
2482
|
+
* Issue a warning to this member.
|
|
2483
|
+
* Requires the `members.moderate` scope.
|
|
2484
|
+
*
|
|
2485
|
+
* @example
|
|
2486
|
+
* await member.warn('Excessive spamming')
|
|
2487
|
+
*/
|
|
2488
|
+
warn(reason: string): Promise<Warning>;
|
|
2489
|
+
/**
|
|
2490
|
+
* Fetch all warnings for this member in this server.
|
|
2491
|
+
* Requires the `members.moderate` scope.
|
|
2492
|
+
*
|
|
2493
|
+
* @example
|
|
2494
|
+
* const warnings = await member.fetchWarnings()
|
|
2495
|
+
* console.log(`${warnings.length} warnings on record`)
|
|
2496
|
+
*/
|
|
2497
|
+
fetchWarnings(): Promise<Warning[]>;
|
|
2498
|
+
/**
|
|
2499
|
+
* Get this member's current XP and level.
|
|
2500
|
+
* Requires the `members.read` scope.
|
|
2501
|
+
*
|
|
2502
|
+
* @example
|
|
2503
|
+
* const xp = await member.getXP()
|
|
2504
|
+
* console.log(`Level ${xp.level} — ${xp.xp} XP`)
|
|
2505
|
+
*/
|
|
2506
|
+
getXP(): Promise<MemberXPData>;
|
|
2507
|
+
/**
|
|
2508
|
+
* Set this member's XP to a specific value.
|
|
2509
|
+
* Requires the `members.manage` scope.
|
|
2510
|
+
*
|
|
2511
|
+
* @example
|
|
2512
|
+
* await member.setXP(500)
|
|
2513
|
+
*/
|
|
2514
|
+
setXP(xp: number): Promise<MemberXPData>;
|
|
2515
|
+
/**
|
|
2516
|
+
* Add (or subtract) XP to this member's current total.
|
|
2517
|
+
* Requires the `members.manage` scope.
|
|
2518
|
+
*
|
|
2519
|
+
* @example
|
|
2520
|
+
* await member.addXP(100) // reward 100 XP
|
|
2521
|
+
* await member.addXP(-50) // deduct 50 XP
|
|
2522
|
+
*/
|
|
2523
|
+
addXP(amount: number): Promise<MemberXPData>;
|
|
2524
|
+
/**
|
|
2525
|
+
* Delete all warnings on record for this member in this server.
|
|
2526
|
+
* Requires the `members.moderate` scope.
|
|
2527
|
+
*
|
|
2528
|
+
* @example
|
|
2529
|
+
* await member.clearWarnings()
|
|
2530
|
+
*/
|
|
2531
|
+
clearWarnings(): Promise<number>;
|
|
2532
|
+
/**
|
|
2533
|
+
* Reset this member's XP back to zero.
|
|
2534
|
+
* Requires the `members.manage` scope.
|
|
2535
|
+
*
|
|
2536
|
+
* @example
|
|
2537
|
+
* await member.resetXP()
|
|
2538
|
+
*/
|
|
2539
|
+
resetXP(): Promise<MemberXPData>;
|
|
2540
|
+
/**
|
|
2541
|
+
* Returns a mention-style string: `@displayName`.
|
|
2542
|
+
*/
|
|
2543
|
+
toString(): string;
|
|
2544
|
+
/** Returns the raw member data. */
|
|
2545
|
+
toJSON(): Member;
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
/**
|
|
2549
|
+
* A rich wrapper around a raw `Role` with convenience methods.
|
|
2550
|
+
*
|
|
2551
|
+
* Returned by `client.fetchRole()` and `client.fetchRoles()`.
|
|
2552
|
+
*
|
|
2553
|
+
* @example
|
|
2554
|
+
* const roles = await client.fetchRoles('server-id')
|
|
2555
|
+
* const mod = roles.find(r => r.name === 'Moderator')
|
|
2556
|
+
* if (mod) await mod.assign('user-id')
|
|
2557
|
+
*/
|
|
2558
|
+
declare class NovaRole {
|
|
2559
|
+
/** Unique role ID. */
|
|
2560
|
+
readonly id: string;
|
|
2561
|
+
/** Display name of the role. */
|
|
2562
|
+
readonly name: string;
|
|
2563
|
+
/** Hex colour string (e.g. `'#00d4ff'`), or `null` for no colour. */
|
|
2564
|
+
readonly color: string | null;
|
|
2565
|
+
/** Sort position — lower numbers appear higher in the role list. */
|
|
2566
|
+
readonly position: number;
|
|
2567
|
+
/** The server this role belongs to. */
|
|
2568
|
+
readonly serverId: string;
|
|
2569
|
+
/** Whether this role is displayed separately in the member sidebar. */
|
|
2570
|
+
readonly hoist: boolean;
|
|
2571
|
+
/** When the role was created. */
|
|
2572
|
+
readonly createdAt: Date;
|
|
2573
|
+
private readonly _roles;
|
|
2574
|
+
constructor(raw: Role, roles: RolesAPI);
|
|
2575
|
+
/**
|
|
2576
|
+
* Edit this role's name, colour, hoist flag, or permissions.
|
|
2577
|
+
*
|
|
2578
|
+
* @example
|
|
2579
|
+
* await role.edit({ color: '#ff0000', name: 'Red Team' })
|
|
2580
|
+
*/
|
|
2581
|
+
edit(options: RoleEditOptions): Promise<Role>;
|
|
2582
|
+
/**
|
|
2583
|
+
* Delete this role from the server.
|
|
2584
|
+
* Any members currently assigned this role will have it removed.
|
|
2585
|
+
*
|
|
2586
|
+
* @example
|
|
2587
|
+
* await role.delete()
|
|
2588
|
+
*/
|
|
2589
|
+
delete(): Promise<{
|
|
2590
|
+
ok: true;
|
|
2591
|
+
}>;
|
|
2592
|
+
/**
|
|
2593
|
+
* Assign this role to a server member.
|
|
2594
|
+
*
|
|
2595
|
+
* @example
|
|
2596
|
+
* await role.assign('user-id')
|
|
2597
|
+
*/
|
|
2598
|
+
assign(userId: string): Promise<{
|
|
2599
|
+
ok: true;
|
|
2600
|
+
}>;
|
|
2601
|
+
/**
|
|
2602
|
+
* Remove this role from a server member.
|
|
2603
|
+
*
|
|
2604
|
+
* @example
|
|
2605
|
+
* await role.remove('user-id')
|
|
2606
|
+
*/
|
|
2607
|
+
remove(userId: string): Promise<{
|
|
2608
|
+
ok: true;
|
|
2609
|
+
}>;
|
|
2610
|
+
/** Returns `true` if the role has a custom hex colour set. */
|
|
2611
|
+
hasColor(): boolean;
|
|
2612
|
+
/** Returns the CSS-safe hex colour string. Falls back to `'#99aab5'` (grey). */
|
|
2613
|
+
toHex(): string;
|
|
2614
|
+
toJSON(): Role;
|
|
2615
|
+
}
|
|
2616
|
+
|
|
2617
|
+
/**
|
|
2618
|
+
* A rich wrapper around a raw `NovaServer` with convenience methods.
|
|
2619
|
+
*
|
|
2620
|
+
* Returned by `client.fetchServer()` and `client.fetchServers()`.
|
|
2621
|
+
*
|
|
2622
|
+
* @example
|
|
2623
|
+
* const server = await client.fetchServer('server-id')
|
|
2624
|
+
* console.log(`${server.name} — ${server.memberCount} members`)
|
|
2625
|
+
* await server.send('welcome-channel-id', 'Bot is online! 🤖')
|
|
2626
|
+
*/
|
|
2627
|
+
declare class NovaServerWrapper {
|
|
2628
|
+
/** Unique server ID. */
|
|
2629
|
+
readonly id: string;
|
|
2630
|
+
/** Server display name. */
|
|
2631
|
+
readonly name: string;
|
|
2632
|
+
/** URL to the server icon, or `null`. */
|
|
2633
|
+
readonly icon: string | null;
|
|
2634
|
+
/** Short description of the server, or `null`. */
|
|
2635
|
+
readonly description: string | null;
|
|
2636
|
+
/** Total member count at time of fetch. */
|
|
2637
|
+
readonly memberCount: number;
|
|
2638
|
+
/** Total channel count at time of fetch. */
|
|
2639
|
+
readonly channelCount: number;
|
|
2640
|
+
/** When the bot joined this server. */
|
|
2641
|
+
readonly joinedAt: Date;
|
|
2642
|
+
private readonly _servers;
|
|
2643
|
+
private readonly _channels;
|
|
2644
|
+
private readonly _members;
|
|
2645
|
+
private readonly _invites;
|
|
2646
|
+
private readonly _roles;
|
|
2647
|
+
private readonly _messages;
|
|
2648
|
+
private readonly _categories;
|
|
2649
|
+
private readonly _events;
|
|
2650
|
+
private readonly _automod;
|
|
2651
|
+
private readonly _auditLog;
|
|
2652
|
+
constructor(raw: NovaServer, servers: ServersAPI, channels: ChannelsAPI, members: MembersAPI, invites: InvitesAPI, roles: RolesAPI, messages: MessagesAPI, categories?: CategoriesAPI, events?: EventsAPI, automod?: AutoModAPI, auditLog?: AuditLogAPI);
|
|
2653
|
+
/**
|
|
2654
|
+
* Update this server's name, description, or icon.
|
|
2655
|
+
* Requires the `server.manage` scope.
|
|
2656
|
+
*
|
|
2657
|
+
* @example
|
|
2658
|
+
* await server.update({ name: 'New Name' })
|
|
2659
|
+
*/
|
|
2660
|
+
update(options: ServerUpdateOptions): Promise<NovaServer>;
|
|
2661
|
+
/**
|
|
2662
|
+
* Fetch all channels in this server.
|
|
2663
|
+
*
|
|
2664
|
+
* @example
|
|
2665
|
+
* const channels = await server.fetchChannels()
|
|
2666
|
+
* const text = channels.filter(c => c.type === 'TEXT')
|
|
2667
|
+
*/
|
|
2668
|
+
fetchChannels(): Promise<Channel[]>;
|
|
2669
|
+
/**
|
|
2670
|
+
* Create a new channel in this server.
|
|
2671
|
+
* Requires the `channels.manage` scope.
|
|
2672
|
+
*
|
|
2673
|
+
* @example
|
|
2674
|
+
* const ch = await server.createChannel({ name: 'bot-logs', type: 'TEXT' })
|
|
2675
|
+
*/
|
|
2676
|
+
createChannel(options: CreateChannelOptions): Promise<Channel>;
|
|
2677
|
+
/**
|
|
2678
|
+
* Fetch members in this server.
|
|
2679
|
+
*
|
|
2680
|
+
* @example
|
|
2681
|
+
* const members = await server.fetchMembers({ limit: 100 })
|
|
2682
|
+
*/
|
|
2683
|
+
fetchMembers(options?: FetchMembersOptions): Promise<Member[]>;
|
|
2684
|
+
/**
|
|
2685
|
+
* Fetch a single member by user ID.
|
|
2686
|
+
*
|
|
2687
|
+
* @example
|
|
2688
|
+
* const member = await server.fetchMember('user-id')
|
|
2689
|
+
*/
|
|
2690
|
+
fetchMember(userId: string): ReturnType<MembersAPI['fetch']>;
|
|
2691
|
+
/**
|
|
2692
|
+
* Kick a member from this server.
|
|
2693
|
+
*
|
|
2694
|
+
* @example
|
|
2695
|
+
* await server.kick('user-id')
|
|
2696
|
+
*/
|
|
2697
|
+
kick(userId: string): Promise<{
|
|
2698
|
+
ok: true;
|
|
2699
|
+
}>;
|
|
2700
|
+
/**
|
|
2701
|
+
* Ban a member from this server.
|
|
2702
|
+
*
|
|
2703
|
+
* @example
|
|
2704
|
+
* await server.ban('user-id', 'Spamming')
|
|
2705
|
+
*/
|
|
2706
|
+
ban(userId: string, reason?: string): Promise<{
|
|
2707
|
+
ok: true;
|
|
2708
|
+
}>;
|
|
2709
|
+
/**
|
|
2710
|
+
* Fetch the ban list for this server.
|
|
2711
|
+
*/
|
|
2712
|
+
fetchBans(): Promise<BanEntry[]>;
|
|
2713
|
+
/**
|
|
2714
|
+
* List all custom roles in this server, sorted by position.
|
|
2715
|
+
*
|
|
2716
|
+
* @example
|
|
2717
|
+
* const roles = await server.fetchRoles()
|
|
2718
|
+
* const admins = roles.filter(r => r.name === 'Admin')
|
|
2719
|
+
*/
|
|
2720
|
+
fetchRoles(): Promise<Role[]>;
|
|
2721
|
+
/**
|
|
2722
|
+
* Create a new custom role in this server.
|
|
2723
|
+
* Requires the `roles.manage` scope.
|
|
2724
|
+
*
|
|
2725
|
+
* @example
|
|
2726
|
+
* const role = await server.createRole({ name: 'Supporter', color: '#00d4ff', hoist: true })
|
|
2727
|
+
*/
|
|
2728
|
+
createRole(options: RoleCreateOptions): Promise<Role>;
|
|
2729
|
+
/**
|
|
2730
|
+
* Fetch all active invites for this server.
|
|
2731
|
+
*
|
|
2732
|
+
* @example
|
|
2733
|
+
* const invites = await server.fetchInvites()
|
|
2734
|
+
*/
|
|
2735
|
+
fetchInvites(): Promise<Invite[]>;
|
|
2736
|
+
/**
|
|
2737
|
+
* Create an invite for this server.
|
|
2738
|
+
*
|
|
2739
|
+
* @example
|
|
2740
|
+
* const invite = await server.createInvite({ maxUses: 10 })
|
|
2741
|
+
* console.log(`https://novachatapp.com/invite/${invite.code}`)
|
|
2742
|
+
*/
|
|
2743
|
+
createInvite(options?: InviteCreateOptions): Promise<Invite>;
|
|
2744
|
+
/**
|
|
2745
|
+
* Send a message to a channel in this server by channel ID.
|
|
2746
|
+
*
|
|
2747
|
+
* @example
|
|
2748
|
+
* await server.send('channel-id', 'Hello, server!')
|
|
2749
|
+
*/
|
|
2750
|
+
send(channelId: string, content: string): ReturnType<MessagesAPI['send']>;
|
|
2751
|
+
/**
|
|
2752
|
+
* Fetch all channel categories in this server.
|
|
2753
|
+
*
|
|
2754
|
+
* @example
|
|
2755
|
+
* const cats = await server.fetchCategories()
|
|
2756
|
+
* const general = cats.find(c => c.name === 'General')
|
|
2757
|
+
*/
|
|
2758
|
+
fetchCategories(): Promise<ChannelCategory[]>;
|
|
2759
|
+
/**
|
|
2760
|
+
* Create a new channel category in this server.
|
|
2761
|
+
* Requires the `channels.manage` scope.
|
|
2762
|
+
*
|
|
2763
|
+
* @example
|
|
2764
|
+
* const cat = await server.createCategory({ name: 'Bot Channels' })
|
|
2765
|
+
*/
|
|
2766
|
+
createCategory(options: CreateCategoryOptions): Promise<ChannelCategory>;
|
|
2767
|
+
/**
|
|
2768
|
+
* Fetch server events. Pass `{ upcoming: true }` to only return future events.
|
|
2769
|
+
*
|
|
2770
|
+
* @example
|
|
2771
|
+
* const events = await server.fetchEvents({ upcoming: true })
|
|
2772
|
+
*/
|
|
2773
|
+
fetchEvents(options?: FetchEventsOptions): Promise<ServerEvent[]>;
|
|
2774
|
+
/**
|
|
2775
|
+
* Create a new server event.
|
|
2776
|
+
* Requires the `server.manage` scope.
|
|
2777
|
+
*
|
|
2778
|
+
* @example
|
|
2779
|
+
* const event = await server.createEvent({
|
|
2780
|
+
* title: 'Game Night',
|
|
2781
|
+
* startAt: new Date('2025-09-01T20:00:00Z').toISOString(),
|
|
2782
|
+
* })
|
|
2783
|
+
*/
|
|
2784
|
+
createEvent(options: CreateEventOptions): Promise<ServerEvent>;
|
|
2785
|
+
/**
|
|
2786
|
+
* Fetch server statistics (member count, message count, etc.).
|
|
2787
|
+
*
|
|
2788
|
+
* @example
|
|
2789
|
+
* const stats = await server.fetchStats()
|
|
2790
|
+
* console.log(`Online: ${stats.onlineCount} / ${stats.memberCount}`)
|
|
2791
|
+
*/
|
|
2792
|
+
fetchStats(): Promise<ServerStats>;
|
|
2793
|
+
/**
|
|
2794
|
+
* Fetch the audit log for this server.
|
|
2795
|
+
* Requires the `audit-log.read` scope.
|
|
2796
|
+
*
|
|
2797
|
+
* @example
|
|
2798
|
+
* const log = await server.fetchAuditLog({ action: 'member.banned', limit: 20 })
|
|
2799
|
+
*/
|
|
2800
|
+
fetchAuditLog(options?: FetchAuditLogsOptions): Promise<AuditLogEntry[]>;
|
|
2801
|
+
/**
|
|
2802
|
+
* Issue a warning to a member in this server.
|
|
2803
|
+
* Requires the `members.moderate` scope.
|
|
2804
|
+
*
|
|
2805
|
+
* @example
|
|
2806
|
+
* await server.warn('user-id', 'Insulting other members')
|
|
2807
|
+
*/
|
|
2808
|
+
warn(userId: string, reason: string): Promise<Warning>;
|
|
2809
|
+
/**
|
|
2810
|
+
* Fetch warnings for this server, optionally filtered by user.
|
|
2811
|
+
* Requires the `members.moderate` scope.
|
|
2812
|
+
*
|
|
2813
|
+
* @example
|
|
2814
|
+
* const all = await server.fetchWarnings()
|
|
2815
|
+
* const userWarns = await server.fetchWarnings({ userId: 'user-id' })
|
|
2816
|
+
*/
|
|
2817
|
+
fetchWarnings(options?: {
|
|
2818
|
+
userId?: string;
|
|
2819
|
+
}): Promise<Warning[]>;
|
|
2820
|
+
/**
|
|
2821
|
+
* Fetch the XP leaderboard for this server.
|
|
2822
|
+
* Requires the `members.read` scope.
|
|
2823
|
+
*
|
|
2824
|
+
* @example
|
|
2825
|
+
* const top = await server.fetchLeaderboard(10)
|
|
2826
|
+
* top.forEach(e => console.log(`#${e.rank} ${e.user.displayName} — ${e.xp} XP`))
|
|
2827
|
+
*/
|
|
2828
|
+
fetchLeaderboard(limit?: number): Promise<LeaderboardEntry[]>;
|
|
2829
|
+
/**
|
|
2830
|
+
* Fetch all AutoMod rules for this server.
|
|
2831
|
+
* Requires the `server.manage` scope.
|
|
2832
|
+
*
|
|
2833
|
+
* @example
|
|
2834
|
+
* const rules = await server.fetchAutoModRules()
|
|
2835
|
+
* const active = rules.filter(r => r.enabled)
|
|
2836
|
+
*/
|
|
2837
|
+
fetchAutoModRules(): Promise<AutoModRule[]>;
|
|
2838
|
+
/**
|
|
2839
|
+
* Create a new AutoMod rule for this server.
|
|
2840
|
+
* Requires the `server.manage` scope.
|
|
2841
|
+
*
|
|
2842
|
+
* @example
|
|
2843
|
+
* await server.createAutoModRule({ type: 'BLOCKED_WORD', value: 'badword' })
|
|
2844
|
+
*/
|
|
2845
|
+
createAutoModRule(options: CreateAutoModRuleOptions): Promise<AutoModRule>;
|
|
2846
|
+
toJSON(): NovaServer;
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2849
|
+
/**
|
|
2850
|
+
* A rich wrapper around a raw `Invite` with convenience methods.
|
|
2851
|
+
*
|
|
2852
|
+
* Returned by `client.fetchInvite()` and `client.fetchInvites()`.
|
|
2853
|
+
*
|
|
2854
|
+
* @example
|
|
2855
|
+
* const invite = await client.fetchInvite('abc123')
|
|
2856
|
+
* if (invite.isExpired()) await invite.revoke()
|
|
2857
|
+
*/
|
|
2858
|
+
declare class NovaInvite {
|
|
2859
|
+
/** The invite code — appended to `https://novachatapp.com/invite/`. */
|
|
2860
|
+
readonly code: string;
|
|
2861
|
+
/** The server this invite grants access to. */
|
|
2862
|
+
readonly serverId: string;
|
|
2863
|
+
/** The user ID of whoever created this invite. */
|
|
2864
|
+
readonly creatorId: string;
|
|
2865
|
+
/** How many times this invite has been used. */
|
|
2866
|
+
readonly uses: number;
|
|
2867
|
+
/** Maximum allowed uses before the invite deactivates. `null` = unlimited. */
|
|
2868
|
+
readonly maxUses: number | null;
|
|
2869
|
+
/** When the invite expires. `null` = never expires. */
|
|
2870
|
+
readonly expiresAt: Date | null;
|
|
2871
|
+
/** When the invite was created. */
|
|
2872
|
+
readonly createdAt: Date;
|
|
2873
|
+
private readonly _invites;
|
|
2874
|
+
constructor(raw: Invite, invites: InvitesAPI);
|
|
2875
|
+
/** The full URL users can follow to join the server. */
|
|
2876
|
+
get url(): string;
|
|
2877
|
+
/**
|
|
2878
|
+
* Returns `true` if the invite has passed its expiry time.
|
|
2879
|
+
* Always `false` for invites with no expiry.
|
|
2880
|
+
*/
|
|
2881
|
+
isExpired(): boolean;
|
|
2882
|
+
/**
|
|
2883
|
+
* Returns `true` if the invite has reached its maximum use count.
|
|
2884
|
+
* Always `false` for unlimited invites.
|
|
2885
|
+
*/
|
|
2886
|
+
isExhausted(): boolean;
|
|
2887
|
+
/** Whether this invite is still usable (not expired and not exhausted). */
|
|
2888
|
+
isValid(): boolean;
|
|
2889
|
+
/**
|
|
2890
|
+
* Revoke (delete) this invite, making the code unusable.
|
|
2891
|
+
* Requires the `invites.manage` scope.
|
|
2892
|
+
*
|
|
2893
|
+
* @example
|
|
2894
|
+
* await invite.revoke()
|
|
2895
|
+
*/
|
|
2896
|
+
revoke(): Promise<{
|
|
2897
|
+
ok: true;
|
|
2898
|
+
}>;
|
|
2899
|
+
toJSON(): Invite;
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2902
|
+
/**
|
|
2903
|
+
* A rich wrapper around a raw `Webhook` with convenience methods.
|
|
2904
|
+
*
|
|
2905
|
+
* Returned by `client.fetchWebhook()` and `client.fetchWebhooks()`.
|
|
2906
|
+
*
|
|
2907
|
+
* @example
|
|
2908
|
+
* const webhook = await client.fetchWebhook('webhook-id')
|
|
2909
|
+
* await webhook.execute({ content: '🚀 Build passed!', username: 'CI Bot' })
|
|
2910
|
+
*/
|
|
2911
|
+
declare class NovaWebhook {
|
|
2912
|
+
/** Unique webhook ID. */
|
|
2913
|
+
readonly id: string;
|
|
2914
|
+
/** The server this webhook belongs to. */
|
|
2915
|
+
readonly serverId: string;
|
|
2916
|
+
/** The channel messages are posted to when this webhook is executed. */
|
|
2917
|
+
readonly channelId: string;
|
|
2918
|
+
/** Display name shown next to messages posted via this webhook. */
|
|
2919
|
+
readonly name: string;
|
|
2920
|
+
/** Secret token — required to execute the webhook via HTTP. */
|
|
2921
|
+
readonly token: string;
|
|
2922
|
+
/** When the webhook was created. */
|
|
2923
|
+
readonly createdAt: Date;
|
|
2924
|
+
private readonly _webhooks;
|
|
2925
|
+
constructor(raw: Webhook, webhooks: WebhooksAPI);
|
|
2926
|
+
/**
|
|
2927
|
+
* Edit this webhook's name or target channel.
|
|
2928
|
+
* Requires the `webhooks.manage` scope.
|
|
2929
|
+
*
|
|
2930
|
+
* @example
|
|
2931
|
+
* await webhook.edit({ name: 'New Name', channelId: 'other-channel-id' })
|
|
2932
|
+
*/
|
|
2933
|
+
edit(options: WebhookEditOptions): Promise<Webhook>;
|
|
2934
|
+
/**
|
|
2935
|
+
* Delete this webhook.
|
|
2936
|
+
* Requires the `webhooks.manage` scope.
|
|
2937
|
+
*
|
|
2938
|
+
* @example
|
|
2939
|
+
* await webhook.delete()
|
|
2940
|
+
*/
|
|
2941
|
+
delete(): Promise<{
|
|
2942
|
+
ok: true;
|
|
2943
|
+
}>;
|
|
2944
|
+
/**
|
|
2945
|
+
* Post a message via this webhook.
|
|
2946
|
+
*
|
|
2947
|
+
* @example
|
|
2948
|
+
* await webhook.execute({ content: '❌ Tests failed on branch main', username: 'CI' })
|
|
2949
|
+
*/
|
|
2950
|
+
execute(options: ExecuteWebhookOptions): Promise<Message>;
|
|
2951
|
+
toJSON(): Webhook;
|
|
2952
|
+
}
|
|
2953
|
+
|
|
2954
|
+
/**
|
|
2955
|
+
* A rich wrapper around a raw `ForumPost` object that provides
|
|
2956
|
+
* convenient helper methods for common operations.
|
|
2957
|
+
*
|
|
2958
|
+
* @example
|
|
2959
|
+
* const posts = await client.fetchForumPosts('channel-id')
|
|
2960
|
+
* for (const post of posts) {
|
|
2961
|
+
* if (post.closed) continue
|
|
2962
|
+
* await post.close()
|
|
2963
|
+
* }
|
|
2964
|
+
*/
|
|
2965
|
+
declare class NovaForumPost implements ForumPost {
|
|
2966
|
+
private readonly raw;
|
|
2967
|
+
private readonly forum;
|
|
2968
|
+
readonly id: string;
|
|
2969
|
+
readonly channelId: string;
|
|
2970
|
+
readonly authorId: string;
|
|
2971
|
+
readonly title: string;
|
|
2972
|
+
readonly body: string;
|
|
2973
|
+
readonly tags: string[];
|
|
2974
|
+
readonly pinned: boolean;
|
|
2975
|
+
readonly closed: boolean;
|
|
2976
|
+
readonly upvoteCount: number;
|
|
2977
|
+
readonly replyCount: number;
|
|
2978
|
+
readonly author: ForumPost['author'];
|
|
2979
|
+
readonly createdAt: string;
|
|
2980
|
+
readonly updatedAt: string;
|
|
2981
|
+
constructor(raw: ForumPost, forum: ForumAPI);
|
|
2982
|
+
/**
|
|
2983
|
+
* Edit this forum post.
|
|
2984
|
+
*
|
|
2985
|
+
* @example
|
|
2986
|
+
* await post.edit({ title: 'Updated title' })
|
|
2987
|
+
*/
|
|
2988
|
+
edit(options: EditForumPostOptions): Promise<NovaForumPost>;
|
|
2989
|
+
/**
|
|
2990
|
+
* Close the forum post (no new replies).
|
|
2991
|
+
*
|
|
2992
|
+
* @example
|
|
2993
|
+
* await post.close()
|
|
2994
|
+
*/
|
|
2995
|
+
close(): Promise<NovaForumPost>;
|
|
2996
|
+
/**
|
|
2997
|
+
* Re-open a closed forum post.
|
|
2998
|
+
*
|
|
2999
|
+
* @example
|
|
3000
|
+
* await post.open()
|
|
3001
|
+
*/
|
|
3002
|
+
open(): Promise<NovaForumPost>;
|
|
3003
|
+
/**
|
|
3004
|
+
* Pin this forum post in the channel.
|
|
3005
|
+
*
|
|
3006
|
+
* @example
|
|
3007
|
+
* await post.pin()
|
|
3008
|
+
*/
|
|
3009
|
+
pin(): Promise<NovaForumPost>;
|
|
3010
|
+
/**
|
|
3011
|
+
* Unpin this forum post.
|
|
3012
|
+
*
|
|
3013
|
+
* @example
|
|
3014
|
+
* await post.unpin()
|
|
3015
|
+
*/
|
|
3016
|
+
unpin(): Promise<NovaForumPost>;
|
|
3017
|
+
/**
|
|
3018
|
+
* Delete this forum post.
|
|
3019
|
+
*
|
|
3020
|
+
* @example
|
|
3021
|
+
* await post.delete()
|
|
3022
|
+
*/
|
|
3023
|
+
delete(): Promise<void>;
|
|
3024
|
+
/** Whether this post was created by the currently connected bot. */
|
|
3025
|
+
get isOwnPost(): boolean;
|
|
3026
|
+
/** Returns `true` if the post has been closed. */
|
|
3027
|
+
get isClosed(): boolean;
|
|
3028
|
+
/** Returns `true` if the post is pinned. */
|
|
3029
|
+
get isPinned(): boolean;
|
|
3030
|
+
toJSON(): ForumPost;
|
|
3031
|
+
}
|
|
3032
|
+
|
|
3033
|
+
/**
|
|
3034
|
+
* A rich wrapper around a raw `ServerEvent` object.
|
|
3035
|
+
*
|
|
3036
|
+
* @example
|
|
3037
|
+
* const events = await client.fetchEvents('server-id', { upcoming: true })
|
|
3038
|
+
* for (const event of events) {
|
|
3039
|
+
* console.log(`${event.title} starts at ${event.startAt}`)
|
|
3040
|
+
* }
|
|
3041
|
+
*/
|
|
3042
|
+
declare class NovaServerEvent implements ServerEvent {
|
|
3043
|
+
private readonly raw;
|
|
3044
|
+
private readonly events;
|
|
3045
|
+
readonly id: string;
|
|
3046
|
+
readonly serverId: string;
|
|
3047
|
+
readonly channelId: string | null;
|
|
3048
|
+
readonly createdById: string;
|
|
3049
|
+
readonly title: string;
|
|
3050
|
+
readonly description: string | null;
|
|
3051
|
+
readonly imageUrl: string | null;
|
|
3052
|
+
readonly location: string | null;
|
|
3053
|
+
readonly startAt: string;
|
|
3054
|
+
readonly endAt: string | null;
|
|
3055
|
+
readonly attendeeCount: number | undefined;
|
|
3056
|
+
readonly createdAt: string;
|
|
3057
|
+
constructor(raw: ServerEvent, events: EventsAPI);
|
|
3058
|
+
/**
|
|
3059
|
+
* Edit this event.
|
|
3060
|
+
*
|
|
3061
|
+
* @example
|
|
3062
|
+
* await event.edit({ title: 'New Title' })
|
|
3063
|
+
*/
|
|
3064
|
+
edit(options: EditEventOptions): Promise<NovaServerEvent>;
|
|
3065
|
+
/**
|
|
3066
|
+
* Fetch full event details including the attendee list.
|
|
3067
|
+
*
|
|
3068
|
+
* @example
|
|
3069
|
+
* const full = await event.fetchAttendees()
|
|
3070
|
+
* console.log(`${full.attendees.length} attendees`)
|
|
3071
|
+
*/
|
|
3072
|
+
fetchAttendees(): Promise<{
|
|
3073
|
+
event: NovaServerEvent;
|
|
3074
|
+
attendees: ServerEventAttendee[];
|
|
3075
|
+
}>;
|
|
3076
|
+
/**
|
|
3077
|
+
* Delete this event.
|
|
3078
|
+
*
|
|
3079
|
+
* @example
|
|
3080
|
+
* await event.delete()
|
|
3081
|
+
*/
|
|
3082
|
+
delete(): Promise<void>;
|
|
3083
|
+
/**
|
|
3084
|
+
* Whether the event has already started.
|
|
3085
|
+
*/
|
|
3086
|
+
get hasStarted(): boolean;
|
|
3087
|
+
/**
|
|
3088
|
+
* Whether the event has ended.
|
|
3089
|
+
* Returns `false` if no `endAt` is set.
|
|
3090
|
+
*/
|
|
3091
|
+
get hasEnded(): boolean;
|
|
3092
|
+
/**
|
|
3093
|
+
* Whether this is an upcoming event that has not yet started.
|
|
3094
|
+
*/
|
|
3095
|
+
get isUpcoming(): boolean;
|
|
3096
|
+
toJSON(): ServerEvent;
|
|
3097
|
+
}
|
|
3098
|
+
|
|
3099
|
+
/**
|
|
3100
|
+
* A rich wrapper around a raw `BanEntry` that adds an `unban()` convenience method.
|
|
3101
|
+
*
|
|
3102
|
+
* Returned by `client.fetchBans()`.
|
|
3103
|
+
*
|
|
3104
|
+
* @example
|
|
3105
|
+
* const bans = await client.fetchBans('server-id')
|
|
3106
|
+
* for (const ban of bans) {
|
|
3107
|
+
* if (ban.reason === 'testing') {
|
|
3108
|
+
* await ban.unban()
|
|
3109
|
+
* console.log(`Unbanned ${ban.displayName}`)
|
|
3110
|
+
* }
|
|
3111
|
+
* }
|
|
3112
|
+
*/
|
|
3113
|
+
declare class NovaBan implements BanEntry {
|
|
3114
|
+
/** The banned user's ID. */
|
|
3115
|
+
readonly userId: string;
|
|
3116
|
+
/** The banned user's username. */
|
|
3117
|
+
readonly username: string;
|
|
3118
|
+
/** The banned user's display name. */
|
|
3119
|
+
readonly displayName: string;
|
|
3120
|
+
/** The banned user's avatar URL, or `null`. */
|
|
3121
|
+
readonly avatar: string | null;
|
|
3122
|
+
/** The reason for the ban, or `null`. */
|
|
3123
|
+
readonly reason: string | null;
|
|
3124
|
+
/** ISO timestamp of when the ban was issued. */
|
|
3125
|
+
readonly bannedAt: string;
|
|
3126
|
+
/** ID of the moderator who issued the ban, or `null`. */
|
|
3127
|
+
readonly moderatorId: string | null;
|
|
3128
|
+
/** ID of the server this ban belongs to. */
|
|
3129
|
+
readonly serverId: string;
|
|
3130
|
+
private readonly _members;
|
|
3131
|
+
constructor(raw: BanEntry, serverId: string, members: MembersAPI);
|
|
3132
|
+
/**
|
|
3133
|
+
* Revoke this ban, allowing the user to rejoin the server.
|
|
3134
|
+
* Requires the `members.ban` scope.
|
|
3135
|
+
*
|
|
3136
|
+
* @example
|
|
3137
|
+
* await ban.unban()
|
|
3138
|
+
*/
|
|
3139
|
+
unban(): Promise<{
|
|
3140
|
+
ok: true;
|
|
3141
|
+
}>;
|
|
3142
|
+
/**
|
|
3143
|
+
* When the ban was issued as a `Date` object.
|
|
3144
|
+
*/
|
|
3145
|
+
get bannedAtDate(): Date;
|
|
3146
|
+
/**
|
|
3147
|
+
* Human-readable label: `"displayName (username)"`.
|
|
3148
|
+
*/
|
|
3149
|
+
get label(): string;
|
|
3150
|
+
toJSON(): BanEntry;
|
|
3151
|
+
}
|
|
3152
|
+
|
|
3153
|
+
/**
|
|
3154
|
+
* A rich wrapper around a raw `Warning` that adds a `delete()` convenience method.
|
|
3155
|
+
*
|
|
3156
|
+
* Returned by `client.fetchMemberWarnings()` and `member.fetchWarnings()`.
|
|
3157
|
+
*
|
|
3158
|
+
* @example
|
|
3159
|
+
* const warnings = await member.fetchWarnings()
|
|
3160
|
+
* for (const warning of warnings) {
|
|
3161
|
+
* console.log(`[${warning.issuedAt.toLocaleDateString()}] ${warning.reason}`)
|
|
3162
|
+
* }
|
|
3163
|
+
*
|
|
3164
|
+
* // Remove the oldest warning if there are too many
|
|
3165
|
+
* if (warnings.length > 5) {
|
|
3166
|
+
* await warnings[0].delete()
|
|
3167
|
+
* }
|
|
3168
|
+
*/
|
|
3169
|
+
declare class NovaWarning implements Warning {
|
|
3170
|
+
/** Unique ID of this warning. */
|
|
3171
|
+
readonly id: string;
|
|
3172
|
+
/** ID of the server where the warning was issued. */
|
|
3173
|
+
readonly serverId: string;
|
|
3174
|
+
/** ID of the user who received the warning. */
|
|
3175
|
+
readonly userId: string;
|
|
3176
|
+
/** ID of the moderator who issued the warning. */
|
|
3177
|
+
readonly moderatorId: string;
|
|
3178
|
+
/** The reason text. */
|
|
3179
|
+
readonly reason: string;
|
|
3180
|
+
/** ISO timestamp of when the warning was issued. */
|
|
3181
|
+
readonly createdAt: string;
|
|
3182
|
+
private readonly _members;
|
|
3183
|
+
constructor(raw: Warning, members: MembersAPI);
|
|
3184
|
+
/**
|
|
3185
|
+
* Delete (expunge) this warning from the record.
|
|
3186
|
+
* Requires the `members.moderate` scope.
|
|
3187
|
+
*
|
|
3188
|
+
* @example
|
|
3189
|
+
* await warning.delete()
|
|
3190
|
+
*/
|
|
3191
|
+
delete(): Promise<{
|
|
3192
|
+
ok: true;
|
|
3193
|
+
}>;
|
|
3194
|
+
/**
|
|
3195
|
+
* When the warning was issued as a `Date` object.
|
|
3196
|
+
*/
|
|
3197
|
+
get issuedAt(): Date;
|
|
3198
|
+
/**
|
|
3199
|
+
* How long ago the warning was issued, in milliseconds.
|
|
3200
|
+
*/
|
|
3201
|
+
get ageMs(): number;
|
|
3202
|
+
toJSON(): Warning;
|
|
3203
|
+
}
|
|
3204
|
+
|
|
3205
|
+
/**
|
|
3206
|
+
* Function called when a value is emitted.
|
|
3207
|
+
*/
|
|
3208
|
+
type Observer<T> = (value: T) => void;
|
|
3209
|
+
/**
|
|
3210
|
+
* A function that transforms one EventStream into another.
|
|
3211
|
+
* Used with the `pipe()` operator.
|
|
3212
|
+
*/
|
|
3213
|
+
type OperatorFn<T, U> = (stream: EventStream<T>) => EventStream<U>;
|
|
3214
|
+
/**
|
|
3215
|
+
* Represents an active subscription to an `EventStream`.
|
|
3216
|
+
* Call `.unsubscribe()` to cancel delivery and free resources.
|
|
3217
|
+
*
|
|
3218
|
+
* @example
|
|
3219
|
+
* const sub = client.stream('messageCreate').subscribe(msg => console.log(msg.content))
|
|
3220
|
+
* // Later:
|
|
3221
|
+
* sub.unsubscribe()
|
|
3222
|
+
*/
|
|
3223
|
+
declare class Subscription {
|
|
3224
|
+
private readonly _teardown;
|
|
3225
|
+
private _closed;
|
|
3226
|
+
constructor(teardown: () => void);
|
|
3227
|
+
/** `true` once `unsubscribe()` has been called. */
|
|
3228
|
+
get closed(): boolean;
|
|
3229
|
+
/** Cancel the subscription. Safe to call multiple times. */
|
|
3230
|
+
unsubscribe(): void;
|
|
3231
|
+
}
|
|
3232
|
+
/**
|
|
3233
|
+
* A lazy, composable reactive stream — like RxJS `Observable` but zero-dependency.
|
|
3234
|
+
*
|
|
3235
|
+
* Streams are **cold** by default: the source function runs fresh for each
|
|
3236
|
+
* `subscribe()` call. When created by `client.stream()` they become effectively
|
|
3237
|
+
* **hot**, sharing the same underlying gateway event source.
|
|
3238
|
+
*
|
|
3239
|
+
* @example
|
|
3240
|
+
* // Filter messages in a specific channel and debounce rapid edits
|
|
3241
|
+
* client.stream('messageCreate')
|
|
3242
|
+
* .filter(msg => msg.channelId === '123')
|
|
3243
|
+
* .debounce(500)
|
|
3244
|
+
* .subscribe(msg => console.log('New message:', msg.content))
|
|
3245
|
+
*
|
|
3246
|
+
* // Collect the next 5 pings, then stop
|
|
3247
|
+
* const pings = await client.stream('messageCreate')
|
|
3248
|
+
* .filter(msg => msg.content === '!ping')
|
|
3249
|
+
* .collect(5)
|
|
3250
|
+
*/
|
|
3251
|
+
declare class EventStream<T> {
|
|
3252
|
+
/** @internal Source function — called once per `subscribe()`. */
|
|
3253
|
+
readonly _source: (observer: Observer<T>) => () => void;
|
|
3254
|
+
constructor(
|
|
3255
|
+
/** @internal Source function — called once per `subscribe()`. */
|
|
3256
|
+
_source: (observer: Observer<T>) => () => void);
|
|
3257
|
+
/**
|
|
3258
|
+
* Activate the stream and receive values via `fn`.
|
|
3259
|
+
* Returns a `Subscription` — call `.unsubscribe()` to stop delivery.
|
|
3260
|
+
*
|
|
3261
|
+
* @example
|
|
3262
|
+
* const sub = stream.subscribe(value => console.log(value))
|
|
3263
|
+
* // later…
|
|
3264
|
+
* sub.unsubscribe()
|
|
3265
|
+
*/
|
|
3266
|
+
subscribe(fn: Observer<T>): Subscription;
|
|
3267
|
+
/**
|
|
3268
|
+
* Only pass values that satisfy `predicate`.
|
|
3269
|
+
*
|
|
3270
|
+
* @example
|
|
3271
|
+
* stream.filter(msg => msg.content.startsWith('!'))
|
|
3272
|
+
*/
|
|
3273
|
+
filter(predicate: (value: T) => boolean): EventStream<T>;
|
|
3274
|
+
/**
|
|
3275
|
+
* Transform each value with `transform`.
|
|
3276
|
+
*
|
|
3277
|
+
* @example
|
|
3278
|
+
* stream.map(msg => msg.content.toUpperCase())
|
|
3279
|
+
*/
|
|
3280
|
+
map<U>(transform: (value: T) => U): EventStream<U>;
|
|
3281
|
+
/**
|
|
3282
|
+
* Map each value to an inner stream and flatten the results.
|
|
3283
|
+
*
|
|
3284
|
+
* @example
|
|
3285
|
+
* client.stream('messageCreate')
|
|
3286
|
+
* .flatMap(msg => client.stream('reactionAdd').filter(r => r.messageId === msg.id))
|
|
3287
|
+
*/
|
|
3288
|
+
flatMap<U>(transform: (value: T) => EventStream<U>): EventStream<U>;
|
|
3289
|
+
/**
|
|
3290
|
+
* Stop after emitting `count` values.
|
|
3291
|
+
*
|
|
3292
|
+
* @example
|
|
3293
|
+
* stream.take(1).subscribe(first => console.log('First:', first))
|
|
3294
|
+
*/
|
|
3295
|
+
take(count: number): EventStream<T>;
|
|
3296
|
+
/**
|
|
3297
|
+
* Skip the first `count` values.
|
|
3298
|
+
*
|
|
3299
|
+
* @example
|
|
3300
|
+
* stream.skip(3) // ignore the first 3
|
|
3301
|
+
*/
|
|
3302
|
+
skip(count: number): EventStream<T>;
|
|
3303
|
+
/**
|
|
3304
|
+
* Emit values while `predicate` returns `true`, then auto-unsubscribe.
|
|
3305
|
+
*
|
|
3306
|
+
* @example
|
|
3307
|
+
* stream.takeWhile(n => n < 10)
|
|
3308
|
+
*/
|
|
3309
|
+
takeWhile(predicate: (value: T) => boolean): EventStream<T>;
|
|
3310
|
+
/**
|
|
3311
|
+
* Stop emitting once `signal` resolves.
|
|
3312
|
+
*
|
|
3313
|
+
* @example
|
|
3314
|
+
* const stop = new Promise(resolve => setTimeout(resolve, 5_000))
|
|
3315
|
+
* stream.takeUntil(stop).subscribe(handler)
|
|
3316
|
+
*/
|
|
3317
|
+
takeUntil(signal: Promise<unknown>): EventStream<T>;
|
|
3318
|
+
/**
|
|
3319
|
+
* Delay forwarding by `ms`. If a new value arrives before the delay expires
|
|
3320
|
+
* the timer resets — only the last value within a quiet period passes.
|
|
3321
|
+
* Useful for suppressing bursts.
|
|
3322
|
+
*
|
|
3323
|
+
* @example
|
|
3324
|
+
* client.stream('typingStart').debounce(300).subscribe(onTyping)
|
|
3325
|
+
*/
|
|
3326
|
+
debounce(ms: number): EventStream<T>;
|
|
3327
|
+
/**
|
|
3328
|
+
* Forward a value at most once per `ms` milliseconds (leading-edge).
|
|
3329
|
+
*
|
|
3330
|
+
* @example
|
|
3331
|
+
* client.stream('reactionAdd').throttle(1_000).subscribe(alert)
|
|
3332
|
+
*/
|
|
3333
|
+
throttle(ms: number): EventStream<T>;
|
|
3334
|
+
/**
|
|
3335
|
+
* Collect emitted values into windows of `windowMs` milliseconds and emit
|
|
3336
|
+
* each window as an array. Empty windows are skipped.
|
|
3337
|
+
*
|
|
3338
|
+
* @example
|
|
3339
|
+
* // Count messages per second
|
|
3340
|
+
* client.stream('messageCreate').windowTime(1_000).subscribe(batch => {
|
|
3341
|
+
* console.log(`${batch.length} msgs in last second`)
|
|
3342
|
+
* })
|
|
3343
|
+
*/
|
|
3344
|
+
windowTime(windowMs: number): EventStream<T[]>;
|
|
3345
|
+
/**
|
|
3346
|
+
* Merge another stream into this one.
|
|
3347
|
+
*
|
|
3348
|
+
* @example
|
|
3349
|
+
* streamA.merge(streamB).subscribe(handler)
|
|
3350
|
+
*/
|
|
3351
|
+
merge(other: EventStream<T>): EventStream<T>;
|
|
3352
|
+
/**
|
|
3353
|
+
* Emit a `[T, U]` tuple each time EITHER stream fires,
|
|
3354
|
+
* pairing with the most recent value from the other stream.
|
|
3355
|
+
* Requires both streams to have emitted at least one value.
|
|
3356
|
+
*
|
|
3357
|
+
* @example
|
|
3358
|
+
* positionStream.combineLatest(speedStream).subscribe(([pos, speed]) => …)
|
|
3359
|
+
*/
|
|
3360
|
+
combineLatest<U>(other: EventStream<U>): EventStream<[T, U]>;
|
|
3361
|
+
/**
|
|
3362
|
+
* Resolve with the first value that satisfies an optional `predicate`,
|
|
3363
|
+
* then automatically unsubscribe.
|
|
3364
|
+
*
|
|
3365
|
+
* @example
|
|
3366
|
+
* const welcome = await client.stream('messageCreate')
|
|
3367
|
+
* .filter(m => m.content === 'hello')
|
|
3368
|
+
* .first()
|
|
3369
|
+
*/
|
|
3370
|
+
first(predicate?: (value: T) => boolean): Promise<T>;
|
|
3371
|
+
/**
|
|
3372
|
+
* Collect exactly `count` values and resolve with them as an array.
|
|
3373
|
+
*
|
|
3374
|
+
* @example
|
|
3375
|
+
* const next3 = await client.stream('messageCreate').collect(3)
|
|
3376
|
+
*/
|
|
3377
|
+
collect(count: number): Promise<T[]>;
|
|
3378
|
+
/**
|
|
3379
|
+
* Apply a sequence of operators left-to-right.
|
|
3380
|
+
* Each operator is a function `(EventStream<In>) => EventStream<Out>`.
|
|
3381
|
+
*
|
|
3382
|
+
* @example
|
|
3383
|
+
* const dedupFilter = (s: EventStream<string>) =>
|
|
3384
|
+
* s.filter(v => v.length > 0)
|
|
3385
|
+
*
|
|
3386
|
+
* stream
|
|
3387
|
+
* .pipe(dedupFilter, s => s.take(10))
|
|
3388
|
+
* .subscribe(console.log)
|
|
3389
|
+
*/
|
|
3390
|
+
pipe<A>(op1: OperatorFn<T, A>): EventStream<A>;
|
|
3391
|
+
pipe<A, B>(op1: OperatorFn<T, A>, op2: OperatorFn<A, B>): EventStream<B>;
|
|
3392
|
+
pipe<A, B, C>(op1: OperatorFn<T, A>, op2: OperatorFn<A, B>, op3: OperatorFn<B, C>): EventStream<C>;
|
|
3393
|
+
pipe<A, B, C, D>(op1: OperatorFn<T, A>, op2: OperatorFn<A, B>, op3: OperatorFn<B, C>, op4: OperatorFn<C, D>): EventStream<D>;
|
|
3394
|
+
/**
|
|
3395
|
+
* Consume the stream with `for await…of`.
|
|
3396
|
+
*
|
|
3397
|
+
* @example
|
|
3398
|
+
* for await (const msg of client.stream('messageCreate').take(10)) {
|
|
3399
|
+
* await msg.reply('Got it')
|
|
3400
|
+
* }
|
|
3401
|
+
*/
|
|
3402
|
+
[Symbol.asyncIterator](): AsyncIterableIterator<T>;
|
|
3403
|
+
/**
|
|
3404
|
+
* Emit a fixed list of values synchronously on subscribe, then complete.
|
|
3405
|
+
*/
|
|
3406
|
+
static of<T>(...values: T[]): EventStream<T>;
|
|
3407
|
+
/**
|
|
3408
|
+
* Emit an incrementing counter every `ms` milliseconds.
|
|
3409
|
+
*
|
|
3410
|
+
* @example
|
|
3411
|
+
* EventStream.interval(1_000).take(10).subscribe(n => console.log('tick', n))
|
|
3412
|
+
*/
|
|
3413
|
+
static interval(ms: number): EventStream<number>;
|
|
3414
|
+
/**
|
|
3415
|
+
* Merge multiple streams into one.
|
|
3416
|
+
*
|
|
3417
|
+
* @example
|
|
3418
|
+
* EventStream.merge(streamA, streamB).subscribe(handler)
|
|
3419
|
+
*/
|
|
3420
|
+
static merge<T>(...streams: EventStream<T>[]): EventStream<T>;
|
|
3421
|
+
/**
|
|
3422
|
+
* Create a hot stream from any Node.js-style `EventEmitter`.
|
|
3423
|
+
*
|
|
3424
|
+
* @example
|
|
3425
|
+
* EventStream.fromEmitter<string>(process, 'message').subscribe(console.log)
|
|
3426
|
+
*/
|
|
3427
|
+
static fromEmitter<T>(emitter: {
|
|
3428
|
+
on(event: string, listener: (v: T) => void): unknown;
|
|
3429
|
+
off(event: string, listener: (v: T) => void): unknown;
|
|
3430
|
+
}, event: string): EventStream<T>;
|
|
3431
|
+
}
|
|
3432
|
+
|
|
3433
|
+
interface EventBufferOptions {
|
|
3434
|
+
/**
|
|
3435
|
+
* Maximum number of events to retain in the ring buffer.
|
|
3436
|
+
* When full, the oldest item is discarded to make room for the newest.
|
|
3437
|
+
* Default: `100`.
|
|
3438
|
+
*/
|
|
3439
|
+
size?: number;
|
|
3440
|
+
}
|
|
3441
|
+
/**
|
|
3442
|
+
* A fixed-size ring buffer that captures events from a `NovaClient` event type
|
|
3443
|
+
* and lets you replay them to new subscribers at any time.
|
|
3444
|
+
*
|
|
3445
|
+
* Obtained via `client.buffer(event, options)` — do **not** construct directly.
|
|
3446
|
+
*
|
|
3447
|
+
* @example
|
|
3448
|
+
* // Start capturing messages (call once, before connect or early in ready)
|
|
3449
|
+
* const msgBuffer = client.buffer('messageCreate', { size: 200 })
|
|
3450
|
+
*
|
|
3451
|
+
* // Later — replay everything received so far, then keep streaming
|
|
3452
|
+
* msgBuffer.asStream({ replay: true }).subscribe(msg => {
|
|
3453
|
+
* console.log('[replayed or live]', msg.content)
|
|
3454
|
+
* })
|
|
3455
|
+
*
|
|
3456
|
+
* // Quickly inspect the last 10 messages without subscribing
|
|
3457
|
+
* const recent = msgBuffer.getLast(10)
|
|
3458
|
+
*
|
|
3459
|
+
* // Use with async iterator
|
|
3460
|
+
* for await (const msg of msgBuffer.asStream({ replay: true })) {
|
|
3461
|
+
* if (msg.content === 'stop') break
|
|
3462
|
+
* }
|
|
3463
|
+
*/
|
|
3464
|
+
declare class EventBuffer<T> {
|
|
3465
|
+
private readonly _ring;
|
|
3466
|
+
private readonly _maxSize;
|
|
3467
|
+
private readonly _observers;
|
|
3468
|
+
constructor(options?: EventBufferOptions);
|
|
3469
|
+
/**
|
|
3470
|
+
* @internal
|
|
3471
|
+
* Called by `NovaClient._deliverEvent()` each time the event fires.
|
|
3472
|
+
* Push to ring buffer and notify live subscribers.
|
|
3473
|
+
*/
|
|
3474
|
+
_push(item: T): void;
|
|
3475
|
+
/** All buffered items, oldest first. Never mutate the returned array. */
|
|
3476
|
+
getAll(): T[];
|
|
3477
|
+
/**
|
|
3478
|
+
* The N most recent items.
|
|
3479
|
+
*
|
|
3480
|
+
* @example
|
|
3481
|
+
* const last5 = buffer.getLast(5)
|
|
3482
|
+
*/
|
|
3483
|
+
getLast(n: number): T[];
|
|
3484
|
+
/** The most recently buffered item, or `undefined` if the buffer is empty. */
|
|
3485
|
+
get latest(): T | undefined;
|
|
3486
|
+
/** Number of items currently stored. */
|
|
3487
|
+
get size(): number;
|
|
3488
|
+
/** Maximum number of items the buffer can hold. */
|
|
3489
|
+
get capacity(): number;
|
|
3490
|
+
/** `true` when no items are stored. */
|
|
3491
|
+
get isEmpty(): boolean;
|
|
3492
|
+
/** Whether the buffer is at maximum capacity. */
|
|
3493
|
+
get isFull(): boolean;
|
|
3494
|
+
/** Remove all buffered items without affecting active subscriptions. */
|
|
3495
|
+
clear(): void;
|
|
3496
|
+
/**
|
|
3497
|
+
* Expose the buffer as an `EventStream`, giving access to all chaining
|
|
3498
|
+
* operators (`.filter()`, `.map()`, `.debounce()`, etc.).
|
|
3499
|
+
*
|
|
3500
|
+
* Pass `{ replay: true }` to emit all currently buffered items to the
|
|
3501
|
+
* subscriber **before** switching to live delivery.
|
|
3502
|
+
*
|
|
3503
|
+
* @example
|
|
3504
|
+
* // Replay + live with filter
|
|
3505
|
+
* buffer
|
|
3506
|
+
* .asStream({ replay: true })
|
|
3507
|
+
* .filter(msg => msg.channelId === '123')
|
|
3508
|
+
* .subscribe(msg => console.log(msg.content))
|
|
3509
|
+
*/
|
|
3510
|
+
asStream(options?: {
|
|
3511
|
+
replay?: boolean;
|
|
3512
|
+
}): EventStream<T>;
|
|
3513
|
+
/**
|
|
3514
|
+
* Subscribe directly, with optional replay.
|
|
3515
|
+
* Equivalent to `.asStream(options).subscribe(fn)`.
|
|
3516
|
+
*
|
|
3517
|
+
* @example
|
|
3518
|
+
* buffer.subscribe(msg => handle(msg), { replay: true })
|
|
3519
|
+
*/
|
|
3520
|
+
subscribe(fn: Observer<T>, options?: {
|
|
3521
|
+
replay?: boolean;
|
|
3522
|
+
}): Subscription;
|
|
3523
|
+
/**
|
|
3524
|
+
* Iterate over all **currently buffered** items synchronously.
|
|
3525
|
+
*
|
|
3526
|
+
* @example
|
|
3527
|
+
* for (const msg of buffer) {
|
|
3528
|
+
* console.log(msg.content)
|
|
3529
|
+
* }
|
|
3530
|
+
*/
|
|
3531
|
+
[Symbol.iterator](): Iterator<T>;
|
|
3532
|
+
}
|
|
3533
|
+
|
|
3534
|
+
interface NovaClientEvents {
|
|
3535
|
+
/** Fired when the bot connects and is identified by the gateway. */
|
|
3536
|
+
ready: (bot: BotApplication) => void;
|
|
3537
|
+
/** Fired for every raw `bot:event` from the gateway. */
|
|
3538
|
+
event: (event: BotEvent) => void;
|
|
3539
|
+
/**
|
|
3540
|
+
* Fired when an interaction is received (slash command, button click, etc.).
|
|
3541
|
+
* Use `client.command()`, `client.button()`, `client.selectMenu()`, or
|
|
3542
|
+
* `client.autocomplete()` for convenient routing instead of handling everything here.
|
|
3543
|
+
*/
|
|
3544
|
+
interactionCreate: (interaction: NovaInteraction) => void;
|
|
3545
|
+
/** Fired when the WebSocket connection drops. */
|
|
3546
|
+
disconnect: (reason: string) => void;
|
|
3547
|
+
/** Fired on gateway / API errors. */
|
|
3548
|
+
error: (err: Error | {
|
|
3549
|
+
code: number;
|
|
3550
|
+
message: string;
|
|
3551
|
+
}) => void;
|
|
3552
|
+
/** A new message was sent in a channel the bot can see. */
|
|
3553
|
+
messageCreate: (message: NovaMessage) => void;
|
|
3554
|
+
/** A message was edited. Returns the updated message. */
|
|
3555
|
+
messageUpdate: (message: NovaMessage) => void;
|
|
3556
|
+
/** A message was deleted. Returns partial data. */
|
|
3557
|
+
messageDelete: (data: {
|
|
3558
|
+
id: string;
|
|
3559
|
+
channelId: string;
|
|
3560
|
+
}) => void;
|
|
3561
|
+
/** A reaction was added to a message. */
|
|
3562
|
+
reactionAdd: (data: {
|
|
3563
|
+
messageId: string;
|
|
3564
|
+
channelId: string;
|
|
3565
|
+
userId: string;
|
|
3566
|
+
emoji: string;
|
|
3567
|
+
}) => void;
|
|
3568
|
+
/** A reaction was removed from a message. */
|
|
3569
|
+
reactionRemove: (data: {
|
|
3570
|
+
messageId: string;
|
|
3571
|
+
channelId: string;
|
|
3572
|
+
userId: string;
|
|
3573
|
+
emoji: string;
|
|
3574
|
+
}) => void;
|
|
3575
|
+
/** A member joined a server the bot is in. */
|
|
3576
|
+
memberAdd: (data: {
|
|
3577
|
+
serverId: string;
|
|
3578
|
+
userId: string;
|
|
3579
|
+
username: string;
|
|
3580
|
+
}) => void;
|
|
3581
|
+
/** A member left a server the bot is in. */
|
|
3582
|
+
memberRemove: (data: {
|
|
3583
|
+
serverId: string;
|
|
3584
|
+
userId: string;
|
|
3585
|
+
}) => void;
|
|
3586
|
+
/** A user started typing in a channel. */
|
|
3587
|
+
typingStart: (data: {
|
|
3588
|
+
channelId: string;
|
|
3589
|
+
userId: string;
|
|
3590
|
+
}) => void;
|
|
3591
|
+
/** A message was pinned. */
|
|
3592
|
+
messagePinned: (data: {
|
|
3593
|
+
messageId: string;
|
|
3594
|
+
channelId: string;
|
|
3595
|
+
pinnedBy: string;
|
|
3596
|
+
}) => void;
|
|
3597
|
+
/** A channel was created in a server. */
|
|
3598
|
+
channelCreate: (channel: Channel) => void;
|
|
3599
|
+
/** A channel was updated. */
|
|
3600
|
+
channelUpdate: (channel: Channel) => void;
|
|
3601
|
+
/** A channel was deleted. */
|
|
3602
|
+
channelDelete: (data: {
|
|
3603
|
+
id: string;
|
|
3604
|
+
serverId: string;
|
|
3605
|
+
}) => void;
|
|
3606
|
+
/** A role was created in a server. */
|
|
3607
|
+
roleCreate: (role: Role) => void;
|
|
3608
|
+
/** A role was updated. */
|
|
3609
|
+
roleUpdate: (role: Role) => void;
|
|
3610
|
+
/** A role was deleted. */
|
|
3611
|
+
roleDelete: (data: {
|
|
3612
|
+
id: string;
|
|
3613
|
+
serverId: string;
|
|
3614
|
+
}) => void;
|
|
3615
|
+
/** A user joined a voice channel. */
|
|
3616
|
+
voiceJoin: (data: {
|
|
3617
|
+
userId: string;
|
|
3618
|
+
channelId: string;
|
|
3619
|
+
serverId: string;
|
|
3620
|
+
}) => void;
|
|
3621
|
+
/** A user left a voice channel. */
|
|
3622
|
+
voiceLeave: (data: {
|
|
3623
|
+
userId: string;
|
|
3624
|
+
channelId: string;
|
|
3625
|
+
serverId: string;
|
|
3626
|
+
}) => void;
|
|
3627
|
+
/** A member was banned from a server. */
|
|
3628
|
+
memberBanned: (data: {
|
|
3629
|
+
userId: string;
|
|
3630
|
+
serverId: string;
|
|
3631
|
+
moderatorId: string | null;
|
|
3632
|
+
reason: string | null;
|
|
3633
|
+
}) => void;
|
|
3634
|
+
/** A member was unbanned. */
|
|
3635
|
+
memberUnbanned: (data: {
|
|
3636
|
+
userId: string;
|
|
3637
|
+
serverId: string;
|
|
3638
|
+
}) => void;
|
|
3639
|
+
/** A member received or lost a custom role. */
|
|
3640
|
+
memberRoleAdded: (data: {
|
|
3641
|
+
serverId: string;
|
|
3642
|
+
userId: string;
|
|
3643
|
+
roleId: string;
|
|
3644
|
+
}) => void;
|
|
3645
|
+
memberRoleRemoved: (data: {
|
|
3646
|
+
serverId: string;
|
|
3647
|
+
userId: string;
|
|
3648
|
+
roleId: string;
|
|
3649
|
+
}) => void;
|
|
3650
|
+
/** A member's profile data was updated. */
|
|
3651
|
+
memberUpdate: (data: {
|
|
3652
|
+
userId: string;
|
|
3653
|
+
serverId: string;
|
|
3654
|
+
}) => void;
|
|
3655
|
+
/** Server metadata (name, icon, etc.) was updated. */
|
|
3656
|
+
serverUpdate: (data: {
|
|
3657
|
+
id: string;
|
|
3658
|
+
name?: string;
|
|
3659
|
+
icon?: string | null;
|
|
3660
|
+
description?: string | null;
|
|
3661
|
+
}) => void;
|
|
3662
|
+
/** An invite was created. */
|
|
3663
|
+
inviteCreate: (invite: Invite) => void;
|
|
3664
|
+
/** An invite was deleted/revoked. */
|
|
3665
|
+
inviteDelete: (data: {
|
|
3666
|
+
code: string;
|
|
3667
|
+
serverId: string;
|
|
3668
|
+
}) => void;
|
|
3669
|
+
/** A forum post was created in a FORUM channel. */
|
|
3670
|
+
forumPostCreate: (post: NovaForumPost) => void;
|
|
3671
|
+
/** A server event was created. */
|
|
3672
|
+
eventCreate: (event: NovaServerEvent) => void;
|
|
3673
|
+
/** A server event was updated. */
|
|
3674
|
+
eventUpdate: (event: ServerEvent) => void;
|
|
3675
|
+
/** A server event was deleted. */
|
|
3676
|
+
eventDelete: (data: {
|
|
3677
|
+
id: string;
|
|
3678
|
+
serverId: string;
|
|
3679
|
+
}) => void;
|
|
3680
|
+
/** A channel category was created. */
|
|
3681
|
+
categoryCreate: (category: ChannelCategory) => void;
|
|
3682
|
+
/** A channel category was updated. */
|
|
3683
|
+
categoryUpdate: (category: ChannelCategory) => void;
|
|
3684
|
+
/** A channel category was deleted. */
|
|
3685
|
+
categoryDelete: (data: {
|
|
3686
|
+
id: string;
|
|
3687
|
+
serverId: string;
|
|
3688
|
+
}) => void;
|
|
3689
|
+
/** A member received a warning. */
|
|
3690
|
+
memberWarned: (data: {
|
|
3691
|
+
serverId: string;
|
|
3692
|
+
userId: string;
|
|
3693
|
+
warning: Warning;
|
|
3694
|
+
}) => void;
|
|
3695
|
+
/** Multiple messages were bulk-deleted. */
|
|
3696
|
+
messagesBulkDelete: (data: {
|
|
3697
|
+
channelId: string;
|
|
3698
|
+
messageIds: string[];
|
|
3699
|
+
count: number;
|
|
3700
|
+
}) => void;
|
|
3701
|
+
}
|
|
3702
|
+
/**
|
|
3703
|
+
* The main Nova bot client.
|
|
3704
|
+
*
|
|
3705
|
+
* @example
|
|
3706
|
+
* import { NovaClient } from 'nova-bot-sdk'
|
|
3707
|
+
*
|
|
3708
|
+
* const client = new NovaClient({ token: 'nova_bot_...' })
|
|
3709
|
+
*
|
|
3710
|
+
* client.on('ready', (bot) => {
|
|
3711
|
+
* console.log(`Logged in as ${bot.botUser.username}`)
|
|
3712
|
+
* })
|
|
3713
|
+
*
|
|
3714
|
+
* client.on('interactionCreate', async (interaction) => {
|
|
3715
|
+
* if (interaction.commandName === 'ping') {
|
|
3716
|
+
* await client.interactions.respond(interaction.id, { content: 'Pong!' })
|
|
3717
|
+
* }
|
|
3718
|
+
* })
|
|
3719
|
+
*
|
|
3720
|
+
* await client.connect()
|
|
3721
|
+
*/
|
|
3722
|
+
declare class NovaClient extends EventEmitter {
|
|
3723
|
+
/** The authenticated bot application. Available after `ready` fires. */
|
|
3724
|
+
botUser: BotApplication | null;
|
|
3725
|
+
/** Send, edit, delete and fetch messages. */
|
|
3726
|
+
readonly messages: MessagesAPI;
|
|
3727
|
+
/** Register and manage slash, prefix, and context menu commands. */
|
|
3728
|
+
readonly commands: CommandsAPI;
|
|
3729
|
+
/** List, kick, ban, and DM server members. */
|
|
3730
|
+
readonly members: MembersAPI;
|
|
3731
|
+
/** List and update servers the bot is a member of. */
|
|
3732
|
+
readonly servers: ServersAPI;
|
|
3733
|
+
/** Acknowledge and respond to interactions. */
|
|
3734
|
+
readonly interactions: InteractionsAPI;
|
|
3735
|
+
/** Query the bot's effective permissions within a server, channel, or role scope. */
|
|
3736
|
+
readonly permissions: PermissionsAPI;
|
|
3737
|
+
/** Create, edit, and delete channels; fetch pins and messages. */
|
|
3738
|
+
readonly channels: ChannelsAPI;
|
|
3739
|
+
/** Add, remove and fetch reactions on messages. */
|
|
3740
|
+
readonly reactions: ReactionsAPI;
|
|
3741
|
+
/** Create, edit, delete and assign custom roles. */
|
|
3742
|
+
readonly roles: RolesAPI;
|
|
3743
|
+
/** Create, fetch and revoke server invites. */
|
|
3744
|
+
readonly invites: InvitesAPI;
|
|
3745
|
+
/** Create, edit, delete and execute webhooks. */
|
|
3746
|
+
readonly webhooks: WebhooksAPI;
|
|
3747
|
+
/** Fetch server audit logs. */
|
|
3748
|
+
readonly auditLog: AuditLogAPI;
|
|
3749
|
+
/** Create and manage forum posts in FORUM channels. */
|
|
3750
|
+
readonly forum: ForumAPI;
|
|
3751
|
+
/** Create and manage server events. */
|
|
3752
|
+
readonly events: EventsAPI;
|
|
3753
|
+
/** Manage channel categories. */
|
|
3754
|
+
readonly categories: CategoriesAPI;
|
|
3755
|
+
/** Manage automod rules (blocked words / links). */
|
|
3756
|
+
readonly automod: AutoModAPI;
|
|
3757
|
+
/** Fetch user profiles. */
|
|
3758
|
+
readonly users: UsersAPI;
|
|
3759
|
+
private socket;
|
|
3760
|
+
private readonly http;
|
|
3761
|
+
private readonly options;
|
|
3762
|
+
private _cronTimers;
|
|
3763
|
+
private readonly _commandHandlers;
|
|
3764
|
+
private readonly _buttonHandlers;
|
|
3765
|
+
private readonly _selectHandlers;
|
|
3766
|
+
private readonly _modalHandlers;
|
|
3767
|
+
private readonly _autocompleteHandlers;
|
|
3768
|
+
private readonly _middlewares;
|
|
3769
|
+
private readonly _streamListeners;
|
|
3770
|
+
private readonly _bufferInstances;
|
|
3771
|
+
constructor(options: NovaClientOptions);
|
|
3772
|
+
/**
|
|
3773
|
+
* Register a handler for a slash or prefix command by name.
|
|
3774
|
+
* Automatically routes `interactionCreate` events whose `commandName` matches.
|
|
3775
|
+
*
|
|
3776
|
+
* @example
|
|
3777
|
+
* client.command('ping', async (interaction) => {
|
|
3778
|
+
* await interaction.reply('Pong! 🏓')
|
|
3779
|
+
* })
|
|
3780
|
+
*/
|
|
3781
|
+
command(name: string, handler: (interaction: NovaInteraction) => unknown): this;
|
|
3782
|
+
/**
|
|
3783
|
+
* Register a handler for a button by its `customId`.
|
|
3784
|
+
*
|
|
3785
|
+
* @example
|
|
3786
|
+
* client.button('confirm_delete', async (interaction) => {
|
|
3787
|
+
* await interaction.replyEphemeral('Deleted.')
|
|
3788
|
+
* })
|
|
3789
|
+
*/
|
|
3790
|
+
button(customId: string, handler: (interaction: NovaInteraction) => unknown): this;
|
|
3791
|
+
/**
|
|
3792
|
+
* Register a handler for a select menu by its `customId`.
|
|
3793
|
+
*
|
|
3794
|
+
* @example
|
|
3795
|
+
* client.selectMenu('colour_pick', async (interaction) => {
|
|
3796
|
+
* const chosen = interaction.values[0]
|
|
3797
|
+
* await interaction.reply(`You picked: ${chosen}`)
|
|
3798
|
+
* })
|
|
3799
|
+
*/
|
|
3800
|
+
selectMenu(customId: string, handler: (interaction: NovaInteraction) => unknown): this;
|
|
3801
|
+
/**
|
|
3802
|
+
* Register a handler for a modal submission by its `customId`.
|
|
3803
|
+
* Called automatically when the user submits a modal with that `customId`.
|
|
3804
|
+
*
|
|
3805
|
+
* @example
|
|
3806
|
+
* client.modal('report_modal', async (interaction) => {
|
|
3807
|
+
* const reason = interaction.modalData.reason
|
|
3808
|
+
* await interaction.replyEphemeral(`Report received: ${reason}`)
|
|
3809
|
+
* })
|
|
3810
|
+
*/
|
|
3811
|
+
modal(customId: string, handler: (interaction: NovaInteraction) => unknown): this;
|
|
3812
|
+
/**
|
|
3813
|
+
* Register a handler for an autocomplete interaction by command name.
|
|
3814
|
+
* Called when the user is typing in an option with `autocomplete: true`.
|
|
3815
|
+
* The handler receives the interaction with `interaction.autocomplete.value`
|
|
3816
|
+
* containing the partial text, and should call `interaction.respondAutocomplete()`
|
|
3817
|
+
* to send completion suggestions.
|
|
3818
|
+
*
|
|
3819
|
+
* @example
|
|
3820
|
+
* client.autocomplete('search', async (interaction) => {
|
|
3821
|
+
* const query = interaction.autocomplete?.value ?? ''
|
|
3822
|
+
* const results = await myDB.search(query)
|
|
3823
|
+
* await interaction.respondAutocomplete(
|
|
3824
|
+
* results.map(r => ({ name: r.label, value: r.id }))
|
|
3825
|
+
* )
|
|
3826
|
+
* })
|
|
3827
|
+
*/
|
|
3828
|
+
autocomplete(commandName: string, handler: (interaction: NovaInteraction) => unknown): this;
|
|
3829
|
+
/** Remove a slash/prefix command handler previously registered with `command()`. */
|
|
3830
|
+
removeCommand(name: string): void;
|
|
3831
|
+
/** Remove a button handler previously registered with `button()`. */
|
|
3832
|
+
removeButton(customId: string): void;
|
|
3833
|
+
/** Remove a select-menu handler previously registered with `selectMenu()`. */
|
|
3834
|
+
removeSelectMenu(customId: string): void;
|
|
3835
|
+
/** Remove a modal handler previously registered with `modal()`. */
|
|
3836
|
+
removeModal(customId: string): void;
|
|
3837
|
+
/** Remove an autocomplete handler previously registered with `autocomplete()`. */
|
|
3838
|
+
removeAutocomplete(name: string): void;
|
|
3839
|
+
/**
|
|
3840
|
+
* Remove a middleware function that was added via `use()`.
|
|
3841
|
+
* This is a reference-equality check — pass the exact same function object.
|
|
3842
|
+
*/
|
|
3843
|
+
removeMiddleware(fn: (event: string, payload: unknown, next: (p: unknown) => void) => void): void;
|
|
3844
|
+
emit(event: string | symbol, ...args: any[]): boolean;
|
|
3845
|
+
private _deliverEvent;
|
|
3846
|
+
/**
|
|
3847
|
+
* Add middleware to the event pipeline.
|
|
3848
|
+
*
|
|
3849
|
+
* Middleware runs **before** any `.on()` listener or stream subscriber.
|
|
3850
|
+
* Call `next(payload)` to continue the chain, passing an optionally modified
|
|
3851
|
+
* payload. Not calling `next` **cancels** the event entirely.
|
|
3852
|
+
*
|
|
3853
|
+
* **Global middleware** (all events):
|
|
3854
|
+
* @example
|
|
3855
|
+
* client.use((event, payload, next) => {
|
|
3856
|
+
* console.log(`[${event}]`)
|
|
3857
|
+
* next(payload) // pass through unchanged
|
|
3858
|
+
* })
|
|
3859
|
+
*
|
|
3860
|
+
* **Per-event typed middleware** (single event):
|
|
3861
|
+
* @example
|
|
3862
|
+
* client.use('messageCreate', (msg, next) => {
|
|
3863
|
+
* if (msg.isFromBot()) return // cancel — bots ignored
|
|
3864
|
+
* next(msg)
|
|
3865
|
+
* })
|
|
3866
|
+
*
|
|
3867
|
+
* **Async middleware** (call next after await):
|
|
3868
|
+
* @example
|
|
3869
|
+
* client.use('interactionCreate', async (interaction, next) => {
|
|
3870
|
+
* const ok = await checkRateLimit(interaction.userId)
|
|
3871
|
+
* if (ok) next(interaction)
|
|
3872
|
+
* })
|
|
3873
|
+
*/
|
|
3874
|
+
use(fn: (event: string, payload: unknown, next: (p: unknown) => void) => void): this;
|
|
3875
|
+
use<K extends keyof NovaClientEvents>(event: K, fn: (payload: Parameters<NovaClientEvents[K]>[0], next: (p: Parameters<NovaClientEvents[K]>[0]) => void) => void): this;
|
|
3876
|
+
/**
|
|
3877
|
+
* Create a reactive `EventStream` for any client event.
|
|
3878
|
+
*
|
|
3879
|
+
* Streams are **hot** (backed by live gateway events) and support a full
|
|
3880
|
+
* operator library: `.filter()`, `.map()`, `.debounce()`, `.throttle()`,
|
|
3881
|
+
* `.take()`, `.flatMap()`, `.combineLatest()`, `.pipe()`, and more.
|
|
3882
|
+
*
|
|
3883
|
+
* Works with `for await…of` thanks to built-in `[Symbol.asyncIterator]`.
|
|
3884
|
+
*
|
|
3885
|
+
* @example
|
|
3886
|
+
* // Only messages in a specific channel, de-duped over 200 ms
|
|
3887
|
+
* client.stream('messageCreate')
|
|
3888
|
+
* .filter(msg => msg.channelId === announcementId)
|
|
3889
|
+
* .debounce(200)
|
|
3890
|
+
* .subscribe(msg => announce(msg))
|
|
3891
|
+
*
|
|
3892
|
+
* // Collect the next 3 pings as an array
|
|
3893
|
+
* const pings = await client.stream('messageCreate')
|
|
3894
|
+
* .filter(m => m.content === '!ping')
|
|
3895
|
+
* .collect(3)
|
|
3896
|
+
*
|
|
3897
|
+
* // Async iteration
|
|
3898
|
+
* for await (const interaction of client.stream('interactionCreate').take(10)) {
|
|
3899
|
+
* await interaction.reply('Processed')
|
|
3900
|
+
* }
|
|
3901
|
+
*
|
|
3902
|
+
* // combineLatest: pair each new message with the latest reaction event
|
|
3903
|
+
* client.stream('messageCreate')
|
|
3904
|
+
* .combineLatest(client.stream('reactionAdd'))
|
|
3905
|
+
* .subscribe(([msg, reaction]) => { … })
|
|
3906
|
+
*/
|
|
3907
|
+
stream<K extends keyof NovaClientEvents>(event: K): EventStream<Parameters<NovaClientEvents[K]>[0]>;
|
|
3908
|
+
/**
|
|
3909
|
+
* Start capturing events of `event` in a ring buffer of up to `size` items.
|
|
3910
|
+
* Repeated calls for the same event return the **same** buffer instance.
|
|
3911
|
+
*
|
|
3912
|
+
* Later subscribers can replay all captured events, then continue receiving
|
|
3913
|
+
* live ones — a built-in alternative to Discord.js "message cache".
|
|
3914
|
+
*
|
|
3915
|
+
* @example
|
|
3916
|
+
* // Capture the last 500 messages (call before connect())
|
|
3917
|
+
* const msgs = client.buffer('messageCreate', { size: 500 })
|
|
3918
|
+
*
|
|
3919
|
+
* // After connect — inspect without subscribing
|
|
3920
|
+
* console.log('Buffered so far:', msgs.size)
|
|
3921
|
+
* const latest = msgs.getLast(5)
|
|
3922
|
+
*
|
|
3923
|
+
* // New handler that replays history first, then receives live events
|
|
3924
|
+
* msgs.asStream({ replay: true })
|
|
3925
|
+
* .filter(m => m.content.includes('@everyone'))
|
|
3926
|
+
* .subscribe(handleMention)
|
|
3927
|
+
*
|
|
3928
|
+
* // Clear the buffer (e.g. when rolling over to a new session)
|
|
3929
|
+
* msgs.clear()
|
|
3930
|
+
*/
|
|
3931
|
+
buffer<K extends keyof NovaClientEvents>(event: K, options?: {
|
|
3932
|
+
size?: number;
|
|
3933
|
+
}): EventBuffer<Parameters<NovaClientEvents[K]>[0]>;
|
|
3934
|
+
/**
|
|
3935
|
+
* Connect to the Nova WebSocket gateway.
|
|
3936
|
+
* Resolves when the `ready` event is received.
|
|
3937
|
+
*
|
|
3938
|
+
* @example
|
|
3939
|
+
* await client.connect()
|
|
3940
|
+
*/
|
|
3941
|
+
connect(): Promise<void>;
|
|
3942
|
+
/**
|
|
3943
|
+
* Register a recurring task that fires at a set interval.
|
|
3944
|
+
* All cron tasks are automatically cancelled on `disconnect()`.
|
|
3945
|
+
*
|
|
3946
|
+
* @param intervalMs - How often to run the task (in milliseconds).
|
|
3947
|
+
* @param fn - Async or sync function to call on each tick.
|
|
3948
|
+
* @returns A cancel function — call it to stop this specific task.
|
|
3949
|
+
*
|
|
3950
|
+
* @example
|
|
3951
|
+
* // Check for new announcements every 30 seconds
|
|
3952
|
+
* client.cron(30_000, async () => {
|
|
3953
|
+
* const messages = await client.messages.fetch(channelId, { limit: 5 })
|
|
3954
|
+
* // do something...
|
|
3955
|
+
* })
|
|
3956
|
+
*/
|
|
3957
|
+
cron(intervalMs: number, fn: () => unknown): () => void;
|
|
3958
|
+
/**
|
|
3959
|
+
* Set the bot's presence status.
|
|
3960
|
+
* Broadcasts to all servers the bot is in via WebSocket.
|
|
3961
|
+
*
|
|
3962
|
+
* @example
|
|
3963
|
+
* client.setStatus('DND') // Do Not Disturb
|
|
3964
|
+
* client.setStatus('IDLE') // Away
|
|
3965
|
+
* client.setStatus('OFFLINE') // Appear offline
|
|
3966
|
+
* client.setStatus('ONLINE') // Back online
|
|
3967
|
+
*/
|
|
3968
|
+
setStatus(status: BotStatus): void;
|
|
3969
|
+
/**
|
|
3970
|
+
* Fetch a single channel and return it as a rich `NovaChannel` wrapper.
|
|
3971
|
+
*
|
|
3972
|
+
* @example
|
|
3973
|
+
* const channel = await client.fetchChannel('channel-id')
|
|
3974
|
+
* await channel.send('Hello!')
|
|
3975
|
+
*/
|
|
3976
|
+
fetchChannel(channelId: string): Promise<NovaChannel>;
|
|
3977
|
+
/**
|
|
3978
|
+
* Fetch all channels in a server and return them as `NovaChannel` wrappers.
|
|
3979
|
+
*
|
|
3980
|
+
* @example
|
|
3981
|
+
* const channels = await client.fetchChannels('server-id')
|
|
3982
|
+
* const textChannels = channels.filter(c => c.isText())
|
|
3983
|
+
*/
|
|
3984
|
+
fetchChannels(serverId: string): Promise<NovaChannel[]>;
|
|
3985
|
+
/**
|
|
3986
|
+
* Fetch all members in a server and return them as `NovaMember` wrappers.
|
|
3987
|
+
*
|
|
3988
|
+
* @example
|
|
3989
|
+
* const members = await client.fetchMembers('server-id')
|
|
3990
|
+
* const bots = members.filter(m => m.isBot)
|
|
3991
|
+
*/
|
|
3992
|
+
fetchMembers(serverId: string): Promise<NovaMember[]>;
|
|
3993
|
+
/**
|
|
3994
|
+
* Fetch a single member from a server and return them as a `NovaMember` wrapper.
|
|
3995
|
+
* Uses the dedicated single-member endpoint (more efficient than listing all members).
|
|
3996
|
+
*
|
|
3997
|
+
* @example
|
|
3998
|
+
* const member = await client.fetchMember('server-id', 'user-id')
|
|
3999
|
+
* await member.dm('Welcome!')
|
|
4000
|
+
*/
|
|
4001
|
+
fetchMember(serverId: string, userId: string): Promise<NovaMember>;
|
|
4002
|
+
/**
|
|
4003
|
+
* Fetch all bans in a server and return them as `NovaBan` wrappers.
|
|
4004
|
+
* Each `NovaBan` has an `.unban()` convenience method.
|
|
4005
|
+
* Requires the `members.ban` scope.
|
|
4006
|
+
*
|
|
4007
|
+
* @example
|
|
4008
|
+
* const bans = await client.fetchBans('server-id')
|
|
4009
|
+
* for (const ban of bans) {
|
|
4010
|
+
* if (ban.reason === 'test') await ban.unban()
|
|
4011
|
+
* }
|
|
4012
|
+
*/
|
|
4013
|
+
fetchBans(serverId: string): Promise<NovaBan[]>;
|
|
4014
|
+
/**
|
|
4015
|
+
* Fetch warnings for a member (or all members) in a server and return them
|
|
4016
|
+
* as `NovaWarning` wrappers. Each wrapper has a `.delete()` convenience method.
|
|
4017
|
+
* Requires the `members.moderate` scope.
|
|
4018
|
+
*
|
|
4019
|
+
* @example
|
|
4020
|
+
* const warnings = await client.fetchMemberWarnings('server-id', 'user-id')
|
|
4021
|
+
* for (const w of warnings) {
|
|
4022
|
+
* if (w.ageMs > 30 * 24 * 60 * 60_000) await w.delete() // older than 30 days
|
|
4023
|
+
* }
|
|
4024
|
+
*/
|
|
4025
|
+
fetchMemberWarnings(serverId: string, userId?: string): Promise<NovaWarning[]>;
|
|
4026
|
+
/**
|
|
4027
|
+
* Fetch a single server by ID and return it as a `NovaServerWrapper`.
|
|
4028
|
+
*
|
|
4029
|
+
* @example
|
|
4030
|
+
* const server = await client.fetchServer('server-id')
|
|
4031
|
+
* console.log(`${server.name} — ${server.memberCount} members`)
|
|
4032
|
+
*/
|
|
4033
|
+
fetchServer(serverId: string): Promise<NovaServerWrapper>;
|
|
4034
|
+
/**
|
|
4035
|
+
* Fetch all servers the bot is in and return them as `NovaServerWrapper` objects.
|
|
4036
|
+
*
|
|
4037
|
+
* @example
|
|
4038
|
+
* const servers = await client.fetchServers()
|
|
4039
|
+
* for (const s of servers) console.log(s.name)
|
|
4040
|
+
*/
|
|
4041
|
+
fetchServers(): Promise<NovaServerWrapper[]>;
|
|
4042
|
+
/**
|
|
4043
|
+
* Fetch all custom roles in a server and return them as `NovaRole` wrappers.
|
|
4044
|
+
*
|
|
4045
|
+
* @example
|
|
4046
|
+
* const roles = await client.fetchRoles('server-id')
|
|
4047
|
+
* const mod = roles.find(r => r.name === 'Moderator')
|
|
4048
|
+
*/
|
|
4049
|
+
fetchRoles(serverId: string): Promise<NovaRole[]>;
|
|
4050
|
+
/**
|
|
4051
|
+
* Fetch all active invites for a server and return them as `NovaInvite` wrappers.
|
|
4052
|
+
*
|
|
4053
|
+
* @example
|
|
4054
|
+
* const invites = await client.fetchInvites('server-id')
|
|
4055
|
+
* const active = invites.filter(i => i.isValid())
|
|
4056
|
+
*/
|
|
4057
|
+
fetchInvites(serverId: string): Promise<NovaInvite[]>;
|
|
4058
|
+
/**
|
|
4059
|
+
* Fetch a single invite by code and return it as a `NovaInvite` wrapper.
|
|
4060
|
+
*
|
|
4061
|
+
* @example
|
|
4062
|
+
* const invite = await client.fetchInvite('abc123')
|
|
4063
|
+
* if (invite.isExpired()) await invite.revoke()
|
|
4064
|
+
*/
|
|
4065
|
+
fetchInvite(code: string): Promise<NovaInvite>;
|
|
4066
|
+
/**
|
|
4067
|
+
* Fetch all webhooks in a channel and return them as `NovaWebhook` wrappers.
|
|
4068
|
+
*
|
|
4069
|
+
* @example
|
|
4070
|
+
* const webhooks = await client.fetchWebhooks('channel-id')
|
|
4071
|
+
*/
|
|
4072
|
+
fetchWebhooks(channelId: string): Promise<NovaWebhook[]>;
|
|
4073
|
+
/**
|
|
4074
|
+
* Fetch a single webhook by ID and return it as a `NovaWebhook` wrapper.
|
|
4075
|
+
*
|
|
4076
|
+
* @example
|
|
4077
|
+
* const webhook = await client.fetchWebhook('webhook-id')
|
|
4078
|
+
* await webhook.execute({ content: 'Build passed! ✅' })
|
|
4079
|
+
*/
|
|
4080
|
+
fetchWebhook(webhookId: string): Promise<NovaWebhook>;
|
|
4081
|
+
/**
|
|
4082
|
+
* Fetch forum posts from a FORUM channel and return them as `NovaForumPost` wrappers.
|
|
4083
|
+
*
|
|
4084
|
+
* @example
|
|
4085
|
+
* const posts = await client.fetchForumPosts('channel-id', { limit: 20 })
|
|
4086
|
+
* const open = posts.filter(p => !p.isClosed)
|
|
4087
|
+
*/
|
|
4088
|
+
fetchForumPosts(channelId: string, options?: FetchForumPostsOptions): Promise<NovaForumPost[]>;
|
|
4089
|
+
/**
|
|
4090
|
+
* Fetch server events and return them as `NovaServerEvent` wrappers.
|
|
4091
|
+
*
|
|
4092
|
+
* @example
|
|
4093
|
+
* const upcoming = await client.fetchEvents('server-id', { upcoming: true })
|
|
4094
|
+
* for (const event of upcoming) console.log(event.title)
|
|
4095
|
+
*/
|
|
4096
|
+
fetchEvents(serverId: string, options?: FetchEventsOptions): Promise<NovaServerEvent[]>;
|
|
4097
|
+
/**
|
|
4098
|
+
* Fetch a single server event by ID and return it as a `NovaServerEvent` wrapper.
|
|
4099
|
+
*
|
|
4100
|
+
* @example
|
|
4101
|
+
* const event = await client.fetchEvent('event-id')
|
|
4102
|
+
* if (event.isUpcoming) await event.edit({ title: 'Updated!' })
|
|
4103
|
+
*/
|
|
4104
|
+
fetchEvent(eventId: string): Promise<NovaServerEvent>;
|
|
4105
|
+
/**
|
|
4106
|
+
* Fetch a user's public profile.
|
|
4107
|
+
*
|
|
4108
|
+
* @example
|
|
4109
|
+
* const user = await client.fetchUserProfile('user-id')
|
|
4110
|
+
* console.log(user.bio)
|
|
4111
|
+
*/
|
|
4112
|
+
fetchUserProfile(userId: string): Promise<UserProfile>;
|
|
4113
|
+
/**
|
|
4114
|
+
* Fetch the XP leaderboard for a server.
|
|
4115
|
+
*
|
|
4116
|
+
* @example
|
|
4117
|
+
* const top = await client.fetchLeaderboard('server-id', 10)
|
|
4118
|
+
* top.forEach(entry => console.log(`#${entry.rank} ${entry.user.username} — ${entry.xp} XP`))
|
|
4119
|
+
*/
|
|
4120
|
+
fetchLeaderboard(serverId: string, limit?: number): Promise<LeaderboardEntry[]>;
|
|
4121
|
+
/**
|
|
4122
|
+
* Fetch warnings in a server, optionally filtered by user.
|
|
4123
|
+
*
|
|
4124
|
+
* @example
|
|
4125
|
+
* const warnings = await client.fetchWarnings('server-id', { userId: 'user-id' })
|
|
4126
|
+
*/
|
|
4127
|
+
fetchWarnings(serverId: string, options?: FetchWarningsOptions): Promise<Warning[]>;
|
|
4128
|
+
/**
|
|
4129
|
+
* Fetch all automod rules for a server.
|
|
4130
|
+
*
|
|
4131
|
+
* @example
|
|
4132
|
+
* const rules = await client.fetchAutoModRules('server-id')
|
|
4133
|
+
*/
|
|
4134
|
+
fetchAutoModRules(serverId: string): Promise<AutoModRule[]>;
|
|
4135
|
+
/**
|
|
4136
|
+
* Fetch all channel categories for a server.
|
|
4137
|
+
*
|
|
4138
|
+
* @example
|
|
4139
|
+
* const cats = await client.fetchCategories('server-id')
|
|
4140
|
+
*/
|
|
4141
|
+
fetchCategories(serverId: string): Promise<ChannelCategory[]>;
|
|
4142
|
+
/**
|
|
4143
|
+
* Fetch soundboard clips for a server.
|
|
4144
|
+
*
|
|
4145
|
+
* @example
|
|
4146
|
+
* const clips = await client.fetchSoundboard('server-id')
|
|
4147
|
+
*/
|
|
4148
|
+
fetchSoundboard(serverId: string): Promise<SoundboardClip[]>;
|
|
4149
|
+
/**
|
|
4150
|
+
* Fetch statistics for a server (member count, message count, etc.).
|
|
4151
|
+
*
|
|
4152
|
+
* @example
|
|
4153
|
+
* const stats = await client.fetchServerStats('server-id')
|
|
4154
|
+
* console.log(`${stats.onlineCount}/${stats.memberCount} online`)
|
|
4155
|
+
*/
|
|
4156
|
+
fetchServerStats(serverId: string): Promise<ServerStats>;
|
|
4157
|
+
/**
|
|
4158
|
+
* Bulk delete up to 100 messages in a channel.
|
|
4159
|
+
* Requires the `messages.manage` scope.
|
|
4160
|
+
*
|
|
4161
|
+
* @example
|
|
4162
|
+
* const result = await client.bulkDelete('channel-id', messageIds)
|
|
4163
|
+
* console.log(`Deleted ${result.deleted} messages`)
|
|
4164
|
+
*/
|
|
4165
|
+
bulkDelete(channelId: string, messageIds: string[]): Promise<BulkDeleteResult>;
|
|
4166
|
+
/**
|
|
4167
|
+
* Wait for a specific event to be emitted, optionally filtered.
|
|
4168
|
+
* Rejects after `timeoutMs` (default 30 s) if the condition never fires.
|
|
4169
|
+
*
|
|
4170
|
+
* @example
|
|
4171
|
+
* // Wait for any message in a specific channel
|
|
4172
|
+
* const msg = await client.waitFor('messageCreate', m => m.channelId === channelId)
|
|
4173
|
+
*
|
|
4174
|
+
* // Wait for a button click with a timeout
|
|
4175
|
+
* const i = await client.waitFor('interactionCreate', i => i.isButton(), 60_000)
|
|
4176
|
+
*/
|
|
4177
|
+
waitFor<K extends keyof NovaClientEvents>(event: K, filter?: (...args: Parameters<NovaClientEvents[K]>) => boolean, timeoutMs?: number): Promise<Parameters<NovaClientEvents[K]>[0]>;
|
|
4178
|
+
/**
|
|
4179
|
+
* Wait for the next message matching an optional filter.
|
|
4180
|
+
* Short for `waitFor('messageCreate', filter, timeoutMs)`.
|
|
4181
|
+
*
|
|
4182
|
+
* @example
|
|
4183
|
+
* // Wait for any message in a specific channel
|
|
4184
|
+
* const msg = await client.waitForMessage(
|
|
4185
|
+
* m => m.channelId === channelId && !m.isFromBot(),
|
|
4186
|
+
* 30_000,
|
|
4187
|
+
* )
|
|
4188
|
+
* console.log(msg.content)
|
|
4189
|
+
*/
|
|
4190
|
+
waitForMessage(filter?: (msg: NovaMessage) => boolean, timeoutMs?: number): Promise<NovaMessage>;
|
|
4191
|
+
/**
|
|
4192
|
+
* Wait for the next button-click interaction matching an optional filter.
|
|
4193
|
+
* Short for `waitFor('interactionCreate', i => i.isButton() && filter(i), timeoutMs)`.
|
|
4194
|
+
*
|
|
4195
|
+
* @example
|
|
4196
|
+
* // Wait for any button on a specific message
|
|
4197
|
+
* const click = await client.waitForButton(
|
|
4198
|
+
* i => i.triggerMsgId === message.id,
|
|
4199
|
+
* 60_000,
|
|
4200
|
+
* )
|
|
4201
|
+
* await click.reply('Button clicked!')
|
|
4202
|
+
*/
|
|
4203
|
+
waitForButton(filter?: (i: NovaInteraction) => boolean, timeoutMs?: number): Promise<NovaInteraction>;
|
|
4204
|
+
/**
|
|
4205
|
+
* Wait for the next select-menu interaction matching an optional filter.
|
|
4206
|
+
* Short for `waitFor('interactionCreate', i => i.isSelectMenu() && filter(i), timeoutMs)`.
|
|
4207
|
+
*
|
|
4208
|
+
* @example
|
|
4209
|
+
* const pick = await client.waitForSelectMenu(
|
|
4210
|
+
* i => i.customId === 'colour_pick',
|
|
4211
|
+
* 60_000,
|
|
4212
|
+
* )
|
|
4213
|
+
* await pick.reply(`You picked: ${pick.values.join(', ')}`)
|
|
4214
|
+
*/
|
|
4215
|
+
waitForSelectMenu(filter?: (i: NovaInteraction) => boolean, timeoutMs?: number): Promise<NovaInteraction>;
|
|
4216
|
+
/**
|
|
4217
|
+
* Disconnect from the gateway and clean up.
|
|
4218
|
+
*/
|
|
4219
|
+
disconnect(): void;
|
|
4220
|
+
/**
|
|
4221
|
+
* Send a message via the WebSocket gateway (lower latency than HTTP).
|
|
4222
|
+
* Requires the `messages.write` scope.
|
|
4223
|
+
*
|
|
4224
|
+
* @example
|
|
4225
|
+
* client.wsSend('channel-id', 'Hello from the gateway!')
|
|
4226
|
+
*/
|
|
4227
|
+
wsSend(channelId: string, content: string): void;
|
|
4228
|
+
/**
|
|
4229
|
+
* Start a typing indicator via WebSocket.
|
|
4230
|
+
*/
|
|
4231
|
+
wsTypingStart(channelId: string): void;
|
|
4232
|
+
/**
|
|
4233
|
+
* Stop a typing indicator via WebSocket.
|
|
4234
|
+
*/
|
|
4235
|
+
wsTypingStop(channelId: string): void;
|
|
4236
|
+
on<K extends keyof NovaClientEvents>(event: K, listener: NovaClientEvents[K]): this;
|
|
4237
|
+
on(event: string | symbol, listener: (...args: unknown[]) => void): this;
|
|
4238
|
+
once<K extends keyof NovaClientEvents>(event: K, listener: NovaClientEvents[K]): this;
|
|
4239
|
+
once(event: string | symbol, listener: (...args: unknown[]) => void): this;
|
|
4240
|
+
off<K extends keyof NovaClientEvents>(event: K, listener: NovaClientEvents[K]): this;
|
|
4241
|
+
off(event: string | symbol, listener: (...args: unknown[]) => void): this;
|
|
4242
|
+
}
|
|
4243
|
+
|
|
4244
|
+
export { type EventBufferOptions as $, type Attachment as A, type BanEntry as B, type ChannelCategory as C, type BotEventType as D, type EmbedField as E, type BotModalDefinition as F, type BotModalField as G, type BotPermissionRecord as H, type InviteCreateOptions as I, type BotStatus as J, type BotUser as K, type BulkDeleteResult as L, type MessageComponent as M, NovaMessage as N, type Channel as O, ChannelsAPI as P, CommandsAPI as Q, type RoleCreateOptions as R, type SlashCommandOption as S, type CreateCategoryOptions as T, type DirectMessage as U, type EditAutoModRuleOptions as V, type EditChannelOptions as W, type EditEventOptions as X, type EditForumPostOptions as Y, type EditMessageOptions as Z, EventBuffer as _, type Embed as a, type VoiceState as a$, EventsAPI as a0, type ExecuteWebhookOptions as a1, type FetchAuditLogsOptions as a2, type FetchChannelsOptions as a3, type FetchEventsOptions as a4, type FetchForumPostsOptions as a5, type FetchMembersOptions as a6, type FetchMessagesOptions as a7, type FetchWarningsOptions as a8, ForumAPI as a9, PermissionsAPI as aA, type PermissionsQueryOptions as aB, type PermissionsResult as aC, type PollInteractionsOptions as aD, type PrefixCommandDefinition as aE, type Reaction as aF, type ReactionDetail as aG, ReactionsAPI as aH, type RegisteredContextCommand as aI, type RegisteredPrefixCommand as aJ, type RegisteredSlashCommand as aK, type RespondInteractionOptions as aL, type Role as aM, type RoleEditOptions as aN, RolesAPI as aO, type ServerEvent as aP, type ServerEventAttendee as aQ, type ServerStats as aR, type ServerUpdateOptions as aS, ServersAPI as aT, type SingleMember as aU, type SoundboardClip as aV, Subscription as aW, TextInputBuilder as aX, type TextInputStyle as aY, type UserProfile as aZ, UsersAPI as a_, type ForumPost as aa, HttpClient as ab, type Interaction as ac, InteractionOptions as ad, type InteractionType as ae, type Invite as af, InvitesAPI as ag, type LeaderboardEntry as ah, type Member as ai, type MemberXPData as aj, MembersAPI as ak, type Message as al, NovaBan as am, NovaChannel as an, type NovaClientOptions as ao, NovaForumPost as ap, NovaInvite as aq, NovaMember as ar, NovaRole as as, type NovaServer as at, NovaServerEvent as au, NovaServerWrapper as av, NovaWarning as aw, NovaWebhook as ax, type Observer as ay, type OperatorFn as az, type SlashCommandDefinition as b, type Warning as b0, type Webhook as b1, type WebhookCreateOptions as b2, type WebhookEditOptions as b3, WebhooksAPI as b4, type SendMessageOptions as c, CategoriesAPI as d, type EditCategoryOptions as e, type CreateForumPostOptions as f, type CreateEventOptions as g, type ChannelType as h, type CreateChannelOptions as i, type CreateAutoModRuleOptions as j, type ContextCommandDefinition as k, NovaInteraction as l, MessagesAPI as m, InteractionsAPI as n, EventStream as o, NovaClient as p, ModalBuilder as q, type NovaClientEvents as r, AuditLogAPI as s, type AuditLogAction as t, type AuditLogEntry as u, AutoModAPI as v, type AutoModRule as w, type AutoModRuleType as x, type BotApplication as y, type BotEvent as z };
|