Skip to content

Commit 2f48fbd

Browse files
committed
feat: guild onboarding
1 parent cd69868 commit 2f48fbd

File tree

7 files changed

+279
-0
lines changed

7 files changed

+279
-0
lines changed

packages/discord.js/src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ exports.GuildBan = require('./structures/GuildBan');
125125
exports.GuildChannel = require('./structures/GuildChannel');
126126
exports.GuildEmoji = require('./structures/GuildEmoji');
127127
exports.GuildMember = require('./structures/GuildMember').GuildMember;
128+
exports.GuildOnboarding = require('./structures/GuildOnboarding').GuildOnboarding;
129+
exports.GuildOnboardingPrompt = require('./structures/GuildOnboardingPrompt').GuildOnboardingPrompt;
130+
exports.GuildOnboardingPromptOption = require('./structures/GuildOnboardingPromptOption').GuildOnboardingPromptOption;
128131
exports.GuildPreview = require('./structures/GuildPreview');
129132
exports.GuildPreviewEmoji = require('./structures/GuildPreviewEmoji');
130133
exports.GuildScheduledEvent = require('./structures/GuildScheduledEvent').GuildScheduledEvent;

packages/discord.js/src/structures/Guild.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const { makeURLSearchParams } = require('@discordjs/rest');
55
const { ChannelType, GuildPremiumTier, Routes, GuildFeature } = require('discord-api-types/v10');
66
const AnonymousGuild = require('./AnonymousGuild');
77
const GuildAuditLogs = require('./GuildAuditLogs');
8+
const { GuildOnboarding } = require('./GuildOnboarding');
89
const GuildPreview = require('./GuildPreview');
910
const GuildTemplate = require('./GuildTemplate');
1011
const Integration = require('./Integration');
@@ -760,6 +761,15 @@ class Guild extends AnonymousGuild {
760761
return new GuildAuditLogs(this, data);
761762
}
762763

