diff --git a/src/client/Client.js b/src/client/Client.js index 3b3ca32..7aad845 100644 --- a/src/client/Client.js +++ b/src/client/Client.js @@ -510,7 +510,7 @@ class Client extends BaseClient { /** * Join this Guild using this invite * @param {InviteResolvable} invite Invite code or URL - * @returns {Promise} + * @returns {Promise} * @example * await client.acceptInvite('https://discord.gg/genshinimpact') */ @@ -518,7 +518,8 @@ class Client extends BaseClient { const code = DataResolver.resolveInviteCode(invite); if (!code) throw new Error('INVITE_RESOLVE_CODE'); const i = await this.fetchInvite(code); - if (this.guilds.cache.has(i.guild?.id)) return; + if (i.guild?.id && this.guilds.cache.has(i.guild?.id)) return this.guilds.cache.get(i.guild?.id); + if (this.channels.cache.has(i.channelId)) return this.channels.cache.get(i.channelId); /* { location: 'Desktop Invite Modal', @@ -527,12 +528,62 @@ class Client extends BaseClient { location_channel_type: typeof i.channel.type == 'number' ? i.channel.type : ChannelTypes[i.channel.type], } */ - await this.api.invites(code).post({ + const data = await this.api.invites(code).post({ DiscordContext: { location: 'Markdown Link' }, data: { session_id: this.ws.shards.first()?.sessionId, }, }); + this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Joined`); + // Guild + if (i.guild?.id) { + // Onboarding + const onboardingData = await this.api.guilds[i.guild?.id].onboarding.get(); + if (onboardingData.enabled) { + // Bypass + this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Bypass onboarding`); + const prompts = onboardingData.prompts.filter(o => o.in_onboarding); + + const onboarding_prompts_seen = {}; + const onboarding_responses = []; + const onboarding_responses_seen = {}; + + const currentDate = Date.now(); + + prompts.forEach(prompt => { + onboarding_prompts_seen[prompt.id] = currentDate; + if (prompt.required) onboarding_responses.push(prompt.options[0].id); + prompt.options.forEach(option => { + onboarding_responses_seen[option.id] = currentDate; + }); + }); + + await this.api.guilds[i.guild?.id]['onboarding-responses'].post({ + data: { + onboarding_prompts_seen, + onboarding_responses, + onboarding_responses_seen, + }, + }); + } + // Read rule + if (data.show_verification_form) { + const getForm = await this.api + .guilds(i.guild?.id) + ['member-verification'].get({ query: { with_guild: false, invite_code: this.code } }) + .catch(() => {}); + if (getForm) { + this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Bypass rule verify`); + const form = Object.assign(getForm.form_fields[0], { response: true }); + await this.api + .guilds(i.guild?.id) + .requests['@me'].put({ data: { form_fields: [form], version: getForm.version } }); + } + } + return this.guilds.cache.get(i.guild?.id); + } else { + return this.channels.cache.has(i.channelId); + } } /** @@ -655,9 +706,6 @@ class Client extends BaseClient { if (typeof options.failIfNotExists !== 'boolean') { throw new TypeError('CLIENT_INVALID_OPTION', 'failIfNotExists', 'a boolean'); } - if (!Array.isArray(options.userAgentSuffix)) { - throw new TypeError('CLIENT_INVALID_OPTION', 'userAgentSuffix', 'an array of strings'); - } if ( typeof options.rejectOnRateLimit !== 'undefined' && !(typeof options.rejectOnRateLimit === 'function' || Array.isArray(options.rejectOnRateLimit)) diff --git a/typings/index.d.ts b/typings/index.d.ts index 56aa1a1..2ea0a4c 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -100,6 +100,7 @@ import { ApplicationRoleConnectionMetadataTypes, RelationshipTypes, SelectMenuComponentTypes, + InviteType, } from './enums'; import { APIApplicationRoleConnectionMetadata, @@ -806,7 +807,7 @@ export class Client extends BaseClient { /** @deprecated Use {@link Sweepers#sweepMessages} instead */ public sweepMessages(lifetime?: number): number; public toJSON(): unknown; - public acceptInvite(invite: InviteResolvable): Promise; + public acceptInvite(invite: InviteResolvable): Promise; public redeemNitro(nitro: string, channel?: TextChannelResolvable, paymentSourceId?: Snowflake): Promise; public authorizeURL(url: string, options?: OAuth2AuthorizeOptions): Promise; @@ -1727,6 +1728,7 @@ export class Invite extends Base { public maxUses: number | null; public memberCount: number; public presenceCount: number; + public type: InviteType | null; public targetApplication: IntegrationApplication | null; public targetUser: User | null; public targetType: InviteTargetType | null; @@ -5261,7 +5263,6 @@ export interface ClientOptions { restSweepInterval?: number; retryLimit?: number; failIfNotExists?: boolean; - userAgentSuffix?: string[]; presence?: PresenceData; waitGuildTimeout?: number; sweepers?: SweeperOptions;