diff --git a/structures/Member.ts b/structures/Member.ts index 0152526..d0b0d92 100644 --- a/structures/Member.ts +++ b/structures/Member.ts @@ -101,7 +101,7 @@ export class Member implements Model { let url: string; if (this.user.bot) { - return this.user.avatarURL() + return this.user.avatarURL(); } if (!this.avatarHash) { @@ -110,7 +110,7 @@ export class Member implements Model { url = Routes.USER_AVATAR(this.user.id, iconBigintToHash(this.avatarHash)); } - return formatImageURL(url, options.size, options.format) + return formatImageURL(url, options.size, options.format); } toString() { diff --git a/structures/Message.ts b/structures/Message.ts index f620ccd..483516b 100644 --- a/structures/Message.ts +++ b/structures/Message.ts @@ -15,6 +15,7 @@ import User from "./User.ts"; import Member from "./Member.ts"; import Attachment from "./Attachment.ts"; import ComponentFactory from "./components/ComponentFactory.ts"; +import { iconHashToBigInt } from "../util/hash.ts"; import * as Routes from "../util/Routes.ts"; /** @@ -57,6 +58,13 @@ export type ReactionResolvable = string | { id: Snowflake; }; +export interface WebhookAuthor { + id: string; + username: string; + discriminator: string; + avatar?: bigint; +} + /** * Represents a message * @link https://discord.com/developers/docs/resources/channel#message-object @@ -77,9 +85,19 @@ export class Message implements Model { this.attachments = data.attachments.map((attachment) => new Attachment(session, attachment)); + // webhook handling + if (data.author && data.author.discriminator === "0000") { + this.webhook = { + id: data.author.id, + username: data.author.username, + discriminator: data.author.discriminator, + avatar: data.author.avatar ? iconHashToBigInt(data.author.avatar) : undefined, + }; + } + // user is always null on MessageCreate and its replaced with author - if (data.guild_id && data.member) { + if (data.guild_id && data.member && data.author && !this.isWebhookMessage()) { this.member = new Member(session, { ...data.member, user: data.author }, data.guild_id); } @@ -101,6 +119,8 @@ export class Message implements Model { member?: Member; components?: Component[]; + webhook?: WebhookAuthor; + get url() { return `https://discord.com/channels/${this.guildId ?? "@me"}/${this.channelId}/${this.id}`; } @@ -284,6 +304,11 @@ export class Message implements Model { inGuild(): this is { guildId: Snowflake } & Message { return !!this.guildId; } + + /** isWebhookMessage if the messages comes from a Webhook */ + isWebhookMessage(): this is User & { author: Partial; webhook: WebhookAuthor; member: undefined } { + return !!this.webhook; + } } export default Message; diff --git a/structures/builders/EmbedBuilder.ts b/structures/builders/EmbedBuilder.ts index 2359c43..8e48e78 100644 --- a/structures/builders/EmbedBuilder.ts +++ b/structures/builders/EmbedBuilder.ts @@ -1,21 +1,17 @@ -import type { - DiscordEmbedField, - DiscordEmbed, - DiscordEmbedProvider -} from '../../vendor/external.ts'; +import type { DiscordEmbed, DiscordEmbedField, DiscordEmbedProvider } from "../../vendor/external.ts"; export interface EmbedFooter { text: string; iconUrl?: string; - proxyIconUrl?: string + proxyIconUrl?: string; } export interface EmbedAuthor { - name: string + name: string; text?: string; url?: string; iconUrl?: string; - proxyIconUrl?: string + proxyIconUrl?: string; } export interface EmbedVideo { @@ -26,10 +22,10 @@ export interface EmbedVideo { } export class EmbedBuilder { - #data: DiscordEmbed + #data: DiscordEmbed; constructor(data: DiscordEmbed = {}) { this.#data = data; - if (!this.#data.fields) this.#data.fields = [] + if (!this.#data.fields) this.#data.fields = []; } setAuthor(author: EmbedAuthor) { @@ -37,7 +33,7 @@ export class EmbedBuilder { name: author.name, icon_url: author.iconUrl, proxy_icon_url: author.proxyIconUrl, - url: author.url + url: author.url, }; return this; } @@ -102,7 +98,7 @@ export class EmbedBuilder { height: video.height, proxy_url: video.proxyUrl, url: video.url, - width: video.width + width: video.width, }; return this; }