diff --git a/handlers/guild.ts b/handlers/guild.ts index 3320cd13d..b6102ae3a 100644 --- a/handlers/guild.ts +++ b/handlers/guild.ts @@ -37,6 +37,7 @@ import { requestAllMembers } from "../module/shardingManager.ts"; import { MemberCreatePayload } from "../types/member.ts"; import { cache } from "../utils/cache.ts"; import { createMember } from "../structures/member.ts"; +import { urlToBase64 } from "../utils/utils.ts"; /** Gets an array of all the channels ids that are the children of this category. */ export function categoryChildrenIDs(guild: Guild, id: string) { @@ -155,8 +156,8 @@ export async function getMember(guildID: string, id: string) { return member; } -/** Create an emoji in the server. Emojis and animated emojis have a maximum file size of 256kb. Attempting to upload an emoji larger than this limit will fail and return 400 Bad Request and an error message, but not a JSON status code. */ -export function createEmoji( +/** Create an emoji in the server. Emojis and animated emojis have a maximum file size of 256kb. Attempting to upload an emoji larger than this limit will fail and return 400 Bad Request and an error message, but not a JSON status code. If a URL is provided to the image parameter, Discordeno will automatically convert it to a base64 string internally. */ +export async function createEmoji( guildID: string, name: string, image: string, @@ -167,6 +168,11 @@ export function createEmoji( ) { throw new Error(Errors.MISSING_MANAGE_EMOJIS); } + + if (image && !image.startsWith("data:image/")) { + image = await urlToBase64(image); + } + return RequestManager.post(endpoints.GUILD_EMOJIS(guildID), { ...options, name, @@ -443,7 +449,10 @@ export function ban(guildID: string, id: string, options: BanOptions) { throw new Error(Errors.MISSING_BAN_MEMBERS); } - return RequestManager.put(endpoints.GUILD_BAN(guildID, id), { ...options, delete_message_days: options.days }); + return RequestManager.put( + endpoints.GUILD_BAN(guildID, id), + { ...options, delete_message_days: options.days }, + ); } /** Remove the ban for a user. REquires BAN_MEMBERS permission */ @@ -496,12 +505,25 @@ export function channelHasPermissions( } /** Modify a guilds settings. Requires the MANAGE_GUILD permission. */ -export function editGuild(guildID: string, options: GuildEditOptions) { +export async function editGuild(guildID: string, options: GuildEditOptions) { if ( !botHasPermission(guildID, [Permissions.MANAGE_GUILD]) ) { throw new Error(Errors.MISSING_MANAGE_GUILD); } + + if (options.icon && !options.icon.startsWith("data:image/")) { + options.icon = await urlToBase64(options.icon); + } + + if (options.banner && !options.banner.startsWith("data:image/")) { + options.banner = await urlToBase64(options.banner); + } + + if (options.splash && !options.splash.startsWith("data:image/")) { + options.splash = await urlToBase64(options.splash); + } + return RequestManager.patch(endpoints.GUILD(guildID), options); } diff --git a/types/guild.ts b/types/guild.ts index c139170e6..9c8469fc1 100644 --- a/types/guild.ts +++ b/types/guild.ts @@ -224,13 +224,13 @@ export interface GuildEditOptions { afk_channel_id?: string; /** The afk timeout in seconds. */ afk_timeout?: number; - /** base64 1024x1024 png/jpeg/gif image for the guild icon (can be animated gif when the server has ANIMATED_ICON feature) */ + /** If a URL is provided to the image parameter, Discordeno will automatically convert it to a base64 string internally. base64 1024x1024 png/jpeg/gif image for the guild icon (can be animated gif when the server has ANIMATED_ICON feature) */ icon?: string; /** user id to transfer guild ownership to (must be owner) */ owner_id?: string; - /** base64 16:9 png/jpeg image for the guild splash (when the server has INVITE_SPLASH feature) */ + /** If a URL is provided to the image parameter, Discordeno will automatically convert it to a base64 string internally. base64 16:9 png/jpeg image for the guild splash (when the server has INVITE_SPLASH feature) */ splash?: string; - /** base64 16:9 png/jpeg image for the guild banner (when the server has BANNER feature) */ + /** If a URL is provided to the image parameter, Discordeno will automatically convert it to a base64 string internally. base64 16:9 png/jpeg image for the guild banner (when the server has BANNER feature) */ banner?: string; /** the id of the channel to which system messages are sent */ system_channel_id?: string; diff --git a/utils/utils.ts b/utils/utils.ts index e3b5f4cca..e9c19cbdf 100644 --- a/utils/utils.ts +++ b/utils/utils.ts @@ -1,6 +1,7 @@ import { StatusType } from "../types/discord.ts"; import { ActivityType } from "../types/activity.ts"; import { sendGatewayCommand } from "../module/shardingManager.ts"; +import { encode } from "https://deno.land/std@0.61.0/encoding/base64.ts"; export const sleep = (timeout: number) => { return new Promise((resolve) => setTimeout(resolve, timeout)); @@ -17,3 +18,10 @@ export function editBotsStatus( export function chooseRandom(array: T[]) { return array[Math.floor(Math.random() * array.length)]; } + +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}`; +}