Merge pull request #38 from DjDeveloperr/main
feat: Gateway Events, Webhooks, and other structures
This commit is contained in:
		
						commit
						214a1065ee
					
				
					 32 changed files with 1368 additions and 869 deletions
				
			
		
							
								
								
									
										3
									
								
								.vscode/settings.json
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.vscode/settings.json
									
										
									
									
										vendored
									
									
								
							|  | @ -5,5 +5,6 @@ | ||||||
|   "deepscan.enable": true, |   "deepscan.enable": true, | ||||||
|   "deno.import_intellisense_origins": { |   "deno.import_intellisense_origins": { | ||||||
|     "https://deno.land": true |     "https://deno.land": true | ||||||
|   } |   }, | ||||||
|  |   "editor.tabSize": 2 | ||||||
| } | } | ||||||
							
								
								
									
										10
									
								
								mod.ts
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								mod.ts
									
										
									
									
									
								
							|  | @ -4,6 +4,7 @@ export * from './src/models/rest.ts' | ||||||
| export * from './src/models/cacheAdapter.ts' | export * from './src/models/cacheAdapter.ts' | ||||||
| export * from './src/models/shard.ts' | export * from './src/models/shard.ts' | ||||||
| export * from './src/models/command.ts' | export * from './src/models/command.ts' | ||||||
|  | export * from './src/models/extensions.ts' | ||||||
| export * from './src/models/commandClient.ts' | export * from './src/models/commandClient.ts' | ||||||
| export * from './src/managers/base.ts' | export * from './src/managers/base.ts' | ||||||
| export * from './src/managers/baseChild.ts' | export * from './src/managers/baseChild.ts' | ||||||
|  | @ -12,10 +13,13 @@ export * from './src/managers/emojis.ts' | ||||||
| export * from './src/managers/gatewayCache.ts' | export * from './src/managers/gatewayCache.ts' | ||||||
| export * from './src/managers/guildChannels.ts' | export * from './src/managers/guildChannels.ts' | ||||||
| export * from './src/managers/guilds.ts' | export * from './src/managers/guilds.ts' | ||||||
|  | export * from './src/managers/guildChannels.ts' | ||||||
|  | export * from './src/managers/guildEmojis.ts' | ||||||
| export * from './src/managers/members.ts' | export * from './src/managers/members.ts' | ||||||
| export * from './src/managers/messages.ts' | export * from './src/managers/messages.ts' | ||||||
| export * from './src/managers/roles.ts' | export * from './src/managers/roles.ts' | ||||||
| export * from './src/managers/users.ts' | export * from './src/managers/users.ts' | ||||||
|  | export * from './src/structures/application.ts' | ||||||
| export * from './src/structures/base.ts' | export * from './src/structures/base.ts' | ||||||
| export * from './src/structures/cdn.ts' | export * from './src/structures/cdn.ts' | ||||||
| export * from './src/structures/channel.ts' | export * from './src/structures/channel.ts' | ||||||
|  | @ -37,6 +41,7 @@ export * from './src/structures/snowflake.ts' | ||||||
| export * from './src/structures/textChannel.ts' | export * from './src/structures/textChannel.ts' | ||||||
| export * from './src/structures/user.ts' | export * from './src/structures/user.ts' | ||||||
| export * from './src/structures/webhook.ts' | export * from './src/structures/webhook.ts' | ||||||
|  | export * from './src/types/application.ts' | ||||||
| export * from './src/types/cdn.ts' | export * from './src/types/cdn.ts' | ||||||
| export * from './src/types/channel.ts' | export * from './src/types/channel.ts' | ||||||
| export * from './src/types/emoji.ts' | export * from './src/types/emoji.ts' | ||||||
|  | @ -55,3 +60,8 @@ export * from './src/types/voice.ts' | ||||||
| export * from './src/types/webhook.ts' | export * from './src/types/webhook.ts' | ||||||
| export * from './src/utils/collection.ts' | export * from './src/utils/collection.ts' | ||||||
| export * from './src/utils/intents.ts' | export * from './src/utils/intents.ts' | ||||||
|  | export * from './src/utils/buildInfo.ts' | ||||||
|  | export * from './src/utils/permissions.ts' | ||||||
|  | export * from './src/utils/userFlags.ts' | ||||||
|  | export * from './src/utils/bitfield.ts' | ||||||
|  | export * from './src/utils/getChannelByType.ts' | ||||||
|  | @ -1,7 +1,5 @@ | ||||||
| import { Channel } from '../../structures/channel.ts' | import { Channel } from '../../structures/channel.ts' | ||||||
| import { Guild } from '../../structures/guild.ts' | import { ChannelPayload } from "../../types/channel.ts" | ||||||
| import { ChannelPayload, GuildChannelPayload } from '../../types/channel.ts' |  | ||||||
| import getChannelByType from '../../utils/getChannelByType.ts' |  | ||||||
| import { Gateway, GatewayEventHandler } from '../index.ts' | import { Gateway, GatewayEventHandler } from '../index.ts' | ||||||
| 
 | 
 | ||||||
