From 45dfc137709bf704aff15f19f494046d3e2ece1e Mon Sep 17 00:00:00 2001 From: Skillz Date: Sun, 16 Feb 2020 14:15:48 -0500 Subject: [PATCH] finalizing channels structure --- constants/discord.ts | 56 +++++++++++++---------- structures/channel.ts | 103 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 125 insertions(+), 34 deletions(-) diff --git a/constants/discord.ts b/constants/discord.ts index 9977bdf1d..7e8d91fa1 100644 --- a/constants/discord.ts +++ b/constants/discord.ts @@ -4,40 +4,46 @@ export const baseEndpoints = { CDN_URL: 'https://cdn.discordapp.com' } +const GUILDS_BASE = (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}` + export const endpoints = { GATEWAY_BOT: `${baseEndpoints.BASE_URL}/gateway/bot`, // Channel Endpoints - CHANNEL_MESSAGE: (id: string, message_id: string) => `${baseEndpoints.BASE_URL}/channels/${id}/messages/${message_id}`, - CHANNEL_MESSAGES: (id: string) => `${baseEndpoints.BASE_URL}/channels/${id}` + CHANNEL_MESSAGE: (id: string, message_id: string) => + `${baseEndpoints.BASE_URL}/channels/${id}/messages/${message_id}`, + CHANNEL_MESSAGES: (id: string) => `${baseEndpoints.BASE_URL}/channels/${id}`, + CHANNEL_PINS: (id: string) => `${baseEndpoints.BASE_URL}/channels/${id}/pins`, + CHANNEL_BULK_DELETE: (id: string) => `${baseEndpoints.BASE_URL}/channels/${id}/messages/bulk-delete`, + CHANNEL_INVITES: (id: string) => `${baseEndpoints.BASE_URL}/channels/${id}/invites`, + CHANNEL_WEBHOOKS: (id: string) => `${baseEndpoints.BASE_URL}/channels/${id}/webhooks`, // Guild Endpoints - GUILD: (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}`, - GUILD_AUDIT_LOGS: (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/audit-logs`, - GUILD_BAN: (id: string, user_id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/bans/${user_id}`, - GUILD_BANS: (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/bans`, + GUILD: (id: string) => `${GUILDS_BASE(id)}`, + GUILD_AUDIT_LOGS: (id: string) => `${GUILDS_BASE(id)}/audit-logs`, + GUILD_BAN: (id: string, user_id: string) => `${GUILDS_BASE(id)}/bans/${user_id}`, + GUILD_BANS: (id: string) => `${GUILDS_BASE(id)}/bans`, GUILD_BANNER: (id: string, icon: string) => `${baseEndpoints.CDN_URL}/banners/${id}/${icon}`, - GUILD_CHANNELS: (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/channels`, - GUILD_EMBED: (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/embed`, - GUILD_EMOJI: (id: string, emoji_id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/emojis/${emoji_id}`, - GUILD_EMOJIS: (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/emojis`, + GUILD_CHANNELS: (id: string) => `${GUILDS_BASE(id)}/channels`, + GUILD_EMBED: (id: string) => `${GUILDS_BASE(id)}/embed`, + GUILD_EMOJI: (id: string, emoji_id: string) => `${GUILDS_BASE(id)}/emojis/${emoji_id}`, + GUILD_EMOJIS: (id: string) => `${GUILDS_BASE(id)}/emojis`, GUILD_ICON: (id: string, icon: string) => `${baseEndpoints.CDN_URL}/icons/${id}/${icon}`, - GUILD_INTEGRATION: (id: string, integration_id: string) => - `${baseEndpoints.BASE_URL}/guilds/${id}/integrations/${integration_id}`, - GUILD_INTEGRATION_SYNC: (id: string, integration_id: string) => - `${baseEndpoints.BASE_URL}/guilds/${id}/integrations/${integration_id}/sync`, - GUILD_INTEGRATIONS: (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/integrations`, - GUILD_INVITES: (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/invites`, - GUILD_LEAVE: (id: string) => `${baseEndpoints.BASE_URL}/users/@me/guilds/${id}`, - GUILD_MEMBER: (id: string, member_id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/members/${member_id}`, - GUILD_MEMBER_ROLE: (id: string, member_id: string, role_id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/members/${member_id}/roles/${role_id}`, - GUILD_PRUNE: (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/prune`, - GUILD_REGIONS: (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/regions`, - GUILD_ROLE: (id: string, role_id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/roles/${role_id}`, - GUILD_ROLES: (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/roles`, + GUILD_INTEGRATION: (id: string, integration_id: string) => `${GUILDS_BASE(id)}/integrations/${integration_id}`, + GUILD_INTEGRATION_SYNC: (id: string, integration_id: string) => `${GUILDS_BASE(id)}/integrations/${integration_id}/sync`, + GUILD_INTEGRATIONS: (id: string) => `${GUILDS_BASE(id)}/integrations`, + GUILD_INVITES: (id: string) => `${GUILDS_BASE(id)}/invites`, + GUILD_LEAVE: (id: string) => `${baseEndpoints.BASE_URL}/users/@me/guilds/${id}`, + GUILD_MEMBER: (id: string, member_id: string) => `${GUILDS_BASE(id)}/members/${member_id}`, + GUILD_MEMBER_ROLE: (id: string, member_id: string, role_id: string) => + `${GUILDS_BASE(id)}/members/${member_id}/roles/${role_id}`, + GUILD_PRUNE: (id: string) => `${GUILDS_BASE(id)}/prune`, + GUILD_REGIONS: (id: string) => `${GUILDS_BASE(id)}/regions`, + GUILD_ROLE: (id: string, role_id: string) => `${GUILDS_BASE(id)}/roles/${role_id}`, + GUILD_ROLES: (id: string) => `${GUILDS_BASE(id)}/roles`, GUILD_SPLASH: (id: string, icon: string) => `${baseEndpoints.CDN_URL}/splashes/${id}/${icon}`, - GUILD_VANITY_URL: (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/vanity-url`, - GUILD_WEBHOOKS: (id: string) => `${baseEndpoints.BASE_URL}/guilds/${id}/webhooks`, + GUILD_VANITY_URL: (id: string) => `${GUILDS_BASE(id)}/vanity-url`, + GUILD_WEBHOOKS: (id: string) => `${GUILDS_BASE(id)}/webhooks`, // User endpoints USER_AVATAR: (id: string, icon: string) => `${baseEndpoints.CDN_URL}/avatars/${id}/${icon}`, diff --git a/structures/channel.ts b/structures/channel.ts index 811807a7d..a34de2c87 100644 --- a/structures/channel.ts +++ b/structures/channel.ts @@ -18,32 +18,72 @@ export interface MessageContent { payload_json?: string } +export interface Get_Messages { + /** Max number of messages to return(1-100). Defaults to 50. */ + limit?: number +} + +export interface Get_Messages_After extends Get_Messages { + /** Get messages after this message id */ + after: string +} + +export interface Get_Messages_Before extends Get_Messages { + /** Get messages before this message id */ + before: string +} + +export interface Get_Messages_Around extends Get_Messages { + /** Get messages around this message id. */ + around: string +} + +export interface Create_Invite_Options { + /** Duration of invite in seconds before expiry, or 0 for never. Defaults to 86400 (24 hours) */ + max_age: number + /** Max number of uses or 0 for unlimited. Default 0 */ + max_uses: number + /** Whether this invite only grants temporary membership. */ + temporary: boolean + /** If true, don't try to reuse a similar invite (useful for creating many unique one time use invites.) */ + unique: boolean +} + export const create_channel = (data: Channel_Create_Options, guild: Guild, client: Client) => { const base_channel = { + /** The unique id of the channel */ id: data.id, + /** The type of the channel. */ type: () => data.type, + /** The id of the guild where this channel exists */ guild_id: () => data.guild_id } const base_text_channel = { + /** A short collection of recently sent messages since bot started. */ messages: new Map(), + /** The last message id in this channel */ last_message_id: () => data.last_message_id, + /** Fetch a single message from the server. Requires VIEW_CHANNEL and READ_MESSAGE_HISTORY */ get_message: async (id: string) => { // TODO: check if the user has VIEW_CHANNEL and READ_MESSAGE_HISTORY const result = await client.RequestManager.get(endpoints.CHANNEL_MESSAGE(data.id, id)) return create_message(result, client) }, + /** Fetches between 2-100 messages. Requires VIEW_CHANNEL and READ_MESSAGE_HISTORY */ get_messages: async (options?: Get_Messages_After | Get_Messages_Before | Get_Messages_Around | Get_Messages) => { // TODO: check if the user has VIEW_CHANNEL and READ_MESSAGE_HISTORY - if (!options.limit || options.limit <= 100) { - const result = await client.RequestManager.get(endpoints.CHANNEL_MESSAGES(data.id), options) - return result.map(res => create_message(res, client)) - } + if (options?.limit && options.limit > 100) return - const fetch_messages = () => {} - const - return client.RequestManager.get(endpoints.CHANNEL_MESSAGES(data.id), options) + const result = await client.RequestManager.get(endpoints.CHANNEL_MESSAGES(data.id), options) + return result.map(res => create_message(res, client)) }, + /** Get pinned messages in this channel. */ + get_pins: async () => { + const result = await client.RequestManager.get(endpoints.CHANNEL_PINS(data.id)) + return result.map(res => create_message(res, client)) + }, + /** Send a message to the channel. Requires SEND_MESSAGES permission. */ send_message: async (content: string | MessageContent) => { if (data.type !== Channel_Types.DM) { // TODO: check if the bot has SEND_MESSAGES permission @@ -54,6 +94,8 @@ export const create_channel = (data: Channel_Create_Options, guild: Guild, clien // TODO: check if the bot has SEND_TTS_MESSAGE } + // TODO: Check content length + const result = await client.RequestManager.post(endpoints.CHANNEL_MESSAGES(data.id), content) return create_message(result, client) } @@ -69,11 +111,16 @@ export const create_channel = (data: Channel_Create_Options, guild: Guild, clien // GUILD CHANNEL ONLY const base_guild_channel = { ...base_channel, + /** Whether this channel NSFW enabled. */ nsfw: () => data.nsfw!, + /** The position of the channel in the server. */ position: () => data.position!, + /** The category id for this channel. */ parent_id: () => data.parent_id, // TODO: fix this from being number on allow and deny to being array of strings + /** Fetch the permission overwrites */ permission_overwrites: () => data.permission_overwrites, + /** Check whether a member has certain permissions in this channel. */ has_permissions: (id: string, permissions: Permission[]) => { if (id === guild.owner_id) return true @@ -103,23 +150,61 @@ export const create_channel = (data: Channel_Create_Options, guild: Guild, clien return { ...base_guild_channel, ...base_text_channel, - mention: () => `<#${data.id}>` + /** The topic of the channel */ + topic: () => data.topic, + /** The mention of the channel */ + mention: () => `<#${data.id}>`, + /** Delete messages from the channel. 2-100. Requires the MANAGE_MESSAGES permission */ + delete_messages: (ids: string[], reason?: string) => { + // TODO: Requires the MANAGE_MESSAGES permission. + if (ids.length < 2) throw 'This endpoint will only accept 2-100 message ids.' + if (ids.length > 100) + console.warn( + `This endpoint only accepts a maximum of 100 messages. Deleting the first 100 message ids provided.` + ) + return client.RequestManager.POST(endpoints.CHANNEL_BULK_DELETE(data.id), { + messages: ids.splice(0, 100), + reason + }) + }, + /** Gets the invites for this channel. Requires MANAGE_CHANNEL */ + get_invites: () => { + // TODO: Requires the MANAGE_CHANNELS permission + return client.RequestManager.get(endpoints.CHANNEL_INVITES(data.id)) + }, + /** Creates a new invite for this channel. Requires CREATE_INSTANT_INVITE */ + create_invite: (options: Create_Invite_Options) => { + // TODO: Requires CREATE_INSTANT_INVITE permissin. + return client.RequestManager.post(endpoints.CHANNEL_INVITES(data.id), options) + }, + /** Gets the webhooks for this channel. Requires MANAGE_WEBHOOKS */ + get_webhooks: () => { + // TODO: Requires MANAGE_WEBHOOKS + return client.RequestManager.get(endpoints.CHANNEL_WEBHOOKS(data.id)) + } } if (data.type === Channel_Types.GUILD_CATEGORY) return { ...base_guild_channel, + /** Gets an array of all the channels ids that are the children of this category. */ children_ids: () => Object.keys(guild.channels).filter(channel => guild.channels.get(channel).parent_id === data.id) } if (data.type === Channel_Types.GUILD_VOICE) return { - ...base_guild_channel + ...base_guild_channel, + // TODO: after learning opus and stuff + /** Join a voice channel. */ + join: () => {}, + /** Leave a voice channel */ + leave: () => {} } return { ...data, + /** The channel mention */ mention: () => `<#${data.id}>` } }