diff --git a/src/bot.ts b/src/bot.ts index 10ff0a7a1..42de59cff 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -313,6 +313,7 @@ import { urlToBase64 } from "./util/url_to_base64.ts"; import { transformAttachment } from "./transformers/attachment.ts"; import { transformEmbed } from "./transformers/embed.ts"; import { transformComponent } from "./transformers/component.ts"; +import { transformThread } from "./transformers/thread.ts"; export function createBot(options: CreateBotOptions) { return { @@ -345,7 +346,7 @@ export function createBot(options: CreateBotOptions) { fetchAllMembersProcessingRequests: new Collection(), messages: { get: async function (id: bigint): Promise { - return {} as any as DiscordenoMessage; + return; }, has: async function (id: bigint): Promise { return false; @@ -359,7 +360,7 @@ export function createBot(options: CreateBotOptions) { }, guilds: { get: async function (id: bigint): Promise { - return {} as any as DiscordenoGuild; + return; }, has: async function (id: bigint): Promise { return false; @@ -376,7 +377,7 @@ export function createBot(options: CreateBotOptions) { }, channels: { get: async function (id: bigint): Promise { - return {} as any as DiscordenoChannel; + return; }, has: async function (id: bigint): Promise { return false; @@ -390,7 +391,7 @@ export function createBot(options: CreateBotOptions) { }, members: { get: async function (id: bigint): Promise { - return {} as any as DiscordenoMember; + return; }, has: async function (id: bigint): Promise { return false; @@ -404,7 +405,7 @@ export function createBot(options: CreateBotOptions) { }, presence: { get: async function (id: bigint): Promise { - return {} as any as DiscordenoPresence; + return; }, has: async function (id: bigint): Promise { return false; @@ -418,7 +419,7 @@ export function createBot(options: CreateBotOptions) { }, users: { get: async function (id: bigint): Promise { - return {} as any as DiscordenoUser; + return; }, has: async function (id: bigint): Promise { return false; @@ -570,7 +571,7 @@ export async function startBot(bot: Bot) { bot.helpers = createHelpers(bot.helpers || {}); // START REST - bot.rest = createRestManager({ token: bot.token }); + bot.rest = createRestManager({ token: bot.token, debug: bot.events.debug }); if (!bot.botGatewayData) bot.botGatewayData = await bot.helpers.getGatewayBot(bot); // START WS @@ -1102,6 +1103,7 @@ export interface Transformers { attachment: typeof transformAttachment; embed: typeof transformEmbed; component: typeof transformComponent; + thread: typeof transformThread; } export function createTransformers(options: Partial) { @@ -1123,6 +1125,7 @@ export function createTransformers(options: Partial) { role: options.role || transformRole, user: options.user || transformUser, team: options.team || transformTeam, + thread: options.thread || transformThread, voiceState: options.voiceState || transformVoiceState, snowflake: options.snowflake || snowflakeToBigint, }; diff --git a/src/handlers/members/GUILD_MEMBERS_CHUNK.ts b/src/handlers/members/GUILD_MEMBERS_CHUNK.ts index b3271660f..8f370eb59 100644 --- a/src/handlers/members/GUILD_MEMBERS_CHUNK.ts +++ b/src/handlers/members/GUILD_MEMBERS_CHUNK.ts @@ -9,7 +9,7 @@ export async function handleGuildMembersChunk(bot: Bot, data: DiscordGatewayPayl const guildId = bot.transformers.snowflake(payload.guild_id); await bot.cache.execute("GUILD_MEMBER_CHUNK", { - members: payload.members.map((m) => bot.transformers.member(bot, m, guildId)), + members: payload.members.map((m) => bot.transformers.member(bot, m, guildId, bot.transformers.snowflake(m.user.id))), users: payload.members.map((m) => bot.transformers.user(bot, m.user)), }); diff --git a/src/handlers/members/GUILD_MEMBER_ADD.ts b/src/handlers/members/GUILD_MEMBER_ADD.ts index 2a8868a4c..86fae5f33 100644 --- a/src/handlers/members/GUILD_MEMBER_ADD.ts +++ b/src/handlers/members/GUILD_MEMBER_ADD.ts @@ -6,8 +6,8 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; export async function handleGuildMemberAdd(bot: Bot, data: DiscordGatewayPayload) { const payload = data.d as SnakeCasedPropertiesDeep; const guildId = bot.transformers.snowflake(payload.guild_id); - const member = bot.transformers.member(bot, payload, guildId); const user = bot.transformers.user(bot, payload.user); + const member = bot.transformers.member(bot, payload, guildId, user.id); await Promise.all([ bot.cache.members.set(member.id, member), diff --git a/src/handlers/members/GUILD_MEMBER_UPDATE.ts b/src/handlers/members/GUILD_MEMBER_UPDATE.ts index 0fde4ceb8..1424bc5ed 100644 --- a/src/handlers/members/GUILD_MEMBER_UPDATE.ts +++ b/src/handlers/members/GUILD_MEMBER_UPDATE.ts @@ -6,12 +6,10 @@ import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; export async function handleGuildMemberUpdate(bot: Bot, data: DiscordGatewayPayload) { const payload = data.d as SnakeCasedPropertiesDeep; - // TODO: IDK IF THIS IS BUT IS IT LURKER IN STAGE CHANNEL WHO ISN'T A MEMBER - if (!payload.joined_at) return; - + const user = bot.transformers.user(bot, payload.user); bot.events.guildMemberUpdate( bot, - bot.transformers.member(bot, payload, bot.transformers.snowflake(payload.guild_id)), - bot.transformers.user(bot, payload.user) + bot.transformers.member(bot, payload, bot.transformers.snowflake(payload.guild_id), user.id), + user ); } diff --git a/src/handlers/messages/MESSAGE_DELETE_BULK.ts b/src/handlers/messages/MESSAGE_DELETE_BULK.ts index 9e3c839fa..f62cb76af 100644 --- a/src/handlers/messages/MESSAGE_DELETE_BULK.ts +++ b/src/handlers/messages/MESSAGE_DELETE_BULK.ts @@ -10,6 +10,10 @@ export async function handleMessageDeleteBulk(bot: Bot, data: DiscordGatewayPayl const messages = await bot.cache.execute("BULK_DELETE_MESSAGES", { messageIds: ids }); ids.forEach((id) => { + // @ts-ignore let itoh fix cache typings hes the king of typigns and cache + const msg = messages.find((m) => m.id === id); + const message = msg ? bot.transformers.message(bot, msg) : undefined; + bot.events.messageDelete( bot, { @@ -17,7 +21,7 @@ export async function handleMessageDeleteBulk(bot: Bot, data: DiscordGatewayPayl channelId: bot.transformers.snowflake(payload.channel_id), guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined, }, - messages.find((m) => m.id === id) + message ); }); } diff --git a/src/handlers/messages/MESSAGE_REACTION_ADD.ts b/src/handlers/messages/MESSAGE_REACTION_ADD.ts index 5fac56c22..bf99fcb3a 100644 --- a/src/handlers/messages/MESSAGE_REACTION_ADD.ts +++ b/src/handlers/messages/MESSAGE_REACTION_ADD.ts @@ -7,12 +7,13 @@ export async function handleMessageReactionAdd(bot: Bot, data: DiscordGatewayPay const payload = data.d as SnakeCasedPropertiesDeep; const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined; + const userId = bot.transformers.snowflake(payload.user_id) bot.events.reactionAdd(bot, { - userId: bot.transformers.snowflake(payload.user_id), + userId, channelId: bot.transformers.snowflake(payload.channel_id), messageId: bot.transformers.snowflake(payload.message_id), guildId, - member: payload.member && guildId ? bot.transformers.member(bot, payload.member, guildId) : undefined, + member: payload.member && guildId ? bot.transformers.member(bot, payload.member, guildId, userId) : undefined, emoji: bot.transformers.emoji(bot, payload.emoji), }); } diff --git a/src/handlers/misc/TYPING_START.ts b/src/handlers/misc/TYPING_START.ts index 27663d867..527b0293f 100644 --- a/src/handlers/misc/TYPING_START.ts +++ b/src/handlers/misc/TYPING_START.ts @@ -7,12 +7,13 @@ export function handleTypingStart(bot: Bot, data: DiscordGatewayPayload) { const payload = data.d as SnakeCasedPropertiesDeep; const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined; - + const userId = bot.transformers.snowflake(payload.user_id) + bot.events.typingStart(bot, { guildId, channelId: bot.transformers.snowflake(payload.channel_id), - userId: bot.transformers.snowflake(payload.user_id), + userId, timestamp: payload.timestamp, - member: payload.member && guildId ? bot.transformers.member(bot, payload.member, guildId) : undefined, + member: payload.member && guildId ? bot.transformers.member(bot, payload.member, guildId, userId) : undefined, }); } diff --git a/src/handlers/voice/VOICE_STATE_UPDATE.ts b/src/handlers/voice/VOICE_STATE_UPDATE.ts index f281a513f..d387a3998 100644 --- a/src/handlers/voice/VOICE_STATE_UPDATE.ts +++ b/src/handlers/voice/VOICE_STATE_UPDATE.ts @@ -16,8 +16,8 @@ export async function handleVoiceStateUpdate(bot: Bot, data: DiscordGatewayPaylo await bot.cache.guilds.set(guild.id, guild); } - const member = payload.member ? bot.transformers.member(bot, payload.member, guildId) : undefined; const user = payload.member ? bot.transformers.user(bot, payload.member.user) : undefined; + const member = payload.member ? bot.transformers.member(bot, payload.member, guildId, user!.id) : undefined; bot.events.voiceStateUpdate(bot, voiceState, { guild, member, user }); } diff --git a/src/helpers/members/edit_member.ts b/src/helpers/members/edit_member.ts index e8b85c595..f8bd68eef 100644 --- a/src/helpers/members/edit_member.ts +++ b/src/helpers/members/edit_member.ts @@ -56,5 +56,5 @@ export async function editMember(bot: Bot, guildId: bigint, memberId: bigint, op } ); - return bot.transformers.member(bot, result, guildId); + return bot.transformers.member(bot, result, guildId, memberId); } diff --git a/src/helpers/members/get_member.ts b/src/helpers/members/get_member.ts index 3acc1306a..3282c36d0 100644 --- a/src/helpers/members/get_member.ts +++ b/src/helpers/members/get_member.ts @@ -16,7 +16,7 @@ export async function getMember(bot: Bot, guildId: bigint, id: bigint, options?: bot.constants.endpoints.GUILD_MEMBER(guildId, id) ); - const discordenoMember = await bot.transformers.member(bot, data, guildId); + const discordenoMember = bot.transformers.member(bot, data, guildId, id); await bot.cache.members.set(discordenoMember.id, discordenoMember); return discordenoMember; diff --git a/src/helpers/members/get_members.ts b/src/helpers/members/get_members.ts index 3758cec3c..48d427755 100644 --- a/src/helpers/members/get_members.ts +++ b/src/helpers/members/get_members.ts @@ -46,7 +46,7 @@ export async function getMembers(bot: Bot, guildId: bigint, options?: ListGuildM const discordenoMembers = await Promise.all( result.map(async (member) => { - const discordenoMember = bot.transformers.member(bot, member, guildId); + const discordenoMember = bot.transformers.member(bot, member, guildId, bot.transformers.snowflake(member.user.id)); if (options?.addToCache !== false) { await bot.cache.members.set(discordenoMember.id, discordenoMember); diff --git a/src/helpers/members/search_members.ts b/src/helpers/members/search_members.ts index 5e9059ce5..5c8e2c006 100644 --- a/src/helpers/members/search_members.ts +++ b/src/helpers/members/search_members.ts @@ -37,7 +37,7 @@ export async function searchMembers( const members = await Promise.all( result.map(async (member) => { - const discordenoMember = bot.transformers.member(bot, member, guildId); + const discordenoMember = bot.transformers.member(bot, member, guildId, bot.transformers.snowflake(member.user.id)); if (options?.cache) { await bot.cache.members.set(discordenoMember.id, discordenoMember); } diff --git a/src/rest/process_global_queue.ts b/src/rest/process_global_queue.ts index 1a33f26ed..8e178d9d4 100644 --- a/src/rest/process_global_queue.ts +++ b/src/rest/process_global_queue.ts @@ -130,5 +130,5 @@ export async function processGlobalQueue(rest: RestManager) { } // ALLOW OTHER QUEUES TO START WHEN NEW REQUEST IS MADE - rest.globalQueueProcessing = true; + rest.globalQueueProcessing = false; } diff --git a/src/transformers/application.ts b/src/transformers/application.ts index b2c30a85c..c58cd7c1c 100644 --- a/src/transformers/application.ts +++ b/src/transformers/application.ts @@ -23,6 +23,7 @@ export function transformApplication(bot: Bot, payload: SnakeCasedPropertiesDeep id: bot.transformers.snowflake(payload.id), icon: payload.icon ? bot.utils.iconHashToBigInt(payload.icon) : undefined, + // @ts-ignore the partial here wont break anything owner: payload.owner ? bot.transformers.user(bot, payload.owner) : undefined, team: payload.team ? bot.transformers.team(bot, payload.team) : undefined, guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined, diff --git a/src/transformers/component.ts b/src/transformers/component.ts index 481877d56..29a86f14d 100644 --- a/src/transformers/component.ts +++ b/src/transformers/component.ts @@ -141,5 +141,5 @@ export interface DiscordenoComponent { /** The maximum number of items that can be selected. Default 1. Between 1-25. */ maxValues?: number; /** a list of child components */ - components?: Component[]; + components?: DiscordenoComponent[]; } diff --git a/src/transformers/interaction.ts b/src/transformers/interaction.ts index 5a1b29263..e7dc45590 100644 --- a/src/transformers/interaction.ts +++ b/src/transformers/interaction.ts @@ -1,11 +1,12 @@ import { Bot } from "../bot.ts"; -import { Interaction, Role } from "../types/mod.ts"; +import { Interaction } from "../types/mod.ts"; import { SnakeCasedPropertiesDeep } from "../types/util.ts"; import { DiscordenoMember, DiscordenoUser } from "./member.ts"; import { DiscordenoMessage } from "./message.ts"; export function transformInteraction(bot: Bot, payload: SnakeCasedPropertiesDeep): DiscordenoInteraction { const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined; + const user = bot.transformers.user(bot, payload.member?.user || payload.user!); return { // UNTRANSFORMED STUFF HERE @@ -15,12 +16,12 @@ export function transformInteraction(bot: Bot, payload: SnakeCasedPropertiesDeep // TRANSFORMED STUFF BELOW guildId, + user, id: bot.transformers.snowflake(payload.id), applicationId: bot.transformers.snowflake(payload.application_id), - user: bot.transformers.user(bot, payload.member?.user || payload.user!), message: payload.message ? bot.transformers.message(bot, payload.message) : undefined, channelId: payload.channel_id ? bot.transformers.snowflake(payload.channel_id) : undefined, - member: payload.member && guildId ? bot.transformers.member(bot, payload.member, guildId) : undefined, + member: payload.member && guildId ? bot.transformers.member(bot, payload.member, guildId, user.id) : undefined, }; } diff --git a/src/transformers/invite.ts b/src/transformers/invite.ts index 74aa4bd59..0f2d2beea 100644 --- a/src/transformers/invite.ts +++ b/src/transformers/invite.ts @@ -26,6 +26,7 @@ export function transformInvite(bot: Bot, invite: SnakeCasedPropertiesDeep): DiscordenoUser { return { - id: bot.transformers.snowflake(payload.id), + id: bot.transformers.snowflake(payload.id || ""), username: payload.username, discriminator: Number(payload.discriminator), avatar: payload.avatar ? bot.utils.iconHashToBigInt(payload.avatar) : null, @@ -75,9 +75,9 @@ export interface DiscordenoMember { /** When this member began boosting this server if this member is boosting the server. */ premiumSince?: number; /** Whether or not the member is deafened. */ - deaf: boolean; + deaf?: boolean; /** Whether or not the member is muted. */ - mute: boolean; + mute?: boolean; /** Whether or not this member is pending in server verification. */ pending?: boolean; } diff --git a/src/transformers/message.ts b/src/transformers/message.ts index c71b0f9da..65a741552 100644 --- a/src/transformers/message.ts +++ b/src/transformers/message.ts @@ -9,10 +9,9 @@ import { DiscordenoEmbed } from "./embed.ts"; import { DiscordMessageTypes } from "../types/messages/message_types.ts"; import { DiscordMessageActivityTypes } from "../types/messages/message_activity_types.ts"; import { DiscordInteractionTypes } from "../types/interactions/interaction_types.ts"; -import { DiscordMessageComponentTypes } from "../types/messages/components/message_component_types.ts"; -import { ButtonStyles } from "../types/messages/components/button_styles.ts"; import { DiscordenoComponent } from "./component.ts"; import { Application } from "../types/applications/application.ts"; +import { DiscordenoThread } from "./thread.ts"; export function transformMessage(bot: Bot, data: SnakeCasedPropertiesDeep): DiscordenoMessage { const guildId = data.guild_id ? bot.transformers.snowflake(data.guild_id) : undefined; @@ -54,7 +53,7 @@ export function transformMessage(bot: Bot, data: SnakeCasedPropertiesDeep bot.transformers.component(bot, component)), stickerItems: data.sticker_items?.map((sticker) => ({ id: bot.transformers.snowflake(sticker.id), @@ -196,7 +195,7 @@ export interface DiscordenoMessage { user: DiscordenoUser; }; /** The thread that was started from this message, includes thread member object */ - thread?: Omit & { member: ThreadMember }; + thread?: DiscordenoThread; /** The components related to this message */ components?: DiscordenoComponent[]; } diff --git a/src/transformers/thread.ts b/src/transformers/thread.ts new file mode 100644 index 000000000..e20613e67 --- /dev/null +++ b/src/transformers/thread.ts @@ -0,0 +1,48 @@ +import { Bot } from "../bot.ts"; +import { Channel } from "../types/channels/channel.ts"; +import { DiscordChannelTypes } from "../types/channels/channel_types.ts"; +import { SnakeCasedPropertiesDeep } from "../types/util.ts"; + +export function transformThread(bot: Bot, channel: SnakeCasedPropertiesDeep): DiscordenoThread { + if ( + channel.type !== DiscordChannelTypes.GuildNewsThread && + channel.type !== DiscordChannelTypes.GuildPublicThread && + channel.type !== DiscordChannelTypes.GuildPrivateThread + ) + throw new Error("Cannot convert non-thread channel to a thread."); + + return { + name: channel.name || "", + id: bot.transformers.snowflake(channel.id), + type: channel.type, + parentId: bot.transformers.snowflake(channel.parent_id!), + memberCount: channel.member_count || 1, + messageCount: channel.message_count || 1, + archiveTimestamp: channel.thread_metadata?.archive_timestamp + ? Date.parse(channel.thread_metadata.archive_timestamp) + : undefined, + autoArchiveDuration: channel.thread_metadata?.auto_archive_duration || 0, + ownerId: bot.transformers.snowflake(channel.owner_id!), + botIsMember: Boolean(channel.member), + archived: channel.thread_metadata?.archived, + locked: channel.thread_metadata?.locked, + }; +} + +export interface DiscordenoThread { + id: bigint; + name: string; + type: + | DiscordChannelTypes.GuildNewsThread + | DiscordChannelTypes.GuildPublicThread + | DiscordChannelTypes.GuildPrivateThread; + parentId: bigint; + memberCount: number; + messageCount: number; + archiveTimestamp?: number; + autoArchiveDuration: number; + archived?: boolean; + locked?: boolean; + ownerId: bigint; + botIsMember: boolean; +} diff --git a/src/types/members/guild_member.ts b/src/types/members/guild_member.ts index cc13d095e..2dd09423d 100644 --- a/src/types/members/guild_member.ts +++ b/src/types/members/guild_member.ts @@ -13,9 +13,9 @@ export interface GuildMember { /** When the user started boosing the guild */ premiumSince?: string | null; /** Whether the user is deafened in voice channels */ - deaf: boolean; + deaf?: boolean; /** Whether the user is muted in voice channels */ - mute: boolean; + mute?: boolean; /** Whether the user has not yet passed the guild's Membership Screening requirements */ pending?: boolean; } diff --git a/src/types/members/guild_member_update.ts b/src/types/members/guild_member_update.ts index d85bb16e5..803318a10 100644 --- a/src/types/members/guild_member_update.ts +++ b/src/types/members/guild_member_update.ts @@ -11,7 +11,7 @@ export interface GuildMemberUpdate { /** Nickname of the user in the guild */ nick?: string | null; /** When the user joined the guild */ - joinedAt: string | null; + joinedAt: string; /** When the user starting boosting the guild */ premiumSince?: string | null; /** Whether the user has not yet passed the guild's Membership Screening requirements */ diff --git a/tests/mod.ts b/tests/mod.ts index 6dedbc60c..69d3e5e27 100644 --- a/tests/mod.ts +++ b/tests/mod.ts @@ -5,11 +5,16 @@ Deno.test("[Bot] - Starting Tests", async (t) => { const bot = createBot({ token: TOKEN || Deno.env.get("DISCORD_TOKEN"), botId: 675412054529540107n, - events: createEventHandlers({}), + events: createEventHandlers({ + debug: console.log, + }), intents: [], }) as Bot; await startBot(bot); + console.log("started"); + const x = await bot.helpers.sendMessage(bot, 806947972004839444n, "testing"); + console.log("x"); console.log("Bot online");