djs-selfbot-v13 3.7.29 → 3.7.32

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.
@@ -0,0 +1,400 @@
1
+ 'use strict';
2
+
3
+ const { fetch } = require('undici');
4
+
5
+ const MaxBitratePerTier = {
6
+ NONE: 64_000,
7
+ TIER_1: 128_000,
8
+ TIER_2: 256_000,
9
+ TIER_3: 384_000,
10
+ };
11
+
12
+ /**
13
+ * @param {string} url
14
+ * @returns {Promise<Buffer>}
15
+ */
16
+ async function fetchBuffer(url) {
17
+ const response = await fetch(url);
18
+ return Buffer.from(await response.arrayBuffer());
19
+ }
20
+
21
+ /**
22
+ * Gets the permissions for a channel
23
+ * @param {import('../../structures/GuildChannel')} channel
24
+ * @returns {Object[]}
25
+ */
26
+ function fetchChannelPermissions(channel) {
27
+ const permissions = [];
28
+
29
+ channel.permissionOverwrites?.cache
30
+ .filter(p => p.type === 'role')
31
+ .forEach(perm => {
32
+ const role = channel.guild.roles.cache.get(perm.id);
33
+ if (role) {
34
+ permissions.push({
35
+ roleName: role.name,
36
+ allow: perm.allow.bitfield.toString(),
37
+ deny: perm.deny.bitfield.toString(),
38
+ });
39
+ }
40
+ });
41
+
42
+ return permissions;
43
+ }
44
+
45
+ /**
46
+ * Fetches voice channel data for backup
47
+ * @param {import('../../structures/GuildChannel')} channel
48
+ * @returns {Promise<Object>}
49
+ */
50
+ async function fetchVoiceChannelData(channel) {
51
+ return {
52
+ type: 'GUILD_VOICE',
53
+ name: channel.name,
54
+ bitrate: channel.bitrate,
55
+ userLimit: channel.userLimit,
56
+ parent: channel.parent ? channel.parent.name : null,
57
+ permissions: fetchChannelPermissions(channel),
58
+ };
59
+ }
60
+
61
+ /**
62
+ * Fetches messages from a channel
63
+ * @param {import('../../structures/interfaces/TextBasedChannel')} channel
64
+ * @param {Object} options
65
+ * @returns {Promise<Object[]>}
66
+ */
67
+ async function fetchChannelMessages(channel, options) {
68
+ const messages = [];
69
+ const maxMessages = Number.isNaN(options.maxMessagesPerChannel) ? 10 : options.maxMessagesPerChannel;
70
+ const fetchOptions = { limit: 100 };
71
+ let lastMessageId;
72
+ const imageRegex = /\.(png|jpg|jpeg|jpe|jif|jfif|jfi)$/i;
73
+
74
+ while (messages.length < maxMessages) {
75
+ if (lastMessageId) fetchOptions.before = lastMessageId;
76
+
77
+ const fetched = await channel.messages.fetch(fetchOptions);
78
+ if (fetched.size === 0) break;
79
+
80
+ lastMessageId = fetched.last().id;
81
+
82
+ for (const msg of fetched.values()) {
83
+ if (messages.length >= maxMessages) break;
84
+ if (!msg.author) continue;
85
+
86
+ const files = await Promise.all(
87
+ msg.attachments.map(async attachment => {
88
+ let attach = attachment.url;
89
+
90
+ if (options.saveImages === 'base64' && imageRegex.test(attachment.url)) {
91
+ try {
92
+ attach = (await fetchBuffer(attachment.url)).toString('base64');
93
+ } catch (error) {
94
+ console.error(`Failed to fetch attachment ${attachment.url}:`, error);
95
+ }
96
+ }
97
+
98
+ return { name: attachment.name, attachment: attach };
99
+ }),
100
+ );
101
+
102
+ messages.push({
103
+ username: msg.author.username,
104
+ avatar: msg.author.displayAvatarURL(),
105
+ content: msg.cleanContent,
106
+ embeds: msg.embeds,
107
+ files,
108
+ pinned: msg.pinned,
109
+ sentAt: msg.createdAt.toISOString(),
110
+ });
111
+ }
112
+
113
+ if (fetched.size < 100) break;
114
+ }
115
+
116
+ return messages;
117
+ }
118
+
119
+ /**
120
+ * Fetches text channel data for backup
121
+ * @param {import('../../structures/GuildChannel')} channel
122
+ * @param {Object} options
123
+ * @returns {Promise<Object>}
124
+ */
125
+ async function fetchTextChannelData(channel, options) {
126
+ const channelData = {
127
+ type: channel.type,
128
+ name: channel.name,
129
+ nsfw: channel.nsfw,
130
+ rateLimitPerUser: channel.type === 'GUILD_TEXT' ? channel.rateLimitPerUser : undefined,
131
+ parent: channel.parent ? channel.parent.name : null,
132
+ topic: channel.topic,
133
+ permissions: fetchChannelPermissions(channel),
134
+ messages: [],
135
+ isNews: channel.type === 'GUILD_NEWS',
136
+ rulesChannel: channel.guild.rulesChannelId === channel.id,
137
+ publicUpdatesChannel: channel.guild.publicUpdatesChannelId === channel.id,
138
+ threads: [],
139
+ };
140
+
141
+ if (channel.threads.cache.size > 0) {
142
+ await Promise.all(
143
+ channel.threads.cache.map(async thread => {
144
+ const threadData = {
145
+ type: thread.type,
146
+ name: thread.name,
147
+ archived: thread.archived,
148
+ autoArchiveDuration: thread.autoArchiveDuration,
149
+ locked: thread.locked,
150
+ rateLimitPerUser: thread.rateLimitPerUser,
151
+ messages: [],
152
+ };
153
+
154
+ try {
155
+ threadData.messages = await fetchChannelMessages(thread, options);
156
+ } catch {
157
+ // Keep empty messages on failure
158
+ }
159
+
160
+ channelData.threads.push(threadData);
161
+ }),
162
+ );
163
+ }
164
+
165
+ try {
166
+ channelData.messages = await fetchChannelMessages(channel, options);
167
+ } catch {
168
+ // Keep empty messages on failure
169
+ }
170
+
171
+ return channelData;
172
+ }
173
+
174
+ /**
175
+ * Creates a category for the guild
176
+ * @param {Object} categoryData
177
+ * @param {import('../../structures/Guild').Guild} guild
178
+ * @returns {Promise<import('../../structures/GuildChannel')>}
179
+ */
180
+ async function loadCategory(categoryData, guild) {
181
+ const category = await guild.channels.create(categoryData.name, { type: 'GUILD_CATEGORY' });
182
+ const finalPermissions = [];
183
+
184
+ categoryData.permissions.forEach(perm => {
185
+ const role = guild.roles.cache.find(r => r.name === perm.roleName);
186
+ if (role) {
187
+ finalPermissions.push({
188
+ id: role.id,
189
+ allow: BigInt(perm.allow),
190
+ deny: BigInt(perm.deny),
191
+ });
192
+ }
193
+ });
194
+
195
+ await category.permissionOverwrites.set(finalPermissions);
196
+ return category;
197
+ }
198
+
199
+ /**
200
+ * Create a channel and returns it
201
+ * @param {Object} channelData
202
+ * @param {import('../../structures/Guild').Guild} guild
203
+ * @param {import('../../structures/GuildChannel')|null} category
204
+ * @param {Object} options
205
+ * @returns {Promise<import('../../structures/GuildChannel')|undefined>}
206
+ */
207
+ async function loadChannel(channelData, guild, category, options) {
208
+ const loadMessages = async (channel, messages, previousWebhook) => {
209
+ const webhook =
210
+ previousWebhook ||
211
+ (await channel.createWebhook('MessagesBackup', {
212
+ avatar: channel.client.user.displayAvatarURL(),
213
+ }).catch(() => null));
214
+
215
+ if (!webhook) return;
216
+
217
+ messages = messages
218
+ .filter(m => m.content.length > 0 || m.embeds.length > 0 || m.files.length > 0)
219
+ .reverse();
220
+ messages = messages.slice(messages.length - options.maxMessagesPerChannel);
221
+
222
+ for (const msg of messages) {
223
+ const sentMsg = await webhook
224
+ .send({
225
+ content: msg.content.length ? msg.content : undefined,
226
+ username: msg.username,
227
+ avatarURL: msg.avatar,
228
+ embeds: msg.embeds,
229
+ files: msg.files,
230
+ allowedMentions: options.allowedMentions,
231
+ threadId: channel.isThread() ? channel.id : undefined,
232
+ })
233
+ .catch(err => {
234
+ console.log(err.message);
235
+ });
236
+
237
+ if (msg.pinned && sentMsg) await sentMsg.pin();
238
+ }
239
+
240
+ return webhook;
241
+ };
242
+
243
+ const createOptions = {
244
+ type: null,
245
+ parent: category,
246
+ };
247
+
248
+ if (channelData.type === 'GUILD_TEXT' || channelData.type === 'GUILD_NEWS') {
249
+ createOptions.topic = channelData.topic;
250
+ createOptions.nsfw = channelData.nsfw;
251
+ createOptions.rateLimitPerUser = channelData.rateLimitPerUser;
252
+ createOptions.type =
253
+ channelData.isNews && guild.features.includes('NEWS') ? 'GUILD_NEWS' : 'GUILD_TEXT';
254
+ } else if (channelData.type === 'GUILD_VOICE') {
255
+ let bitrate = channelData.bitrate;
256
+ const bitrates = Object.values(MaxBitratePerTier);
257
+
258
+ while (bitrate > MaxBitratePerTier[guild.premiumTier]) {
259
+ bitrate = bitrates[Object.keys(MaxBitratePerTier).indexOf(guild.premiumTier) - 1];
260
+ }
261
+
262
+ createOptions.bitrate = bitrate;
263
+ createOptions.userLimit = channelData.userLimit;
264
+ createOptions.type = 'GUILD_VOICE';
265
+ }
266
+
267
+ const channel = await guild.channels.create(channelData.name, createOptions);
268
+
269
+ if (channelData.rulesChannel) {
270
+ try {
271
+ const oldRules = guild.rulesChannel;
272
+ await guild.setRulesChannel(channel.id);
273
+ if (oldRules) await guild.client.api.channels(oldRules.id).delete();
274
+ } catch {
275
+ // Ignore community channel errors
276
+ }
277
+ }
278
+
279
+ if (channelData.publicUpdatesChannel) {
280
+ try {
281
+ const oldPublic = guild.publicUpdatesChannel;
282
+ await guild.setPublicUpdatesChannel(channel.id);
283
+ if (oldPublic) await guild.client.api.channels(oldPublic.id).delete();
284
+ } catch {
285
+ // Ignore community channel errors
286
+ }
287
+ }
288
+
289
+ const finalPermissions = [];
290
+
291
+ channelData.permissions.forEach(perm => {
292
+ const role = guild.roles.cache.find(r => r.name === perm.roleName);
293
+ if (role) {
294
+ finalPermissions.push({
295
+ id: role.id,
296
+ allow: BigInt(perm.allow),
297
+ deny: BigInt(perm.deny),
298
+ });
299
+ }
300
+ });
301
+
302
+ await channel.permissionOverwrites.set(finalPermissions);
303
+
304
+ if (channelData.type === 'GUILD_TEXT') {
305
+ let webhook;
306
+ if (channelData.messages.length > 0) {
307
+ webhook = await loadMessages(channel, channelData.messages).catch(() => null);
308
+ }
309
+
310
+ if (channelData.threads.length > 0) {
311
+ await Promise.all(
312
+ channelData.threads.map(async threadData => {
313
+ let autoArchiveDuration = threadData.autoArchiveDuration;
314
+ if (!guild.features.includes('SEVEN_DAY_THREAD_ARCHIVE') && autoArchiveDuration === 10_080) {
315
+ autoArchiveDuration = 4320;
316
+ }
317
+ if (!guild.features.includes('THREE_DAY_THREAD_ARCHIVE') && autoArchiveDuration === 4320) {
318
+ autoArchiveDuration = 1440;
319
+ }
320
+
321
+ const thread = await channel.threads.create({
322
+ name: threadData.name,
323
+ autoArchiveDuration,
324
+ });
325
+
326
+ if (webhook) await loadMessages(thread, threadData.messages, webhook);
327
+ }),
328
+ );
329
+ }
330
+ }
331
+
332
+ return channel;
333
+ }
334
+
335
+ /**
336
+ * Delete all roles, channels, emojis, etc. of a guild
337
+ * @param {import('../../structures/Guild').Guild} guild
338
+ * @returns {Promise<void>}
339
+ */
340
+ async function clearGuild(guild) {
341
+ guild.roles.cache
342
+ .filter(role => !role.managed && role.editable && role.id !== guild.id)
343
+ .forEach(role => {
344
+ role.delete().catch(() => {});
345
+ });
346
+
347
+ guild.channels.cache.forEach(channel => {
348
+ channel.delete().catch(() => {});
349
+ });
350
+
351
+ guild.emojis.cache.forEach(emoji => {
352
+ emoji.delete().catch(() => {});
353
+ });
354
+
355
+ const webhooks = await guild.fetchWebhooks().catch(() => null);
356
+ if (webhooks) {
357
+ webhooks.forEach(webhook => {
358
+ webhook.delete().catch(() => {});
359
+ });
360
+ }
361
+
362
+ const bans = await guild.bans.fetch({ limit: 99 });
363
+ bans.forEach(ban => {
364
+ guild.members.unban(ban.user).catch(() => {});
365
+ });
366
+
367
+ guild.setAFKChannel(null);
368
+ guild.setAFKTimeout(60 * 5);
369
+ guild.setIcon(null);
370
+ guild.setBanner(null).catch(() => {});
371
+ guild.setSplash(null).catch(() => {});
372
+ guild.setDefaultMessageNotifications('ONLY_MENTIONS');
373
+ guild.setWidgetSettings({
374
+ enabled: false,
375
+ channel: null,
376
+ });
377
+
378
+ if (!guild.features.includes('COMMUNITY')) {
379
+ guild.setExplicitContentFilter('DISABLED');
380
+ guild.setVerificationLevel('NONE');
381
+ }
382
+
383
+ guild.setSystemChannel(null);
384
+ guild.setSystemChannelFlags([
385
+ 'SUPPRESS_GUILD_REMINDER_NOTIFICATIONS',
386
+ 'SUPPRESS_JOIN_NOTIFICATIONS',
387
+ 'SUPPRESS_PREMIUM_SUBSCRIPTIONS',
388
+ ]);
389
+ }
390
+
391
+ module.exports = {
392
+ fetchBuffer,
393
+ fetchChannelPermissions,
394
+ fetchVoiceChannelData,
395
+ fetchChannelMessages,
396
+ fetchTextChannelData,
397
+ loadCategory,
398
+ loadChannel,
399
+ clearGuild,
400
+ };
@@ -875,6 +875,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
875
875
  public billing: BillingManager;
