feat: createEmoji deleteEmoji and editEmoji

This commit is contained in:
Yuzu 2022-06-26 19:07:06 -05:00
parent 044db4c290
commit f8b4ca669c
5 changed files with 200 additions and 1 deletions

7
mod.ts
View File

@ -16,3 +16,10 @@ export * from "./structures/VoiceChannel.ts";
export * from "./structures/ThreadChannel.ts"; export * from "./structures/ThreadChannel.ts";
export * from "./structures/NewsChannel.ts"; export * from "./structures/NewsChannel.ts";
export * from "./structures/Emoji.ts"; export * from "./structures/Emoji.ts";
export * from "./structures/VoiceChannel.ts";
export * from "./structures/Emoji.ts";
export * from "./structures/GuildEmoji.ts";
export * from "./structures/WelcomeChannel.ts";
export * from "./structures/WelcomeScreen.ts";
export * from "./structures/Invite.ts";
export * from "./structures/InviteGuild.ts";

View File

@ -1,15 +1,18 @@
import type { Snowflake } from "../util/Snowflake.ts"; import type { Snowflake } from "../util/Snowflake.ts";
import type { Session } from "../session/Session.ts"; import type { Session } from "../session/Session.ts";
import type { DiscordGuild, DiscordRole } from "../vendor/external.ts"; import type { DiscordEmoji, DiscordGuild, DiscordRole } from "../vendor/external.ts";
import { import {
DefaultMessageNotificationLevels, DefaultMessageNotificationLevels,
ExplicitContentFilterLevels, ExplicitContentFilterLevels,
VerificationLevels, VerificationLevels,
} from "../vendor/external.ts"; } from "../vendor/external.ts";
import { iconBigintToHash, iconHashToBigInt } from "../util/hash.ts"; import { iconBigintToHash, iconHashToBigInt } from "../util/hash.ts";
import { urlToBase64 } from "../util/urlToBase64.ts";
import { Member } from "./Member.ts"; import { Member } from "./Member.ts";
import { BaseGuild } from "./BaseGuild.ts"; import { BaseGuild } from "./BaseGuild.ts";
import { Role } from "./Role.ts"; import { Role } from "./Role.ts";
import { Emoji } from "./Emoji.ts";
import { GuildEmoji } from "./GuildEmoji.ts";
import { Routes } from "../util/mod.ts"; import { Routes } from "../util/mod.ts";
export interface CreateRole { export interface CreateRole {
@ -21,6 +24,18 @@ export interface CreateRole {
mentionable?: boolean; mentionable?: boolean;
} }
export interface CreateGuildEmoji {
name: string;
image: string;
roles?: Snowflake[];
reason?: string;
}
export interface ModifyGuildEmoji {
name?: string;
roles?: Snowflake[];
}
/** /**
* Represents a guild * Represents a guild
* @link https://discord.com/developers/docs/resources/guild#guild-object * @link https://discord.com/developers/docs/resources/guild#guild-object
@ -39,6 +54,7 @@ export class Guild extends BaseGuild {
this.explicitContentFilterLevel = data.explicit_content_filter; this.explicitContentFilterLevel = data.explicit_content_filter;
this.members = data.members?.map((member) => new Member(session, { ...member, user: member.user! })) ?? []; this.members = data.members?.map((member) => new Member(session, { ...member, user: member.user! })) ?? [];
this.roles = data.roles.map((role) => new Role(session, role, data.id)); this.roles = data.roles.map((role) => new Role(session, role, data.id));
this.emojis = data.emojis.map((guildEmoji) => new GuildEmoji(session, guildEmoji, data.id));
} }
splashHash?: bigint; splashHash?: bigint;
@ -51,6 +67,42 @@ export class Guild extends BaseGuild {
explicitContentFilterLevel: ExplicitContentFilterLevels; explicitContentFilterLevel: ExplicitContentFilterLevels;
members: Member[]; members: Member[];
roles: Role[]; roles: Role[];
emojis: GuildEmoji[];
async createEmoji(options: CreateGuildEmoji) {
if (options.image && !options.image.startsWith("data:image/")) {
options.image = await urlToBase64(options.image);
}
const emoji = await this.session.rest.runMethod<DiscordEmoji>(
this.session.rest,
"POST",
Routes.GUILD_EMOJIS(this.id),
options,
);
return new Emoji(this.session, emoji);
}
async deleteEmoji(id: Snowflake, { reason }: { reason?: string } = {}) {
await this.session.rest.runMethod<undefined>(
this.session.rest,
"DELETE",
Routes.GUILD_EMOJI(this.id, id),
{ reason },
);
}
async editEmoji(id: Snowflake, options: ModifyGuildEmoji) {
const emoji = await this.session.rest.runMethod<DiscordEmoji>(
this.session.rest,
"PATCH",
Routes.GUILD_EMOJI(this.id, id),
options,
);
return new GuildEmoji(this.session, emoji, this.id);
}
async createRole(options: CreateRole) { async createRole(options: CreateRole) {
let icon: string | undefined; let icon: string | undefined;

View File

@ -1,6 +1,8 @@
import type { Snowflake } from "../util/Snowflake.ts"; import type { Snowflake } from "../util/Snowflake.ts";
import type { Session } from "../session/Session.ts"; import type { Session } from "../session/Session.ts";
import type { DiscordEmoji } from "../vendor/external.ts"; import type { DiscordEmoji } from "../vendor/external.ts";
import type { ModifyGuildEmoji } from "./Guild.ts";
import { Guild } from "./Guild.ts";
import { Emoji } from "./Emoji.ts"; import { Emoji } from "./Emoji.ts";
import { User } from "./User.ts"; import { User } from "./User.ts";
@ -11,11 +13,30 @@ export class GuildEmoji extends Emoji {
this.roles = data.roles; this.roles = data.roles;
this.user = data.user ? new User(this.session, data.user) : undefined; this.user = data.user ? new User(this.session, data.user) : undefined;
this.managed = !!data.managed; this.managed = !!data.managed;
this.id = super.id!;
} }
guildId: Snowflake; guildId: Snowflake;
roles?: Snowflake[]; roles?: Snowflake[];
user?: User; user?: User;
managed?: boolean; managed?: boolean;
// id cannot be null in a GuildEmoji
override id: Snowflake;
async edit(options: ModifyGuildEmoji): Promise<GuildEmoji> {
const emoji = await Guild.prototype.editEmoji.call(
{ id: this.guildId, session: this.session },
this.id,
options,
);
return emoji;
}
async delete({ reason }: { reason?: string } = {}): Promise<GuildEmoji> {
await Guild.prototype.deleteEmoji.call({ id: this.guildId, session: this.session }, this.id, { reason });
return this;
}
} }
export default GuildEmoji; export default GuildEmoji;

View File

@ -109,3 +109,11 @@ export function GUILD_ROLES(guildId: Snowflake) {
export function USER_DM() { export function USER_DM() {
return `/users/@me/channels`; return `/users/@me/channels`;
} }
export function GUILD_EMOJIS(guildId: Snowflake) {
return `/guilds/${guildId}/emojis`;
}
export function GUILD_EMOJI(guildId: Snowflake, emojiId: Snowflake) {
return `/guilds/${guildId}/emojis/${emojiId}`;
}

111
util/urlToBase64.ts Normal file
View File

@ -0,0 +1,111 @@
/** Converts a url to base 64. Useful for example, uploading/creating server emojis. */
export async function urlToBase64(url: string) {
const buffer = await fetch(url).then((res) => res.arrayBuffer());
const imageStr = encode(buffer);
const type = url.substring(url.lastIndexOf(".") + 1);
return `data:image/${type};base64,${imageStr}`;
}
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
const base64abc = [
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
"q",
"r",
"s",
"t",
"u",
"v",
"w",
"x",
"y",
"z",
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"+",
"/",
];
/**
* CREDIT: https://gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727
* Encodes a given Uint8Array, ArrayBuffer or string into RFC4648 base64 representation
* @param data
*/
export function encode(data: ArrayBuffer | string): string {
const uint8 = typeof data === "string"
? new TextEncoder().encode(data)
: data instanceof Uint8Array
? data
: new Uint8Array(data);
let result = "",
i;
const l = uint8.length;
for (i = 2; i < l; i += 3) {
result += base64abc[uint8[i - 2] >> 2];
result += base64abc[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)];
result += base64abc[((uint8[i - 1] & 0x0f) << 2) | (uint8[i] >> 6)];
result += base64abc[uint8[i] & 0x3f];
}
if (i === l + 1) {
// 1 octet yet to write
result += base64abc[uint8[i - 2] >> 2];
result += base64abc[(uint8[i - 2] & 0x03) << 4];
result += "==";
}
if (i === l) {
// 2 octets yet to write
result += base64abc[uint8[i - 2] >> 2];
result += base64abc[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)];
result += base64abc[(uint8[i - 1] & 0x0f) << 2];
result += "=";
}
return result;
}