harmony/src/managers/channels.ts

200 lines
5.9 KiB
TypeScript
Raw Normal View History

2021-04-04 05:42:15 +00:00
import { Client } from '../client/mod.ts'
2020-11-08 07:57:24 +00:00
import { Channel } from '../structures/channel.ts'
2021-03-19 10:50:16 +00:00
import { Embed } from '../structures/embed.ts'
import { Message } from '../structures/message.ts'
2021-04-04 09:29:56 +00:00
import type { TextChannel } from '../structures/textChannel.ts'
2021-04-30 06:05:19 +00:00
import type { User } from '../structures/user.ts'
2021-04-04 09:29:56 +00:00
import type {
2021-03-19 10:50:16 +00:00
ChannelPayload,
GuildChannelPayload,
2021-03-19 11:18:11 +00:00
MessageOptions
2021-03-19 10:50:16 +00:00
} from '../types/channel.ts'
2020-11-08 07:57:24 +00:00
import { CHANNEL } from '../types/endpoint.ts'
2021-04-04 11:27:02 +00:00
import getChannelByType from '../utils/channel.ts'
2020-11-08 07:57:24 +00:00
import { BaseManager } from './base.ts'
2021-03-19 10:50:16 +00:00
export type AllMessageOptions = MessageOptions | Embed
export class ChannelsManager extends BaseManager<ChannelPayload, Channel> {
2020-12-02 12:29:52 +00:00
constructor(client: Client) {
2020-11-25 11:53:40 +00:00
super(client, 'channels', Channel)
}
2021-04-30 06:05:19 +00:00
async getUserDM(user: User | string): Promise<string | undefined> {
return this.client.cache.get(
'user_dms',
typeof user === 'string' ? user : user.id
)
}
async setUserDM(user: User | string, id: string): Promise<void> {
await this.client.cache.set(
'user_dms',
typeof user === 'string' ? user : user.id,
id
)
}
// Override get method as Generic
2020-12-02 12:29:52 +00:00
async get<T = Channel>(key: string): Promise<T | undefined> {
2020-11-03 09:21:29 +00:00
const data = await this._get(key)
2020-11-03 15:19:20 +00:00
if (data === undefined) return
let guild
2020-11-25 11:53:40 +00:00
if ('guild_id' in data) {
guild = await this.client.guilds.get(
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
(data as GuildChannelPayload).guild_id
)
}
2020-11-03 09:21:29 +00:00
const res = getChannelByType(this.client, data, guild)
return res as any
}
2020-12-19 07:58:40 +00:00
async array(): Promise<Channel[]> {
2020-11-25 11:53:40 +00:00
const arr = await (this.client.cache.array(
this.cacheName
) as ChannelPayload[])
if (arr === undefined) return []
2020-11-03 09:21:29 +00:00
const result: any[] = []
2020-11-03 23:00:03 +00:00
for (const elem of arr) {
let guild
2020-11-25 11:53:40 +00:00
if ('guild_id' in elem) {
guild = await this.client.guilds.get(
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
(elem as GuildChannelPayload).guild_id
)
}
2020-11-03 09:21:29 +00:00
result.push(getChannelByType(this.client, elem, guild))
}
return result
}
2020-12-05 02:39:37 +00:00
/** Fetches a Channel by ID, cache it, resolve it */
2020-12-02 12:29:52 +00:00
async fetch<T = Channel>(id: string): Promise<T> {
2020-11-03 09:21:29 +00:00
return await new Promise((resolve, reject) => {
2020-11-25 11:53:40 +00:00
this.client.rest
.get(CHANNEL(id))
2020-12-02 12:29:52 +00:00
.then(async (data) => {
2020-11-25 11:53:40 +00:00
this.set(id, data as ChannelPayload)
let guild
if (data.guild_id !== undefined) {
guild = await this.client.guilds.get(data.guild_id)
}
2020-12-02 12:29:52 +00:00
resolve(
(getChannelByType(
this.client,
data as ChannelPayload,
guild
) as unknown) as T
)
2020-11-25 11:53:40 +00:00
})
2020-12-02 12:29:52 +00:00
.catch((e) => reject(e))
})
}
2021-03-19 10:50:16 +00:00
async sendMessage(
channel: string | TextChannel,
content?: string | AllMessageOptions,
2021-03-19 11:18:11 +00:00
option?: AllMessageOptions
2021-03-19 10:50:16 +00:00
): Promise<Message> {
const channelID = typeof channel === 'string' ? channel : channel.id
if (typeof content === 'object') {
option = content
content = undefined
}
if (content === undefined && option === undefined) {
throw new Error('Either text or option is necessary.')
}
if (option instanceof Embed) {
option = {
embed: option
}
}
const payload: any = {
2021-04-30 06:05:19 +00:00
content: content ?? option?.content,
2021-03-19 10:50:16 +00:00
embed: option?.embed,
file: option?.file,
files: option?.files,
tts: option?.tts,
2021-03-19 11:18:11 +00:00
allowed_mentions: option?.allowedMentions,
message_reference:
option?.reply === undefined
? undefined
: typeof option.reply === 'string'
? {
message_id: option.reply
}
: typeof option.reply === 'object'
? option.reply instanceof Message
? {
message_id: option.reply.id,
channel_id: option.reply.channel.id,
guild_id: option.reply.guild?.id
}
: option.reply
: undefined
2021-03-19 10:50:16 +00:00
}
2021-04-08 08:52:33 +00:00
if (payload.content === undefined && payload.embed === undefined) {
payload.content = ''
}
2021-03-19 10:50:16 +00:00
const resp = await this.client.rest.api.channels[channelID].messages.post(
payload
)
const chan =
typeof channel === 'string'
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
(await this.get<TextChannel>(channel))!
: channel
const res = new Message(this.client, resp, chan, this.client.user as any)
await res.mentions.fromPayload(resp)
return res
}
async editMessage(
channel: string | TextChannel,
message: Message | string,
2021-03-19 11:21:25 +00:00
text?: string | MessageOptions,
2021-03-19 10:50:16 +00:00
option?: MessageOptions
): Promise<Message> {
const channelID = typeof channel === 'string' ? channel : channel.id
if (text === undefined && option === undefined) {
throw new Error('Either text or option is necessary.')
}
if (this.client.user === undefined) {
throw new Error('Client user has not initialized.')
}
2021-03-19 11:21:25 +00:00
if (typeof text === 'object') {
if (typeof option === 'object') Object.assign(option, text)
else option = text
text = undefined
}
2021-03-19 10:50:16 +00:00
const newMsg = await this.client.rest.api.channels[channelID].messages[
typeof message === 'string' ? message : message.id
].patch({
2021-04-30 06:05:19 +00:00
content: text ?? option?.content,
2021-03-19 10:50:16 +00:00
embed: option?.embed !== undefined ? option.embed.toJSON() : undefined,
// Cannot upload new files with Message
// file: option?.file,
tts: option?.tts,
allowed_mentions: option?.allowedMentions
})
const chan =
typeof channel === 'string'
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
(await this.get<TextChannel>(channel))!
: channel
const res = new Message(this.client, newMsg, chan, this.client.user)
await res.mentions.fromPayload(newMsg)
return res
}
}