876
876
  public developers: DeveloperManager;
877
877
  public quests: QuestManager;
878
+ public backups: BackupManager;
878
879
  public settings: ClientUserSettingManager;
879
880
  public readonly sessionId: If<Ready, string, undefined>;
880
881
  public destroy(): void;
@@ -2796,6 +2797,20 @@ export class DeveloperManager extends BaseManager {
2796
2797
  public disableIntents(applicationId: Snowflake): Promise<Application>;
2797
2798
  }
2798
2799
 
2800
+ export interface QuestHeartbeatOptions {
2801
+ applicationId?: string;
2802
+ streamKey?: string;
2803
+ terminal?: boolean;
2804
+ }
2805
+
2806
+ export interface QuestVideoProgressOptions {
2807
+ isAndroid?: boolean;
2808
+ }
2809
+
2810
+ export interface QuestAutoCompleteOptions {
2811
+ redeem?: boolean;
2812
+ }
2813
+
2799
2814
  export class QuestManager extends BaseManager {
2800
2815
  constructor(client: Client);
2801
2816
  public cache: Collection<string, Quest>;
@@ -2807,13 +2822,15 @@ export class QuestManager extends BaseManager {
2807
2822
  public getCompleted(): Quest[];
2808
2823
  public getClaimable(): Quest[];
2809
2824
  public filterQuestsValid(): Quest[];
2825
+ public filterQuestsValidToRedeem(): Quest[];
2810
2826
  public hasQuest(id: string): boolean;
2811
2827
  public getApplicationData(ids: string[]): Promise<ApplicationData[]>;
2812
2828
  public acceptQuest(questId: string, options?: QuestEnrollOptions): Promise<Quest | undefined>;
2813
- public videoProgress(questId: string, timestamp: number): Promise<any>;
2814
- public heartbeat(questId: string, applicationId: string, terminal?: boolean): Promise<any>;
2829
+ public videoProgress(questId: string, timestamp: number, options?: QuestVideoProgressOptions): Promise<any>;
2830
+ public heartbeat(questId: string, applicationIdOrOptions: string | QuestHeartbeatOptions, terminal?: boolean): Promise<any>;
2831
+ public redeemQuest(quest: Quest | string): Promise<Quest | undefined>;
2815
2832
  public doingQuest(quest: Quest): Promise<void>;
2816
- public autoCompleteAll(): Promise<void>;
2833
+ public autoCompleteAll(options?: QuestAutoCompleteOptions): Promise<void>;
2817
2834
  public readonly size: number;
2818
2835
  public clear(): void;
2819
2836
  public [Symbol.iterator](): IterableIterator<Quest>;
@@ -4002,30 +4019,28 @@ export interface WidgetsResponse {
4002
4019
  export interface QuestEnrollOptions {
4003
4020
  location?: number;
4004
4021
  isTargeted?: boolean;
4005
- metadataRaw?: any;
4022
+ isAndroid?: boolean;
4006
4023
  }
4007
4024
 
4025
+ export type QuestTaskType =
4026
+ | 'WATCH_VIDEO'
4027
+ | 'WATCH_VIDEO_ON_MOBILE'
4028
+ | 'PLAY_ON_DESKTOP'
4029
+ | 'PLAY_ON_XBOX'
4030
+ | 'PLAY_ON_PLAYSTATION'
4031
+ | 'STREAM_ON_DESKTOP'
4032
+ | 'PLAY_ACTIVITY'
4033
+ | 'ACHIEVEMENT_IN_ACTIVITY';
4034
+
4008
4035
  export interface QuestTaskConfig {
4009
- tasks?: {
4010
- WATCH_VIDEO?: { target: number };
4011
- WATCH_VIDEO_ON_MOBILE?: { target: number };
4012
- PLAY_ON_DESKTOP?: { target: number };
4013
- STREAM_ON_DESKTOP?: { target: number };
4014
- PLAY_ACTIVITY?: { target: number };
4015
- };
4036
+ tasks?: Partial<Record<QuestTaskType, { target: number; type?: QuestTaskType; event_name?: string }>>;
4016
4037
  }
4017
4038
 
4018
4039
  export interface QuestUserStatus {
4019
4040
  enrolled_at?: string;
4020
4041
  completed_at?: string;
4021
4042
  claimed_at?: string;
4022
- progress?: {
4023
- WATCH_VIDEO?: { value: number };
4024
- WATCH_VIDEO_ON_MOBILE?: { value: number };
4025
- PLAY_ON_DESKTOP?: { value: number };
4026
- STREAM_ON_DESKTOP?: { value: number };
4027
- PLAY_ACTIVITY?: { value: number };
4028
- };
4043
+ progress?: Partial<Record<QuestTaskType, { value: number; event_name?: string; updated_at?: string; completed_at?: string | null }>>;
4029
4044
  }
4030
4045
 
4031
4046
  export interface QuestConfig {
@@ -4037,14 +4052,19 @@ export interface QuestConfig {
4037
4052
  id: string;
4038
4053
  name: string;
4039
4054
  };
4040
- task_config: QuestTaskConfig;
4055
+ task_config?: QuestTaskConfig;
4041
4056
  task_config_v2?: QuestTaskConfig;
4057
+ rewards_config?: {
4058
+ platforms?: string[];
4059
+ };
4042
4060
  }
4043
4061
 
4044
4062
  export interface QuestRawData {
4045
4063
  id: string;
4046
4064
  config: QuestConfig;
4047
4065
  user_status?: QuestUserStatus;
4066
+ traffic_metadata_raw?: string;
4067
+ traffic_metadata_sealed?: string;
4048
4068
  }
4049
4069
 
4050
4070
  export class Quest {
@@ -4052,11 +4072,12 @@ export class Quest {
4052
4072
  public id: string;
4053
4073
  public config: QuestConfig;
4054
4074
  public userStatus?: QuestUserStatus;
4075
+ public readonly raw: QuestRawData;
4055
4076
  public isExpired(date?: Date): boolean;
4056
4077
  public isCompleted(): boolean;
4057
4078
  public hasClaimedRewards(): boolean;
4058
4079
  public isEnrolledQuest(): boolean;
4059
- public updateUserStatus(status: Partial<QuestUserStatus>): void;
4080
+ public updateUserStatus(status: QuestUserStatus): void;
4060
4081
  }
4061
4082
 
4062
4083
  export interface QuestData {
@@ -4079,6 +4100,184 @@ export interface ApplicationData {
4079
4100
  }[];
4080
4101
  }
4081
4102
 
4103
+ export interface BackupAfkData {
4104
+ name: string;
4105
+ timeout: number;
4106
+ }
4107
+
4108
+ export interface BackupWidgetData {
4109
+ enabled: boolean;
4110
+ channel?: string | null;
4111
+ }
4112
+
4113
+ export interface BackupCommunityData {
4114
+ enabled: boolean;
4115
+ systemChannelFlags: number | null;
4116
+ systemChannelId: Snowflake | null;
4117
+ rulesChannelId: Snowflake | null;
4118
+ publicUpdatesChannelId: Snowflake | null;
4119
+ safetyAlertsChannelId: Snowflake | null;
4120
+ }
4121
+
4122
+ export interface BackupChannelPermissionData {
4123
+ roleName: string;
4124
+ allow: string;
4125
+ deny: string;
4126
+ }
4127
+
4128
+ export interface BackupBaseChannelData {
4129
+ oldId?: string;
4130
+ type: keyof typeof ChannelTypes;
4131
+ name: string;
4132
+ parent?: string | null;
4133
+ permissions: BackupChannelPermissionData[];
4134
+ }
4135
+
4136
+ export interface BackupMessageData {
4137
+ oldId?: string;
4138
+ userId?: string;
4139
+ username: string;
4140
+ avatar?: string;
4141
+ content?: string;
4142
+ embeds?: MessageEmbed[];
4143
+ components?: MessageActionRow[];
4144
+ files?: Record<string, unknown>;
4145
+ pinned?: boolean;
4146
+ sentAt: string;
4147
+ }
4148
+
4149
+ export interface BackupThreadChannelData {
4150
+ id?: string;
4151
+ type: keyof typeof ChannelTypes;
4152
+ name: string;
4153
+ archived: boolean;
4154
+ autoArchiveDuration: ThreadAutoArchiveDuration;
4155
+ locked: boolean;
4156
+ rateLimitPerUser: number;
4157
+ messages: BackupMessageData[];
4158
+ }
4159
+
4160
+ export interface BackupTextChannelData extends BackupBaseChannelData {
4161
+ nsfw: boolean;
4162
+ topic?: string;
4163
+ rateLimitPerUser?: number;
4164
+ isNews: boolean;
4165
+ messages: BackupMessageData[];
4166
+ threads: BackupThreadChannelData[];
4167
+ }
4168
+
4169
+ export interface BackupVoiceChannelData extends BackupBaseChannelData {
4170
+ bitrate: number;
4171
+ userLimit: number;
4172
+ }
4173
+
4174
+ export interface BackupCategoryData {
4175
+ name: string;
4176
+ permissions: BackupChannelPermissionData[];
4177
+ children: Array<BackupTextChannelData | BackupVoiceChannelData>;
4178
+ }
4179
+
4180
+ export interface BackupChannelsData {
4181
+ categories: BackupCategoryData[];
4182
+ others: Array<BackupTextChannelData | BackupVoiceChannelData>;
4183
+ }
4184
+
4185
+ export interface BackupRoleData {
4186
+ oldId: string;
4187
+ name: string;
4188
+ color: string;
4189
+ icon?: string | null;
4190
+ hoist: boolean;
4191
+ permissions: string;
4192
+ mentionable: boolean;
4193
+ position: number;
4194
+ isEveryone: boolean;
4195
+ }
4196
+
4197
+ export interface BackupBanData {
4198
+ id: Snowflake;
4199
+ reason: string;
4200
+ }
4201
+
4202
+ export interface BackupEmojiData {
4203
+ name: string;
4204
+ url?: string;
4205
+ base64?: string;
4206
+ }
4207
+
4208
+ export interface BackupMemberData {
4209
+ userId: string;
4210
+ username: string;
4211
+ discriminator: string;
4212
+ avatarUrl: string | null;
4213
+ joinedTimestamp: number | null;
4214
+ roles: string[];
4215
+ bot: boolean;
4216
+ }
4217
+
4218
+ export interface BackupData {
4219
+ name: string;
4220
+ iconURL?: string;
4221
+ iconBase64?: string;
4222
+ verificationLevel: VerificationLevel;
4223
+ explicitContentFilter: ExplicitContentFilterLevel;
4224
+ defaultMessageNotifications: DefaultMessageNotificationLevel | number;
4225
+ afk?: BackupAfkData | null;
4226
+ widget: BackupWidgetData;
4227
+ community?: BackupCommunityData;
4228
+ splashURL?: string;
4229
+ splashBase64?: string;
4230
+ bannerURL?: string;
4231
+ bannerBase64?: string;
4232
+ channels: BackupChannelsData;
4233
+ roles: BackupRoleData[];
4234
+ bans: BackupBanData[];
4235
+ emojis: BackupEmojiData[];
4236
+ members: BackupMemberData[];
4237
+ createdTimestamp: number;
4238
+ guildID: string;
4239
+ id: Snowflake;
4240
+ }
4241
+
4242
+ export interface BackupInfo {
4243
+ id: string;
4244
+ size: number;
4245
+ data: BackupData;
4246
+ }
4247
+
4248
+ export interface BackupCreateOptions {
4249
+ backupId?: string;
4250
+ backupID?: string;
4251
+ maxMessagesPerChannel?: number;
4252
+ jsonSave?: boolean;
4253
+ jsonBeautify?: boolean;
4254
+ doNotBackup?: string[];
4255
+ backupMembers?: boolean;
4256
+ saveImages?: string;
4257
+ }
4258
+
4259
+ export interface BackupLoadOptions {
4260
+ clearGuildBeforeRestore?: boolean;
4261
+ maxMessagesPerChannel?: number;
4262
+ allowedMentions?: MessageMentionOptions;
4263
+ doNotBackup?: string[];
4264
+ }
4265
+
4266
+ export class BackupCacheManager {
4267
+ public constructor(manager: BackupManager);
4268
+ public create(guildId: Snowflake, options?: BackupCreateOptions): Promise<BackupData>;
4269
+ public delete(backupId: string): boolean;
4270
+ public clearAll(): void;
4271
+ public load(guildId: Snowflake, backupId: string, options?: BackupLoadOptions): Promise<BackupData>;
4272
+ public get(backupId: string): BackupInfo | undefined;
4273
+ public list(): string[];
4274
+ }
4275
+
4276
+ export class BackupManager extends BaseManager {
4277
+ public constructor(client: Client);
4278
+ public cache: BackupCacheManager;
4279
+ }
4280
+
4082
4281
  export type FontName = 'Sans' | 'Tempo' | 'Sakura' | 'JellyBean' | 'Modern' | 'Medieval' | '8Bit' | 'Vampire';
4083
4282
 
4084
4283
  export type EffectName = 'Solid' | 'Gradient' | 'Neon' | 'Toon' | 'Pop';