From 837f045bddafc16199eb48c66cd805c7781c7b66 Mon Sep 17 00:00:00 2001
From: Helloyunho <yunho050840@gmail.com>
Date: Sun, 20 Dec 2020 17:13:25 +0900
Subject: [PATCH 1/4] Remove nsfw property in some channels

Some guild channels can't be a nsfw channel
---
 src/types/channel.ts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/types/channel.ts b/src/types/channel.ts
index 534a5ee..f72e024 100644
--- a/src/types/channel.ts
+++ b/src/types/channel.ts
@@ -18,13 +18,13 @@ export interface GuildChannelPayload extends ChannelPayload {
   name: string
   position: number
   permission_overwrites: Overwrite[]
-  nsfw: boolean
   parent_id?: string
 }
 
 export interface GuildTextChannelPayload
   extends TextChannelPayload,
     GuildChannelPayload {
+  nsfw: boolean
   rate_limit_per_user: number
   topic?: string
 }
@@ -33,6 +33,7 @@ export interface GuildNewsChannelPayload
   extends TextChannelPayload,
     GuildChannelPayload {
   topic?: string
+  nsfw: boolean
 }
 
 export interface GuildVoiceChannelPayload extends GuildChannelPayload {

From dd70d96d50854c3aec2f6a8be7713c5f4cc3df29 Mon Sep 17 00:00:00 2001
From: Helloyunho <yunho050840@gmail.com>
Date: Sun, 20 Dec 2020 17:14:05 +0900
Subject: [PATCH 2/4] Change category channel payload name

---
 src/types/channel.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/types/channel.ts b/src/types/channel.ts
index f72e024..fd792ca 100644
--- a/src/types/channel.ts
+++ b/src/types/channel.ts
@@ -51,7 +51,7 @@ export interface GroupDMChannelPayload extends DMChannelPayload {
   owner_id: string
 }
 
-export interface GuildChannelCategoryPayload
+export interface GuildCategoryChannelPayload
   extends ChannelPayload,
     GuildChannelPayload {}
 

From dced786e60cfffe0899ed8de320837b9383130c8 Mon Sep 17 00:00:00 2001
From: Helloyunho <yunho050840@gmail.com>
Date: Sun, 20 Dec 2020 17:14:57 +0900
Subject: [PATCH 3/4] Add interfaces for channel edit

---
 src/types/channel.ts | 55 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/src/types/channel.ts b/src/types/channel.ts
index fd792ca..103222a 100644
--- a/src/types/channel.ts
+++ b/src/types/channel.ts
@@ -55,6 +55,61 @@ export interface GuildCategoryChannelPayload
   extends ChannelPayload,
     GuildChannelPayload {}
 
+export interface ModifyChannelPayload {
+  name?: string
+  position?: number | null
+  permission_overwrites?: Overwrite[] | null
+  parent_id?: string
+}
+
+export interface ModifyGuildCategoryChannelPayload
+  extends ModifyChannelPayload {}
+
+export interface ModifyGuildTextChannelPayload extends ModifyChannelPayload {
+  type?: number
+  topic?: string | null
+  nsfw?: boolean | null
+  rate_limit_per_user?: number | null
+}
+
+export interface ModifyGuildNewsChannelPayload extends ModifyChannelPayload {
+  type?: number
+  topic?: string | null
+  nsfw?: boolean | null
+}
+
+export interface ModifyVoiceChannelPayload extends ModifyChannelPayload {
+  bitrate?: number | null
+  user_limit?: number | null
+}
+
+export interface ModifyChannelOption {
+  name?: string
+  position?: number | null
+  permissionOverwrites?: Overwrite[] | null
+  parentID?: string
+}
+
+export interface ModifyGuildCategoryChannelOption extends ModifyChannelOption {}
+
+export interface ModifyGuildTextChannelOption extends ModifyChannelOption {
+  type?: number
+  topic?: string | null
+  nsfw?: boolean | null
+  rateLimitPerUser?: number | null
+}
+
+export interface ModifyGuildNewsChannelOption extends ModifyChannelOption {
+  type?: number
+  topic?: string | null
+  nsfw?: boolean | null
+}
+
+export interface ModifyVoiceChannelOption extends ModifyChannelOption {
+  bitrate?: number | null
+  userLimit?: number | null
+}
+
 export interface Overwrite {
   id: string
   type: number

From 9688d248e3d06e1534d63930d13b62b3ad30bcfe Mon Sep 17 00:00:00 2001
From: Helloyunho <yunho050840@gmail.com>
Date: Sun, 20 Dec 2020 18:11:37 +0900
Subject: [PATCH 4/4] Add edit channel feature

---
 mod.ts                                        |  2 +-
 .../handlers/guildIntegrationsUpdate.ts       |  1 -
 src/managers/guildChannels.ts                 |  4 +--
 src/structures/guildCategoryChannel.ts        | 30 +++++++++++++----
 src/structures/guildNewsChannel.ts            | 24 +++++++++++++-
 src/structures/guildVoiceChannel.ts           | 26 ++++++++++++---
 src/structures/textChannel.ts                 | 23 ++++++++++++-
 src/test/index.ts                             | 32 +++++++++++++++----
 src/utils/getChannelByType.ts                 |  6 ++--
 9 files changed, 122 insertions(+), 26 deletions(-)

diff --git a/mod.ts b/mod.ts
index 91ddb18..2c2e779 100644
--- a/mod.ts
+++ b/mod.ts
@@ -92,7 +92,7 @@ export type {
   ChannelPayload,
   FollowedChannel,
   GuildNewsChannelPayload,
-  GuildChannelCategoryPayload,
+  GuildCategoryChannelPayload,
   GuildChannelPayload,
   GuildTextChannelPayload,
   GuildVoiceChannelPayload,
diff --git a/src/gateway/handlers/guildIntegrationsUpdate.ts b/src/gateway/handlers/guildIntegrationsUpdate.ts
index 0cc31ee..cbef290 100644
--- a/src/gateway/handlers/guildIntegrationsUpdate.ts
+++ b/src/gateway/handlers/guildIntegrationsUpdate.ts
@@ -6,7 +6,6 @@ export const guildIntegrationsUpdate: GatewayEventHandler = async (
   gateway: Gateway,
   d: GuildIntegrationsUpdatePayload
 ) => {
-  console.log(d)
   const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
   if (guild === undefined) return
 
diff --git a/src/managers/guildChannels.ts b/src/managers/guildChannels.ts
index cc7749c..a6854a8 100644
--- a/src/managers/guildChannels.ts
+++ b/src/managers/guildChannels.ts
@@ -5,7 +5,7 @@ import { CategoryChannel } from '../structures/guildCategoryChannel.ts'
 import { GuildTextChannel } from '../structures/textChannel.ts'
 import { VoiceChannel } from '../structures/guildVoiceChannel.ts'
 import {
-  GuildChannelCategoryPayload,
+  GuildCategoryChannelPayload,
   GuildTextChannelPayload,
   GuildVoiceChannelPayload
 } from '../types/channel.ts'
@@ -16,7 +16,7 @@ import { ChannelsManager } from './channels.ts'
 export type GuildChannelPayloads =
   | GuildTextChannelPayload
   | GuildVoiceChannelPayload
-  | GuildChannelCategoryPayload
+  | GuildCategoryChannelPayload
 export type GuildChannel = GuildTextChannel | VoiceChannel | CategoryChannel
 
 export class GuildChannelsManager extends BaseChildManager<
diff --git a/src/structures/guildCategoryChannel.ts b/src/structures/guildCategoryChannel.ts
index 104b70b..46e4a30 100644
--- a/src/structures/guildCategoryChannel.ts
+++ b/src/structures/guildCategoryChannel.ts
@@ -1,38 +1,56 @@
 import { Client } from '../models/client.ts'
 import { Channel } from './channel.ts'
-import { GuildChannelCategoryPayload, Overwrite } from '../types/channel.ts'
+import {
+  GuildCategoryChannelPayload,
+  ModifyGuildCategoryChannelOption,
+  ModifyGuildCategoryChannelPayload,
+  Overwrite
+} from '../types/channel.ts'
 import { Guild } from './guild.ts'
+import { CHANNEL } from '../types/endpoint.ts'
 
 export class CategoryChannel extends Channel {
   guildID: string
   name: string
   position: number
   permissionOverwrites: Overwrite[]
-  nsfw: boolean
   guild: Guild
   parentID?: string
 
-  constructor(client: Client, data: GuildChannelCategoryPayload, guild: Guild) {
+  constructor(client: Client, data: GuildCategoryChannelPayload, guild: Guild) {
     super(client, data)
     this.guildID = data.guild_id
     this.name = data.name
     this.guild = guild
     this.position = data.position
     this.permissionOverwrites = data.permission_overwrites
-    this.nsfw = data.nsfw
     this.parentID = data.parent_id
     // TODO: Cache in Gateway Event Code
     // cache.set('guildcategorychannel', this.id, this)
   }
 
-  readFromData(data: GuildChannelCategoryPayload): void {
+  readFromData(data: GuildCategoryChannelPayload): void {
     super.readFromData(data)
     this.guildID = data.guild_id ?? this.guildID
     this.name = data.name ?? this.name
     this.position = data.position ?? this.position
     this.permissionOverwrites =
       data.permission_overwrites ?? this.permissionOverwrites
-    this.nsfw = data.nsfw ?? this.nsfw
     this.parentID = data.parent_id ?? this.parentID
   }
+
+  async edit(
+    options?: ModifyGuildCategoryChannelOption
+  ): Promise<CategoryChannel> {
+    const body: ModifyGuildCategoryChannelPayload = {
+      name: options?.name,
+      position: options?.position,
+      permission_overwrites: options?.permissionOverwrites,
+      parent_id: options?.parentID
+    }
+
+    const resp = await this.client.rest.patch(CHANNEL(this.id), body)
+
+    return new CategoryChannel(this.client, resp, this.guild)
+  }
 }
diff --git a/src/structures/guildNewsChannel.ts b/src/structures/guildNewsChannel.ts
index e9bbf72..e6d312e 100644
--- a/src/structures/guildNewsChannel.ts
+++ b/src/structures/guildNewsChannel.ts
@@ -1,5 +1,11 @@
 import { Client } from '../models/client.ts'
-import { GuildNewsChannelPayload, Overwrite } from '../types/channel.ts'
+import {
+  GuildNewsChannelPayload,
+  ModifyGuildNewsChannelOption,
+  ModifyGuildNewsChannelPayload,
+  Overwrite
+} from '../types/channel.ts'
+import { CHANNEL } from '../types/endpoint.ts'
 import { Guild } from './guild.ts'
 import { TextChannel } from './textChannel.ts'
 
@@ -36,4 +42,20 @@ export class NewsChannel extends TextChannel {
     this.parentID = data.parent_id ?? this.parentID
     this.topic = data.topic ?? this.topic
   }
+
+  async edit(options?: ModifyGuildNewsChannelOption): Promise<NewsChannel> {
+    const body: ModifyGuildNewsChannelPayload = {
+      name: options?.name,
+      position: options?.position,
+      permission_overwrites: options?.permissionOverwrites,
+      parent_id: options?.parentID,
+      type: options?.type,
+      topic: options?.topic,
+      nsfw: options?.nsfw
+    }
+
+    const resp = await this.client.rest.patch(CHANNEL(this.id), body)
+
+    return new NewsChannel(this.client, resp, this.guild)
+  }
 }
diff --git a/src/structures/guildVoiceChannel.ts b/src/structures/guildVoiceChannel.ts
index ee47e95..eb5dc7e 100644
--- a/src/structures/guildVoiceChannel.ts
+++ b/src/structures/guildVoiceChannel.ts
@@ -1,7 +1,13 @@
 import { VoiceServerUpdateData } from '../gateway/handlers/index.ts'
 import { VoiceStateOptions } from '../gateway/index.ts'
 import { Client } from '../models/client.ts'
-import { GuildVoiceChannelPayload, Overwrite } from '../types/channel.ts'
+import {
+  GuildVoiceChannelPayload,
+  ModifyVoiceChannelOption,
+  ModifyVoiceChannelPayload,
+  Overwrite
+} from '../types/channel.ts'
+import { CHANNEL } from '../types/endpoint.ts'
 import { Channel } from './channel.ts'
 import { Guild } from './guild.ts'
 import { VoiceState } from './voiceState.ts'
@@ -14,7 +20,6 @@ export class VoiceChannel extends Channel {
   guild: Guild
   position: number
   permissionOverwrites: Overwrite[]
-  nsfw: boolean
   parentID?: string
 
   constructor(client: Client, data: GuildVoiceChannelPayload, guild: Guild) {
@@ -26,7 +31,6 @@ export class VoiceChannel extends Channel {
     this.position = data.position
     this.guild = guild
     this.permissionOverwrites = data.permission_overwrites
-    this.nsfw = data.nsfw
     this.parentID = data.parent_id
     // TODO: Cache in Gateway Event Code
     // cache.set('guildvoicechannel', this.id, this)
@@ -85,7 +89,21 @@ export class VoiceChannel extends Channel {
     this.position = data.position ?? this.position
     this.permissionOverwrites =
       data.permission_overwrites ?? this.permissionOverwrites
-    this.nsfw = data.nsfw ?? this.nsfw
     this.parentID = data.parent_id ?? this.parentID
   }
+
+  async edit(options?: ModifyVoiceChannelOption): Promise<VoiceChannel> {
+    const body: ModifyVoiceChannelPayload = {
+      name: options?.name,
+      position: options?.position,
+      permission_overwrites: options?.permissionOverwrites,
+      parent_id: options?.parentID,
+      bitrate: options?.bitrate,
+      user_limit: options?.userLimit
+    }
+
+    const resp = await this.client.rest.patch(CHANNEL(this.id), body)
+
+    return new VoiceChannel(this.client, resp, this.guild)
+  }
 }
diff --git a/src/structures/textChannel.ts b/src/structures/textChannel.ts
index 5fed099..699b4ad 100644
--- a/src/structures/textChannel.ts
+++ b/src/structures/textChannel.ts
@@ -4,10 +4,16 @@ import {
   GuildTextChannelPayload,
   MessageOption,
   MessageReference,
+  ModifyGuildTextChannelOption,
+  ModifyGuildTextChannelPayload,
   Overwrite,
   TextChannelPayload
 } from '../types/channel.ts'
-import { CHANNEL_MESSAGE, CHANNEL_MESSAGES } from '../types/endpoint.ts'
+import {
+  CHANNEL,
+  CHANNEL_MESSAGE,
+  CHANNEL_MESSAGES
+} from '../types/endpoint.ts'
 import { Channel } from './channel.ts'
 import { Embed } from './embed.ts'
 import { Guild } from './guild.ts'
@@ -164,4 +170,19 @@ export class GuildTextChannel extends TextChannel {
     this.topic = data.topic ?? this.topic
     this.rateLimit = data.rate_limit_per_user ?? this.rateLimit
   }
+
+  async edit(
+    options?: ModifyGuildTextChannelOption
+  ): Promise<GuildTextChannel> {
+    const body: ModifyGuildTextChannelPayload = {
+      name: options?.name,
+      position: options?.position,
+      permission_overwrites: options?.permissionOverwrites,
+      parent_id: options?.parentID
+    }
+
+    const resp = await this.client.rest.patch(CHANNEL(this.id), body)
+
+    return new GuildTextChannel(this.client, resp, this.guild)
+  }
 }
diff --git a/src/test/index.ts b/src/test/index.ts
index 5d0456e..f42d145 100644
--- a/src/test/index.ts
+++ b/src/test/index.ts
@@ -34,14 +34,12 @@ client.on('channelUpdate', (b: EveryChannelTypes, a: EveryChannelTypes) => {
   if (b.type === ChannelTypes.GUILD_TEXT) {
     const before = (b as unknown) as GuildTextChannel
     const after = (a as unknown) as GuildTextChannel
-    console.log(
-      before.send('', {
-        embed: new Embed({
-          title: 'Channel Update',
-          description: `Name Before: ${before.name}\nName After: ${after.name}`
-        })
+    before.send('', {
+      embed: new Embed({
+        title: 'Channel Update',
+        description: `Name Before: ${before.name}\nName After: ${after.name}`
       })
-    )
+    })
   }
 })
 
@@ -94,6 +92,26 @@ client.on('messageCreate', async (msg: Message) => {
       })
       .join('\n') as string
     msg.channel.send('Channels List:\n' + data)
+  } else if (msg.content === '!messages') {
+    const col = await msg.channel.messages.array()
+    const data = col
+      ?.slice(-5)
+      .map((c: Message, i: number) => {
+        return `${i + 1}. ${c.content}`
+      })
+      .join('\n') as string
+    msg.channel.send('Top 5 Message List:\n' + data)
+  } else if (msg.content === '!editChannel') {
+    // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
+    const channel = msg.channel as GuildTextChannel
+    const newChannel = await channel.edit({
+      name: 'gggg'
+    })
+    if (newChannel.name === 'gggg') {
+      msg.channel.send('Done!')
+    } else {
+      msg.channel.send('Failed...')
+    }
   }
 })
 
diff --git a/src/utils/getChannelByType.ts b/src/utils/getChannelByType.ts
index 3915d92..0e5ac9c 100644
--- a/src/utils/getChannelByType.ts
+++ b/src/utils/getChannelByType.ts
@@ -4,7 +4,7 @@ import {
   ChannelTypes,
   DMChannelPayload,
   GroupDMChannelPayload,
-  GuildChannelCategoryPayload,
+  GuildCategoryChannelPayload,
   GuildNewsChannelPayload,
   GuildTextChannelPayload,
   GuildVoiceChannelPayload,
@@ -41,7 +41,7 @@ export type EveryChannelTypes =
 
 export type EveryChannelPayloadTypes =
   | ChannelPayload
-  | GuildChannelCategoryPayload
+  | GuildCategoryChannelPayload
   | GuildVoiceChannelPayload
   | EveryTextChannelPayloadTypes
 
@@ -57,7 +57,7 @@ const getChannelByType = (
         throw new Error('No Guild was provided to construct Channel')
       return new CategoryChannel(
         client,
-        data as GuildChannelCategoryPayload,
+        data as GuildCategoryChannelPayload,
         guild
       )
     case ChannelTypes.GUILD_NEWS: