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: Support new application properties and patch endpoint #9709

Merged
merged 9 commits into from
Oct 10, 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
21 changes: 20 additions & 1 deletion packages/core/src/api/applications.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/* eslint-disable jsdoc/check-param-names */

import type { RequestData, REST } from '@discordjs/rest';
import { type RESTGetCurrentApplicationResult, Routes } from 'discord-api-types/v10';
import {
type RESTGetCurrentApplicationResult,
type RESTPatchCurrentApplicationJSONBody,
type RESTPatchCurrentApplicationResult,
Routes,
} from 'discord-api-types/v10';

export class ApplicationsAPI {
public constructor(private readonly rest: REST) {}
Expand All @@ -15,4 +20,18 @@ export class ApplicationsAPI {
public async getCurrent({ signal }: Pick<RequestData, 'signal'> = {}) {
return this.rest.get(Routes.currentApplication(), { signal }) as Promise<RESTGetCurrentApplicationResult>;
}

/**
* Edits properties of the application associated with the requesting bot user.
*
* @see {@link https://discord.com/developers/docs/resources/application#edit-current-application}
* @param body - The new application data
* @param options - The options for editing the application
*/
public async editCurrent(body: RESTPatchCurrentApplicationJSONBody, { signal }: Pick<RequestData, 'signal'> = {}) {
return this.rest.patch(Routes.currentApplication(), {
body,
signal,
}) as Promise<RESTPatchCurrentApplicationResult>;
}
}
70 changes: 70 additions & 0 deletions packages/discord.js/src/structures/ClientApplication.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const Team = require('./Team');
const Application = require('./interfaces/Application');
const ApplicationCommandManager = require('../managers/ApplicationCommandManager');
const ApplicationFlagsBitField = require('../util/ApplicationFlagsBitField');
const DataResolver = require('../util/DataResolver');
const PermissionsBitField = require('../util/PermissionsBitField');

/**
Expand Down Expand Up @@ -119,6 +120,16 @@ class ClientApplication extends Application {
this.botRequireCodeGrant ??= null;
}

if ('bot' in data) {
/**
* The bot associated with this application.
* @type {?User}
*/
this.bot = this.client.users._add(data.bot);
} else {
this.bot ??= null;
}

if ('bot_public' in data) {
/**
* If this application's bot is public
Expand All @@ -129,6 +140,16 @@ class ClientApplication extends Application {
this.botPublic ??= null;
}

if ('interactions_endpoint_url' in data) {
/**
* This application's interaction endpoint URL.
* @type {?string}
*/
this.interactionsEndpointURL = data.interactions_endpoint_url;
} else {
this.interactionsEndpointURL ??= null;
}

if ('role_connections_verification_url' in data) {
/**
* This application's role connection verification entry point URL
Expand Down Expand Up @@ -168,6 +189,55 @@ class ClientApplication extends Application {
return !this.name;
}

/**
* Options used for editing an application.
* @typedef {Object} ClientApplicationEditOptions
* @property {string} [customInstallURL] The application's custom installation URL
* @property {string} [description] The application's description
* @property {string} [roleConnectionsVerificationURL] The application's role connection verification URL
* @property {ClientApplicationInstallParams} [installParams]
* Settings for the application's default in-app authorization
* @property {ApplicationFlagsResolvable} [flags] The flags for the application
* @property {?(BufferResolvable|Base64Resolvable)} [icon] The application's icon
* @property {?(BufferResolvable|Base64Resolvable)} [coverImage] The application's cover image
* @property {string} [interactionsEndpointURL] The application's interaction endpoint URL
* @property {string[]} [tags] The application's tags
*/

/**
* Edits this application.
* @param {ClientApplicationEditOptions} [options] The options for editing this application
* @returns {Promise<ClientApplication>}
*/
async edit({
customInstallURL,
description,
roleConnectionsVerificationURL,
installParams,
flags,
icon,
coverImage,
interactionsEndpointURL,
tags,
} = {}) {
const data = await this.client.rest.patch(Routes.currentApplication(), {
body: {
custom_install_url: customInstallURL,
description,
role_connections_verification_url: roleConnectionsVerificationURL,
install_params: installParams,
flags: flags === undefined ? undefined : ApplicationFlagsBitField.resolve(flags),
icon: icon && (await DataResolver.resolveImage(icon)),
cover_image: coverImage && (await DataResolver.resolveImage(coverImage)),
interactions_endpoint_url: interactionsEndpointURL,
tags,
},
});

this._patch(data);
return this;
}

/**
* Obtains this application from Discord.
* @returns {Promise<ClientApplication>}
Expand Down
15 changes: 15 additions & 0 deletions packages/discord.js/src/util/ApplicationFlagsBitField.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,19 @@ class ApplicationFlagsBitField extends BitField {
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
*/

/**
* Bitfield of the packed bits
* @type {number}
* @name ApplicationFlagsBitField#bitfield
*/

/**
* Data that can be resolved to give an application flag bit field. This can be:
* * A string (see {@link ApplicationFlagsBitField.Flags})
* * An application flag
* * An instance of ApplicationFlagsBitField
* * An Array of ApplicationFlagsResolvable
* @typedef {string|number|ApplicationFlagsBitField|ApplicationFlagsResolvable[]} ApplicationFlagsResolvable
*/

module.exports = ApplicationFlagsBitField;
17 changes: 17 additions & 0 deletions packages/discord.js/typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,8 @@ export class ApplicationFlagsBitField extends BitField<ApplicationFlagsString> {
public static resolve(bit?: BitFieldResolvable<ApplicationFlagsString, number>): number;
}

export type ApplicationFlagsResolvable = BitFieldResolvable<ApplicationFlagsString, number>;

export type AutoModerationRuleResolvable = AutoModerationRule | Snowflake;

export abstract class Base {
Expand Down Expand Up @@ -1019,6 +1021,7 @@ export class ClientApplication extends Application {
private constructor(client: Client<true>, data: RawClientApplicationData);
public botPublic: boolean | null;
public botRequireCodeGrant: boolean | null;
public bot: User | null;
public commands: ApplicationCommandManager;
public guildId: Snowflake | null;
public get guild(): Guild | null;
Expand All @@ -1030,8 +1033,10 @@ export class ClientApplication extends Application {
public customInstallURL: string | null;
public owner: User | Team | null;
public get partial(): boolean;
public interactionsEndpointURL: string | null;
public roleConnectionsVerificationURL: string | null;
public rpcOrigins: string[];
public edit(optins: ClientApplicationEditOptions): Promise<ClientApplication>;
public fetch(): Promise<ClientApplication>;
public fetchRoleConnectionMetadataRecords(): Promise<ApplicationRoleConnectionMetadata[]>;
public editRoleConnectionMetadataRecords(
Expand Down Expand Up @@ -6518,6 +6523,18 @@ export interface WelcomeScreenEditOptions {
welcomeChannels?: WelcomeChannelData[];
}

export interface ClientApplicationEditOptions {
customInstallURL?: string;
description?: string;
roleConnectionsVerificationURL?: string;
installParams?: ClientApplicationInstallParams;
flags?: ApplicationFlagsResolvable;
icon?: BufferResolvable | Base64Resolvable | null;
coverImage?: BufferResolvable | Base64Resolvable | null;
interactionsEndpointURL?: string;
tags?: readonly string[];
}

export interface ClientApplicationInstallParams {
scopes: OAuth2Scopes[];
permissions: Readonly<PermissionsBitField>;
Expand Down