2021-01-25 11:28:46 +00:00
|
|
|
import { SnowflakeBase } from './base.ts'
|
2020-12-02 12:29:52 +00:00
|
|
|
import {
|
|
|
|
Attachment,
|
|
|
|
MessageActivity,
|
|
|
|
MessageApplication,
|
2021-03-26 07:17:11 +00:00
|
|
|
MessageInteractionPayload,
|
2021-01-24 14:20:49 +00:00
|
|
|
MessageOptions,
|
2020-12-02 12:29:52 +00:00
|
|
|
MessagePayload,
|
|
|
|
MessageReference
|
|
|
|
} from '../types/channel.ts'
|
|
|
|
import { Client } from '../models/client.ts'
|
|
|
|
import { User } from './user.ts'
|
|
|
|
import { Member } from './member.ts'
|
|
|
|
import { Embed } from './embed.ts'
|
|
|
|
import { CHANNEL_MESSAGE } from '../types/endpoint.ts'
|
|
|
|
import { MessageMentions } from './messageMentions.ts'
|
2021-03-19 15:39:14 +00:00
|
|
|
import { TextChannel } from './textChannel.ts'
|
|
|
|
import { GuildTextBasedChannel } from './guildTextChannel.ts'
|
2020-12-02 12:29:52 +00:00
|
|
|
import { Guild } from './guild.ts'
|
|
|
|
import { MessageReactionsManager } from '../managers/messageReactions.ts'
|
2020-12-17 01:20:06 +00:00
|
|
|
import { MessageSticker } from './messageSticker.ts'
|
2020-12-24 00:37:57 +00:00
|
|
|
import { Emoji } from './emoji.ts'
|
2021-03-26 07:17:11 +00:00
|
|
|
import { InteractionType } from '../types/slash.ts'
|
2021-04-04 04:51:39 +00:00
|
|
|
import { encodeText } from '../utils/encoding.ts'
|
2020-12-02 12:29:52 +00:00
|
|
|
|
2021-01-24 14:20:49 +00:00
|
|
|
type AllMessageOptions = MessageOptions | Embed
|
2020-12-02 12:29:52 +00:00
|
|
|
|
2021-03-26 07:17:11 +00:00
|
|
|
export class MessageInteraction extends SnowflakeBase {
|
|
|
|
id: string
|
|
|
|
name: string
|
|
|
|
type: InteractionType
|
|
|
|
user: User
|
|
|
|
|
|
|
|
constructor(client: Client, data: MessageInteractionPayload) {
|
|
|
|
super(client)
|
|
|
|
this.id = data.id
|
|
|
|
this.name = data.name
|
|
|
|
this.type = data.type
|
|
|
|
this.user = new User(this.client, data.user)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-25 11:28:46 +00:00
|
|
|
export class Message extends SnowflakeBase {
|
2020-12-02 12:29:52 +00:00
|
|
|
id: string
|
|
|
|
channelID: string
|
|
|
|
channel: TextChannel
|
|
|
|
guildID?: string
|
|
|
|
guild?: Guild
|
|
|
|
author: User
|
|
|
|
member?: Member
|
|
|
|
content: string
|
2021-01-25 11:34:43 +00:00
|
|
|
editedTimestamp?: Date
|
2020-12-02 12:29:52 +00:00
|
|
|
tts: boolean
|
|
|
|
mentions: MessageMentions
|
|
|
|
attachments: Attachment[]
|
|
|
|
embeds: Embed[]
|
|
|
|
reactions: MessageReactionsManager
|
|
|
|
nonce?: string | number
|
|
|
|
pinned: boolean
|
|
|
|
webhookID?: string
|
|
|
|
type: number
|
|
|
|
activity?: MessageActivity
|
|
|
|
application?: MessageApplication
|
|
|
|
messageReference?: MessageReference
|
|
|
|
flags?: number
|
2020-12-17 01:20:06 +00:00
|
|
|
stickers?: MessageSticker[]
|
2021-03-26 07:17:11 +00:00
|
|
|
interaction?: MessageInteraction
|
2020-12-02 12:29:52 +00:00
|
|
|
|
2020-12-22 10:10:19 +00:00
|
|
|
get createdAt(): Date {
|
|
|
|
return new Date(this.timestamp)
|
|
|
|
}
|
|
|
|
|
2020-12-02 12:29:52 +00:00
|
|
|
constructor(
|
|
|
|
client: Client,
|
|
|
|
data: MessagePayload,
|
|
|
|
channel: TextChannel,
|
|
|
|
author: User
|
|
|
|
) {
|
|
|
|
super(client)
|
|
|
|
this.id = data.id
|
|
|
|
this.channelID = data.channel_id
|
|
|
|
this.guildID = data.guild_id
|
|
|
|
this.author = author
|
|
|
|
this.content = data.content
|
2021-01-25 11:34:43 +00:00
|
|
|
this.editedTimestamp =
|
|
|
|
data.edited_timestamp === undefined
|
|
|
|
? undefined
|
|
|
|
: new Date(data.edited_timestamp)
|
2020-12-02 12:29:52 +00:00
|
|
|
this.tts = data.tts
|
|
|
|
this.mentions = new MessageMentions(this.client, this)
|
|
|
|
this.attachments = data.attachments
|
|
|
|
this.embeds = data.embeds.map((v) => new Embed(v))
|
|
|
|
this.reactions = new MessageReactionsManager(this.client, this)
|
|
|
|
this.nonce = data.nonce
|
|
|
|
this.pinned = data.pinned
|
|
|
|
this.webhookID = data.webhook_id
|
|
|
|
this.type = data.type
|
|
|
|
this.activity = data.activity
|
|
|
|
this.application = data.application
|
|
|
|
this.messageReference = data.message_reference
|
|
|
|
this.flags = data.flags
|
|
|
|
this.channel = channel
|
2020-12-17 01:20:06 +00:00
|
|
|
this.stickers =
|
|
|
|
data.stickers !== undefined
|
|
|
|
? data.stickers.map(
|
|
|
|
(payload) => new MessageSticker(this.client, payload)
|
|
|
|
)
|
|
|
|
: undefined
|
2021-03-26 07:17:11 +00:00
|
|
|
this.interaction =
|
|
|
|
data.interaction === undefined
|
|
|
|
? undefined
|
|
|
|
: new MessageInteraction(this.client, data.interaction)
|
2020-12-02 12:29:52 +00:00
|
|
|
}
|
|
|
|
|
2020-12-03 05:28:20 +00:00
|
|
|
readFromData(data: MessagePayload): void {
|
2020-12-02 12:29:52 +00:00
|
|
|
this.channelID = data.channel_id ?? this.channelID
|
|
|
|
this.guildID = data.guild_id ?? this.guildID
|
|
|
|
this.content = data.content ?? this.content
|
2021-01-25 11:34:43 +00:00
|
|
|
this.editedTimestamp =
|
|
|
|
data.edited_timestamp === undefined
|
|
|
|
? this.editedTimestamp
|
|
|
|
: new Date(data.edited_timestamp)
|
2020-12-02 12:29:52 +00:00
|
|
|
this.tts = data.tts ?? this.tts
|
|
|
|
this.attachments = data.attachments ?? this.attachments
|
|
|
|
this.embeds = data.embeds.map((v) => new Embed(v)) ?? this.embeds
|
|
|
|
this.nonce = data.nonce ?? this.nonce
|
|
|
|
this.pinned = data.pinned ?? this.pinned
|
|
|
|
this.webhookID = data.webhook_id ?? this.webhookID
|
|
|
|
this.type = data.type ?? this.type
|
|
|
|
this.activity = data.activity ?? this.activity
|
|
|
|
this.application = data.application ?? this.application
|
|
|
|
this.messageReference = data.message_reference ?? this.messageReference
|
|
|
|
this.flags = data.flags ?? this.flags
|
2020-12-17 01:20:06 +00:00
|
|
|
this.stickers =
|
|
|
|
data.stickers !== undefined
|
|
|
|
? data.stickers.map(
|
|
|
|
(payload) => new MessageSticker(this.client, payload)
|
|
|
|
)
|
|
|
|
: this.stickers
|
2020-12-02 12:29:52 +00:00
|
|
|
}
|
|
|
|
|
2021-02-06 13:55:45 +00:00
|
|
|
async updateRefs(): Promise<void> {
|
|
|
|
if (this.guildID !== undefined)
|
|
|
|
this.guild = await this.client.guilds.get(this.guildID)
|
|
|
|
const newVal = await this.client.channels.get<TextChannel>(this.channelID)
|
|
|
|
if (newVal !== undefined) this.channel = newVal
|
|
|
|
const newUser = await this.client.users.get(this.author.id)
|
|
|
|
if (newUser !== undefined) this.author = newUser
|
|
|
|
if (this.member !== undefined) {
|
|
|
|
const newMember = await this.guild?.members.get(this.member?.id)
|
|
|
|
if (newMember !== undefined) this.member = newMember
|
|
|
|
}
|
2021-03-19 15:39:14 +00:00
|
|
|
if (
|
|
|
|
((this.channel as unknown) as GuildTextBasedChannel).guild !== undefined
|
|
|
|
)
|
|
|
|
this.guild = ((this.channel as unknown) as GuildTextBasedChannel).guild
|
2021-02-06 13:55:45 +00:00
|
|
|
if (this.guild !== undefined && this.guildID === undefined)
|
|
|
|
this.guildID = this.guild.id
|
|
|
|
}
|
|
|
|
|
2020-12-05 02:24:08 +00:00
|
|
|
/** Edits this message. */
|
2020-12-25 13:09:29 +00:00
|
|
|
async edit(
|
|
|
|
content?: string | AllMessageOptions,
|
|
|
|
option?: AllMessageOptions
|
|
|
|
): Promise<Message> {
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
2020-12-02 12:29:52 +00:00
|
|
|
if (
|
|
|
|
this.client.user !== undefined &&
|
|
|
|
this.author.id !== this.client.user?.id
|
2020-12-25 13:09:29 +00:00
|
|
|
) {
|
2020-12-02 12:29:52 +00:00
|
|
|
throw new Error("Cannot edit other users' messages")
|
2020-12-25 13:09:29 +00:00
|
|
|
}
|
|
|
|
return this.channel.editMessage(this.id, content, option)
|
2020-12-02 12:29:52 +00:00
|
|
|
}
|
|
|
|
|
2020-12-05 02:24:08 +00:00
|
|
|
/** Creates a Reply to this Message. */
|
2020-12-02 12:29:52 +00:00
|
|
|
async reply(
|
2020-12-25 13:09:29 +00:00
|
|
|
content?: string | AllMessageOptions,
|
2020-12-02 12:29:52 +00:00
|
|
|
option?: AllMessageOptions
|
|
|
|
): Promise<Message> {
|
2020-12-25 13:09:29 +00:00
|
|
|
return this.channel.send(content, option, this)
|
2020-12-02 12:29:52 +00:00
|
|
|
}
|
|
|
|
|
2020-12-05 02:24:08 +00:00
|
|
|
/** Deletes the Message. */
|
2020-12-02 12:29:52 +00:00
|
|
|
async delete(): Promise<void> {
|
|
|
|
return this.client.rest.delete(CHANNEL_MESSAGE(this.channelID, this.id))
|
|
|
|
}
|
2020-12-24 00:37:57 +00:00
|
|
|
|
2021-01-18 11:56:51 +00:00
|
|
|
/**
|
|
|
|
* Adds a reaction to the message.
|
|
|
|
* @param emoji Emoji in string or object
|
|
|
|
*/
|
2020-12-24 00:37:57 +00:00
|
|
|
async addReaction(emoji: string | Emoji): Promise<void> {
|
|
|
|
return this.channel.addReaction(this, emoji)
|
|
|
|
}
|
|
|
|
|
2021-01-18 11:56:51 +00:00
|
|
|
/**
|
|
|
|
* Removes a reaction to the message.
|
|
|
|
* @param emoji Emoji in string or object
|
|
|
|
* @param user User or Member or user id
|
|
|
|
*/
|
2020-12-25 04:44:42 +00:00
|
|
|
async removeReaction(
|
|
|
|
emoji: string | Emoji,
|
|
|
|
user?: User | Member | string
|
|
|
|
): Promise<void> {
|
|
|
|
return this.channel.removeReaction(this, emoji, user)
|
2020-12-24 00:37:57 +00:00
|
|
|
}
|
2020-12-02 12:29:52 +00:00
|
|
|
}
|
2021-01-24 14:20:49 +00:00
|
|
|
|
|
|
|
/** Message Attachment that can be sent while Creating Message */
|
|
|
|
export class MessageAttachment {
|
|
|
|
name: string
|
|
|
|
blob: Blob
|
|
|
|
|
|
|
|
constructor(name: string, blob: Blob | Uint8Array | string) {
|
|
|
|
this.name = name
|
|
|
|
this.blob =
|
|
|
|
typeof blob === 'string'
|
2021-04-04 04:51:39 +00:00
|
|
|
? new Blob([encodeText(blob)])
|
2021-01-24 14:20:49 +00:00
|
|
|
: blob instanceof Uint8Array
|
|
|
|
? new Blob([blob])
|
|
|
|
: blob
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Load an Message Attachment from local file or URL */
|
|
|
|
static async load(
|
|
|
|
path: string,
|
|
|
|
filename?: string
|
|
|
|
): Promise<MessageAttachment> {
|
|
|
|
const blob = path.startsWith('http')
|
|
|
|
? await fetch(path).then((res) => res.blob())
|
|
|
|
: await Deno.readFile(path)
|
|
|
|
|
|
|
|
if (filename === undefined) {
|
|
|
|
const split = path.replaceAll('\\', '/').split('/').pop()
|
|
|
|
if (split !== undefined) filename = split.split('?')[0].split('#')[0]
|
|
|
|
else filename = 'unnamed_attachment'
|
|
|
|
}
|
|
|
|
|
|
|
|
return new MessageAttachment(filename, blob)
|
|
|
|
}
|
|
|
|
}
|