| export const channelUpdate: GatewayEventHandler = async ( | export const channelUpdate: GatewayEventHandler = async ( | ||||||
|  | @ -9,20 +7,15 @@ export const channelUpdate: GatewayEventHandler = async ( | ||||||
|   d: ChannelPayload |   d: ChannelPayload | ||||||
| ) => { | ) => { | ||||||
|   const oldChannel: Channel | undefined = await gateway.client.channels.get(d.id) |   const oldChannel: Channel | undefined = await gateway.client.channels.get(d.id) | ||||||
|  |   await gateway.client.channels.set(d.id, d) | ||||||
|  |   const newChannel: Channel = (await gateway.client.channels.get(d.id) as unknown) as Channel | ||||||
| 
 | 
 | ||||||
|   if (oldChannel !== undefined) { |   if (oldChannel !== undefined) { | ||||||
|     await gateway.client.channels.set(d.id, d) |     // (DjDeveloperr): Already done by ChannelsManager. I'll recheck later
 | ||||||
|     let guild: undefined | Guild; |     // if ('guild_id' in d) {
 | ||||||
|     if ('guild_id' in d) { |     //   // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
 | ||||||
|       // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
 |     //   (newChannel as GuildChannel).guild = await gateway.client.guilds.get((d as GuildChannelPayload).guild_id) as Guild
 | ||||||
|       guild = await gateway.client.guilds.get((d as GuildChannelPayload).guild_id) as Guild | undefined |     // }
 | ||||||
|     } |     gateway.client.emit('channelUpdate', oldChannel, newChannel) | ||||||
|     if (oldChannel.type !== d.type) { |   } else gateway.client.emit('channelUpdateUncached', newChannel) | ||||||
|       const channel: Channel = getChannelByType(gateway.client, d, guild) ?? oldChannel |  | ||||||
|       gateway.client.emit('channelUpdate', oldChannel, channel) |  | ||||||
|     } else { |  | ||||||
|       const before = oldChannel.refreshFromData(d) |  | ||||||
|       gateway.client.emit('channelUpdate', before, oldChannel) |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -39,15 +39,15 @@ export const guildEmojiUpdate: GatewayEventHandler = async ( | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     for (const emoji of deleted) { |     for (const emoji of deleted) { | ||||||
|       gateway.client.emit('guildEmojiDelete', emoji) |       gateway.client.emit('guildEmojiDelete', guild, emoji) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     for (const emoji of added) { |     for (const emoji of added) { | ||||||
|       gateway.client.emit('guildEmojiAdd', emoji) |       gateway.client.emit('guildEmojiAdd', guild, emoji) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     for (const emoji of updated) { |     for (const emoji of updated) { | ||||||
|       gateway.client.emit('guildEmojiUpdate', emoji.before, emoji.after) |       gateway.client.emit('guildEmojiUpdate', guild, emoji.before, emoji.after) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								src/gateway/handlers/guildIntegrationsUpdate.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/gateway/handlers/guildIntegrationsUpdate.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | ||||||
|  | import { Gateway, GatewayEventHandler } from '../index.ts' | ||||||
|  | import { Guild } from '../../structures/guild.ts' | ||||||
|  | import { GuildIntegrationsUpdatePayload } from "../../types/gateway.ts" | ||||||
|  | 
 | ||||||
|  | export const guildIntegrationsUpdate: GatewayEventHandler = async ( | ||||||
|  |   gateway: Gateway, | ||||||
|  |   d: GuildIntegrationsUpdatePayload | ||||||
|  | ) => { | ||||||
|  |   console.log(d) | ||||||
|  |   const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id) | ||||||
|  |   if (guild === undefined) return | ||||||
|  | 
 | ||||||
|  |   gateway.client.emit('guildIntegrationsUpdate', guild) | ||||||
|  | } | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| import { Gateway, GatewayEventHandler } from '../index.ts' | import { Gateway, GatewayEventHandler } from '../index.ts' | ||||||
| import { Guild } from '../../structures/guild.ts' | import { Guild } from '../../structures/guild.ts' | ||||||
| import { GuildMemberAddPayload } from "../../../mod.ts" | import { GuildMemberAddPayload } from "../../types/gateway.ts" | ||||||
|  | import { Member } from "../../structures/member.ts" | ||||||
| 
 | 
 | ||||||
| export const guildMemberAdd: GatewayEventHandler = async ( | export const guildMemberAdd: GatewayEventHandler = async ( | ||||||
|   gateway: Gateway, |   gateway: Gateway, | ||||||
|  | @ -11,6 +12,6 @@ export const guildMemberAdd: GatewayEventHandler = async ( | ||||||
|   if (guild === undefined) return |   if (guild === undefined) return | ||||||
| 
 | 
 | ||||||
|   await guild.members.set(d.user.id, d) |   await guild.members.set(d.user.id, d) | ||||||
|   const member = await guild.members.get(d.user.id) |   const member = await guild.members.get(d.user.id) as Member | ||||||
|   gateway.client.emit('guildMemberAdd', member) |   gateway.client.emit('guildMemberAdd', member) | ||||||
| } | } | ||||||
|  | @ -2,6 +2,7 @@ import { Gateway, GatewayEventHandler } from '../index.ts' | ||||||
| import { Guild } from '../../structures/guild.ts' | import { Guild } from '../../structures/guild.ts' | ||||||
| import { GuildMemberUpdatePayload } from '../../types/gateway.ts' | import { GuildMemberUpdatePayload } from '../../types/gateway.ts' | ||||||
| import { MemberPayload } from '../../types/guild.ts' | import { MemberPayload } from '../../types/guild.ts' | ||||||
|  | import { Member } from "../../structures/member.ts" | ||||||
| 
 | 
 | ||||||
| export const guildMemberUpdate: GatewayEventHandler = async ( | export const guildMemberUpdate: GatewayEventHandler = async ( | ||||||
|   gateway: Gateway, |   gateway: Gateway, | ||||||
|  | @ -25,7 +26,7 @@ export const guildMemberUpdate: GatewayEventHandler = async ( | ||||||
|   const newMember = await guild.members.get(d.user.id) |   const newMember = await guild.members.get(d.user.id) | ||||||
| 
 | 
 | ||||||
|   if (member !== undefined) |   if (member !== undefined) | ||||||
|     gateway.client.emit('guildMemberRemove', member, newMember) |     gateway.client.emit('guildMemberUpdate', member, (newMember as unknown) as Member) | ||||||
|   else { |   else { | ||||||
|     gateway.client.emit('guildMemberUpdateUncached', newMember) |     gateway.client.emit('guildMemberUpdateUncached', newMember) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| import { Gateway, GatewayEventHandler } from '../index.ts' | import { Gateway, GatewayEventHandler } from '../index.ts' | ||||||
| import { Guild } from '../../structures/guild.ts' | import { Guild } from '../../structures/guild.ts' | ||||||
| import { GuildRoleCreatePayload } from "../../types/gateway.ts" | import { GuildRoleCreatePayload } from "../../types/gateway.ts" | ||||||
|  | import { Role } from "../../structures/role.ts" | ||||||
| 
 | 
 | ||||||
| export const guildRoleCreate: GatewayEventHandler = async ( | export const guildRoleCreate: GatewayEventHandler = async ( | ||||||
|   gateway: Gateway, |   gateway: Gateway, | ||||||
|  | @ -12,5 +13,5 @@ export const guildRoleCreate: GatewayEventHandler = async ( | ||||||
| 
 | 
 | ||||||
|   await guild.roles.set(d.role.id, d.role) |   await guild.roles.set(d.role.id, d.role) | ||||||
|   const role = await guild.roles.get(d.role.id) |   const role = await guild.roles.get(d.role.id) | ||||||
|   gateway.client.emit('guildRoleCreate', role) |   gateway.client.emit('guildRoleCreate', (role as unknown) as Role) | ||||||
| } | } | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| import { Gateway, GatewayEventHandler } from '../index.ts' | import { Gateway, GatewayEventHandler } from '../index.ts' | ||||||
| import { Guild } from '../../structures/guild.ts' | import { Guild } from '../../structures/guild.ts' | ||||||
| import { GuildRoleUpdatePayload } from "../../types/gateway.ts" | import { GuildRoleUpdatePayload } from "../../types/gateway.ts" | ||||||
|  | import { Role } from "../../structures/role.ts" | ||||||
| 
 | 
 | ||||||
| export const guildRoleUpdate: GatewayEventHandler = async ( | export const guildRoleUpdate: GatewayEventHandler = async ( | ||||||
|   gateway: Gateway, |   gateway: Gateway, | ||||||
|  | @ -17,5 +18,5 @@ export const guildRoleUpdate: GatewayEventHandler = async ( | ||||||
|   // Shouldn't happen either
 |   // Shouldn't happen either
 | ||||||
|   if(role === undefined) return gateway.client.emit('guildRoleUpdateUncached', newRole) |   if(role === undefined) return gateway.client.emit('guildRoleUpdateUncached', newRole) | ||||||
| 
 | 
 | ||||||
|   gateway.client.emit('guildRoleUpdate', role, newRole) |   gateway.client.emit('guildRoleUpdate', role, (newRole as unknown) as Role) | ||||||
| } | } | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| import { GatewayEventHandler } from '../index.ts' | import { GatewayEventHandler } from '../index.ts' | ||||||
| import { GatewayEvents } from '../../types/gateway.ts' | import { GatewayEvents, TypingStartGuildData } from '../../types/gateway.ts' | ||||||
| import { channelCreate } from './channelCreate.ts' | import { channelCreate } from './channelCreate.ts' | ||||||
| import { channelDelete } from './channelDelete.ts' | import { channelDelete } from './channelDelete.ts' | ||||||
| import { channelUpdate } from './channelUpdate.ts' | import { channelUpdate } from './channelUpdate.ts' | ||||||
|  | @ -22,6 +22,20 @@ import { guildMemberUpdate } from "./guildMemberUpdate.ts" | ||||||
| import { guildRoleCreate } from "./guildRoleCreate.ts" | import { guildRoleCreate } from "./guildRoleCreate.ts" | ||||||
| import { guildRoleDelete } from "./guildRoleDelete.ts" | import { guildRoleDelete } from "./guildRoleDelete.ts" | ||||||
| import { guildRoleUpdate } from "./guildRoleUpdate.ts" | import { guildRoleUpdate } from "./guildRoleUpdate.ts" | ||||||
|  | import { guildIntegrationsUpdate } from "./guildIntegrationsUpdate.ts" | ||||||
|  | import { webhooksUpdate } from "./webhooksUpdate.ts" | ||||||
|  | import { messageDeleteBulk } from "./messageDeleteBulk.ts" | ||||||
|  | import { userUpdate } from "./userUpdate.ts" | ||||||
|  | import { typingStart } from "./typingStart.ts" | ||||||
|  | import { Channel } from "../../structures/channel.ts" | ||||||
|  | import { GuildTextChannel, TextChannel } from "../../structures/textChannel.ts" | ||||||
|  | import { Guild } from "../../structures/guild.ts" | ||||||
|  | import { User } from "../../structures/user.ts" | ||||||
|  | import { Emoji } from "../../structures/emoji.ts" | ||||||
|  | import { Member } from "../../structures/member.ts" | ||||||
|  | import { Role } from "../../structures/role.ts" | ||||||
|  | import { Message } from "../../structures/message.ts" | ||||||
|  | import { Collection } from "../../utils/collection.ts" | ||||||
| 
 | 
 | ||||||
| export const gatewayHandlers: { | export const gatewayHandlers: { | ||||||
|   [eventCode in GatewayEvents]: GatewayEventHandler | undefined |   [eventCode in GatewayEvents]: GatewayEventHandler | undefined | ||||||
|  | @ -39,7 +53,7 @@ export const gatewayHandlers: { | ||||||
|   GUILD_BAN_ADD: guildBanAdd, |   GUILD_BAN_ADD: guildBanAdd, | ||||||
|   GUILD_BAN_REMOVE: guildBanRemove, |   GUILD_BAN_REMOVE: guildBanRemove, | ||||||
|   GUILD_EMOJIS_UPDATE: guildEmojiUpdate, |   GUILD_EMOJIS_UPDATE: guildEmojiUpdate, | ||||||
|   GUILD_INTEGRATIONS_UPDATE: undefined, |   GUILD_INTEGRATIONS_UPDATE: guildIntegrationsUpdate, | ||||||
|   GUILD_MEMBER_ADD: guildMemberAdd, |   GUILD_MEMBER_ADD: guildMemberAdd, | ||||||
|   GUILD_MEMBER_REMOVE: guildMemberRemove, |   GUILD_MEMBER_REMOVE: guildMemberRemove, | ||||||
|   GUILD_MEMBER_UPDATE: guildMemberUpdate, |   GUILD_MEMBER_UPDATE: guildMemberUpdate, | ||||||
|  | @ -52,14 +66,50 @@ export const gatewayHandlers: { | ||||||
|   MESSAGE_CREATE: messageCreate, |   MESSAGE_CREATE: messageCreate, | ||||||
|   MESSAGE_UPDATE: messageUpdate, |   MESSAGE_UPDATE: messageUpdate, | ||||||
|   MESSAGE_DELETE: messageDelete, |   MESSAGE_DELETE: messageDelete, | ||||||
|   MESSAGE_DELETE_BULK: undefined, |   MESSAGE_DELETE_BULK: messageDeleteBulk, | ||||||
|   MESSAGE_REACTION_ADD: undefined, |   MESSAGE_REACTION_ADD: undefined, | ||||||
|   MESSAGE_REACTION_REMOVE: undefined, |   MESSAGE_REACTION_REMOVE: undefined, | ||||||
|   MESSAGE_REACTION_REMOVE_ALL: undefined, |   MESSAGE_REACTION_REMOVE_ALL: undefined, | ||||||
|   MESSAGE_REACTION_REMOVE_EMOJI: undefined, |   MESSAGE_REACTION_REMOVE_EMOJI: undefined, | ||||||
|   PRESENCE_UPDATE: undefined, |   PRESENCE_UPDATE: undefined, | ||||||
|   TYPING_START: undefined, |   TYPING_START: typingStart, | ||||||
|   USER_UPDATE: undefined, |   USER_UPDATE: userUpdate, | ||||||
|   VOICE_SERVER_UPDATE: undefined, |   VOICE_SERVER_UPDATE: undefined, | ||||||
|   WEBHOOKS_UPDATE: undefined |   WEBHOOKS_UPDATE: webhooksUpdate | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface EventTypes { | ||||||
|  |   [name: string]: (...args: any[]) => void | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface ClientEvents extends EventTypes { | ||||||
|  |   'ready': () => void | ||||||
|  |   'reconnect': () => void | ||||||
|  |   'resumed': () => void | ||||||
|  |   'channelCreate': (channel: Channel) => void | ||||||
|  |   'channelDelete': (channel: Channel) => void | ||||||
|  |   'channelPinsUpdate': (before: TextChannel, after: TextChannel) => void | ||||||
|  |   'channelUpdate': (before: Channel, after: Channel) => void | ||||||
|  |   'guildBanAdd': (guild: Guild, user: User) => void | ||||||
|  |   'guildBanRemove': (guild: Guild, user: User) => void | ||||||
|  |   'guildCreate': (guild: Guild) => void | ||||||
|  |   'guildDelete': (guild: Guild) => void | ||||||
|  |   'guildEmojiAdd': (guild: Guild, emoji: Emoji) => void | ||||||
|  |   'guildEmojiDelete': (guild: Guild, emoji: Emoji) => void | ||||||
|  |   'guildEmojiUpdate': (guild: Guild, before: Emoji, after: Emoji) => void | ||||||
|  |   'guildIntegrationsUpdate': (guild: Guild) => void | ||||||
|  |   'guildMemberAdd': (member: Member) => void | ||||||
|  |   'guildMemberRemove': (member: Member) => void | ||||||
|  |   'guildMemberUpdate': (before: Member, after: Member) => void | ||||||
|  |   'guildRoleCreate': (role: Role) => void | ||||||
|  |   'guildRoleDelete': (role: Role) => void | ||||||
|  |   'guildRoleUpdate': (before: Role, after: Role) => void | ||||||
|  |   'guildUpdate': (before: Guild, after: Guild) => void | ||||||
|  |   'messageCreate': (message: Message) => void | ||||||
|  |   'messageDelete': (message: Message) => void | ||||||
|  |   'messageDeleteBulk': (channel: GuildTextChannel, messages: Collection<string, Message>, uncached: Set<string>) => void | ||||||
|  |   'messageUpdate': (before: Message, after: Message) => void | ||||||
|  |   'typingStart': (user: User, channel: TextChannel, at: Date, guildData?: TypingStartGuildData) => void | ||||||
|  |   'userUpdate': (before: User, after: User) => void | ||||||
|  |   'webhooksUpdate': (guild: Guild, channel: GuildTextChannel) => void | ||||||
| } | } | ||||||
							
								
								
									
										29
									
								
								src/gateway/handlers/messageDeleteBulk.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/gateway/handlers/messageDeleteBulk.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | ||||||
|  | import { Message } from "../../structures/message.ts" | ||||||
|  | import { GuildTextChannel } from '../../structures/textChannel.ts' | ||||||
|  | import { MessageDeleteBulkPayload } from "../../types/gateway.ts" | ||||||
|  | import { Collection } from "../../utils/collection.ts" | ||||||
|  | import { Gateway, GatewayEventHandler } from '../index.ts' | ||||||
|  | 
 | ||||||
|  | export const messageDeleteBulk: GatewayEventHandler = async ( | ||||||
|  |   gateway: Gateway, | ||||||
|  |   d: MessageDeleteBulkPayload | ||||||
|  | ) => { | ||||||
|  |   let channel = await gateway.client.channels.get<GuildTextChannel>(d.channel_id) | ||||||
|  |   // Fetch the channel if not cached
 | ||||||
|  |   if (channel === undefined) | ||||||
|  |     // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
 | ||||||
|  |     channel = (await gateway.client.channels.fetch(d.channel_id)) as GuildTextChannel | ||||||
|  | 
 | ||||||
|  |   const messages = new Collection<string, Message>() | ||||||
|  |   const uncached = new Set<string>() | ||||||
|  |   for (const id of d.ids) { | ||||||
|  |     const message = await channel.messages.get(id) | ||||||
|  |     if (message === undefined) uncached.add(id) | ||||||
|  |     else { | ||||||
|  |       messages.set(id, message) | ||||||
|  |       await channel.messages.delete(id) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   gateway.client.emit('messageDeleteBulk', channel, messages, uncached) | ||||||
|  | } | ||||||
							
								
								
									
										23
									
								
								src/gateway/handlers/typingStart.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/gateway/handlers/typingStart.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,23 @@ | ||||||
|  | import { Member } from "../../structures/member.ts" | ||||||
|  | import { TextChannel } from "../../structures/textChannel.ts" | ||||||
|  | import { TypingStartPayload } from "../../types/gateway.ts" | ||||||
|  | import { Gateway, GatewayEventHandler } from '../index.ts' | ||||||
|  | 
 | ||||||
|  | // TODO: Do we need to add uncached events here?
 | ||||||
|  | export const typingStart: GatewayEventHandler = async ( | ||||||
|  |   gateway: Gateway, | ||||||
|  |   d: TypingStartPayload | ||||||
|  | ) => { | ||||||
|  |   const user = await gateway.client.users.get(d.user_id) | ||||||
|  |   if (user === undefined) return console.log('user not cached') | ||||||
|  | 
 | ||||||
|  |   const channel = await gateway.client.channels.get(d.channel_id) | ||||||
|  |   if (channel === undefined) return console.log(`channel not cached`) | ||||||
|  | 
 | ||||||
|  |   const guild = d.guild_id !== undefined ? await gateway.client.guilds.get(d.guild_id) : undefined | ||||||
|  |   if(guild === undefined && d.guild_id !== undefined) return console.log('guild not cached') | ||||||
|  | 
 | ||||||
|  |   const member = d.member !== undefined && guild !== undefined ? new Member(gateway.client, d.member, user, guild) : undefined | ||||||
|  | 
 | ||||||
|  |   gateway.client.emit('typingStart', user, (channel as unknown) as TextChannel, new Date(d.timestamp), guild !== undefined && member !== undefined ? { guild, member } : undefined) | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								src/gateway/handlers/userUpdate.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/gateway/handlers/userUpdate.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | ||||||
|  | import { User } from "../../structures/user.ts" | ||||||
|  | import { UserPayload } from "../../types/user.ts" | ||||||
|  | import { Gateway, GatewayEventHandler } from '../index.ts' | ||||||
|  | 
 | ||||||
|  | export const userUpdate: GatewayEventHandler = async ( | ||||||
|  |   gateway: Gateway, | ||||||
|  |   d: UserPayload | ||||||
|  | ) => { | ||||||
|  |   const oldUser: User | undefined = await gateway.client.users.get(d.id) | ||||||
|  |   await gateway.client.users.set(d.id, d) | ||||||
|  |   const newUser: User = (await gateway.client.users.get(d.id) as unknown) as User | ||||||
|  | 
 | ||||||
|  |   if (oldUser !== undefined) { | ||||||
|  |     gateway.client.emit('userUpdate', oldUser, newUser) | ||||||
|  |   } else gateway.client.emit('userUpdateUncached', newUser) | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								src/gateway/handlers/webhooksUpdate.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/gateway/handlers/webhooksUpdate.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | ||||||
|  | import { Gateway, GatewayEventHandler } from '../index.ts' | ||||||
|  | import { Guild } from '../../structures/guild.ts' | ||||||
|  | import { WebhooksUpdatePayload } from "../../types/gateway.ts" | ||||||
|  | import { GuildTextChannel } from "../../structures/textChannel.ts" | ||||||
|  | 
 | ||||||
|  | export const webhooksUpdate: GatewayEventHandler = async ( | ||||||
|  |   gateway: Gateway, | ||||||
|  |   d: WebhooksUpdatePayload | ||||||
|  | ) => { | ||||||
|  |   const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id) | ||||||
|  |   if (guild === undefined) return | ||||||
|  | 
 | ||||||
|  |   const channel: GuildTextChannel | undefined = await guild.channels.get(d.channel_id) as GuildTextChannel | ||||||
|  |   if (channel === undefined) gateway.client.emit('webhooksUpdateUncached', guild, d.channel_id) | ||||||
|  |   else gateway.client.emit('webhooksUpdate', guild, channel) | ||||||
|  | } | ||||||
|  | @ -43,7 +43,7 @@ export class ChannelsManager extends BaseManager<ChannelPayload, Channel> { | ||||||
|     return result |     return result | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async fetch (id: string): Promise<Channel> { |   async fetch<T = Channel> (id: string): Promise<T> { | ||||||
|     return await new Promise((resolve, reject) => { |     return await new Promise((resolve, reject) => { | ||||||
|       this.client.rest |       this.client.rest | ||||||
|         .get(CHANNEL(id)) |         .get(CHANNEL(id)) | ||||||
|  | @ -53,7 +53,7 @@ export class ChannelsManager extends BaseManager<ChannelPayload, Channel> { | ||||||
|           if (data.guild_id !== undefined) { |           if (data.guild_id !== undefined) { | ||||||
|             guild = await this.client.guilds.get(data.guild_id) |             guild = await this.client.guilds.get(data.guild_id) | ||||||
|           } |           } | ||||||
|           resolve(getChannelByType(this.client, data as ChannelPayload, guild)) |           resolve((getChannelByType(this.client, data as ChannelPayload, guild) as unknown) as T) | ||||||
|         }) |         }) | ||||||
|         .catch(e => reject(e)) |         .catch(e => reject(e)) | ||||||
|     }) |     }) | ||||||
|  |  | ||||||
|  | @ -20,7 +20,6 @@ export class GatewayCache { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async delete (key: string): Promise<boolean> { |   async delete (key: string): Promise<boolean> { | ||||||
|     console.log(`[GatewayCache] DEL ${key}`) |  | ||||||
|     const result = await this.client.cache.delete(this.cacheName, key) |     const result = await this.client.cache.delete(this.cacheName, key) | ||||||
|     return result |     return result | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -12,6 +12,8 @@ import { | ||||||
| } from '../structures/presence.ts' | } from '../structures/presence.ts' | ||||||
| import { EmojisManager } from '../managers/emojis.ts' | import { EmojisManager } from '../managers/emojis.ts' | ||||||
| import { ActivityGame, ClientActivity } from "../types/presence.ts" | import { ActivityGame, ClientActivity } from "../types/presence.ts" | ||||||
|  | import { ClientEvents } from "../gateway/handlers/index.ts" | ||||||
|  | // import { Application } from "../../mod.ts"
 | ||||||
| 
 | 
 | ||||||
| /** Some Client Options to modify behaviour */ | /** Some Client Options to modify behaviour */ | ||||||
| export interface ClientOptions { | export interface ClientOptions { | ||||||
|  | @ -33,6 +35,17 @@ export interface ClientOptions { | ||||||
|   messageCacheLifetime?: number |   messageCacheLifetime?: number | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export declare interface Client { | ||||||
|  |   on: <U extends string>( | ||||||
|  |     event: U, listener: ClientEvents[U] | ||||||
|  |   ) => this | ||||||
|  | 
 | ||||||
|  |   emit: <U extends string>( | ||||||
|  |     event: U, ...args: Parameters<ClientEvents[U]> | ||||||
|  |   ) => boolean | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * Discord Client. |  * Discord Client. | ||||||
|  */ |  */ | ||||||
|  | @ -103,6 +116,9 @@ export class Client extends EventEmitter { | ||||||
|     this.emit('debug', `[${tag}] ${msg}`) |     this.emit('debug', `[${tag}] ${msg}`) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   // TODO(DjDeveloperr): Implement this
 | ||||||
|  |   // fetchApplication(): Promise<Application>
 | ||||||
|  | 
 | ||||||
|   /** |   /** | ||||||
|    * This function is used for connect to discord. |    * This function is used for connect to discord. | ||||||
|    * @param token Your token. This is required. |    * @param token Your token. This is required. | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| import { delay } from '../utils/index.ts' |  | ||||||
| import * as baseEndpoints from '../consts/urlsAndVersions.ts' | import * as baseEndpoints from '../consts/urlsAndVersions.ts' | ||||||
| import { Client } from './client.ts' | import { Client } from './client.ts' | ||||||
| import { getBuildInfo } from '../utils/buildInfo.ts' | import { getBuildInfo } from '../utils/buildInfo.ts' | ||||||
|  | @ -45,13 +44,13 @@ export interface RateLimit { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export class RESTManager { | export class RESTManager { | ||||||
|   client: Client |   client?: Client | ||||||
|   queues: { [key: string]: QueuedItem[] } = {} |   queues: { [key: string]: QueuedItem[] } = {} | ||||||
|   rateLimits = new Collection<string, RateLimit>() |   rateLimits = new Collection<string, RateLimit>() | ||||||
|   globalRateLimit: boolean = false |   globalRateLimit: boolean = false | ||||||
|   processing: boolean = false |   processing: boolean = false | ||||||
| 
 | 
 | ||||||
|   constructor(client: Client) { |   constructor(client?: Client) { | ||||||
|     this.client = client |     this.client = client | ||||||
|     // eslint-disable-next-line @typescript-eslint/no-floating-promises
 |     // eslint-disable-next-line @typescript-eslint/no-floating-promises
 | ||||||
|     this.handleRateLimits() |     this.handleRateLimits() | ||||||
|  | @ -125,7 +124,7 @@ export class RESTManager { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (Object.keys(this.queues).length !== 0) { |     if (Object.keys(this.queues).length !== 0) { | ||||||
|       await delay(1000) |       // await delay(100)
 | ||||||
|       // eslint-disable-next-line @typescript-eslint/no-floating-promises
 |       // eslint-disable-next-line @typescript-eslint/no-floating-promises
 | ||||||
|       this.processQueue() |       this.processQueue() | ||||||
|       // eslint-disable-next-line @typescript-eslint/no-floating-promises
 |       // eslint-disable-next-line @typescript-eslint/no-floating-promises
 | ||||||
|  | @ -139,11 +138,12 @@ export class RESTManager { | ||||||
|   ): { [key: string]: any } { |   ): { [key: string]: any } { | ||||||
| 
 | 
 | ||||||
|     const headers: RequestHeaders = { |     const headers: RequestHeaders = { | ||||||
|       'Authorization': `Bot ${this.client.token}`, |  | ||||||
|       'User-Agent': `DiscordBot (harmony, https://github.com/harmony-org/harmony)` |       'User-Agent': `DiscordBot (harmony, https://github.com/harmony-org/harmony)` | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (this.client.token === undefined) delete headers.Authorization |     if (this.client !== undefined) headers.Authorization = `Bot ${this.client.token}` | ||||||
|  | 
 | ||||||
|  |     if (this.client?.token === undefined) delete headers.Authorization | ||||||
| 
 | 
 | ||||||
|     if (method === 'get' || method === 'head' || method === 'delete') body = undefined |     if (method === 'get' || method === 'head' || method === 'delete') body = undefined | ||||||
| 
 | 
 | ||||||
|  | @ -166,7 +166,7 @@ export class RESTManager { | ||||||
|       method: method.toUpperCase() |       method: method.toUpperCase() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (this.client.bot === false) { |     if (this.client?.bot === false) { | ||||||
|       // This is a selfbot. Use requests similar to Discord Client
 |       // This is a selfbot. Use requests similar to Discord Client
 | ||||||
|       data.headers.authorization = this.client.token as string |       data.headers.authorization = this.client.token as string | ||||||
|       data.headers['accept-language'] = 'en-US' |       data.headers['accept-language'] = 'en-US' | ||||||
|  | @ -290,7 +290,8 @@ export class RESTManager { | ||||||
|     url: string, |     url: string, | ||||||
|     body?: unknown, |     body?: unknown, | ||||||
|     maxRetries = 0, |     maxRetries = 0, | ||||||
|     bucket?: string | null |     bucket?: string | null, | ||||||
|  |     rawResponse?: boolean, | ||||||
|   ): Promise<any> { |   ): Promise<any> { | ||||||
|     return await new Promise((resolve, reject) => { |     return await new Promise((resolve, reject) => { | ||||||
|       const onComplete = async (): Promise<undefined | any> => { |       const onComplete = async (): Promise<undefined | any> => { | ||||||
|  | @ -318,7 +319,7 @@ export class RESTManager { | ||||||
|           let urlToUse = |           let urlToUse = | ||||||
|             method === 'get' && query !== '' ? `${url}?${query}` : url |             method === 'get' && query !== '' ? `${url}?${query}` : url | ||||||
| 
 | 
 | ||||||
|           if (this.client.canary === true) { |           if (this.client?.canary === true) { | ||||||
|             const split = urlToUse.split('//') |             const split = urlToUse.split('//') | ||||||
|             urlToUse = split[0] + '//canary.' + split[1] |             urlToUse = split[0] + '//canary.' + split[1] | ||||||
|           } |           } | ||||||
|  | @ -328,7 +329,7 @@ export class RESTManager { | ||||||
|           const response = await fetch(urlToUse, requestData) |           const response = await fetch(urlToUse, requestData) | ||||||
|           const bucketFromHeaders = this.processHeaders(url, response.headers) |           const bucketFromHeaders = this.processHeaders(url, response.headers) | ||||||
| 
 | 
 | ||||||
|           if (response.status === 204) return resolve(undefined) |           if (response.status === 204) return resolve(rawResponse === true ? { response, body: null } : undefined) | ||||||
| 
 | 
 | ||||||
|           const json: any = await response.json() |           const json: any = await response.json() | ||||||
|           await this.handleStatusCode(response, json, requestData) |           await this.handleStatusCode(response, json, requestData) | ||||||
|  | @ -347,7 +348,7 @@ export class RESTManager { | ||||||
|               bucket: bucketFromHeaders |               bucket: bucketFromHeaders | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|           return resolve(json) |           return resolve(rawResponse === true ? { response, body: json } : json) | ||||||
|         } catch (error) { |         } catch (error) { | ||||||
|           return reject(error) |           return reject(error) | ||||||
|         } |         } | ||||||
|  | @ -375,23 +376,23 @@ export class RESTManager { | ||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async get(url: string, body?: unknown): Promise<any> { |   async get(url: string, body?: unknown, maxRetries = 0, bucket?: string | null, rawResponse?: boolean): Promise<any> { | ||||||
|     return await this.make('get', url, body) |     return await this.make('get', url, body, maxRetries, bucket, rawResponse) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async post(url: string, body?: unknown): Promise<any> { |   async post(url: string, body?: unknown, maxRetries = 0, bucket?: string | null, rawResponse?: boolean): Promise<any> { | ||||||
|     return await this.make('post', url, body) |     return await this.make('post', url, body, maxRetries, bucket, rawResponse) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async delete(url: string, body?: unknown): Promise<any> { |   async delete(url: string, body?: unknown, maxRetries = 0, bucket?: string | null, rawResponse?: boolean): Promise<any> { | ||||||
|     return await this.make('delete', url, body) |     return await this.make('delete', url, body, maxRetries, bucket, rawResponse) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async patch(url: string, body?: unknown): Promise<any> { |   async patch(url: string, body?: unknown, maxRetries = 0, bucket?: string | null, rawResponse?: boolean): Promise<any> { | ||||||
|     return await this.make('patch', url, body) |     return await this.make('patch', url, body, maxRetries, bucket, rawResponse) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async put(url: string, body?: unknown): Promise<any> { |   async put(url: string, body?: unknown, maxRetries = 0, bucket?: string | null, rawResponse?: boolean): Promise<any> { | ||||||
|     return await this.make('put', url, body) |     return await this.make('put', url, body, maxRetries, bucket, rawResponse) | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								src/models/voice.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/models/voice.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | import { Client } from './client.ts' | ||||||
|  | 
 | ||||||
|  | export class VoiceClient { | ||||||
|  |   client: Client | ||||||
|  | 
 | ||||||
|  |   constructor(client: Client) { | ||||||
|  |     this.client = client | ||||||
|  |      | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								src/structures/application.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/structures/application.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | import { Client } from "../models/client.ts"; | ||||||
|  | import { ApplicationPayload } from "../types/application.ts"; | ||||||
|  | import { Base } from "./base.ts"; | ||||||
|  | import { User } from "./user.ts"; | ||||||
|  | 
 | ||||||
|  | export class Application extends Base { | ||||||
|  |   id: string | ||||||
|  |   name: string | ||||||
|  |   icon: string | ||||||
|  |   description: string | ||||||
|  |   summary: string | ||||||
|  |   bot?: User | ||||||
|  | 
 | ||||||
|  |   constructor(client: Client, data: ApplicationPayload) { | ||||||
|  |     super(client, data) | ||||||
|  | 
 | ||||||
|  |     this.id = data.id | ||||||
|  |     this.name = data.name | ||||||
|  |     this.icon = data.icon | ||||||
|  |     this.description = data.description | ||||||
|  |     this.summary = data.summary | ||||||
|  |     this.bot = data.bot !== undefined ? new User(client, data.bot) : undefined | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| import { Client } from '../models/client.ts' | import { Client } from '../models/client.ts' | ||||||
| import { GuildFeatures, GuildPayload } from '../types/guild.ts' | import { GuildFeatures, GuildIntegrationPayload, GuildPayload, IntegrationAccountPayload, IntegrationExpireBehavior } from '../types/guild.ts' | ||||||
| import { PresenceUpdatePayload } from '../types/gateway.ts' | import { PresenceUpdatePayload } from '../types/gateway.ts' | ||||||
| import { Base } from './base.ts' | import { Base } from './base.ts' | ||||||
| import { VoiceState } from './voiceState.ts' | import { VoiceState } from './voiceState.ts' | ||||||
|  | @ -9,6 +9,9 @@ import { MembersManager } from '../managers/members.ts' | ||||||
| import { Role } from './role.ts' | import { Role } from './role.ts' | ||||||
| import { GuildEmojisManager } from '../managers/guildEmojis.ts' | import { GuildEmojisManager } from '../managers/guildEmojis.ts' | ||||||
| import { Member } from "./member.ts" | import { Member } from "./member.ts" | ||||||
|  | import { User } from "./user.ts" | ||||||
|  | import { Application } from "./application.ts" | ||||||
|  | import { GUILD_INTEGRATIONS } from "../types/endpoint.ts" | ||||||
| 
 | 
 | ||||||
| export class Guild extends Base { | export class Guild extends Base { | ||||||
|   id: string |   id: string | ||||||
|  | @ -213,7 +216,7 @@ export class Guild extends Base { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async getEveryoneRole (): Promise<Role> { |   async getEveryoneRole (): Promise<Role> { | ||||||
|     return (await this.roles.array().then(arr => arr?.sort((b, a) => a.position - b.position)[0]) as any) as Role |     return (await this.roles.get(this.id) as unknown) as Role | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async me(): Promise<Member> { |   async me(): Promise<Member> { | ||||||
|  | @ -221,4 +224,47 @@ export class Guild extends Base { | ||||||
|     if (get === undefined) throw new Error('Guild#me is not cached') |     if (get === undefined) throw new Error('Guild#me is not cached') | ||||||
|     return get |     return get | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|  |   async fetchIntegrations(): Promise<GuildIntegration[]> { | ||||||
|  |     const raw = await this.client.rest.get(GUILD_INTEGRATIONS(this.id)) as GuildIntegrationPayload[] | ||||||
|  |     return raw.map(e => new GuildIntegration(this.client, e)) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export class GuildIntegration extends Base { | ||||||
|  |   id: string | ||||||
|  |   name: string | ||||||
|  |   type: string | ||||||
|  |   enabled: boolean | ||||||
|  |   syncing?: boolean | ||||||
|  |   roleID?: string | ||||||
|  |   enableEmoticons?: boolean | ||||||
|  |   expireBehaviour?: IntegrationExpireBehavior | ||||||
|  |   expireGracePeriod?: number | ||||||
|  |   user?: User | ||||||
|  |   account: IntegrationAccountPayload | ||||||
|  |   syncedAt?: string // Actually a ISO Timestamp, but we parse in constructor'
 | ||||||
|  |   subscriberCount?: number | ||||||
|  |   revoked?: boolean | ||||||
|  |   application?: Application | ||||||
|  | 
 | ||||||
|  |   constructor(client: Client, data: GuildIntegrationPayload) { | ||||||
|  |     super(client, data) | ||||||
|  | 
 | ||||||
|  |     this.id = data.id | ||||||
|  |     this.name= data.name | ||||||
|  |     this.type = data.type | ||||||
|  |     this.enabled = data.enabled | ||||||
|  |     this.syncing = data.syncing | ||||||
|  |     this.roleID = data.role_id | ||||||
|  |     this.enableEmoticons = data.enable_emoticons | ||||||
|  |     this.expireBehaviour = data.expire_behaviour | ||||||
|  |     this.expireGracePeriod = data.expire_grace_period | ||||||
|  |     this.user = data.user !== undefined ? new User(client, data.user) : undefined | ||||||
|  |     this.account = data.account | ||||||
|  |     this.syncedAt = data.synced_at | ||||||
|  |     this.subscriberCount = data.subscriber_count | ||||||
|  |     this.revoked = data.revoked | ||||||
|  |     this.application = data.application !== undefined ? new Application(client, data.application) : undefined | ||||||
|  |   } | ||||||
| } | } | ||||||
|  | @ -7,7 +7,7 @@ import { Embed } from './embed.ts' | ||||||
| import { Guild } from "./guild.ts" | import { Guild } from "./guild.ts" | ||||||
| import { Message } from './message.ts' | import { Message } from './message.ts' | ||||||
| 
 | 
 | ||||||
| type AllMessageOptions = MessageOption | Embed | export type AllMessageOptions = MessageOption | Embed | ||||||
| 
 | 
 | ||||||
| export class TextChannel extends Channel { | export class TextChannel extends Channel { | ||||||
|   lastMessageID?: string |   lastMessageID?: string | ||||||
|  | @ -27,6 +27,12 @@ export class TextChannel extends Channel { | ||||||
|     this.lastPinTimestamp = data.last_pin_timestamp ?? this.lastPinTimestamp |     this.lastPinTimestamp = data.last_pin_timestamp ?? this.lastPinTimestamp | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /** | ||||||
|  |    *  | ||||||
|  |    * @param text Text content of the Message to send. | ||||||
|  |    * @param option Various other Message options. | ||||||
|  |    * @param reply Reference to a Message object to reply-to. | ||||||
|  |    */ | ||||||
|   async send(text?: string | AllMessageOptions, option?: AllMessageOptions, reply?: Message): Promise<Message> { |   async send(text?: string | AllMessageOptions, option?: AllMessageOptions, reply?: Message): Promise<Message> { | ||||||
|     if (typeof text === "object") { |     if (typeof text === "object") { | ||||||
|       option = text |       option = text | ||||||
|  | @ -44,7 +50,7 @@ export class TextChannel extends Channel { | ||||||
|       embed: option?.embed, |       embed: option?.embed, | ||||||
|       file: option?.file, |       file: option?.file, | ||||||
|       tts: option?.tts, |       tts: option?.tts, | ||||||
|       allowed_mentions: option?.allowedMention |       allowed_mentions: option?.allowedMentions | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (reply !== undefined) { |     if (reply !== undefined) { | ||||||
|  | @ -63,6 +69,12 @@ export class TextChannel extends Channel { | ||||||
|     return res |     return res | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /** | ||||||
|  |    *  | ||||||
|  |    * @param message Message to edit. ID or the Message object itself. | ||||||
|  |    * @param text New text contents of the Message. | ||||||
|  |    * @param option Other options to edit the message. | ||||||
|  |    */ | ||||||
|   async editMessage( |   async editMessage( | ||||||
|     message: Message | string, |     message: Message | string, | ||||||
|     text?: string, |     text?: string, | ||||||
|  | @ -84,9 +96,10 @@ export class TextChannel extends Channel { | ||||||
|       { |       { | ||||||
|         content: text, |         content: text, | ||||||
|         embed: option?.embed !== undefined ? option.embed.toJSON() : undefined, |         embed: option?.embed !== undefined ? option.embed.toJSON() : undefined, | ||||||
|         file: option?.file, |         // Cannot upload new files with Message
 | ||||||
|  |         // file: option?.file,
 | ||||||
|         tts: option?.tts, |         tts: option?.tts, | ||||||
|         allowed_mentions: option?.allowedMention |         allowed_mentions: option?.allowedMentions | ||||||
|       } |       } | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -15,6 +15,13 @@ export class User extends Base { | ||||||
|   verified?: boolean |   verified?: boolean | ||||||
|   email?: string |   email?: string | ||||||
|   flags?: UserFlagsManager |   flags?: UserFlagsManager | ||||||
|  |   /**  | ||||||
|  |    * Nitro type of the User.  | ||||||
|  |    *  | ||||||
|  |    * 0 = No Nitro | ||||||
|  |    * 1 = Classic Nitro | ||||||
|  |    * 2 = Regular Nitro | ||||||
|  |    */ | ||||||
|   premiumType?: 0 | 1 | 2 |   premiumType?: 0 | 1 | 2 | ||||||
|   publicFlags?: UserFlagsManager |   publicFlags?: UserFlagsManager | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,23 +1,158 @@ | ||||||
|  | import { DISCORD_API_URL, DISCORD_API_VERSION } from "../consts/urlsAndVersions.ts" | ||||||
| import { Client } from '../models/client.ts' | import { Client } from '../models/client.ts' | ||||||
|  | import { RESTManager } from "../models/rest.ts" | ||||||
|  | import { MessageOption } from "../types/channel.ts" | ||||||
| import { UserPayload } from '../types/user.ts' | import { UserPayload } from '../types/user.ts' | ||||||
| import { WebhookPayload } from '../types/webhook.ts' | import { WebhookPayload } from '../types/webhook.ts' | ||||||
| import { Base } from './base.ts' | import { Embed } from "./embed.ts" | ||||||
|  | import { Message } from "./message.ts" | ||||||
|  | import { TextChannel } from "./textChannel.ts" | ||||||
|  | import { User } from "./user.ts" | ||||||
|  | import { fetchAuto } from 'https://raw.githubusercontent.com/DjDeveloperr/fetch-base64/main/mod.ts' | ||||||
| 
 | 
 | ||||||
| export class Webhook extends Base { | export interface WebhookMessageOptions extends MessageOption { | ||||||
|  |   embeds?: Embed[] | ||||||
|  |   name?: string | ||||||
|  |   avatar?: string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export type AllWebhookMessageOptions = string | WebhookMessageOptions | ||||||
|  | 
 | ||||||
|  | export interface WebhookEditOptions { | ||||||
|  |   /** New name to set for Webhook. */ | ||||||
|  |   name?: string | ||||||
|  |   /** New avatar to set for Webhook. URL of image or base64 encoded data. */ | ||||||
|  |   avatar?: string | ||||||
|  |   /** New channel for Webhook. Requires authentication. */ | ||||||
|  |   channelID?: string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** Webhook follows different way of instantiation */ | ||||||
|  | export class Webhook { | ||||||
|  |   client?: Client | ||||||
|   id: string |   id: string | ||||||
|   type: 1 | 2 |   type: 1 | 2 | ||||||
|   guildID?: string |   guildID?: string | ||||||
|   channelID: string |   channelID: string | ||||||
|   user?: UserPayload |   user?: User | ||||||
|  |   userRaw?: UserPayload | ||||||
|   name?: string |   name?: string | ||||||
|   avatar?: string |   avatar?: string | ||||||
|   token?: string |   token?: string | ||||||
|   applicationID?: string |   applicationID?: string | ||||||
|  |   rest: RESTManager | ||||||
| 
 | 
 | ||||||
|   constructor (client: Client, data: WebhookPayload) { |   get url(): string { | ||||||
|     super(client) |     return `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/webhooks/${this.id}/${this.token}` | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   constructor(data: WebhookPayload, client?: Client, rest?: RESTManager) { | ||||||
|     this.id = data.id |     this.id = data.id | ||||||
|     this.type = data.type |     this.type = data.type | ||||||
|     this.channelID = data.channel_id |     this.channelID = data.channel_id | ||||||
|  |     this.guildID = data.guild_id | ||||||
|  |     this.user = data.user === undefined || client === undefined ? undefined : new User(client, data.user) | ||||||
|  |     if (data.user !== undefined && client === undefined) this.userRaw = data.user | ||||||
|  |     this.name = data.name | ||||||
|  |     this.avatar = data.avatar | ||||||
|  |     this.token = data.token | ||||||
|  |     this.applicationID = data.application_id | ||||||
|  | 
 | ||||||
|  |     if (rest !== undefined) this.rest = rest | ||||||
|  |     else if (client !== undefined) this.rest = client.rest | ||||||
|  |     else this.rest = new RESTManager() | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   private fromPayload(data: WebhookPayload): Webhook { | ||||||
|  |     this.id = data.id | ||||||
|  |     this.type = data.type | ||||||
|  |     this.channelID = data.channel_id | ||||||
|  |     this.guildID = data.guild_id | ||||||
|  |     this.user = data.user === undefined || this.client === undefined ? undefined : new User(this.client, data.user) | ||||||
|  |     if (data.user !== undefined && this.client === undefined) this.userRaw = data.user | ||||||
|  |     this.name = data.name | ||||||
|  |     this.avatar = data.avatar | ||||||
|  |     this.token = data.token | ||||||
|  |     this.applicationID = data.application_id | ||||||
|  | 
 | ||||||
|  |     return this | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** Send a Message through Webhook. */ | ||||||
|  |   async send(text?: string | AllWebhookMessageOptions, option?: AllWebhookMessageOptions): Promise<Message> { | ||||||
|  |     if (typeof text === "object") { | ||||||
|  |       option = text | ||||||
|  |       text = undefined | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (text === undefined && option === undefined) { | ||||||
|  |       throw new Error('Either text or option is necessary.') | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (option instanceof Embed) option = { | ||||||
|  |       embeds: [ option ], | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const payload: any = { | ||||||
|  |       content: text, | ||||||
|  |       embeds: (option as WebhookMessageOptions)?.embed !== undefined ? [ (option as WebhookMessageOptions).embed ] : ((option as WebhookMessageOptions)?.embeds !== undefined ? (option as WebhookMessageOptions).embeds : undefined), | ||||||
|  |       file: (option as WebhookMessageOptions)?.file, | ||||||
|  |       tts: (option as WebhookMessageOptions)?.tts, | ||||||
|  |       allowed_mentions: (option as WebhookMessageOptions)?.allowedMentions | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if ((option as WebhookMessageOptions).name !== undefined) { | ||||||
|  |       payload.username = (option as WebhookMessageOptions)?.name | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if ((option as WebhookMessageOptions).avatar !== undefined) { | ||||||
|  |       payload.avatar = (option as WebhookMessageOptions)?.avatar | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (payload.embeds !== undefined && payload.embeds instanceof Array && payload.embeds.length > 10) throw new Error(`Cannot send more than 10 embeds through Webhook`) | ||||||
|  | 
 | ||||||
|  |     const resp = await this.rest.post(this.url + '?wait=true', payload) | ||||||
|  | 
 | ||||||
|  |     const res = new Message(this.client as Client, resp, (this as unknown) as TextChannel, (this as unknown) as User) | ||||||
|  |     await res.mentions.fromPayload(resp) | ||||||
|  |     return res | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** | ||||||
|  |    * Create a Webhook object from URL | ||||||
|  |    * @param url URL of the Webhook | ||||||
|  |    * @param client Client (bot) object, if any. | ||||||
|  |   */ | ||||||
|  |   static async fromURL(url: string | URL, client?: Client): Promise<Webhook> { | ||||||
|  |     const rest = client !== undefined ? client.rest : new RESTManager() | ||||||
|  | 
 | ||||||
|  |     const raw = await rest.get(typeof url === 'string' ? url : url.toString()) | ||||||
|  |     if (typeof raw !== 'object') throw new Error(`Failed to load Webhook from URL: ${url}`) | ||||||
|  | 
 | ||||||
|  |     const webhook = new Webhook(raw, client, rest) | ||||||
|  |     return webhook | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** | ||||||
|  |    * Edit the Webhook name, avatar, or channel (requires authentication). | ||||||
|  |    * @param options Options to edit the Webhook. | ||||||
|  |    */ | ||||||
|  |   async edit(options: WebhookEditOptions): Promise<Webhook> { | ||||||
|  |     if (options.channelID !== undefined && this.rest.client === undefined) throw new Error('Authentication is required for editing Webhook Channel') | ||||||
|  |     if (options.avatar !== undefined && (options.avatar.startsWith('http:') || options.avatar.startsWith('https:'))) { | ||||||
|  |       options.avatar = await fetchAuto(options.avatar) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const data = await this.rest.patch(this.url, options) | ||||||
|  |     this.fromPayload(data) | ||||||
|  | 
 | ||||||
|  |     return this | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** Delete the Webhook. */ | ||||||
|  |   async delete(): Promise<boolean> { | ||||||
|  |     const resp = await this.rest.delete(this.url, undefined, 0, undefined, true) | ||||||
|  |     if (resp.response.status !== 204) return false | ||||||
|  |     else return true | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,11 +1,4 @@ | ||||||
| import { Command, CommandClient, Intents } from '../../mod.ts' | import { Command, CommandClient, Intents, GuildChannel, CommandContext, Extension } from '../../mod.ts' | ||||||
| import { GuildChannel } from "../managers/guildChannels.ts" |  | ||||||
| import { CommandContext } from "../models/command.ts" |  | ||||||
| import { Extension } from "../models/extensions.ts" |  | ||||||
| import { Member } from "../structures/member.ts" |  | ||||||
| import { Message } from "../structures/message.ts" |  | ||||||
| import { Role } from "../structures/role.ts" |  | ||||||
| import { MessageDeletePayload } from "../types/gateway.ts" |  | ||||||
| import { TOKEN } from './config.ts' | import { TOKEN } from './config.ts' | ||||||
| 
 | 
 | ||||||
| const client = new CommandClient({ | const client = new CommandClient({ | ||||||
|  | @ -20,45 +13,47 @@ client.on('ready', () => { | ||||||
|   console.log(`[Login] Logged in as ${client.user?.tag}!`) |   console.log(`[Login] Logged in as ${client.user?.tag}!`) | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| client.on('messageDelete', (msg: Message) => { | client.on('messageDelete', (msg) => { | ||||||
|   console.log(`Message Deleted: ${msg.id}, ${msg.author.tag}, ${msg.content}`) |   console.log(`Message Deleted: ${msg.id}, ${msg.author.tag}, ${msg.content}`) | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| client.on('messageDeleteUncached', (d: MessageDeletePayload) => { | client.on('messageUpdate', (before, after) => { | ||||||
|   console.log(`Uncached Message Deleted: ${d.id} in ${d.channel_id}`) |  | ||||||
| }) |  | ||||||
| 
 |  | ||||||
| client.on('messageUpdate', (before: Message, after: Message) => { |  | ||||||
|   console.log('Message Update') |   console.log('Message Update') | ||||||
|   console.log(`Before: ${before.author.tag}: ${before.content}`) |   console.log(`Before: ${before.author.tag}: ${before.content}`) | ||||||
|   console.log(`After: ${after.author.tag}: ${after.content}`) |   console.log(`After: ${after.author.tag}: ${after.content}`) | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| client.on('messageUpdateUncached', (msg: Message) => { | client.on('messageUpdateUncached', (msg) => { | ||||||
|   console.log(`Message: ${msg.author.tag}: ${msg.content}`) |   console.log(`Message: ${msg.author.tag}: ${msg.content}`) | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| client.on('guildMemberAdd', (member: Member) => { | client.on('guildMemberAdd', (member) => { | ||||||
|   console.log(`Member Join: ${member.user.tag}`) |   console.log(`Member Join: ${member.user.tag}`) | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| client.on('guildMemberRemove', (member: Member) => { | client.on('guildMemberRemove', (member) => { | ||||||
|   console.log(`Member Leave: ${member.user.tag}`) |   console.log(`Member Leave: ${member.user.tag}`) | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| client.on('guildRoleCreate', (role: Role) => { | client.on('guildRoleCreate', (role) => { | ||||||
|   console.log(`Role Create: ${role.name}`) |   console.log(`Role Create: ${role.name}`) | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| client.on('guildRoleDelete', (role: Role) => { | client.on('guildRoleDelete', (role) => { | ||||||
|   console.log(`Role Delete: ${role.name}`) |   console.log(`Role Delete: ${role.name}`) | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| client.on('guildRoleUpdate', (role: Role, after: Role) => { | client.on('guildRoleUpdate', (role, after) => { | ||||||
|   console.log(`Role Update: ${role.name}, ${after.name}`) |   console.log(`Role Update: ${role.name}, ${after.name}`) | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| // client.on('messageCreate', msg => console.log(`${msg.author.tag}: ${msg.content}`))
 | client.on('guildIntegrationsUpdate', (guild) => { | ||||||
|  |   console.log(`Guild Integrations Update: ${guild.name}`) | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | client.on('webhooksUpdate', (guild, channel) => { | ||||||
|  |   console.log(`Webhooks Updated in #${channel.name} from ${guild.name}`) | ||||||
|  | }) | ||||||
| 
 | 
 | ||||||
| client.on("commandError", console.error) | client.on("commandError", console.error) | ||||||
| 
 | 
 | ||||||
|  | @ -85,19 +80,30 @@ class ChannelLog extends Extension { | ||||||
| 
 | 
 | ||||||
| client.extensions.load(ChannelLog) | client.extensions.load(ChannelLog) | ||||||
| 
 | 
 | ||||||
| // eslint-disable-next-line @typescript-eslint/no-floating-promises
 | client.on('messageDeleteBulk', (channel, messages, uncached) => { | ||||||
| ;(async() => { |   console.log(`=== Message Delete Bulk ===\nMessages: ${messages.map(m => m.id).join(', ')}\nUncached: ${[...uncached.values()].join(', ')}`) | ||||||
|   const files = Deno.readDirSync('./src/test/cmds') | }) | ||||||
| 
 | 
 | ||||||
|   for (const file of files) { | client.on('channelUpdate', (before, after) => { | ||||||
|     const module = await import(`./cmds/${file.name}`) |   console.log(`Channel Update: ${(before as GuildChannel).name}, ${(after as GuildChannel).name}`) | ||||||
|     // eslint-disable-next-line new-cap
 | }) | ||||||
|     const cmd = new module.default() |  | ||||||
|     client.commands.add(cmd) |  | ||||||
|     console.log(`Loaded command ${cmd.name}!`) |  | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   console.log(`Loaded ${client.commands.count} commands!`) | client.on('typingStart', (user, channel, at, guildData) => { | ||||||
|  |   console.log(`${user.tag} started typing in ${channel.id} at ${at}${guildData !== undefined ? `\nGuild: ${guildData.guild.name}` : ''}`) | ||||||
|  | }) | ||||||
| 
 | 
 | ||||||
|   client.connect(TOKEN, Intents.All) | // client.on('raw', (evt: string) => console.log(`EVENT: ${evt}`))
 | ||||||
| })() | 
 | ||||||
|  | const files = Deno.readDirSync('./src/test/cmds') | ||||||
|  | 
 | ||||||
|  | for (const file of files) { | ||||||
|  |   const module = await import(`./cmds/${file.name}`) | ||||||
|  |   // eslint-disable-next-line new-cap
 | ||||||
|  |   const cmd = new module.default() | ||||||
|  |   client.commands.add(cmd) | ||||||
|  |   console.log(`Loaded command ${cmd.name}!`) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | console.log(`Loaded ${client.commands.count} commands!`) | ||||||
|  | 
 | ||||||
|  | client.connect(TOKEN, Intents.create(['GUILD_MEMBERS', 'GUILD_PRESENCES'])) | ||||||
							
								
								
									
										9
									
								
								src/test/hook.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/test/hook.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | ||||||
|  | import { Webhook } from '../../mod.ts' | ||||||
|  | import { WEBHOOK } from "./config.ts" | ||||||
|  | 
 | ||||||
|  | const webhook = await Webhook.fromURL(WEBHOOK) | ||||||
|  | console.log('Fetched webhook!') | ||||||
|  | 
 | ||||||
|  | webhook.send('Hello World', { | ||||||
|  |   name: 'OwO' | ||||||
|  | }).then(() => 'Sent message!') | ||||||
							
								
								
									
										10
									
								
								src/types/application.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/types/application.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | import { UserPayload } from "./user.ts"; | ||||||
|  | 
 | ||||||
|  | export interface ApplicationPayload { | ||||||
|  |   id: string | ||||||
|  |   name: string | ||||||
|  |   icon: string | ||||||
|  |   description: string | ||||||
|  |   summary: string | ||||||
|  |   bot?: UserPayload | ||||||
|  | } | ||||||
|  | @ -102,7 +102,7 @@ export interface MessageOption { | ||||||
|   tts?: boolean |   tts?: boolean | ||||||
|   embed?: Embed |   embed?: Embed | ||||||
|   file?: Attachment |   file?: Attachment | ||||||
|   allowedMention?: { |   allowedMentions?: { | ||||||
|     parse: 'everyone' | 'users' | 'roles' |     parse: 'everyone' | 'users' | 'roles' | ||||||
|     roles: string[] |     roles: string[] | ||||||
|     users: string[] |     users: string[] | ||||||
|  |  | ||||||
|  | @ -1,5 +1,7 @@ | ||||||
| // https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway
 | // https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway
 | ||||||
| // https://discord.com/developers/docs/topics/gateway#commands-and-events-gateway-events
 | // https://discord.com/developers/docs/topics/gateway#commands-and-events-gateway-events
 | ||||||
|  | import { Guild } from "../structures/guild.ts" | ||||||
|  | import { Member } from "../structures/member.ts" | ||||||
| import { EmojiPayload } from './emoji.ts' | import { EmojiPayload } from './emoji.ts' | ||||||
| import { MemberPayload } from './guild.ts' | import { MemberPayload } from './guild.ts' | ||||||
| import { | import { | ||||||
|  | @ -320,3 +322,16 @@ export interface WebhooksUpdatePayload { | ||||||
|   guild_id: string |   guild_id: string | ||||||
|   channel_id: string |   channel_id: string | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | export interface TypingStartPayload { | ||||||
|  |   channel_id: string | ||||||
|  |   user_id: string | ||||||
|  |   guild_id?: string | ||||||
|  |   timestamp: number | ||||||
|  |   member?: MemberPayload | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface TypingStartGuildData { | ||||||
|  |   guild: Guild | ||||||
|  |   member: Member | ||||||
|  | } | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | import { ApplicationPayload } from "./application.ts" | ||||||
| import { ChannelPayload } from './channel.ts' | import { ChannelPayload } from './channel.ts' | ||||||
| import { EmojiPayload } from './emoji.ts' | import { EmojiPayload } from './emoji.ts' | ||||||
| import { PresenceUpdatePayload } from './gateway.ts' | import { PresenceUpdatePayload } from './gateway.ts' | ||||||
|  | @ -112,3 +113,31 @@ export type GuildFeatures = | ||||||
|   | 'FEATURABLE' |   | 'FEATURABLE' | ||||||
|   | 'ANIMATED_ICON' |   | 'ANIMATED_ICON' | ||||||
|   | 'BANNER' |   | 'BANNER' | ||||||
|  | 
 | ||||||
|  | export enum IntegrationExpireBehavior { | ||||||
|  |   REMOVE_ROLE = 0, | ||||||
|  |   KICK = 1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface IntegrationAccountPayload { | ||||||
|  |   id: string | ||||||
|  |   name: string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export interface GuildIntegrationPayload { | ||||||
|  |   id: string | ||||||
|  |   name: string | ||||||
|  |   type: string | ||||||
|  |   enabled: boolean | ||||||
|  |   syncing?: boolean | ||||||
|  |   role_id?: string | ||||||
|  |   enable_emoticons?: boolean | ||||||
|  |   expire_behaviour?: IntegrationExpireBehavior | ||||||
|  |   expire_grace_period?: number | ||||||
|  |   user?: UserPayload | ||||||
|  |   account: IntegrationAccountPayload | ||||||
|  |   synced_at?: string // Actually a ISO Timestamp, but we parse in constructor'
 | ||||||
|  |   subscriber_count?: number | ||||||
|  |   revoked?: boolean | ||||||
|  |   application?: ApplicationPayload | ||||||
|  | } | ||||||
|  | @ -1,10 +1,10 @@ | ||||||
| import { GatewayIntents } from '../types/gateway.ts' | import { GatewayIntents } from '../types/gateway.ts' | ||||||
| 
 | 
 | ||||||
|  | export type PriviligedIntents = 'GUILD_MEMBERS' | 'GUILD_PRESENCES' | ||||||
|  | 
 | ||||||
| // eslint-disable-next-line @typescript-eslint/no-extraneous-class
 | // eslint-disable-next-line @typescript-eslint/no-extraneous-class
 | ||||||
| export class Intents { | export class Intents { | ||||||
|   static All: number[] = [ |   static NonPriviliged: number[] = [ | ||||||
|     GatewayIntents.GUILD_MEMBERS, |  | ||||||
|     GatewayIntents.GUILD_PRESENCES, |  | ||||||
|     GatewayIntents.GUILD_MESSAGES, |     GatewayIntents.GUILD_MESSAGES, | ||||||
|     GatewayIntents.DIRECT_MESSAGES, |     GatewayIntents.DIRECT_MESSAGES, | ||||||
|     GatewayIntents.DIRECT_MESSAGE_REACTIONS, |     GatewayIntents.DIRECT_MESSAGE_REACTIONS, | ||||||
|  | @ -20,17 +20,40 @@ export class Intents { | ||||||
|     GatewayIntents.GUILD_WEBHOOKS |     GatewayIntents.GUILD_WEBHOOKS | ||||||
|   ] |   ] | ||||||
| 
 | 
 | ||||||
|  |   static All: number[] = [ | ||||||
|  |     GatewayIntents.GUILD_MEMBERS, | ||||||
|  |     GatewayIntents.GUILD_PRESENCES, | ||||||
|  |     ...Intents.NonPriviliged | ||||||
|  |   ] | ||||||
|  | 
 | ||||||
|   static Presence: number[] = [ |   static Presence: number[] = [ | ||||||
|     GatewayIntents.GUILD_PRESENCES, |     GatewayIntents.GUILD_PRESENCES, | ||||||
|     GatewayIntents.GUILDS |     ...Intents.NonPriviliged | ||||||
|   ] |   ] | ||||||
| 
 | 
 | ||||||
|   static GuildMembers: number[] = [ |   static GuildMembers: number[] = [ | ||||||
|     GatewayIntents.GUILD_MEMBERS, |     GatewayIntents.GUILD_MEMBERS, | ||||||
|     GatewayIntents.GUILDS, |     ...Intents.NonPriviliged | ||||||
|     GatewayIntents.GUILD_BANS, |  | ||||||
|     GatewayIntents.GUILD_VOICE_STATES |  | ||||||
|   ] |   ] | ||||||
| 
 | 
 | ||||||
|   static None: number[] = [] |   static None: number[] = [ | ||||||
|  |     ...Intents.NonPriviliged | ||||||
|  |   ] | ||||||
|  | 
 | ||||||
|  |   static create(priviliged?: PriviligedIntents[], disable?: number[]): number[] { | ||||||
|  |     let intents: number[] = [ | ||||||
|  |       ...Intents.NonPriviliged | ||||||
|  |     ] | ||||||
|  |      | ||||||
|  |     if (priviliged !== undefined && priviliged.length !== 0) { | ||||||
|  |       if (priviliged.includes('GUILD_MEMBERS')) intents.push(GatewayIntents.GUILD_MEMBERS) | ||||||
|  |       if (priviliged.includes('GUILD_PRESENCES')) intents.push(GatewayIntents.GUILD_PRESENCES) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (disable !== undefined) { | ||||||
|  |       intents = intents.filter(intent => !disable.includes(intent)) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return intents | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue