Skip to content

Commit

Permalink
Support for application emojis (#181)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheKodeToad authored and DonovanDMC committed Jul 20, 2024
1 parent babbe7b commit e48ab9b
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 30 deletions.
88 changes: 87 additions & 1 deletion lib/routes/Applications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,17 @@ import SKU from "../structures/SKU";
import Entitlement from "../structures/Entitlement";
import TestEntitlement from "../structures/TestEntitlement";
import ClientApplication from "../structures/ClientApplication";
import type { EditApplicationOptions, RESTApplication, RawClientApplication } from "../types";
import type {
ApplicationEmoji,
ApplicationEmojis,
CreateApplicationEmojiOptions,
EditApplicationEmojiOptions,
EditApplicationOptions,
RESTApplication,
RawApplicationEmoji,
RawApplicationEmojis,
RawClientApplication
} from "../types";
import Application from "../structures/Application";

/** Various methods for interacting with application commands. Located at {@link Client#rest | Client#rest}{@link RESTManager#applications | .applications}. */
Expand Down Expand Up @@ -103,6 +113,27 @@ export default class Applications {
});
}

/**
* Create an emoji for an application.
* @param applicationID The ID of the application.
* @param options The options for creating the emoji.
* @caching This method **does not** cache its result.
*/
async createEmoji(applicationID: string, options: CreateApplicationEmojiOptions): Promise<ApplicationEmoji> {
if (options.image) {
options.image = this._manager.client.util._convertImage(options.image, "image");
}

return this._manager.authRequest<RawApplicationEmoji>({
method: "POST",
path: Routes.APPLICATION_EMOJIS(applicationID),
json: {
name: options.name,
image: options.image
}
}).then(emoji => this._manager.client.util.convertApplicationEmoji(emoji));
}

/**
* Create a global application command.
* @param applicationID The ID of the application.
Expand Down Expand Up @@ -173,6 +204,19 @@ export default class Applications {
}).then(data => new TestEntitlement(data, this._manager.client));
}

/**
* Delete an emoji for an application.
* @param applicationID The ID of the application.
* @param emojiID The ID of the emoji to be deleted.
* @caching This method **does not** cache its result.
*/
async deleteEmoji(applicationID: string, emojiID: string): Promise<void> {
await this._manager.authRequest<null>({
method: "DELETE",
path: Routes.APPLICATION_EMOJI(applicationID, emojiID)
});
}

/**
* Delete a global application command.
* @param applicationID The ID of the application.
Expand Down Expand Up @@ -244,6 +288,21 @@ export default class Applications {
}).then(data => new Application(data, this._manager.client));
}

/**
* Edit an existing emoji for an application.
* @param applicationID The ID of the application.
* @param emojiID The ID of the emoji to be edited.
* @param options The options for editing the emoji.
* @caching This method **does not** cache its result.
*/
async editEmoji(applicationID: string, emojiID: string, options: EditApplicationEmojiOptions): Promise<ApplicationEmoji> {
return this._manager.authRequest<RawApplicationEmoji>({
method: "PATCH",
path: Routes.APPLICATION_EMOJI(applicationID, emojiID),
json: { name: options.name }
}).then(emoji => this._manager.client.util.convertApplicationEmoji(emoji));
}

/**
* Edit a global application command.
* @param applicationID The ID of the application.
Expand Down Expand Up @@ -344,6 +403,33 @@ export default class Applications {
}).then(data => new Application(data, this._manager.client));
}

/**
* Get an emoji for an application.
* @param applicationID The ID of the application to get the emojis of.
* @param emojiID The ID of the emoji to get.
* @caching This method **does not** cache its result.
*/
async getEmoji(applicationID: string, emojiID: string): Promise<ApplicationEmoji> {
return this._manager.authRequest<RawApplicationEmoji>({
method: "GET",
path: Routes.APPLICATION_EMOJI(applicationID, emojiID)
}).then(emoji => this._manager.client.util.convertApplicationEmoji(emoji));
}

