From e2ceefdc0a7efd4169290bd381177a2d737e5414 Mon Sep 17 00:00:00 2001 From: socram03 Date: Sat, 25 Jun 2022 13:31:24 -0400 Subject: [PATCH] feat: Channels structures --- structures/Channel.ts | 16 +++---- structures/DMChannel.ts | 22 +++++++++ structures/GuildChannel.ts | 24 +++++----- structures/NewsChannel.ts | 11 +++++ structures/TextChannel.ts | 89 +++++++++++++++++++++++++++++++------ structures/ThreadChannel.ts | 23 ++++++++++ structures/VoiceChannel.ts | 19 ++++++++ util/Routes.ts | 20 +++++++++ vendor/types/discord.ts | 2 + 9 files changed, 190 insertions(+), 36 deletions(-) create mode 100644 structures/DMChannel.ts create mode 100644 structures/NewsChannel.ts create mode 100644 structures/ThreadChannel.ts create mode 100644 structures/VoiceChannel.ts diff --git a/structures/Channel.ts b/structures/Channel.ts index f7d33f6..0013d98 100644 --- a/structures/Channel.ts +++ b/structures/Channel.ts @@ -1,20 +1,16 @@ import type { Model } from "./Base.ts"; import { Snowflake, Session, DiscordChannel, ChannelTypes } from "../mod.ts"; -export class Channel implements Model { +export abstract class Channel implements Model { constructor(session: Session, data: DiscordChannel) { this.id = data.id; - this.data = data; this.session = session; - this.name = this.data.name; + this.name = data.name; + this.type = data.type; } - readonly data: DiscordChannel; readonly id: Snowflake; readonly session: Session; - public readonly name: string | undefined; - - get type() { - return ChannelTypes[this.data.type]; - } - + readonly name: string | undefined; + readonly type: ChannelTypes; + } \ No newline at end of file diff --git a/structures/DMChannel.ts b/structures/DMChannel.ts new file mode 100644 index 0000000..4d4b758 --- /dev/null +++ b/structures/DMChannel.ts @@ -0,0 +1,22 @@ +import { Channel } from "./Channel.ts"; +//import { User } from "./User.ts"; +import { Session, DiscordChannel, Snowflake, Routes } from "../mod.ts"; + +export class DMChannel extends Channel { + constructor(session: Session, data: DiscordChannel) { + super(session, data); + data.last_message_id ? this.lastMessageId = data.last_message_id : undefined; + // Waiting for implementation of botId in session + //this.user = new User(this.session, data.recipents!.find((r) => r.id !== this.session.botId)); + } + lastMessageId?: Snowflake; + + async close() { + const channel = await this.session.rest.runMethod( + this.session.rest, + "DELETE", + Routes.CHANNEL(this.id) + ) + return new DMChannel(this.session, channel); + } +} \ No newline at end of file diff --git a/structures/GuildChannel.ts b/structures/GuildChannel.ts index 56529e2..a4a941c 100644 --- a/structures/GuildChannel.ts +++ b/structures/GuildChannel.ts @@ -1,21 +1,21 @@ import { Channel } from "./Channel.ts"; -import { DiscordChannel, Routes, Session } from "../mod.ts"; +import { Guild } from "./Guild.ts"; +import { DiscordChannel, Routes, Session, Snowflake } from "../mod.ts"; + export class GuildChannel extends Channel { - constructor(session: Session, data: DiscordChannel) { + constructor(session: Session, data: DiscordChannel, guild: Guild) { super(session, data); - this.guild_id = data.guild_id; + this.guildId = guild.id; + this.position = data.position; + data.topic ? this.topic = data.topic : null; + data.parent_id ? this.parentId = data.parent_id : undefined; } - guild_id?: string; - - get topic() { - return this.data.topic; - } - - get guildId() { - return this.guild_id; - } + guildId: Snowflake; + topic?: string; + position?: number; + parentId?: Snowflake; delete(reason?: string) { return this.session.rest.runMethod( diff --git a/structures/NewsChannel.ts b/structures/NewsChannel.ts new file mode 100644 index 0000000..ede8a7a --- /dev/null +++ b/structures/NewsChannel.ts @@ -0,0 +1,11 @@ +import { Guild } from "./Guild.ts"; +import { TextChannel } from "./TextChannel.ts" +import { Session, DiscordChannel } from "../mod.ts"; + +export class NewsChannel extends TextChannel { + constructor(session: Session, data: DiscordChannel , guild: Guild) { + super(session, data, guild); + this.defaultAutoArchiveDuration = data.default_auto_archive_duration; + } + defaultAutoArchiveDuration?: number; +} \ No newline at end of file diff --git a/structures/TextChannel.ts b/structures/TextChannel.ts index eff5c15..f901d57 100644 --- a/structures/TextChannel.ts +++ b/structures/TextChannel.ts @@ -1,27 +1,88 @@ import { GuildChannel } from "./GuildChannel.ts"; -import { DiscordChannel, Session } from "../mod.ts"; +import { Guild } from "./Guild.ts"; +import { ThreadChannel } from "./ThreadChannel.ts"; +import { Message } from "./Message.ts"; +import { + DiscordChannel, + DiscordInviteCreate, + Routes, + Session, + Snowflake, + DiscordMessage +} from "../mod.ts"; +import { GetMessagesOptions } from "../util/Routes.ts" + +export interface DiscordInvite { + max_age?: number; + max_uses?: number; + unique?: boolean; + temporary: boolean; + reason?: string; +} + +export interface ThreadCreateOptions { + name: string; + autoArchiveDuration: 60 | 1440 | 4320 | 10080; + type: 10 | 11 | 12; + invitable?: boolean; + reason?: string; +} export class TextChannel extends GuildChannel { - constructor(session: Session, data: DiscordChannel) { - super(session, data); + constructor(session: Session, data: DiscordChannel, guild: Guild) { + super(session, data, guild); + data.last_message_id ? this.lastMessageId = data.last_message_id : undefined; + data.last_pin_timestamp ? this.lastPinTimestamp = data.last_pin_timestamp : undefined; + this.rateLimitPerUser = data.rate_limit_per_user ?? 0; + this.nsfw = !!data.nsfw ?? false; } - get lastMessageId() { - return this.data.last_message_id; - } - get rateLimitPerUser() { - return this.data.rate_limit_per_user; + lastMessageId?: Snowflake; + lastPinTimestamp?: string; + rateLimitPerUser: number; + nsfw: boolean; + + async fetchPins(): Promise { + const messages = await this.session.rest.runMethod( + this.session.rest, + "GET", + Routes.CHANNEL_PINS(this.id), + ); + return messages[0] ? messages.map((x: DiscordMessage) => new Message(this.session, x)) : undefined; } - get parentId() { - return this.data.parent_id; + createInvite(options?: DiscordInvite) { + return this.session.rest.runMethod( + this.session.rest, + "POST", + Routes.CHANNEL_INVITES(this.id), + options, + ); } - get permissionOverwrites() { - return this.data.permission_overwrites; + createThread(options: ThreadCreateOptions) { + this.session.rest.runMethod( + this.session.rest, + "POST", + Routes.CHANNEL_CREATE_THREAD(this.id), + options, + ); } - get nsfw() { - return this.data.nsfw; + fetchMessages(options?: GetMessagesOptions) { + if (options?.limit! > 100) throw Error("Values must be between 0-100") + return this.session.rest.runMethod( + this.session.rest, + "GET", + Routes.CHANNEL_MESSAGES(this.id, options) + ) + } + + sendTyping() { + this.session.rest.runMethod( + this.session.rest, + "POST", + Routes.CHANNEL_TYPING(this.id), + ); } } diff --git a/structures/ThreadChannel.ts b/structures/ThreadChannel.ts new file mode 100644 index 0000000..50daa18 --- /dev/null +++ b/structures/ThreadChannel.ts @@ -0,0 +1,23 @@ +import { GuildChannel } from "./GuildChannel.ts"; +import { Guild } from "./Guild.ts"; +import { DiscordChannel, Session, Snowflake } from "../mod.ts"; + +export class ThreadChannel extends GuildChannel { + constructor(session: Session, data: DiscordChannel, guild: Guild) { + super(session, data, guild); + this.archived = !!data.thread_metadata?.archived; + this.archiveTimestamp = data.thread_metadata?.archive_timestamp; + this.autoArchiveDuration = data.thread_metadata?.auto_archive_duration; + this.locked = !!data.thread_metadata?.locked; + this.messageCount = data.message_count; + this.memberCount = data.member_count; + this.ownerId = data.owner_id; + } + archived?: boolean; + archiveTimestamp?: string; + autoArchiveDuration?: number; + locked?: boolean; + messageCount?: number; + memberCount?: number; + ownerId?: Snowflake; +} diff --git a/structures/VoiceChannel.ts b/structures/VoiceChannel.ts new file mode 100644 index 0000000..8496cd7 --- /dev/null +++ b/structures/VoiceChannel.ts @@ -0,0 +1,19 @@ +import { GuildChannel } from "./GuildChannel.ts"; +import { Guild } from "./Guild.ts"; +import { DiscordChannel, Session, VideoQualityModes } from "../mod.ts"; + +export class VoiceChannel extends GuildChannel { + constructor(session: Session, data: DiscordChannel, guild: Guild) { + super(session, data, guild); + this.bitRate = data.bitrate; + this.userLimit = data.user_limit; + data.rtc_region ? this.rtcRegion = data.rtc_region : undefined; + this.videoQuality = data.video_quality_mode; + this.nsfw = !!data.nsfw; + } + bitRate?: number; + userLimit?: number; + rtcRegion?: string; + videoQuality?: VideoQualityModes; + nsfw?: boolean; +} diff --git a/util/Routes.ts b/util/Routes.ts index d207558..ae76a34 100644 --- a/util/Routes.ts +++ b/util/Routes.ts @@ -30,6 +30,26 @@ export function CHANNEL(channelId: Snowflake) { return `/channels/${channelId}`; } +export function CHANNEL_INVITES(channelId: Snowflake) { + return `/channels/${channelId}/invites`; +} + +export function CHANNEL_TYPING(channelId: Snowflake) { + return `/channels/${channelId}/typing`; +} + +export function CHANNEL_CREATE_THREAD(channelId: Snowflake) { + return `/channels/${channelId}/threads`; +} + +export function MESSAGE_CREATE_THREAD(channelId: Snowflake, messageId: Snowflake) { + return `/channels/${channelId}/messages/${messageId}/threads`; +} + +export function CHANNEL_PINS(channelId: Snowflake) { + return `/channels/${channelId}/pins`; +} + /** used to send messages */ export function CHANNEL_MESSAGES(channelId: Snowflake, options?: GetMessagesOptions) { let url = `/channels/${channelId}/messages?`; diff --git a/vendor/types/discord.ts b/vendor/types/discord.ts index 5fec56a..5123cbb 100644 --- a/vendor/types/discord.ts +++ b/vendor/types/discord.ts @@ -752,6 +752,8 @@ export interface DiscordChannel { permissions?: string; /** When a thread is created this will be true on that channel payload for the thread. */ newly_created?: boolean; + /** The recipients of the DM*/ + recipents?: DiscordUser[]; } /** https://discord.com/developers/docs/topics/gateway#presence-update */