mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-18 04:23:31 +01:00
feat: guild onboarding (#9120)
* feat: guild onboarding * feat: types and /core method * fix: route * fix: make emoji name non-nullable --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
@@ -127,6 +127,9 @@ exports.GuildBan = require('./structures/GuildBan');
|
||||
exports.GuildChannel = require('./structures/GuildChannel');
|
||||
exports.GuildEmoji = require('./structures/GuildEmoji');
|
||||
exports.GuildMember = require('./structures/GuildMember').GuildMember;
|
||||
exports.GuildOnboarding = require('./structures/GuildOnboarding').GuildOnboarding;
|
||||
exports.GuildOnboardingPrompt = require('./structures/GuildOnboardingPrompt').GuildOnboardingPrompt;
|
||||
exports.GuildOnboardingPromptOption = require('./structures/GuildOnboardingPromptOption').GuildOnboardingPromptOption;
|
||||
exports.GuildPreview = require('./structures/GuildPreview');
|
||||
exports.GuildPreviewEmoji = require('./structures/GuildPreviewEmoji');
|
||||
exports.GuildScheduledEvent = require('./structures/GuildScheduledEvent').GuildScheduledEvent;
|
||||
|
||||
@@ -5,6 +5,7 @@ const { makeURLSearchParams } = require('@discordjs/rest');
|
||||
const { ChannelType, GuildPremiumTier, Routes, GuildFeature } = require('discord-api-types/v10');
|
||||
const AnonymousGuild = require('./AnonymousGuild');
|
||||
const GuildAuditLogs = require('./GuildAuditLogs');
|
||||
const { GuildOnboarding } = require('./GuildOnboarding');
|
||||
const GuildPreview = require('./GuildPreview');
|
||||
const GuildTemplate = require('./GuildTemplate');
|
||||
const Integration = require('./Integration');
|
||||
@@ -760,6 +761,15 @@ class Guild extends AnonymousGuild {
|
||||
return new GuildAuditLogs(this, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the guild onboarding data for this guild.
|
||||
* @returns {Promise<GuildOnboarding>}
|
||||
*/
|
||||
async fetchOnboarding() {
|
||||
const data = await this.client.rest.get(Routes.guildOnboarding(this.id));
|
||||
return new GuildOnboarding(this.client, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* The data for editing a guild.
|
||||
* @typedef {Object} GuildEditOptions
|
||||
|
||||
58
packages/discord.js/src/structures/GuildOnboarding.js
Normal file
58
packages/discord.js/src/structures/GuildOnboarding.js
Normal file
@@ -0,0 +1,58 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const Base = require('./Base');
|
||||
const { GuildOnboardingPrompt } = require('./GuildOnboardingPrompt');
|
||||
|
||||
/**
|
||||
* Represents the onboarding data of a guild.
|
||||
* @extends {Base}
|
||||
*/
|
||||
class GuildOnboarding extends Base {
|
||||
constructor(client, data) {
|
||||
super(client);
|
||||
|
||||
/**
|
||||
* The id of the guild this onboarding data is for
|
||||
* @type {Snowflake}
|
||||
*/
|
||||
this.guildId = data.guild_id;
|
||||
|
||||
const guild = this.guild;
|
||||
|
||||
/**
|
||||
* The prompts shown during onboarding and in customize community
|
||||
* @type {Collection<Snowflake, GuildOnboardingPrompt>}
|
||||
*/
|
||||
this.prompts = data.prompts.reduce(
|
||||
(prompts, prompt) => prompts.set(prompt.id, new GuildOnboardingPrompt(client, prompt, this.guildId)),
|
||||
new Collection(),
|
||||
);
|
||||
|
||||
/**
|
||||
* The ids of the channels that new members get opted into automatically
|
||||
* @type {Collection<Snowflake, GuildChannel>}
|
||||
*/
|
||||
this.defaultChannels = data.default_channel_ids.reduce(
|
||||
(channels, channelId) => channels.set(channelId, guild.channels.cache.get(channelId)),
|
||||
new Collection(),
|
||||
);
|
||||
|
||||
/**
|
||||
* Whether onboarding is enabled
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.enabled = data.enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* The guild this onboarding is from
|
||||
* @type {Guild}
|
||||
* @readonly
|
||||
*/
|
||||
get guild() {
|
||||
return this.client.guilds.cache.get(this.guildId);
|
||||
}
|
||||
}
|
||||
|
||||
exports.GuildOnboarding = GuildOnboarding;
|
||||
78
packages/discord.js/src/structures/GuildOnboardingPrompt.js
Normal file
78
packages/discord.js/src/structures/GuildOnboardingPrompt.js
Normal file
@@ -0,0 +1,78 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const Base = require('./Base');
|
||||
const { GuildOnboardingPromptOption } = require('./GuildOnboardingPromptOption');
|
||||
|
||||
/**
|
||||
* Represents the data of a prompt of a guilds onboarding.
|
||||
* @extends {Base}
|
||||
*/
|
||||
class GuildOnboardingPrompt extends Base {
|
||||
constructor(client, data, guildId) {
|
||||
super(client);
|
||||
|
||||
/**
|
||||
* The id of the guild this onboarding prompt is from
|
||||
* @type {Snowflake}
|
||||
*/
|
||||
this.guildId = guildId;
|
||||
|
||||
/**
|
||||
* The id of the prompt
|
||||
* @type {Snowflake}
|
||||
*/
|
||||
this.id = data.id;
|
||||
|
||||
/**
|
||||
* The options available within the prompt
|
||||
* @type {Collection<Snowflake, GuildOnboardingPromptOption>}
|
||||
*/
|
||||
this.options = data.options.reduce(
|
||||
(options, option) => options.set(option.id, new GuildOnboardingPromptOption(client, option, guildId)),
|
||||
new Collection(),
|
||||
);
|
||||
|
||||
/**
|
||||
* The title of the prompt
|
||||
* @type {string}
|
||||
*/
|
||||
this.title = data.title;
|
||||
|
||||
/**
|
||||
* Whether users are limited to selecting one option for the prompt
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.singleSelect = data.single_select;
|
||||
|
||||
/**
|
||||
* Whether the prompt is required before a user completes the onboarding flow
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.required = data.required;
|
||||
|
||||
/**
|
||||
* Whether the prompt is present in the onboarding flow.
|
||||
* If `false`, the prompt will only appear in the Channels & Roles tab
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.inOnboarding = data.in_onboarding;
|
||||
|
||||
/**
|
||||
* The type of the prompt
|
||||
* @type {GuildOnboardingPromptType}
|
||||
*/
|
||||
this.type = data.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The guild this onboarding prompt is from
|
||||
* @type {Guild}
|
||||
* @readonly
|
||||
*/
|
||||
get guild() {
|
||||
return this.client.guilds.cache.get(this.guildId);
|
||||
}
|
||||
}
|
||||
|
||||
exports.GuildOnboardingPrompt = GuildOnboardingPrompt;
|
||||
@@ -0,0 +1,84 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const Base = require('./Base');
|
||||
const { resolvePartialEmoji } = require('../util/Util');
|
||||
|
||||
/**
|
||||
* Represents the data of an option from a prompt of a guilds onboarding.
|
||||
* @extends {Base}
|
||||
*/
|
||||
class GuildOnboardingPromptOption extends Base {
|
||||
constructor(client, data, guildId) {
|
||||
super(client);
|
||||
|
||||
/**
|
||||
* The id of the guild this onboarding prompt option is from
|
||||
* @type {Snowflake}
|
||||
*/
|
||||
this.guildId = guildId;
|
||||
|
||||
const guild = this.guild;
|
||||
|
||||
/**
|
||||
* The id of the option
|
||||
* @type {Snowflake}
|
||||
*/
|
||||
this.id = data.id;
|
||||
|
||||
/**
|
||||
* The channels a member is added to when the option is selected
|
||||
* @type {Collection<Snowflake, GuildChannel>}
|
||||
*/
|
||||
this.channels = data.channel_ids.reduce(
|
||||
(channels, channelId) => channels.set(channelId, guild.channels.cache.get(channelId)),
|
||||
new Collection(),
|
||||
);
|
||||
|
||||
/**
|
||||
* The roles assigned to a member when the option is selected
|
||||
* @type {Collection<Snowflake, Role>}
|
||||
*/
|
||||
this.roles = data.role_ids.reduce(
|
||||
(roles, roleId) => roles.set(roleId, guild.roles.cache.get(roleId)),
|
||||
new Collection(),
|
||||
);
|
||||
|
||||
/**
|
||||
* The data for an emoji of a guilds onboarding prompt option
|
||||
* @typedef {Object} GuildOnboardingPromptOptionEmoji
|
||||
* @property {?Snowflake} id The id of the emoji
|
||||
* @property {string} name The name of the emoji
|
||||
* @property {boolean} animated Whether the emoji is animated
|
||||
*/
|
||||
|
||||
/**
|
||||
* The emoji of the option
|
||||
* @type {?GuildOnboardingPromptOptionEmoji}
|
||||
*/
|
||||
this.emoji = resolvePartialEmoji(data.emoji);
|
||||
|
||||
/**
|
||||
* The title of the option
|
||||
* @type {string}
|
||||
*/
|
||||
this.title = data.title;
|
||||
|
||||
/**
|
||||
* The description of the option
|
||||
* @type {?string}
|
||||
*/
|
||||
this.description = data.description;
|
||||
}
|
||||
|
||||
/**
|
||||
* The guild this onboarding prompt option is from
|
||||
* @type {Guild}
|
||||
* @readonly
|
||||
*/
|
||||
get guild() {
|
||||
return this.client.guilds.cache.get(this.guildId);
|
||||
}
|
||||
}
|
||||
|
||||
exports.GuildOnboardingPromptOption = GuildOnboardingPromptOption;
|
||||
@@ -310,6 +310,11 @@
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildNSFWLevel}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external GuildOnboardingPromptType
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildOnboardingPromptType}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external GuildPremiumTier
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildPremiumTier}
|
||||
|
||||
45
packages/discord.js/typings/index.d.ts
vendored
45
packages/discord.js/typings/index.d.ts
vendored
@@ -157,6 +157,10 @@ import {
|
||||
ImageFormat,
|
||||
GuildMemberFlags,
|
||||
RESTGetAPIGuildThreadsResult,
|
||||
RESTGetAPIGuildOnboardingResult,
|
||||
APIGuildOnboardingPrompt,
|
||||
APIGuildOnboardingPromptOption,
|
||||
GuildOnboardingPromptType,
|
||||
} from 'discord-api-types/v10';
|
||||
import { ChildProcess } from 'node:child_process';
|
||||
import { EventEmitter } from 'node:events';
|
||||
@@ -1356,6 +1360,7 @@ export class Guild extends AnonymousGuild {
|
||||
options?: GuildAuditLogsFetchOptions<T>,
|
||||
): Promise<GuildAuditLogs<T>>;
|
||||
public fetchIntegrations(): Promise<Collection<Snowflake | string, Integration>>;
|
||||
public fetchOnboarding(): Promise<GuildOnboarding>;
|
||||
public fetchOwner(options?: BaseFetchOptions): Promise<GuildMember>;
|
||||
public fetchPreview(): Promise<GuildPreview>;
|
||||
public fetchTemplates(): Promise<Collection<GuildTemplate['code'], GuildTemplate>>;
|
||||
@@ -1566,6 +1571,40 @@ export class GuildMember extends PartialTextBasedChannel(Base) {
|
||||
public valueOf(): string;
|
||||
}
|
||||
|
||||
export class GuildOnboarding extends Base {
|
||||
private constructor(client: Client, data: RESTGetAPIGuildOnboardingResult);
|
||||
public get guild(): Guild;
|
||||
public guildId: Snowflake;
|
||||
public prompts: Collection<Snowflake, GuildOnboardingPrompt>;
|
||||
public defaultChannels: Collection<Snowflake, GuildChannel>;
|
||||
public enabled: boolean;
|
||||
}
|
||||
|
||||
export class GuildOnboardingPrompt extends Base {
|
||||
private constructor(client: Client, data: APIGuildOnboardingPrompt, guildId: Snowflake);
|
||||
public id: Snowflake;
|
||||
public get guild(): Guild;
|
||||
public guildId: Snowflake;
|
||||
public options: Collection<Snowflake, GuildOnboardingPromptOption>;
|
||||
public title: string;
|
||||
public singleSelect: boolean;
|
||||
public required: boolean;
|
||||
public inOnboarding: boolean;
|
||||
public type: GuildOnboardingPromptType;
|
||||
}
|
||||
|
||||
export class GuildOnboardingPromptOption extends Base {
|
||||
private constructor(client: Client, data: APIGuildOnboardingPromptOption, guildId: Snowflake);
|
||||
public id: Snowflake;
|
||||
public get guild(): Guild;
|
||||
public guildId: Snowflake;
|
||||
public channels: Collection<Snowflake, GuildChannel>;
|
||||
public roles: Collection<Snowflake, Role>;
|
||||
public emoji: GuildOnboardingPromptOptionEmoji | null;
|
||||
public title: string;
|
||||
public description: string | null;
|
||||
}
|
||||
|
||||
export class GuildPreview extends Base {
|
||||
private constructor(client: Client<true>, data: RawGuildPreviewData);
|
||||
public approximateMemberCount: number;
|
||||
@@ -5648,6 +5687,12 @@ export type GuildTemplateResolvable = string;
|
||||
|
||||
export type GuildVoiceChannelResolvable = VoiceBasedChannel | Snowflake;
|
||||
|
||||
export interface GuildOnboardingPromptOptionEmoji {
|
||||
id: Snowflake | null;
|
||||
name: string;
|
||||
animated: boolean;
|
||||
}
|
||||
|
||||
export type HexColorString = `#${string}`;
|
||||
|
||||
export interface IntegrationAccount {
|
||||
|
||||
@@ -173,6 +173,7 @@ import {
|
||||
ApplicationCommandSubCommand,
|
||||
ChatInputApplicationCommandData,
|
||||
ApplicationCommandPermissionsManager,
|
||||
GuildOnboarding,
|
||||
} from '.';
|
||||
import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';
|
||||
import type { ContextMenuCommandBuilder, SlashCommandBuilder } from '@discordjs/builders';
|
||||
@@ -2288,3 +2289,8 @@ client.on('guildAuditLogEntryCreate', (auditLogEntry, guild) => {
|
||||
});
|
||||
|
||||
expectType<Readonly<GuildMemberFlagsBitField>>(guildMember.flags);
|
||||
|
||||
{
|
||||
const onboarding = await guild.fetchOnboarding();
|
||||
expectType<GuildOnboarding>(onboarding);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user