/**
* Get the emojis for an application.
* @param applicationID The ID of the application to get the emojis of.
* @caching This method **does not** cache its result.
*/
async getEmojis(applicationID: string): Promise<ApplicationEmojis> {
return this._manager.authRequest<RawApplicationEmojis>({
method: "GET",
path: Routes.APPLICATION_EMOJIS(applicationID)
}).then(({ items }) => ({
items: items.map(item => this._manager.client.util.convertApplicationEmoji(item))
}));
}

/**
* Get the entitlements for an application.
* @param applicationID The ID of the application to get the entitlements of.
Expand Down
16 changes: 8 additions & 8 deletions lib/routes/Guilds.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/** @module REST/Guilds */
import type {
CreateEmojiOptions,
CreateGuildEmojiOptions,
CreateGuildOptions,
EditEmojiOptions,
EditGuildEmojiOptions,
EditGuildOptions,
GuildEmoji,
ModifyChannelPositionsEntry,
Expand Down Expand Up @@ -334,7 +334,7 @@ export default class Guilds {
* @caching This method **may** cache its result. The result will not be cached if the guild is not cached.
* @caches {@link Guild#emojis | Guild#emojis}<br>{@link Client#users | Client#users} (creator, if applicable)
*/
async createEmoji(guildID: string, options: CreateEmojiOptions): Promise<GuildEmoji> {
async createEmoji(guildID: string, options: CreateGuildEmojiOptions): Promise<GuildEmoji> {
const reason = options.reason;
if (options.reason) {
delete options.reason;
Expand All @@ -351,7 +351,7 @@ export default class Guilds {
roles: options.roles
},
reason
}).then(data => this._manager.client.guilds.get(guildID)?.emojis.update(data) ?? this._manager.client.util.convertEmoji(data));
}).then(data => this._manager.client.guilds.get(guildID)?.emojis.update(data) ?? this._manager.client.util.convertGuildEmoji(data));
}

/**
Expand Down Expand Up @@ -767,7 +767,7 @@ export default class Guilds {
* @caching This method **may** cache its result. The result will not be cached if the guild is not cached.
* @caches {@link Guild#emojis | Guild#emojis}
*/
async editEmoji(guildID: string, emojiID: string, options: EditEmojiOptions): Promise<GuildEmoji> {
async editEmoji(guildID: string, emojiID: string, options: EditGuildEmojiOptions): Promise<GuildEmoji> {
const reason = options.reason;
if (options.reason) {
delete options.reason;
Expand All @@ -780,7 +780,7 @@ export default class Guilds {
roles: options.roles
},
reason
}).then(data => this._manager.client.guilds.get(guildID)?.emojis.update(data) ?? this._manager.client.util.convertEmoji(data));
}).then(data => this._manager.client.guilds.get(guildID)?.emojis.update(data) ?? this._manager.client.util.convertGuildEmoji(data));
}

/**
Expand Down Expand Up @@ -1337,7 +1337,7 @@ export default class Guilds {
return this._manager.authRequest<RawGuildEmoji>({
method: "GET",
path: Routes.GUILD_EMOJI(guildID, emojiID)
}).then(data => this._manager.client.guilds.get(guildID)?.emojis.update(data) ?? this._manager.client.util.convertEmoji(data));
}).then(data => this._manager.client.guilds.get(guildID)?.emojis.update(data) ?? this._manager.client.util.convertGuildEmoji(data));
}

/**
Expand All @@ -1353,7 +1353,7 @@ export default class Guilds {
}).then(data => {
const guild = this._manager.client.guilds.get(guildID);
guild?.emojis.clear();
return data.map(emoji => guild?.emojis.update(emoji) ?? this._manager.client.util.convertEmoji(emoji));
return data.map(emoji => guild?.emojis.update(emoji) ?? this._manager.client.util.convertGuildEmoji(emoji));
});
}

Expand Down
48 changes: 47 additions & 1 deletion lib/structures/ClientApplication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import type {
RawTestEntitlement,
SearchEntitlementsOptions,
RawClientApplication,
EditApplicationOptions
EditApplicationOptions,
ApplicationEmoji,
ApplicationEmojis,
CreateApplicationEmojiOptions,
EditApplicationEmojiOptions
} from "../types/applications";
import type { JSONClientApplication } from "../types/json";
import type { ApplicationCommandTypes } from "../Constants";
Expand Down Expand Up @@ -81,6 +85,15 @@ export default class ClientApplication extends Base {
return this.client.rest.applications.consumeEntitlement(this.id, entitlementID);
}

/**
* Create an emoji for this application.
* @param options The options for creating the emoji.
* @caching This method **does not** cache its result.
*/
async createEmoji(options: CreateApplicationEmojiOptions): Promise<ApplicationEmoji> {
return this.client.rest.applications.createEmoji(this.id, options);
}