764+
/**
765+
* Fetches the guild onboarding data for this guild.
766+
* @returns {Promise<GuildOnboarding>}
767+
*/
768+
async fetchOnboarding() {
769+
const data = await this.client.rest.get(`/guilds/${this.id}/onboarding`);
770+
return new GuildOnboarding(this.client, data);
771+
}
772+
763773
/**
764774
* The data for editing a guild.
765775
* @typedef {Object} GuildEditOptions
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
'use strict';
2+
3+
const { Collection } = require('@discordjs/collection');
4+
const Base = require('./Base');
5+
const { GuildOnboardingPrompt } = require('./GuildOnboardingPrompt');
6+
7+
/**
8+
* Represents the onboarding data of a guild.
9+
* @extends {Base}
10+
*/
11+
class GuildOnboarding extends Base {
12+
constructor(client, data) {
13+
super(client);
14+
15+
/**
16+
* The id of the guild this onboarding data is for
17+
* @type {Snowflake}
18+
*/
19+
this.guildId = data.guild_id;
20+
21+
const guild = this.guild;
22+
23+
/**
24+
* The prompts shown during onboarding and in customize community
25+
* @type {Collection<Snowflake, GuildOnboardingPrompt>}
26+
*/
27+
this.prompts = data.prompts.reduce(
28+
(prompts, prompt) => prompts.set(prompt.id, new GuildOnboardingPrompt(client, prompt, this.guildId)),
29+
new Collection(),
30+
);
31+
32+
/**
33+
* The ids of the channels that new members get opted into automatically
34+
* @type {Collection<Snowflake, GuildChannel>}
35+
*/
36+
this.defaultChannels = data.default_channel_ids.reduce(
37+
(channels, channelId) => channels.set(channelId, guild.channels.cache.get(channelId)),
38+
new Collection(),
39+
);
40+
41+
/**
42+
* Whether onboarding is enabled
43+
* @type {boolean}
44+
*/
45+
this.enabled = data.enabled;
46+
}
47+
48+
/**
49+
* The guild this onboarding is from
50+
* @type {Guild}
51+
* @readonly
52+
*/
53+
get guild() {
54+
return this.client.guilds.cache.get(this.guildId);
55+
}
56+
}
57+
58+
exports.GuildOnboarding = GuildOnboarding;
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
'use strict';
2+
3+
const { Collection } = require('@discordjs/collection');
4+
const Base = require('./Base');
5+
const { GuildOnboardingPromptOption } = require('./GuildOnboardingPromptOption');
6+
7+
/**
8+
* Represents the data of a prompt of a guilds onboarding.
9+
* @extends {Base}
10+
*/
11+
class GuildOnboardingPrompt extends Base {
12+
constructor(client, data, guildId) {
13+
super(client);
14+
15+
/**
16+
* The id of the guild this onboarding prompt is from
17+
* @type {Snowflake}
18+
*/
19+
this.guildId = guildId;
20+
21+
/**
22+
* The id of the prompt
23+
* @type {Snowflake}
24+
*/
25+
this.id = data.id;
26+
27+
/**
28+
* The options available within the prompt
29+
* @type {Collection<Snowflake, GuildOnboardingPromptOption>}
30+
*/
31+
this.options = data.options.reduce(
32+
(options, option) => options.set(option.id, new GuildOnboardingPromptOption(client, option, guildId)),
33+
new Collection(),
34+
);
35+
36+
/**
37+
* The title of the prompt
38+
* @type {string}
39+
*/
40+
this.title = data.title;
41+
42+
/**
43+
* Whether users are limited to selecting one option for the prompt
44+
* @type {boolean}
45+
*/
46+
this.singleSelect = data.single_select;
47+
48+
/**
49+
* Whether the prompt is required before a user completes the onboarding flow
50+
* @type {boolean}
51+
*/
52+
this.required = data.required;
53+
54+
/**
55+
* Whether the prompt is present in the onboarding flow.
56+
* If `false`, the prompt will only appear in the Channels & Roles tab
57+
* @type {boolean}
58+
*/
59+
this.inOnboarding = data.in_onboarding;
60+
61+
/**
62+
* The type of the prompt
63+
* @type {GuildOnboardingPromptType}
64+
*/
65+
this.type = data.type;
66+
}
67+
68+
/**
69+
* The guild this onboarding prompt is from
70+
* @type {Guild}
71+
* @readonly
72+
*/
73+
get guild() {
74+
return this.client.guilds.cache.get(this.guildId);
75+
}
76+
}
77+
78+
exports.GuildOnboardingPrompt = GuildOnboardingPrompt;
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
'use strict';
2+
3+
const { Collection } = require('@discordjs/collection');
4+
const Base = require('./Base');
5+
const { resolvePartialEmoji } = require('../util/Util');
6+
7+
/**
8+
* Represents the data of an option from a prompt of a guilds onboarding.
9+
* @extends {Base}
10+
*/
11+
class GuildOnboardingPromptOption extends Base {
12+
constructor(client, data, guildId) {
13+
super(client);
14+
15+
/**
16+
* The id of the guild this onboarding prompt option is from
17+
* @type {Snowflake}
18+
*/
19+
this.guildId = guildId;
20+
21+
const guild = this.guild;
22+
23+
/**
24+
* The id of the option
25+
* @type {Snowflake}
26+
*/
27+
this.id = data.id;
28+
29+
/**
30+
* The channels a member is added to when the option is selected
31+
* @type {Collection<Snowflake, GuildChannel>}
32+
*/
33+
this.channels = data.channel_ids.reduce(
34+
(channels, channelId) => channels.set(channelId, guild.channels.cache.get(channelId)),
35+
new Collection(),
36+
);
37+
38+
/**
39+
* The roles assigned to a member when the option is selected
40+
* @type {Collection<Snowflake, Role>}
41+
*/
42+
this.roles = data.role_ids.reduce(
43+
(roles, roleId) => roles.set(roleId, guild.roles.cache.get(roleId)),
44+
new Collection(),
45+
);
46+
47+
/**
48+
* The data for an emoji of a guilds onboarding prompt option
49+
* @typedef {Object} GuildOnboardingPromptOptionEmoji
50+
* @property {?Snowflake} id The id of the emoji
51+
* @property {?string} name The name of the emoji
52+
* @property {boolean} animated Whether the emoji is animated
53+
*/
54+
55+
/**
56+
* The emoji of the option
57+
* @type {?GuildOnboardingPromptOptionEmoji}
58+
*/
59+
this.emoji = resolvePartialEmoji(data.emoji);
60+
61+
/**
62+
* The title of the option
63+
* @type {string}
64+
*/
65+
this.title = data.title;
66+
67+
/**
68+
* The description of the option
69+
* @type {?string}
70+
*/
71+
this.description = data.description;
72+
}
73+
74+
/**
75+
* The guild this onboarding prompt option is from
76+
* @type {Guild}
77+
* @readonly
78+
*/
79+
get guild() {
80+
return this.client.guilds.cache.get(this.guildId);
81+
}
82+
}
83+
84+
exports.GuildOnboardingPromptOption = GuildOnboardingPromptOption;

