feat: acceptInvite bypass onboarding

#837
This commit is contained in:
Elysia 2024-01-24 19:54:38 +07:00
parent 3910ca2257
commit f83dcf1eba
2 changed files with 57 additions and 8 deletions

View File

@ -510,7 +510,7 @@ class Client extends BaseClient {
/** /**
* Join this Guild using this invite * Join this Guild using this invite
* @param {InviteResolvable} invite Invite code or URL * @param {InviteResolvable} invite Invite code or URL
* @returns {Promise<void>} * @returns {Promise<Guild|DMChannel|GroupDMChannel>}
* @example * @example
* await client.acceptInvite('https://discord.gg/genshinimpact') * await client.acceptInvite('https://discord.gg/genshinimpact')
*/ */
@ -518,7 +518,8 @@ class Client extends BaseClient {
const code = DataResolver.resolveInviteCode(invite); const code = DataResolver.resolveInviteCode(invite);
if (!code) throw new Error('INVITE_RESOLVE_CODE'); if (!code) throw new Error('INVITE_RESOLVE_CODE');
const i = await this.fetchInvite(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', 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], 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' }, DiscordContext: { location: 'Markdown Link' },
data: { data: {
session_id: this.ws.shards.first()?.sessionId, 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') { if (typeof options.failIfNotExists !== 'boolean') {
throw new TypeError('CLIENT_INVALID_OPTION', 'failIfNotExists', 'a 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 ( if (
typeof options.rejectOnRateLimit !== 'undefined' && typeof options.rejectOnRateLimit !== 'undefined' &&
!(typeof options.rejectOnRateLimit === 'function' || Array.isArray(options.rejectOnRateLimit)) !(typeof options.rejectOnRateLimit === 'function' || Array.isArray(options.rejectOnRateLimit))

5
typings/index.d.ts vendored
View File

@ -100,6 +100,7 @@ import {
ApplicationRoleConnectionMetadataTypes, ApplicationRoleConnectionMetadataTypes,
RelationshipTypes, RelationshipTypes,
SelectMenuComponentTypes, SelectMenuComponentTypes,
InviteType,
} from './enums'; } from './enums';
import { import {
APIApplicationRoleConnectionMetadata, APIApplicationRoleConnectionMetadata,
@ -806,7 +807,7 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
/** @deprecated Use {@link Sweepers#sweepMessages} instead */ /** @deprecated Use {@link Sweepers#sweepMessages} instead */
public sweepMessages(lifetime?: number): number; public sweepMessages(lifetime?: number): number;
public toJSON(): unknown; public toJSON(): unknown;
public acceptInvite(invite: InviteResolvable): Promise<void>; public acceptInvite(invite: InviteResolvable): Promise<Guild | DMChannel | GroupDMChannel>;
public redeemNitro(nitro: string, channel?: TextChannelResolvable, paymentSourceId?: Snowflake): Promise<any>; public redeemNitro(nitro: string, channel?: TextChannelResolvable, paymentSourceId?: Snowflake): Promise<any>;
public authorizeURL(url: string, options?: OAuth2AuthorizeOptions): Promise<any>; public authorizeURL(url: string, options?: OAuth2AuthorizeOptions): Promise<any>;
@ -1727,6 +1728,7 @@ export class Invite extends Base {
public maxUses: number | null; public maxUses: number | null;
public memberCount: number; public memberCount: number;
public presenceCount: number; public presenceCount: number;
public type: InviteType | null;
public targetApplication: IntegrationApplication | null; public targetApplication: IntegrationApplication | null;
public targetUser: User | null; public targetUser: User | null;
public targetType: InviteTargetType | null; public targetType: InviteTargetType | null;
@ -5261,7 +5263,6 @@ export interface ClientOptions {
restSweepInterval?: number; restSweepInterval?: number;
retryLimit?: number; retryLimit?: number;
failIfNotExists?: boolean; failIfNotExists?: boolean;
userAgentSuffix?: string[];
presence?: PresenceData; presence?: PresenceData;
waitGuildTimeout?: number; waitGuildTimeout?: number;
sweepers?: SweeperOptions; sweepers?: SweeperOptions;