/**
* Create a global application command.
* @param options The options for creating the command.
Expand All @@ -105,6 +118,14 @@ export default class ClientApplication extends Base {
async createTestEntitlement(options: CreateTestEntitlementOptions): Promise<TestEntitlement> {
return this.client.rest.applications.createTestEntitlement(this.id, options);
}
/**
* Delete an emoji for this application.
* @param emojiID The ID of the emoji to be deleted.
* @caching This method **does not** cache its result.
*/
async deleteEmoji(emojiID: string): Promise<void> {
return this.client.rest.applications.deleteEmoji(this.id, emojiID);
}

/**
* Delete a global application command.
Expand Down Expand Up @@ -139,6 +160,16 @@ export default class ClientApplication extends Base {
return this.client.rest.applications.editCurrent(options);
}

/**
* Edit an existing emoji for this application.
* @param emojiID The ID of the emoji to be edited.
* @param options The options for editing the emoji.
* @caching This method **does not** cache its result.
*/
async editEmoji(emojiID: string, options: EditApplicationEmojiOptions): Promise<ApplicationEmoji> {
return this.client.rest.applications.editEmoji(this.id, emojiID, options);
}

/**
* Edit a global application command.
* @param commandID The ID of the command.
Expand Down Expand Up @@ -168,6 +199,21 @@ export default class ClientApplication extends Base {
return this.client.rest.applications.editGuildCommandPermissions(this.id, guildID, commandID, options);
}

/**
* Get an emoji for this application.
* @param emojiID The ID of the emoji to get.
*/
async getEmoji(emojiID: string): Promise<ApplicationEmoji> {
return this.client.rest.applications.getEmoji(this.id, emojiID);
}

/**
* Get the emojis for this application.
*/
async getEmojis(): Promise<ApplicationEmojis> {
return this.client.rest.applications.getEmojis(this.id);
}

