diff --git a/.github/workflows/blank.yml b/.github/workflows/testing.yml similarity index 94% rename from .github/workflows/blank.yml rename to .github/workflows/testing.yml index 666acdb..47dbc67 100644 --- a/.github/workflows/blank.yml +++ b/.github/workflows/testing.yml @@ -24,4 +24,4 @@ jobs: - uses: denolib/setup-deno@master with: deno-version: v1.x - - run: deno test --allow-read ./tests/tests.ts + - run: deno test --allow-read ./tests diff --git a/src/client/rest/RestAPIHandler.ts b/src/client/rest/RestAPIHandler.ts index 7adaa73..e01a9af 100644 --- a/src/client/rest/RestAPIHandler.ts +++ b/src/client/rest/RestAPIHandler.ts @@ -91,6 +91,17 @@ export default class RestAPIHandler { ); } + async editMessage(options: MessageOptions, channelId: string, messageId: string) { + return fetch( + `${Constants.API}/${ENDPOINTS.CHANNELS}/${channelId}/${ENDPOINTS.MESSAGES}/${messageId}`, + { + method: 'PATCH', + headers, + body: JSON.stringify(options), + } + ) + } + async createReaction(channelId: string, messageId: string, emoji: any): Promise { const response = await fetch ( `${Constants.API}/${ENDPOINTS.CHANNELS}/${channelId}/${ENDPOINTS.MESSAGES}/${messageId}/${ENDPOINTS.REACTIONS}/${emoji}/@me`, diff --git a/src/index.ts b/src/index.ts index 1c7a47a..f35d676 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,7 @@ import { Client } from "../mod.ts"; import "https://deno.land/x/dotenv/load.ts"; import Guild from "./models/Guild.ts"; import Message from "./models/Message.ts"; +import { MessageEmbed } from './models/embeds/Embeds.ts'; const client = new Client(); @@ -11,16 +12,26 @@ client.on("ready", () => { console.log("Bot has logged in."); }); +const embed = new MessageEmbed() + .setDescription('Hello') + .setColor(3313064) + .setFooter('hello') + .addField('Hi', 'Hello'); client.on("message", async (message: Message) => { console.log(message.channel.messages.size); if (message.content === "?hello") { const msg = await message.channel.send("hello"); - msg.delete(); + // msg.delete(); } else if (message.content === '?react') { const reaction = await message.react('😂'); console.log(reaction); + } else if (message.content === '?edit') { + const msg = await message.channel.send('Hello World'); + msg?.edit(embed); + } else if (message.content === '?embed') { + } }); diff --git a/src/models/Message.ts b/src/models/Message.ts index 16ac5d6..abe8a07 100644 --- a/src/models/Message.ts +++ b/src/models/Message.ts @@ -7,6 +7,7 @@ import { StatusCode } from '../constants/Constants.ts'; import { MessageReaction } from './MessageReaction.ts'; import { validateEmoji, checkGuildEmoji } from '../utils/checks.ts'; import Emoji from './Emoji.ts'; +import { MessageEmbed } from './embeds/Embeds.ts'; export default class Message { constructor( @@ -47,6 +48,7 @@ export default class Message { public get type(): number { return this._type; } public get content(): string { return this._content; } + public delete(options?: MessageDeleteOptions): Promise { return new Promise((resolve, reject) => { setTimeout(async () => { @@ -61,10 +63,11 @@ export default class Message { } /** - * - * @param emoji the emoji to add to the Message + * Reacts to a message + * @param emoji - the emoji id, name joined with id, or a unicode emoji + * @returns ReactionMessage - the reaction that was added */ - public async react(emoji: any): Promise { + public async react(emoji: string): Promise { const result = validateEmoji(emoji); if (Array.isArray(result)) { const [name,id] = result; @@ -87,6 +90,15 @@ export default class Message { await this.channel.client.rest.createReaction(this.channel.id, this.id, emoji); return null; } + + public async edit(payload: string | MessageEmbed) { + if (typeof payload === 'string') { + return this.channel.client.rest.editMessage({ content: payload }, this.channel.id, this.id); + } + if (payload instanceof MessageEmbed) { + return this.channel.client.rest.editMessage({ embed: payload }, this.channel.id, this.id); + } + } } diff --git a/src/models/channels/TextChannel.ts b/src/models/channels/TextChannel.ts index 61741b6..3eb2abc 100644 --- a/src/models/channels/TextChannel.ts +++ b/src/models/channels/TextChannel.ts @@ -7,6 +7,7 @@ import { MessageOptions } from "../../typedefs/MessageOptions.ts"; import Collection from "../Collection.ts"; import Message from "../Message.ts"; import { buildMessage } from '../../utils/resolvers.ts'; +import { MessageEmbed } from '../embeds/Embeds.ts'; export class TextChannel extends GuildChannel implements TextBasedChannel { @@ -46,13 +47,21 @@ export class TextChannel extends GuildChannel implements TextBasedChannel { get messages(): Collection { return this._messages; } - async send(payload: string | MessageOptions) { + async send(payload: string | MessageOptions | MessageEmbed) { if (typeof payload === "string") { const body: MessageOptions = { content: payload }; const response = await this.client.rest.createMessage(body, this.id); response.guild_id = this.guild.id; return await buildMessage(this.client, response); } + if (payload instanceof MessageEmbed) { + const options: MessageOptions = { + embed: payload + } + console.log(JSON.stringify(options)); + const response = await this.client.rest.createMessage(options, this.id); + return; + } const response = await this.client.rest.createMessage(payload, this.id); response.guild_id = this.guild.id; return await buildMessage(this.client, response); diff --git a/src/models/embeds/Embeds.ts b/src/models/embeds/Embeds.ts new file mode 100644 index 0000000..679ebdf --- /dev/null +++ b/src/models/embeds/Embeds.ts @@ -0,0 +1,8 @@ +export { MessageEmbed } from './MessageEmbed.ts'; +export { MessageEmbedFooter } from './MessageEmbedFooter.ts'; +export { MessageEmbedImage } from './MessageEmbedImage.ts'; +export { MessageEmbedAuthor } from './MessageEmbedAuthor.ts'; +export { MessageEmbedField } from './MessageEmbedField.ts'; +export { MessageEmbedProvider } from './MessageEmbedProvider.ts'; +export { MessageEmbedThumbnail } from './MessageEmbedThumbnail.ts'; +export { MessageEmbedVideo } from './MessageEmbedVideo.ts'; \ No newline at end of file diff --git a/src/models/embeds/MessageEmbed.ts b/src/models/embeds/MessageEmbed.ts new file mode 100644 index 0000000..9b6ebc3 --- /dev/null +++ b/src/models/embeds/MessageEmbed.ts @@ -0,0 +1,132 @@ +import { + MessageEmbedAuthor, + MessageEmbedField, + MessageEmbedFooter, + MessageEmbedImage, + MessageEmbedProvider, + MessageEmbedThumbnail, + MessageEmbedVideo +} from './Embeds.ts'; + +export class MessageEmbed { + + private title?: string; + private type?: string; + private description?: string; + private url?: string; + private timestamp?: Date; + private color?: number; + private footer?: MessageEmbedFooter; + private image?: MessageEmbedImage; + private thumbnail?: MessageEmbedThumbnail; + private video?: MessageEmbedVideo; + private provider?: MessageEmbedProvider; + private author?: MessageEmbedAuthor; + private fields: Array = []; + + constructor( + title?: string, + type?: string, + description?: string, + url?: string, + timestamp?: Date, + color?: number, + footer?: MessageEmbedFooter, + image?: MessageEmbedImage, + thumbnail?: MessageEmbedThumbnail, + video?: MessageEmbedVideo, + provider?: MessageEmbedProvider, + author?: MessageEmbedAuthor, + ) { + this.title = title; + this.type = type; + this.description = description; + this.url = url; + this.timestamp = timestamp; + this.color = color; + this.footer = footer; + this.image = image; + this.thumbnail = thumbnail; + this.video = video; + this.provider = provider; + this.author = author; + } + + getTitle(): string | undefined { return this.title; } + setTitle(title: string | undefined): MessageEmbed { + this.title = title; + return this; + } + + getType(): string | undefined { return this.type; } + setType(type: string | undefined): MessageEmbed { + this.type = type; + return this; + } + + getDescription(): string | undefined { return this.description; } + setDescription(description: string) { + this.description = description; + return this; + } + + getUrl(): string | undefined { return this.url; } + setUrl(url: string | undefined) { + this.url = url; + return this; + } + + getTimestamp(): Date | undefined { return this.timestamp; } + setTimestamp(timestamp?: Date | undefined) { + if (timestamp) this.timestamp = timestamp; + else this.timestamp = new Date(); + return this; + } + + getColor(): number | undefined { return this.color; } + setColor(color: number | undefined) { + this.color = color; + return this; + } + + getFooter(): MessageEmbedFooter | undefined { return this.footer; } + setFooter(text?: string, icon?: string, proxyIconUrl?: string) { + this.footer = new MessageEmbedFooter(text, icon, proxyIconUrl); + return this; + } + + getImage(): MessageEmbedImage | undefined { return this.image; } + setImage(url?: string, proxyUrl?: string, height?: number, width?: number): MessageEmbed { + this.image = new MessageEmbedImage(url, proxyUrl, height, width); + return this; + } + + getThumbnail(): MessageEmbedThumbnail | undefined { return this.thumbnail; } + setThumbnail(url?: string, proxyUrl?: string, height?: number, width?: number): MessageEmbed { + this.thumbnail = new MessageEmbedThumbnail(url, proxyUrl, height, width); + return this; + } + + getVideo(): MessageEmbedVideo | undefined { return this.video; } + // setVideo(url?: string, height?: number, width?: number): MessageEmbed { + // this.video = new MessageEmbedVideo(url, height, width); + // return this; + // } + + getProvider(): MessageEmbedProvider | undefined { return this.provider; } + setProvider(name?: string, url?: string): MessageEmbed { + this.provider = new MessageEmbedProvider(name, url); + return this; + } + + getAuthor(): MessageEmbedAuthor | undefined { return this.author; } + setAuthor(name?: string, url?: string, iconUrl?: string, proxyIconUrl?: string): MessageEmbed { + this.author = new MessageEmbedAuthor(name, url, iconUrl, proxyIconUrl); + return this; + } + + addField(text: string, value: string, inline?: boolean): MessageEmbed { + this.fields.push(new MessageEmbedField(text,value,inline)); + return this; + } +} diff --git a/src/models/embeds/MessageEmbedAuthor.ts b/src/models/embeds/MessageEmbedAuthor.ts new file mode 100644 index 0000000..ac76722 --- /dev/null +++ b/src/models/embeds/MessageEmbedAuthor.ts @@ -0,0 +1,29 @@ +export class MessageEmbedAuthor { + + private _name: string | undefined; + private _url: string | undefined; + private _iconUrl: string | undefined; + private _proxyIconUrl: string | undefined; + + constructor( + name?: string, + url?: string, + iconUrl?: string, + proxyIconUrl?: string, + ) { + this._name = name; + this._url = url; + this._iconUrl = iconUrl; + this._proxyIconUrl = proxyIconUrl; + } + + get name(): string | undefined { return this._name; } + get url(): string | undefined { return this._url; } + get iconUrl(): string | undefined { return this._iconUrl; } + get proxyIconUrl(): string | undefined { return this._proxyIconUrl; } + + set name(name: string | undefined) { this._name = name; } + set url(url: string | undefined ) { this._url = url; } + set iconUrl(iconUrl: string | undefined) { this._iconUrl = iconUrl; } + set proxyIconUrl(proxyIconUrl: string | undefined) { this._proxyIconUrl = proxyIconUrl; } +} \ No newline at end of file diff --git a/src/models/embeds/MessageEmbedField.ts b/src/models/embeds/MessageEmbedField.ts new file mode 100644 index 0000000..a2296e9 --- /dev/null +++ b/src/models/embeds/MessageEmbedField.ts @@ -0,0 +1,24 @@ +export class MessageEmbedField { + + private name: string; + private value: string; + private inline?: boolean; + + constructor( + name: string, + value: string, + inline?: boolean + ) { + this.name = name; + this.value = value; + this.inline = inline; + } + + getName(): string { return this.name; } + getValue(): string { return this.value; } + getInline(): boolean | undefined { return this.inline; } + + setName(name: string) { this.name = name; } + setValue(value: string) { this.value = value; } + setInline(inline: boolean) { this.inline = inline; } +} \ No newline at end of file diff --git a/src/models/embeds/MessageEmbedFooter.ts b/src/models/embeds/MessageEmbedFooter.ts new file mode 100644 index 0000000..f1dacff --- /dev/null +++ b/src/models/embeds/MessageEmbedFooter.ts @@ -0,0 +1,23 @@ +export class MessageEmbedFooter { + + private text: string | undefined; + private icon_url: string | undefined; + private proxy_icon_url: string | undefined; + constructor( + text?: string, + iconUrl?: string, + proxyIconUrl?: string + ) { + this.text = text; + this.icon_url = iconUrl; + this.proxy_icon_url = proxyIconUrl; + } + + getText(): string | undefined { return this.text; } + getIconUrl(): string | undefined { return this.icon_url; } + getProxyIconUrl(): string | undefined { return this.proxy_icon_url; } + + setText(text: string | undefined) { this.text = text; } + setIconUrl(iconUrl: string | undefined) { this.icon_url = iconUrl; } + setProxyIconUrl(proxyIconUrl: string | undefined) { this.proxy_icon_url = proxyIconUrl; } +} \ No newline at end of file diff --git a/src/models/embeds/MessageEmbedImage.ts b/src/models/embeds/MessageEmbedImage.ts new file mode 100644 index 0000000..35fabdb --- /dev/null +++ b/src/models/embeds/MessageEmbedImage.ts @@ -0,0 +1,29 @@ +export class MessageEmbedImage { + + private url: string | undefined; + private proxyUrl: string | undefined; + private height: number | undefined; + private width: number | undefined; + + constructor( + url?: string, + proxyUrl?: string, + height?: number, + width?: number + ) { + this.url = url; + this.proxyUrl = proxyUrl; + this.height = height; + this.width = width; + } + + getUrl(): string | undefined { return this.url; } + getProxyUrl(): string | undefined { return this.proxyUrl; } + getHeight(): number | undefined { return this.height; } + getWidth(): number | undefined { return this.width; } + + setUrl(url: string | undefined ) { this.url = url; } + setProxyUrl(proxyUrl: string | undefined) { this.proxyUrl = proxyUrl; } + setHeight(height: number | undefined){ this.height = height; } + setWidth(width: number | undefined) { this.width = width; } +} \ No newline at end of file diff --git a/src/models/embeds/MessageEmbedProvider.ts b/src/models/embeds/MessageEmbedProvider.ts new file mode 100644 index 0000000..6ce0c3c --- /dev/null +++ b/src/models/embeds/MessageEmbedProvider.ts @@ -0,0 +1,19 @@ +export class MessageEmbedProvider { + + private _name: string | undefined; + private _url: string | undefined; + + constructor( + name?: string, + url?: string + ) { + this._name = name; + this._url = url; + } + + get name(): string | undefined { return this._name; } + get url(): string | undefined { return this._url; } + + set name(name: string | undefined) { this._name = name; } + set url(url: string | undefined) { this._url = url; } +} \ No newline at end of file diff --git a/src/models/embeds/MessageEmbedThumbnail.ts b/src/models/embeds/MessageEmbedThumbnail.ts new file mode 100644 index 0000000..2c5e249 --- /dev/null +++ b/src/models/embeds/MessageEmbedThumbnail.ts @@ -0,0 +1,29 @@ +export class MessageEmbedThumbnail { + + private url: string | undefined; + private proxy_url: string | undefined; + private height: number | undefined; + private width: number | undefined; + + constructor( + url?: string, + proxyUrl?: string, + height?: number, + width?: number + ) { + this.url = url; + this.proxy_url = proxyUrl; + this.height = height; + this.width = width; + } + + getUrl(): string | undefined { return this.url; } + getProxyUrl(): string | undefined { return this.proxy_url; } + getHeight(): number | undefined { return this.height; } + getWidth(): number | undefined { return this.width; } + + setUrl(url: string | undefined ) { this.url = url; } + setProxyUrl(proxyUrl: string | undefined) { this.proxy_url = proxyUrl; } + setHeight(height: number | undefined){ this.height = height; } + setWidth(width: number | undefined) { this.width = width; } +} \ No newline at end of file diff --git a/src/models/embeds/MessageEmbedVideo.ts b/src/models/embeds/MessageEmbedVideo.ts new file mode 100644 index 0000000..1507924 --- /dev/null +++ b/src/models/embeds/MessageEmbedVideo.ts @@ -0,0 +1,24 @@ +export class MessageEmbedVideo { + + private url: string | undefined; + private height: number | undefined; + private width: number | undefined; + + constructor( + url?: string, + height?: number, + width?: number + ) { + this.url = url; + this.height = height; + this.width = width; + } + + getUrl(): string | undefined { return this.url; } + getHeight(): number | undefined { return this.height; } + getWidth(): number | undefined { return this.width; } + + setUrl(url: string | undefined ) { this.url = url; } + setHeight(height: number | undefined){ this.height = height; } + setWidth(width: number | undefined) { this.width = width; } +} \ No newline at end of file diff --git a/src/typedefs/MessageOptions.ts b/src/typedefs/MessageOptions.ts index 85c2abf..fe84743 100644 --- a/src/typedefs/MessageOptions.ts +++ b/src/typedefs/MessageOptions.ts @@ -1,14 +1,11 @@ +import { MessageEmbed } from '../models/embeds/Embeds.ts'; + export interface MessageOptions { content?: string; tts?: boolean; embed?: MessageEmbed; } -export interface MessageEmbed { - title: string; - description?: string; -} - export interface MessageDeleteOptions { timeout?: number; reason?: string; diff --git a/src/utils/test.ts b/src/utils/test.ts new file mode 100644 index 0000000..e69de29 diff --git a/tests/tests.ts b/tests/index.test.ts similarity index 100% rename from tests/tests.ts rename to tests/index.test.ts