Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: guild onboarding #9120

Merged
merged 5 commits into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 104 additions & 92 deletions packages/core/src/api/guild.ts
Original file line number Diff line number Diff line change
@@ -1,98 +1,99 @@
/* eslint-disable jsdoc/check-param-names */

import { makeURLSearchParams, type REST, type RawFile, type RequestData } from '@discordjs/rest';
import { Routes } from 'discord-api-types/v10';
import type {
RESTPatchAPIGuildVoiceStateCurrentMemberJSONBody,
RESTPatchAPIGuildVoiceStateCurrentMemberResult,
GuildMFALevel,
GuildWidgetStyle,
RESTGetAPIAuditLogQuery,
RESTGetAPIAuditLogResult,
RESTGetAPIAutoModerationRuleResult,
RESTGetAPIAutoModerationRulesResult,
RESTGetAPIGuildBanResult,
RESTGetAPIGuildBansQuery,
RESTGetAPIGuildBansResult,
RESTGetAPIGuildChannelsResult,
RESTGetAPIGuildEmojiResult,
RESTGetAPIGuildEmojisResult,
RESTGetAPIGuildIntegrationsResult,
RESTGetAPIGuildInvitesResult,
RESTGetAPIGuildMemberResult,
RESTGetAPIGuildMembersResult,
RESTGetAPIGuildMembersQuery,
RESTGetAPIGuildMembersSearchResult,
RESTGetAPIGuildPreviewResult,
RESTGetAPIGuildPruneCountResult,
RESTGetAPIGuildResult,
RESTGetAPIGuildRolesResult,
RESTGetAPIGuildScheduledEventQuery,
RESTGetAPIGuildScheduledEventResult,
RESTGetAPIGuildScheduledEventsQuery,
RESTGetAPIGuildScheduledEventsResult,
RESTGetAPIGuildScheduledEventUsersQuery,
RESTGetAPIGuildScheduledEventUsersResult,
RESTGetAPIGuildStickerResult,
RESTGetAPIGuildStickersResult,
RESTGetAPIGuildTemplatesResult,
RESTGetAPIGuildThreadsResult,
RESTGetAPIGuildVanityUrlResult,
RESTGetAPIGuildVoiceRegionsResult,
RESTGetAPIGuildPruneCountQuery,
RESTPostAPIGuildStickerFormDataBody,
RESTPostAPIGuildStickerResult,
RESTGetAPIGuildMembersSearchQuery,
RESTGetAPIGuildWebhooksResult,
RESTGetAPIGuildWelcomeScreenResult,
RESTGetAPIGuildWidgetImageResult,
RESTGetAPIGuildWidgetJSONResult,
RESTGetAPIGuildWidgetSettingsResult,
RESTGetAPITemplateResult,
RESTPatchAPIAutoModerationRuleJSONBody,
RESTPatchAPIAutoModerationRuleResult,
RESTPatchAPIGuildChannelPositionsJSONBody,
RESTPatchAPIGuildEmojiJSONBody,
RESTPatchAPIGuildEmojiResult,
RESTPatchAPIGuildJSONBody,
RESTPatchAPIGuildMemberJSONBody,
RESTPatchAPIGuildMemberResult,
RESTPatchAPIGuildResult,
RESTPatchAPIGuildRoleJSONBody,
RESTPatchAPIGuildRolePositionsJSONBody,
RESTPatchAPIGuildRolePositionsResult,
RESTPatchAPIGuildRoleResult,
RESTPatchAPIGuildScheduledEventJSONBody,
RESTPatchAPIGuildScheduledEventResult,
RESTPatchAPIGuildStickerJSONBody,
RESTPatchAPIGuildStickerResult,
RESTPatchAPIGuildTemplateJSONBody,
RESTPatchAPIGuildTemplateResult,
RESTPatchAPIGuildVoiceStateUserJSONBody,
RESTPatchAPIGuildWelcomeScreenJSONBody,
RESTPatchAPIGuildWelcomeScreenResult,
RESTPatchAPIGuildWidgetSettingsJSONBody,
RESTPatchAPIGuildWidgetSettingsResult,
RESTPostAPIAutoModerationRuleJSONBody,
RESTPostAPIAutoModerationRuleResult,
RESTPostAPIGuildChannelJSONBody,
RESTPostAPIGuildChannelResult,
RESTPostAPIGuildEmojiJSONBody,
RESTPostAPIGuildEmojiResult,
RESTPostAPIGuildPruneJSONBody,
RESTPostAPIGuildPruneResult,
RESTPostAPIGuildRoleJSONBody,
RESTPostAPIGuildRoleResult,
RESTPostAPIGuildScheduledEventJSONBody,
RESTPostAPIGuildScheduledEventResult,
RESTPostAPIGuildsJSONBody,
RESTPostAPIGuildsMFAResult,
RESTPostAPIGuildsResult,
RESTPostAPIGuildTemplatesJSONBody,
RESTPostAPIGuildTemplatesResult,
RESTPutAPIGuildBanJSONBody,
RESTPutAPIGuildTemplateSyncResult,
Snowflake,
import {
Routes,
type GuildMFALevel,
type GuildWidgetStyle,
type RESTGetAPIAuditLogQuery,
type RESTGetAPIAuditLogResult,
type RESTGetAPIAutoModerationRuleResult,
type RESTGetAPIAutoModerationRulesResult,
type RESTGetAPIGuildBanResult,
type RESTGetAPIGuildBansQuery,
type RESTGetAPIGuildBansResult,
type RESTGetAPIGuildChannelsResult,
type RESTGetAPIGuildEmojiResult,
type RESTGetAPIGuildEmojisResult,
type RESTGetAPIGuildIntegrationsResult,
type RESTGetAPIGuildInvitesResult,
type RESTGetAPIGuildMemberResult,
type RESTGetAPIGuildMembersQuery,
type RESTGetAPIGuildMembersResult,
type RESTGetAPIGuildMembersSearchQuery,
type RESTGetAPIGuildMembersSearchResult,
type RESTGetAPIGuildOnboardingResult,
type RESTGetAPIGuildPreviewResult,
type RESTGetAPIGuildPruneCountQuery,
type RESTGetAPIGuildPruneCountResult,
type RESTGetAPIGuildResult,
type RESTGetAPIGuildRolesResult,
type RESTGetAPIGuildScheduledEventQuery,
type RESTGetAPIGuildScheduledEventResult,
type RESTGetAPIGuildScheduledEventUsersQuery,
type RESTGetAPIGuildScheduledEventUsersResult,
type RESTGetAPIGuildScheduledEventsQuery,
type RESTGetAPIGuildScheduledEventsResult,
type RESTGetAPIGuildStickerResult,
type RESTGetAPIGuildStickersResult,
type RESTGetAPIGuildTemplatesResult,
type RESTGetAPIGuildThreadsResult,
type RESTGetAPIGuildVanityUrlResult,
type RESTGetAPIGuildVoiceRegionsResult,
type RESTGetAPIGuildWebhooksResult,
type RESTGetAPIGuildWelcomeScreenResult,
type RESTGetAPIGuildWidgetImageResult,
type RESTGetAPIGuildWidgetJSONResult,
type RESTGetAPIGuildWidgetSettingsResult,
type RESTGetAPITemplateResult,
type RESTPatchAPIAutoModerationRuleJSONBody,
type RESTPatchAPIAutoModerationRuleResult,
type RESTPatchAPIGuildChannelPositionsJSONBody,
type RESTPatchAPIGuildEmojiJSONBody,
type RESTPatchAPIGuildEmojiResult,
type RESTPatchAPIGuildJSONBody,
type RESTPatchAPIGuildMemberJSONBody,
type RESTPatchAPIGuildMemberResult,
type RESTPatchAPIGuildResult,
type RESTPatchAPIGuildRoleJSONBody,
type RESTPatchAPIGuildRolePositionsJSONBody,
type RESTPatchAPIGuildRolePositionsResult,
type RESTPatchAPIGuildRoleResult,
type RESTPatchAPIGuildScheduledEventJSONBody,
type RESTPatchAPIGuildScheduledEventResult,
type RESTPatchAPIGuildStickerJSONBody,
type RESTPatchAPIGuildStickerResult,
type RESTPatchAPIGuildTemplateJSONBody,
type RESTPatchAPIGuildTemplateResult,
type RESTPatchAPIGuildVoiceStateCurrentMemberJSONBody,
type RESTPatchAPIGuildVoiceStateCurrentMemberResult,
type RESTPatchAPIGuildVoiceStateUserJSONBody,
type RESTPatchAPIGuildWelcomeScreenJSONBody,
type RESTPatchAPIGuildWelcomeScreenResult,
type RESTPatchAPIGuildWidgetSettingsJSONBody,
type RESTPatchAPIGuildWidgetSettingsResult,
type RESTPostAPIAutoModerationRuleJSONBody,
type RESTPostAPIAutoModerationRuleResult,
type RESTPostAPIGuildChannelJSONBody,
type RESTPostAPIGuildChannelResult,
type RESTPostAPIGuildEmojiJSONBody,
type RESTPostAPIGuildEmojiResult,
type RESTPostAPIGuildPruneJSONBody,
type RESTPostAPIGuildPruneResult,
type RESTPostAPIGuildRoleJSONBody,
type RESTPostAPIGuildRoleResult,
type RESTPostAPIGuildScheduledEventJSONBody,
type RESTPostAPIGuildScheduledEventResult,
type RESTPostAPIGuildStickerFormDataBody,
type RESTPostAPIGuildStickerResult,
type RESTPostAPIGuildTemplatesJSONBody,
type RESTPostAPIGuildTemplatesResult,
type RESTPostAPIGuildsJSONBody,
type RESTPostAPIGuildsMFAResult,
type RESTPostAPIGuildsResult,
type RESTPutAPIGuildBanJSONBody,
type RESTPutAPIGuildTemplateSyncResult,
type Snowflake,
} from 'discord-api-types/v10';

export class GuildsAPI {
Expand Down Expand Up @@ -1229,4 +1230,15 @@ export class GuildsAPI {
body,
}) as Promise<RESTPatchAPIGuildVoiceStateCurrentMemberResult>;
}

/**
* Fetches a guild onboarding
*
* @see {@link https://discord.com/developers/docs/resources/guild#get-guild-onboarding}
* @param guildId - The id of the guild
* @param options - The options for fetching the guild onboarding
*/
public async getOnboarding(guildId: Snowflake, { signal }: Pick<RequestData, 'signal'> = {}) {
return this.rest.get(Routes.guildOnboarding(guildId), { signal }) as Promise<RESTGetAPIGuildOnboardingResult>;
}
}
3 changes: 3 additions & 0 deletions packages/discord.js/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
almeidx marked this conversation as resolved.
Show resolved Hide resolved
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;
Expand Down
10 changes: 10 additions & 0 deletions packages/discord.js/src/structures/Guild.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -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
Expand Down
58 changes: 58 additions & 0 deletions packages/discord.js/src/structures/GuildOnboarding.js
Original file line number Diff line number Diff line change
@@ -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;
almeidx marked this conversation as resolved.
Show resolved Hide resolved

/**
* 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 changes: 78 additions & 0 deletions packages/discord.js/src/structures/GuildOnboardingPrompt.js
Original file line number Diff line number Diff line change
@@ -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;
Loading