/**
* Get the entitlements for this application.
* @param options The options for getting the entitlements.
Expand Down
10 changes: 5 additions & 5 deletions lib/structures/Guild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ import type {
BeginPruneOptions,
CreateBanOptions,
CreateChannelOptions,
CreateEmojiOptions,
CreateGuildEmojiOptions,
CreateRoleOptions,
EditCurrentMemberOptions,
EditCurrentUserVoiceStateOptions,
EditEmojiOptions,
EditGuildEmojiOptions,
EditGuildOptions,
EditMemberOptions,
EditRoleOptions,
Expand Down Expand Up @@ -277,7 +277,7 @@ export default class Guild extends Base {
this.defaultMessageNotifications = data.default_message_notifications;
this.description = null;
this.discoverySplash = null;
this.emojis = new SimpleCollection(rawEmoji => this.client.util.convertEmoji(rawEmoji), client.util._getLimit("emojis", this.id), "merge");
this.emojis = new SimpleCollection(rawEmoji => this.client.util.convertGuildEmoji(rawEmoji), client.util._getLimit("emojis", this.id), "merge");
this.explicitContentFilter = data.explicit_content_filter;
this.features = [];
this.icon = null;
Expand Down Expand Up @@ -759,7 +759,7 @@ export default class Guild extends Base {
* Create an emoji in this guild.
* @param options The options for creating the emoji.
*/
async createEmoji(options: CreateEmojiOptions): Promise<GuildEmoji> {
async createEmoji(options: CreateGuildEmojiOptions): Promise<GuildEmoji> {
return this.client.rest.guilds.createEmoji(this.id, options);
}

Expand Down Expand Up @@ -965,7 +965,7 @@ export default class Guild extends Base {
* Edit an existing emoji in this guild.
* @param options The options for editing the emoji.
*/
async editEmoji(emojiID: string, options: EditEmojiOptions): Promise<GuildEmoji> {
async editEmoji(emojiID: string, options: EditGuildEmojiOptions): Promise<GuildEmoji> {
return this.client.rest.guilds.editEmoji(this.id, emojiID, options);
}

Expand Down
24 changes: 23 additions & 1 deletion lib/types/applications.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @module Types/Applications */
import type { ImplementedChannels, InstallParams, RawOAuthGuild, RawUser } from ".";
import type { ExclusifyUnion } from "./shared";
import type { WithRequired } from "./misc";
import type { Emoji, WithRequired } from "./misc";
import type {
ApplicationCommandOptionTypes,
ApplicationCommandPermissionTypes,
Expand Down Expand Up @@ -464,3 +464,25 @@ export interface EditApplicationOptions {
/** The tags for the application. Max 5 per application, 20 characters each. */
tags?: Array<string>;
}

export interface RawApplicationEmoji extends Required<Omit<Emoji, "user" | "id">> { id: string; user?: RawUser; }
export interface ApplicationEmoji extends Omit<RawApplicationEmoji, "user" | "id" | "require_colons"> { id: string; requireColons?: boolean; user?: User; }

export interface RawApplicationEmojis {
items: Array<RawApplicationEmoji>;
}

export interface ApplicationEmojis {
items: Array<ApplicationEmoji>;
}

export interface CreateApplicationEmojiOptions {
/** The image (buffer, or full data url). */
image: Buffer | string;
/** The name of the emoji (must be unique). */
name: string;
}

export interface EditApplicationEmojiOptions {
name: string;
}
15 changes: 3 additions & 12 deletions lib/types/guilds.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type { RawScheduledEvent } from "./scheduled-events";
import type { ClientStatus, PresenceUpdate, Activity as GatewayActivity } from "./gateway";
import type { RawVoiceState } from "./voice";
import { type File } from "./request-handler";
import type { Emoji } from "./misc";
import type {
ChannelTypes,
DefaultMessageNotificationLevels,
Expand Down Expand Up @@ -132,16 +133,6 @@ export interface RoleTags {
premiumSubscriber: boolean;
subscriptionListingID?: string;
}
export interface Emoji {
animated?: boolean;
available?: boolean;
id: string | null;
managed?: boolean;
name: string;
require_colons?: boolean;
roles?: Array<string>;
user?: RawUser;
}
export interface RawGuildEmoji extends Required<Omit<Emoji, "user" | "id">> { id: string; user?: RawUser; }
export interface GuildEmoji extends Omit<RawGuildEmoji, "user" | "id" | "require_colons"> { id: string; requireColons?: boolean; user?: User; }
export interface RawWelcomeScreen {
Expand Down Expand Up @@ -262,7 +253,7 @@ export interface NullablePartialEmoji {
name?: string | null;
}

export interface CreateEmojiOptions {
export interface CreateGuildEmojiOptions {
/** The image (buffer, or full data url). */
image: Buffer | string;
/** The name of the emoji. */
Expand All @@ -273,7 +264,7 @@ export interface CreateEmojiOptions {
roles?: Array<string>;
}

export interface EditEmojiOptions {
export interface EditGuildEmojiOptions {
/** The name of the emoji. */
name?: string;
/** The reason for creating the emoji. */
Expand Down
Loading

0 comments on commit e48ab9b

Please sign in to comment.