From a65a6e3bdee3f096b8ab564c7872deee7791f320 Mon Sep 17 00:00:00 2001 From: Skillz4Killz Date: Wed, 16 Dec 2020 12:24:22 -0500 Subject: [PATCH] messages are annoying --- src/structures/message.ts | 204 ++++++++++++++++++++++++++++++++++---- 1 file changed, 183 insertions(+), 21 deletions(-) diff --git a/src/structures/message.ts b/src/structures/message.ts index 1b3263dca..f0c8a26dd 100644 --- a/src/structures/message.ts +++ b/src/structures/message.ts @@ -1,20 +1,82 @@ -import { MessageCreateOptions, Unpromise } from "../types/types.ts"; +import { Channel } from "../../mod.ts"; +import { sendMessage } from "../handlers/channel.ts"; +import { addReaction, addReactions, deleteMessageByID, editMessage, pin, removeAllReactions, removeReaction, removeReactionEmoji } from "../handlers/message.ts"; +import { Activity, Application, Attachment, Embed, GuildMember, MessageContent, MessageCreateOptions, MessageSticker, Reaction, Reference, Unpromise, UserPayload } from "../types/types.ts"; import { cache } from "../utils/cache.ts"; +import { createNewProp } from "../utils/utils.ts"; +import { Guild } from "./guild.ts"; +import { Member } from "./member.ts"; +import { Role } from "./role.ts"; -const baseMessage: any = { +const baseMessage: Partial = { get guild() { return cache.guilds.get(this.guildID); }, get member() { - return cache.members.get(this.authorID); + return cache.members.get(this.author?.id); }, get guildMember() { - return this.member.guilds.get(this.guildID); + return this.member?.guilds.get(this.guildID); }, get link() { return `https://discord.com/channels/${this.guildID || "@me"}/${this.channelID}/${this.id}`; }, + get mentionedRoles() { + return this.mentionRoleIDs?.map(id => this.guild?.roles.get(id)) || []; + }, + get mentionedChannels() { + return this.mentionChannelIDs?.map(id => cache.channels.get(id)) || []; + }, + get mentionedMembers() { + return this.mentions?.map(id => cache.members.get(id)) || [] + }, + + // METHODS + delete(reason, delayMilliseconds) { + return deleteMessageByID(this.channelID!, this.id!, reason, delayMilliseconds); + }, + edit(content) { + return editMessage(this, content); + }, + pin() { + return pin(this.channelID!, this.id!) + }, + addReaction(reaction) { + return addReaction(this.channelID!, this.id!, reaction); + }, + addReactions(reactions, ordered) { + return addReactions(this.channelID!, this.id!, reactions, ordered); + }, + sendResponse(content) { + const contentWithMention = typeof content === "string" + ? { content, mentions: { repliedUser: true }, replyMessageID: this.id } + : { + ...content, + mentions: { ...(content.mentions || {}), repliedUser: true }, + replyMessageID: this.id, + }; + + return sendMessage(this.channelID!, contentWithMention); + }, + reply(content) { + return sendMessage(this.channelID!, content); + }, + alert(content, timeout = 10, reason = "") { + return sendMessage(this.channelID!, content).then(response => response.delete(reason, timeout * 1000).catch(console.error)) + }, + alertResponse(content, timeout = 10, reason = "") { + return this.sendResponse!(content).then(response => response.delete(reason, timeout * 1000).catch(console.error)) + }, + removeAllReactions() { + return removeAllReactions(this.channelID!, this.id!); + }, + removeReactionEmoji(reaction) { + return removeReactionEmoji(this.channelID!, this.id!, reaction); + }, + removeReaction(reaction) { + return removeReaction(this.channelID!, this.id!, reaction); + }, }; export async function createMessage(data: MessageCreateOptions) { @@ -22,8 +84,8 @@ export async function createMessage(data: MessageCreateOptions) { guild_id: guildID, channel_id: channelID, mentions_everyone: mentionsEveryone, - mention_channels: mentionChannels, - mention_roles: mentionRoles, + mention_channels: mentionChannelIDs, + mention_roles: mentionRoleIDs, webhook_id: webhookID, message_reference: messageReference, edited_timestamp: editedTimestamp, @@ -31,23 +93,123 @@ export async function createMessage(data: MessageCreateOptions) { ...rest } = data; - const message = { - ...rest, + const restProps = {}; + for (const key of Object.keys(rest)) { + // @ts-ignore + restProps[key] = createNewProp(rest[key]); + } + + const message = Object.create(baseMessage, { + ...restProps, /** The message id of the original message if this message was sent as a reply. If null, the original message was deleted. */ - referencedMessageID, - channelID, - guildID: guildID || "", - mentions: data.mentions.map((m) => m.id), - mentionsEveryone, - mentionRoles, - mentionChannels: mentionChannels || [], - webhookID, - messageReference, - timestamp: Date.parse(data.timestamp), - editedTimestamp: editedTimestamp ? Date.parse(editedTimestamp) : undefined, - }; + referencedMessageID: createNewProp(referencedMessageID), + channelID: createNewProp(channelID), + guildID: createNewProp(guildID || ""), + mentions: createNewProp(data.mentions.map((m) => m.id)), + mentionsEveryone: createNewProp(mentionsEveryone), + mentionRoleIDs: createNewProp(mentionRoleIDs), + mentionChannelIDs: createNewProp(mentionChannelIDs?.map(m => m.id) || []), + webhookID: createNewProp(webhookID), + messageReference: createNewProp(messageReference), + timestamp: createNewProp(Date.parse(data.timestamp)), + editedTimestamp: createNewProp(editedTimestamp ? Date.parse(editedTimestamp) : undefined), + }); return message; } -export interface Message extends Unpromise> {} +export interface Message { + /** The id of the message */ + id: string; + /** The id of the channel the message was sent in */ + channelID: string; + /** The id of the guild the message was sent in */ + guildID: string; + /** The author of this message (not guaranteed to be a valid user such as a webhook.) */ + author: UserPayload; + /** The contents of the message */ + content: string; + /** When this message was sent */ + timestamp: string; + /** When this message was edited (if it was not edited, null) */ + editedTimestamp?: string; + /** Whether this was a TextToSpeech message. */ + tts: boolean; + /** Whether this message mentions everyone */ + mentionsEveryone: boolean; + /** Users specifically mentioned in the message. */ + mentions: string[]; + /** Roles specifically mentioned in this message */ + mentionRoleIDs: string[]; + /** Channels specifically mentioned in this message */ + mentionChannelIDs: string[]; + /** Any attached files */ + attachments: Attachment[]; + /** Any embedded content */ + embeds: Embed[]; + /** Reactions to the message */ + reactions?: Reaction[]; + /** Used for validating a message was sent */ + nonce?: number | string; + /** Whether this message is pinned */ + pinned: boolean; + /** If the message is generated by a webhook, this is the webhooks id */ + webhook_id?: string; + /** The type of message */ + type: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12; + /** The activities sent with Rich Presence-related chat embeds. */ + activity?: Activity; + /** Applications that sent with Rich Presence related chat embeds. */ + applications?: Application; + /** The reference data sent with crossposted messages */ + messageReference?: Reference; + /** The message flags combined like permission bits describe extra features of the message */ + flags?: 1 | 2 | 4 | 8 | 16; + /** the stickers sent with the message (bots currently can only receive messages with stickers, not send) */ + stickers?: MessageSticker[]; + /** The message id of the original message if this message was sent as a reply. If null, the original message was deleted. */ + referencedMessageID?: MessageCreateOptions | null; + + // GETTERS + /** The guild of this message. Can be undefined if not in cache or in DM */ + guild?: Guild; + /** The member for the user who sent the message. Can be undefined if not in cache or in dm. */ + member?: Member; + /** The guild member details for this guild and member. Can be undefined if not in cache or in dm. */ + guildMember?: GuildMember; + /** The url link to this message */ + link: string; + /** The role objects for all the roles that were mentioned in this message */ + mentionedRoles: Role[]; + /** The channel objects for all the channels that were mentioned in this message. */ + mentionedChannels: Channel[]; + /** The member objects for all the members that were mentioned in this message. */ + mentionedMembers: Member[]; + + // METHODS + + /** Delete the message */ + delete(reason?: string, delayMilliseconds?: number): Promise; + /** Edit the message */ + edit(content: string | MessageContent): Promise; + /** Pins the message in the channel */ + pin(): Promise; + /** Add a reaction to the message */ + addReaction(reaction: string): Promise; + /** Add multiple reactions to the message without or without order. */ + addReactions(reactions: string[], ordered?: boolean): Promise; + /** Send a inline reply to this message */ + sendResponse(content: string | MessageContent): Promise; + /** Send a message to this channel where this message is */ + reply(content: string | MessageContent): Promise; + /** Send a message to this channel and then delete it after a bit. By default it will delete after 10 seconds with no reason provided. */ + alert(content: string | MessageContent, timeout?: number, reason?: string): Promise; + /** Send a inline reply to this message but then delete it after a bit. By default it will delete after 10 seconds with no reason provided. */ + alertResponse(content: string | MessageContent, timeout?: number, reason?: string): Promise; + /** Remove all reactions */ + removeAllReactions(): Promise; + /** Remove all reactions */ + removeReactionEmoji(reaction: string): Promise; + /** Remove all reactions */ + removeReaction(reaction: string): Promise; +} \ No newline at end of file