packages/discord.js/src/util/APITypes.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,11 @@
310310
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildNSFWLevel}
311311
*/
312312

313+
/**
314+
* @external GuildOnboardingPromptType
315+
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildOnboardingPromptType}
316+
*/
317+
313318
/**
314319
* @external GuildPremiumTier
315320
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildPremiumTier}

packages/discord.js/typings/index.d.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,6 +1356,7 @@ export class Guild extends AnonymousGuild {
13561356
options?: GuildAuditLogsFetchOptions<T>,
13571357
): Promise<GuildAuditLogs<T>>;
13581358
public fetchIntegrations(): Promise<Collection<Snowflake | string, Integration>>;
1359+
public fetchOnboarding(): Promise<GuildOnboarding>;
13591360
public fetchOwner(options?: BaseFetchOptions): Promise<GuildMember>;
13601361
public fetchPreview(): Promise<GuildPreview>;
13611362
public fetchTemplates(): Promise<Collection<GuildTemplate['code'], GuildTemplate>>;
@@ -1566,6 +1567,40 @@ export class GuildMember extends PartialTextBasedChannel(Base) {
15661567
public valueOf(): string;
15671568
}
15681569

1570+
export class GuildOnboarding extends Base {
1571+
private constructor(client: Client, data: any);
1572+
public get guild(): Guild;
1573+
public guildId: Snowflake;
1574+
public prompts: Collection<Snowflake, GuildOnboardingPrompt>;
1575+
public defaultChannels: Collection<Snowflake, GuildChannel>;
1576+
public enabled: boolean;
1577+
}
1578+
1579+
export class GuildOnboardingPrompt extends Base {
1580+
private constructor(client: Client, data: any, guildId: Snowflake);
1581+
public id: Snowflake;
1582+
public get guild(): Guild;
1583+
public guildId: Snowflake;
1584+
public options: Collection<Snowflake, GuildOnboardingPromptOption>;
1585+
public title: string;
1586+
public singleSelect: boolean;
1587+
public required: boolean;
1588+
public inOnboarding: boolean;
1589+
public type: any;
1590+
}
1591+
1592+
export class GuildOnboardingPromptOption extends Base {
1593+
private constructor(client: Client, data: any, guildId: Snowflake);
1594+
public id: Snowflake;
1595+
public get guild(): Guild;
1596+
public guildId: Snowflake;
1597+
public channels: Collection<Snowflake, GuildChannel>;
1598+
public roles: Collection<Snowflake, Role>;
1599+
public emoji: GuildOnboardingPromptOptionEmoji | null;
1600+
public title: string;
1601+
public description: string | null;
1602+
}
1603+
15691604
export class GuildPreview extends Base {
15701605
private constructor(client: Client<true>, data: RawGuildPreviewData);
15711606
public approximateMemberCount: number;
@@ -5641,6 +5676,12 @@ export type GuildTemplateResolvable = string;
56415676

56425677
export type GuildVoiceChannelResolvable = VoiceBasedChannel | Snowflake;
56435678

5679+
export interface GuildOnboardingPromptOptionEmoji {
5680+
id: Snowflake | null;
5681+
name: string | null;
5682+
animated: boolean;
5683+
}
5684+
56445685
export type HexColorString = `#${string}`;
56455686

56465687
export interface IntegrationAccount {

0 commit comments

Comments
 (0)