feat(reactions): implemented structures and events
This commit is contained in:
		
							parent
							
								
									a7336c19e3
								
							
						
					
					
						commit
						c7ef17a6d2
					
				
					 13 changed files with 431 additions and 153 deletions
				
			
		|  | @ -39,6 +39,12 @@ import { Collection } from '../../utils/collection.ts' | |||
| import { voiceServerUpdate } from './voiceServerUpdate.ts' | ||||
| import { voiceStateUpdate } from './voiceStateUpdate.ts' | ||||
| import { VoiceState } from '../../structures/voiceState.ts' | ||||
| import { messageReactionAdd } from './messageReactionAdd.ts' | ||||
| import { messageReactionRemove } from './messageReactionRemove.ts' | ||||
| import { messageReactionRemoveAll } from './messageReactionRemoveAll.ts' | ||||
| import { messageReactionRemoveEmoji } from './messageReactionRemoveEmoji.ts' | ||||
| import { guildMembersChunk } from './guildMembersChunk.ts' | ||||
| import { presenceUpdate } from './presenceUpdate.ts' | ||||
| 
 | ||||
| export const gatewayHandlers: { | ||||
|   [eventCode in GatewayEvents]: GatewayEventHandler | undefined | ||||
|  | @ -60,7 +66,7 @@ export const gatewayHandlers: { | |||
|   GUILD_MEMBER_ADD: guildMemberAdd, | ||||
|   GUILD_MEMBER_REMOVE: guildMemberRemove, | ||||
|   GUILD_MEMBER_UPDATE: guildMemberUpdate, | ||||
|   GUILD_MEMBERS_CHUNK: undefined, | ||||
|   GUILD_MEMBERS_CHUNK: guildMembersChunk, | ||||
|   GUILD_ROLE_CREATE: guildRoleCreate, | ||||
|   GUILD_ROLE_UPDATE: guildRoleUpdate, | ||||
|   GUILD_ROLE_DELETE: guildRoleDelete, | ||||
|  | @ -70,11 +76,11 @@ export const gatewayHandlers: { | |||
|   MESSAGE_UPDATE: messageUpdate, | ||||
|   MESSAGE_DELETE: messageDelete, | ||||
|   MESSAGE_DELETE_BULK: messageDeleteBulk, | ||||
|   MESSAGE_REACTION_ADD: undefined, | ||||
|   MESSAGE_REACTION_REMOVE: undefined, | ||||
|   MESSAGE_REACTION_REMOVE_ALL: undefined, | ||||
|   MESSAGE_REACTION_REMOVE_EMOJI: undefined, | ||||
|   PRESENCE_UPDATE: undefined, | ||||
|   MESSAGE_REACTION_ADD: messageReactionAdd, | ||||
|   MESSAGE_REACTION_REMOVE: messageReactionRemove, | ||||
|   MESSAGE_REACTION_REMOVE_ALL: messageReactionRemoveAll, | ||||
|   MESSAGE_REACTION_REMOVE_EMOJI: messageReactionRemoveEmoji, | ||||
|   PRESENCE_UPDATE: presenceUpdate, | ||||
|   TYPING_START: typingStart, | ||||
|   USER_UPDATE: userUpdate, | ||||
|   VOICE_STATE_UPDATE: voiceStateUpdate, | ||||
|  |  | |||
							
								
								
									
										51
									
								
								src/gateway/handlers/messageReactionAdd.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/gateway/handlers/messageReactionAdd.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | |||
| import { Gateway, GatewayEventHandler } from '../index.ts' | ||||
| import { MessageReactionAddPayload } from '../../types/gateway.ts' | ||||
| import { TextChannel } from '../../structures/textChannel.ts' | ||||
| import { MessageReaction } from '../../structures/messageReaction.ts' | ||||
| import { UserPayload } from '../../types/user.ts' | ||||
| 
 | ||||
| export const messageReactionAdd: GatewayEventHandler = async ( | ||||
|   gateway: Gateway, | ||||
|   d: MessageReactionAddPayload | ||||
| ) => { | ||||
|   let channel = await gateway.client.channels.get<TextChannel>(d.channel_id) | ||||
|   if (channel === undefined) | ||||
|     channel = await gateway.client.channels.fetch<TextChannel>(d.channel_id) | ||||
|   if (channel === undefined) return | ||||
| 
 | ||||
|   let message = await channel.messages.get(d.message_id) | ||||
|   if (message === undefined) { | ||||
|     if (gateway.client.fetchUncachedReactions === true) { | ||||
|       message = await channel.messages.fetch(d.message_id) | ||||
|       if (message === undefined) return | ||||
|     } else return | ||||
|   } | ||||
| 
 | ||||
|   let user = await gateway.client.users.get(d.user_id) | ||||
|   if (user === undefined) { | ||||
|     if (gateway.client.fetchUncachedReactions === true) { | ||||
|       user = await gateway.client.users.fetch(d.user_id) | ||||
|       if (user === undefined) return | ||||
|     } else return | ||||
|   } | ||||
| 
 | ||||
|   let reaction = await message.reactions.get(d.emoji.id) | ||||
|   if (reaction === undefined) { | ||||
|     await message.reactions.set(d.emoji.id, { | ||||
|       count: 1, | ||||
|       emoji: d.emoji, | ||||
|       me: d.user_id === gateway.client.user?.id, | ||||
|     }) | ||||
|     reaction = ((await message.reactions.get( | ||||
|       d.emoji.id | ||||
|     )) as unknown) as MessageReaction | ||||
|   } | ||||
| 
 | ||||
|   const rawUser = ((await gateway.client.users.get( | ||||
|     d.user_id | ||||
|   )) as unknown) as UserPayload | ||||
| 
 | ||||
|   reaction.users.set(rawUser.id, rawUser) | ||||
| 
 | ||||
|   gateway.client.emit('messageReactionAdd', reaction, user) | ||||
| } | ||||
							
								
								
									
										36
									
								
								src/gateway/handlers/messageReactionRemove.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/gateway/handlers/messageReactionRemove.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | |||
| import { Gateway, GatewayEventHandler } from '../index.ts' | ||||
| import { MessageReactionRemovePayload } from '../../types/gateway.ts' | ||||
| import { TextChannel } from '../../structures/textChannel.ts' | ||||
| 
 | ||||
| export const messageReactionRemove: GatewayEventHandler = async ( | ||||
|   gateway: Gateway, | ||||
|   d: MessageReactionRemovePayload | ||||
| ) => { | ||||
|   let channel = await gateway.client.channels.get<TextChannel>(d.channel_id) | ||||
|   if (channel === undefined) | ||||
|     channel = await gateway.client.channels.fetch<TextChannel>(d.channel_id) | ||||
|   if (channel === undefined) return | ||||
| 
 | ||||
|   let message = await channel.messages.get(d.message_id) | ||||
|   if (message === undefined) { | ||||
|     if (gateway.client.fetchUncachedReactions === true) { | ||||
|       message = await channel.messages.fetch(d.message_id) | ||||
|       if (message === undefined) return | ||||
|     } else return | ||||
|   } | ||||
| 
 | ||||
|   let user = await gateway.client.users.get(d.user_id) | ||||
|   if (user === undefined) { | ||||
|     if (gateway.client.fetchUncachedReactions === true) { | ||||
|       user = await gateway.client.users.fetch(d.user_id) | ||||
|       if (user === undefined) return | ||||
|     } else return | ||||
|   } | ||||
| 
 | ||||
|   const reaction = await message.reactions.get(d.emoji.id) | ||||
|   if (reaction === undefined) return | ||||
| 
 | ||||
|   reaction.users.delete(d.user_id) | ||||
| 
 | ||||
|   gateway.client.emit('messageReactionRemove', reaction, user) | ||||
| } | ||||
							
								
								
									
										25
									
								
								src/gateway/handlers/messageReactionRemoveAll.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/gateway/handlers/messageReactionRemoveAll.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| import { Gateway, GatewayEventHandler } from '../index.ts' | ||||
| import { MessageReactionRemoveAllPayload } from '../../types/gateway.ts' | ||||
| import { TextChannel } from '../../structures/textChannel.ts' | ||||
| 
 | ||||
| export const messageReactionRemoveAll: GatewayEventHandler = async ( | ||||
|   gateway: Gateway, | ||||
|   d: MessageReactionRemoveAllPayload | ||||
| ) => { | ||||
|   let channel = await gateway.client.channels.get<TextChannel>(d.channel_id) | ||||
|   if (channel === undefined) | ||||
|     channel = await gateway.client.channels.fetch<TextChannel>(d.channel_id) | ||||
|   if (channel === undefined) return | ||||
| 
 | ||||
|   let message = await channel.messages.get(d.message_id) | ||||
|   if (message === undefined) { | ||||
|     if (gateway.client.fetchUncachedReactions === true) { | ||||
|       message = await channel.messages.fetch(d.message_id) | ||||
|       if (message === undefined) return | ||||
|     } else return | ||||
|   } | ||||
| 
 | ||||
|   await message.reactions.flush() | ||||
| 
 | ||||
|   gateway.client.emit('messageReactionRemoveAll', message) | ||||
| } | ||||
							
								
								
									
										28
									
								
								src/gateway/handlers/messageReactionRemoveEmoji.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/gateway/handlers/messageReactionRemoveEmoji.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | |||
| import { Gateway, GatewayEventHandler } from '../index.ts' | ||||
| import { MessageReactionRemoveEmojiPayload } from '../../types/gateway.ts' | ||||
| import { TextChannel } from '../../structures/textChannel.ts' | ||||
| 
 | ||||
| export const messageReactionRemoveEmoji: GatewayEventHandler = async ( | ||||
|   gateway: Gateway, | ||||
|   d: MessageReactionRemoveEmojiPayload | ||||
| ) => { | ||||
|   let channel = await gateway.client.channels.get<TextChannel>(d.channel_id) | ||||
|   if (channel === undefined) | ||||
|     channel = await gateway.client.channels.fetch<TextChannel>(d.channel_id) | ||||
|   if (channel === undefined) return | ||||
| 
 | ||||
|   let message = await channel.messages.get(d.message_id) | ||||
|   if (message === undefined) { | ||||
|     if (gateway.client.fetchUncachedReactions === true) { | ||||
|       message = await channel.messages.fetch(d.message_id) | ||||
|       if (message === undefined) return | ||||
|     } else return | ||||
|   } | ||||
| 
 | ||||
|   const reaction = await message.reactions.get(d.emoji.id) | ||||
|   if (reaction === undefined) return | ||||
| 
 | ||||
|   await reaction.users.flush() | ||||
| 
 | ||||
|   gateway.client.emit('messageReactionRemoveEmoji', message, reaction.emoji) | ||||
| } | ||||
							
								
								
									
										6
									
								
								src/gateway/handlers/presenceUpdate.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/gateway/handlers/presenceUpdate.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| import { Gateway, GatewayEventHandler } from '../index.ts' | ||||
| 
 | ||||
| export const presenceUpdate: GatewayEventHandler = async ( | ||||
|   gateway: Gateway, | ||||
|   d: any | ||||
| ) => {} | ||||
							
								
								
									
										44
									
								
								src/managers/messageReactions.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/managers/messageReactions.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { Emoji } from '../structures/emoji.ts' | ||||
| import { Guild } from '../structures/guild.ts' | ||||
| import { Message } from '../structures/message.ts' | ||||
| import { MessageReaction } from '../structures/messageReaction.ts' | ||||
| import { Reaction } from '../types/channel.ts' | ||||
| import { BaseManager } from './base.ts' | ||||
| 
 | ||||
| export class MessageReactionsManager extends BaseManager< | ||||
|   Reaction, | ||||
|   MessageReaction | ||||
| > { | ||||
|   message: Message | ||||
| 
 | ||||
|   constructor(client: Client, message: Message) { | ||||
|     super(client, `reactions:${message.id}`, Guild) | ||||
|     this.message = message | ||||
|   } | ||||
| 
 | ||||
|   async get(id: string): Promise<MessageReaction | undefined> { | ||||
|     const raw = await this._get(id) | ||||
|     if (raw === undefined) return | ||||
| 
 | ||||
|     let emoji = await this.client.emojis.get(raw.emoji.id) | ||||
|     if (emoji === undefined) emoji = new Emoji(this.client, raw.emoji) | ||||
| 
 | ||||
|     const reaction = new MessageReaction(this.client, raw, this.message, emoji) | ||||
|     return reaction | ||||
|   } | ||||
| 
 | ||||
|   async set(key: string, value: Reaction): Promise<any> { | ||||
|     return this.client.cache.set( | ||||
|       this.cacheName, | ||||
|       key, | ||||
|       value, | ||||
|       this.client.reactionCacheLifetime | ||||
|     ) | ||||
|   } | ||||
| 
 | ||||
|   async flush(): Promise<any> { | ||||
|     await this.client.cache.deleteCache(`reaction_users:${this.message.id}`) | ||||
|     return this.client.cache.deleteCache(this.cacheName) | ||||
|   } | ||||
| } | ||||
							
								
								
									
										13
									
								
								src/managers/reactionUsers.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/managers/reactionUsers.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { MessageReaction } from '../structures/messageReaction.ts' | ||||
| import { UserManager } from './users.ts' | ||||
| 
 | ||||
| export class ReactionUsersManager extends UserManager { | ||||
|   reaction: MessageReaction | ||||
| 
 | ||||
|   constructor(client: Client, reaction: MessageReaction) { | ||||
|     super(client) | ||||
|     this.cacheName = `reaction_users:${reaction.message.id}` | ||||
|     this.reaction = reaction | ||||
|   } | ||||
| } | ||||
|  | @ -7,12 +7,10 @@ import { DefaultCacheAdapter, ICacheAdapter } from './cacheAdapter.ts' | |||
| import { UserManager } from '../managers/users.ts' | ||||
| import { GuildManager } from '../managers/guilds.ts' | ||||
| import { ChannelsManager } from '../managers/channels.ts' | ||||
| import { | ||||
|   ClientPresence | ||||
| } from '../structures/presence.ts' | ||||
| import { ClientPresence } from '../structures/presence.ts' | ||||
| import { EmojisManager } from '../managers/emojis.ts' | ||||
| import { ActivityGame, ClientActivity } from "../types/presence.ts" | ||||
| import { ClientEvents } from "../gateway/handlers/index.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 */ | ||||
|  | @ -22,9 +20,9 @@ export interface ClientOptions { | |||
|   /** Gateway Intents */ | ||||
|   intents?: GatewayIntents[] | ||||
|   /** Cache Adapter to use, defaults to Collections one */ | ||||
|   cache?: ICacheAdapter, | ||||
|   cache?: ICacheAdapter | ||||
|   /** Force New Session and don't use cached Session (by persistent caching) */ | ||||
|   forceNewSession?: boolean, | ||||
|   forceNewSession?: boolean | ||||
|   /** Startup presence of client */ | ||||
|   presence?: ClientPresence | ClientActivity | ActivityGame | ||||
|   /** Whether it's a bot user or not? Use this if selfbot! */ | ||||
|  | @ -33,19 +31,21 @@ export interface ClientOptions { | |||
|   canary?: boolean | ||||
|   /** Time till which Messages are to be cached, in MS. Default is 3600000 */ | ||||
|   messageCacheLifetime?: number | ||||
|   /** Time till which Message Reactions are to be cached, in MS. Default is 3600000 */ | ||||
|   reactionCacheLifetime?: number | ||||
|   /** Whether to fetch Uncached Message of Reaction or not? */ | ||||
|   fetchUncachedReactions?: boolean | ||||
| } | ||||
| 
 | ||||
| export declare interface Client { | ||||
|   on: <U extends string>( | ||||
|     event: U, listener: ClientEvents[U] | ||||
|   ) => this | ||||
|   on: <U extends string>(event: U, listener: ClientEvents[U]) => this | ||||
| 
 | ||||
|   emit: <U extends string>( | ||||
|     event: U, ...args: Parameters<ClientEvents[U]> | ||||
|     event: U, | ||||
|     ...args: Parameters<ClientEvents[U]> | ||||
|   ) => boolean | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * Discord Client. | ||||
|  */ | ||||
|  | @ -68,12 +68,16 @@ export class Client extends EventEmitter { | |||
|   forceNewSession?: boolean | ||||
|   /** Time till messages to stay cached, in MS. */ | ||||
|   messageCacheLifetime: number = 3600000 | ||||
|   /** Time till messages to stay cached, in MS. */ | ||||
|   reactionCacheLifetime: number = 3600000 | ||||
|   /** Whether to fetch Uncached Message of Reaction or not? */ | ||||
|   fetchUncachedReactions: boolean = false | ||||
| 
 | ||||
|   users: UserManager = new UserManager(this) | ||||
|   guilds: GuildManager = new GuildManager(this) | ||||
|   channels: ChannelsManager = new ChannelsManager(this) | ||||
|   emojis: EmojisManager = new EmojisManager(this) | ||||
|    | ||||
| 
 | ||||
|   /** Whether this client will login as bot user or not */ | ||||
|   bot: boolean = true | ||||
|   /** Whether the REST Manager will use Canary API or not */ | ||||
|  | @ -81,7 +85,7 @@ export class Client extends EventEmitter { | |||
|   /** Client's presence. Startup one if set before connecting */ | ||||
|   presence: ClientPresence = new ClientPresence() | ||||
| 
 | ||||
|   constructor (options: ClientOptions = {}) { | ||||
|   constructor(options: ClientOptions = {}) { | ||||
|     super() | ||||
|     this.token = options.token | ||||
|     this.intents = options.intents | ||||
|  | @ -94,17 +98,22 @@ export class Client extends EventEmitter { | |||
|           : new ClientPresence(options.presence) | ||||
|     if (options.bot === false) this.bot = false | ||||
|     if (options.canary === true) this.canary = true | ||||
|     if (options.messageCacheLifetime !== undefined) this.messageCacheLifetime = options.messageCacheLifetime | ||||
|     if (options.messageCacheLifetime !== undefined) | ||||
|       this.messageCacheLifetime = options.messageCacheLifetime | ||||
|     if (options.reactionCacheLifetime !== undefined) | ||||
|       this.reactionCacheLifetime = options.reactionCacheLifetime | ||||
|     if (options.fetchUncachedReactions === true) | ||||
|       this.fetchUncachedReactions = true | ||||
|   } | ||||
| 
 | ||||
|   /** Set Cache Adapter */ | ||||
|   setAdapter (adapter: ICacheAdapter): Client { | ||||
|   setAdapter(adapter: ICacheAdapter): Client { | ||||
|     this.cache = adapter | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   /** Change Presence of Client */ | ||||
|   setPresence (presence: ClientPresence | ClientActivity | ActivityGame): void { | ||||
|   setPresence(presence: ClientPresence | ClientActivity | ActivityGame): void { | ||||
|     if (presence instanceof ClientPresence) { | ||||
|       this.presence = presence | ||||
|     } else this.presence = new ClientPresence(presence) | ||||
|  | @ -112,7 +121,7 @@ export class Client extends EventEmitter { | |||
|   } | ||||
| 
 | ||||
|   /** Emit debug event */ | ||||
|   debug (tag: string, msg: string): void { | ||||
|   debug(tag: string, msg: string): void { | ||||
|     this.emit('debug', `[${tag}] ${msg}`) | ||||
|   } | ||||
| 
 | ||||
|  | @ -124,7 +133,7 @@ export class Client extends EventEmitter { | |||
|    * @param token Your token. This is required. | ||||
|    * @param intents Gateway intents in array. This is required. | ||||
|    */ | ||||
|   connect (token?: string, intents?: GatewayIntents[]): void { | ||||
|   connect(token?: string, intents?: GatewayIntents[]): void { | ||||
|     if (token === undefined && this.token !== undefined) token = this.token | ||||
|     else if (this.token === undefined && token !== undefined) { | ||||
|       this.token = token | ||||
|  |  | |||
|  | @ -1,120 +1,129 @@ | |||
| import { Base } from './base.ts' | ||||
| import { | ||||
|   Attachment, | ||||
|   ChannelMention, | ||||
|   MessageActivity, | ||||
|   MessageApplication, | ||||
|   MessageOption, | ||||
|   MessagePayload, | ||||
|   MessageReference, | ||||
|   Reaction | ||||
| } from '../types/channel.ts' | ||||
| import { Client } from '../models/client.ts' | ||||
| import { User } from './user.ts' | ||||
| import { Member } from './member.ts' | ||||
| import { Embed } from './embed.ts' | ||||
| import { CHANNEL_MESSAGE } from '../types/endpoint.ts' | ||||
| import { MessageMentions } from './messageMentions.ts' | ||||
| import { TextChannel } from './textChannel.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| 
 | ||||
| type AllMessageOptions = MessageOption | Embed | ||||
| 
 | ||||
| export class Message extends Base { | ||||
|   id: string | ||||
|   channelID: string | ||||
|   channel: TextChannel | ||||
|   guildID?: string | ||||
|   guild?: Guild | ||||
|   author: User | ||||
|   member?: Member | ||||
|   content: string | ||||
|   timestamp: string | ||||
|   editedTimestamp?: string | ||||
|   tts: boolean | ||||
|   mentionEveryone: boolean | ||||
|   mentions: MessageMentions | ||||
|   mentionRoles: string[] | ||||
|   mentionChannels?: ChannelMention[] | ||||
|   attachments: Attachment[] | ||||
|   embeds: Embed[] | ||||
|   reactions?: Reaction[] | ||||
|   nonce?: string | number | ||||
|   pinned: boolean | ||||
|   webhookID?: string | ||||
|   type: number | ||||
|   activity?: MessageActivity | ||||
|   application?: MessageApplication | ||||
|   messageReference?: MessageReference | ||||
|   flags?: number | ||||
| 
 | ||||
|   constructor ( | ||||
|     client: Client, | ||||
|     data: MessagePayload, | ||||
|     channel: TextChannel, | ||||
|     author: User | ||||
|   ) { | ||||
|     super(client) | ||||
|     this.id = data.id | ||||
|     this.channelID = data.channel_id | ||||
|     this.guildID = data.guild_id | ||||
|     this.author = author | ||||
|     this.content = data.content | ||||
|     this.timestamp = data.timestamp | ||||
|     this.editedTimestamp = data.edited_timestamp | ||||
|     this.tts = data.tts | ||||
|     this.mentionEveryone = data.mention_everyone | ||||
|     this.mentions = new MessageMentions(this.client, this) | ||||
|     this.mentionRoles = data.mention_roles | ||||
|     this.mentionChannels = data.mention_channels | ||||
|     this.attachments = data.attachments | ||||
|     this.embeds = data.embeds.map(v => new Embed(v)) | ||||
|     this.reactions = data.reactions | ||||
|     this.nonce = data.nonce | ||||
|     this.pinned = data.pinned | ||||
|     this.webhookID = data.webhook_id | ||||
|     this.type = data.type | ||||
|     this.activity = data.activity | ||||
|     this.application = data.application | ||||
|     this.messageReference = data.message_reference | ||||
|     this.flags = data.flags | ||||
|     this.channel = channel | ||||
|   } | ||||
| 
 | ||||
|   protected readFromData (data: MessagePayload): void { | ||||
|     super.readFromData(data) | ||||
|     this.channelID = data.channel_id ?? this.channelID | ||||
|     this.guildID = data.guild_id ?? this.guildID | ||||
|     this.content = data.content ?? this.content | ||||
|     this.timestamp = data.timestamp ?? this.timestamp | ||||
|     this.editedTimestamp = data.edited_timestamp ?? this.editedTimestamp | ||||
|     this.tts = data.tts ?? this.tts | ||||
|     this.mentionEveryone = data.mention_everyone ?? this.mentionEveryone | ||||
|     this.mentionRoles = data.mention_roles ?? this.mentionRoles | ||||
|     this.mentionChannels = data.mention_channels ?? this.mentionChannels | ||||
|     this.attachments = data.attachments ?? this.attachments | ||||
|     this.embeds = data.embeds.map(v => new Embed(v)) ?? this.embeds | ||||
|     this.reactions = data.reactions ?? this.reactions | ||||
|     this.nonce = data.nonce ?? this.nonce | ||||
|     this.pinned = data.pinned ?? this.pinned | ||||
|     this.webhookID = data.webhook_id ?? this.webhookID | ||||
|     this.type = data.type ?? this.type | ||||
|     this.activity = data.activity ?? this.activity | ||||
|     this.application = data.application ?? this.application | ||||
|     this.messageReference = data.message_reference ?? this.messageReference | ||||
|     this.flags = data.flags ?? this.flags | ||||
|   } | ||||
| 
 | ||||
|   async edit (text?: string, option?: MessageOption): Promise<Message> { | ||||
|     return this.channel.editMessage(this.id, text, option)   | ||||
|   } | ||||
| 
 | ||||
|   /** These will **not** work in all servers, as this feature is coming slowly. */ | ||||
|   async reply(text?: string | AllMessageOptions, option?: AllMessageOptions): Promise<Message> { | ||||
|     return this.channel.send(text, option, this) | ||||
|   } | ||||
| 
 | ||||
|   async delete (): Promise<void> { | ||||
|     return this.client.rest.delete(CHANNEL_MESSAGE(this.channelID, this.id)) | ||||
|   } | ||||
| } | ||||
| import { Base } from './base.ts' | ||||
| import { | ||||
|   Attachment, | ||||
|   ChannelMention, | ||||
|   MessageActivity, | ||||
|   MessageApplication, | ||||
|   MessageOption, | ||||
|   MessagePayload, | ||||
|   MessageReference, | ||||
| } from '../types/channel.ts' | ||||
| import { Client } from '../models/client.ts' | ||||
| import { User } from './user.ts' | ||||
| import { Member } from './member.ts' | ||||
| import { Embed } from './embed.ts' | ||||
| import { CHANNEL_MESSAGE } from '../types/endpoint.ts' | ||||
| import { MessageMentions } from './messageMentions.ts' | ||||
| import { TextChannel } from './textChannel.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| import { MessageReactionsManager } from '../managers/messageReactions.ts' | ||||
| 
 | ||||
| type AllMessageOptions = MessageOption | Embed | ||||
| 
 | ||||
| export class Message extends Base { | ||||
|   id: string | ||||
|   channelID: string | ||||
|   channel: TextChannel | ||||
|   guildID?: string | ||||
|   guild?: Guild | ||||
|   author: User | ||||
|   member?: Member | ||||
|   content: string | ||||
|   timestamp: string | ||||
|   editedTimestamp?: string | ||||
|   tts: boolean | ||||
|   mentionEveryone: boolean | ||||
|   mentions: MessageMentions | ||||
|   mentionRoles: string[] | ||||
|   mentionChannels?: ChannelMention[] | ||||
|   attachments: Attachment[] | ||||
|   embeds: Embed[] | ||||
|   reactions: MessageReactionsManager | ||||
|   nonce?: string | number | ||||
|   pinned: boolean | ||||
|   webhookID?: string | ||||
|   type: number | ||||
|   activity?: MessageActivity | ||||
|   application?: MessageApplication | ||||
|   messageReference?: MessageReference | ||||
|   flags?: number | ||||
| 
 | ||||
|   constructor( | ||||
|     client: Client, | ||||
|     data: MessagePayload, | ||||
|     channel: TextChannel, | ||||
|     author: User | ||||
|   ) { | ||||
|     super(client) | ||||
|     this.id = data.id | ||||
|     this.channelID = data.channel_id | ||||
|     this.guildID = data.guild_id | ||||
|     this.author = author | ||||
|     this.content = data.content | ||||
|     this.timestamp = data.timestamp | ||||
|     this.editedTimestamp = data.edited_timestamp | ||||
|     this.tts = data.tts | ||||
|     this.mentionEveryone = data.mention_everyone | ||||
|     this.mentions = new MessageMentions(this.client, this) | ||||
|     this.mentionRoles = data.mention_roles | ||||
|     this.mentionChannels = data.mention_channels | ||||
|     this.attachments = data.attachments | ||||
|     this.embeds = data.embeds.map((v) => new Embed(v)) | ||||
|     this.reactions = new MessageReactionsManager(this.client, this) | ||||
|     this.nonce = data.nonce | ||||
|     this.pinned = data.pinned | ||||
|     this.webhookID = data.webhook_id | ||||
|     this.type = data.type | ||||
|     this.activity = data.activity | ||||
|     this.application = data.application | ||||
|     this.messageReference = data.message_reference | ||||
|     this.flags = data.flags | ||||
|     this.channel = channel | ||||
|   } | ||||
| 
 | ||||
|   protected readFromData(data: MessagePayload): void { | ||||
|     super.readFromData(data) | ||||
|     this.channelID = data.channel_id ?? this.channelID | ||||
|     this.guildID = data.guild_id ?? this.guildID | ||||
|     this.content = data.content ?? this.content | ||||
|     this.timestamp = data.timestamp ?? this.timestamp | ||||
|     this.editedTimestamp = data.edited_timestamp ?? this.editedTimestamp | ||||
|     this.tts = data.tts ?? this.tts | ||||
|     this.mentionEveryone = data.mention_everyone ?? this.mentionEveryone | ||||
|     this.mentionRoles = data.mention_roles ?? this.mentionRoles | ||||
|     this.mentionChannels = data.mention_channels ?? this.mentionChannels | ||||
|     this.attachments = data.attachments ?? this.attachments | ||||
|     this.embeds = data.embeds.map((v) => new Embed(v)) ?? this.embeds | ||||
|     this.nonce = data.nonce ?? this.nonce | ||||
|     this.pinned = data.pinned ?? this.pinned | ||||
|     this.webhookID = data.webhook_id ?? this.webhookID | ||||
|     this.type = data.type ?? this.type | ||||
|     this.activity = data.activity ?? this.activity | ||||
|     this.application = data.application ?? this.application | ||||
|     this.messageReference = data.message_reference ?? this.messageReference | ||||
|     this.flags = data.flags ?? this.flags | ||||
|   } | ||||
| 
 | ||||
|   /** Edit this message. */ | ||||
|   async edit(text?: string, option?: MessageOption): Promise<Message> { | ||||
|     if ( | ||||
|       this.client.user !== undefined && | ||||
|       this.author.id !== this.client.user?.id | ||||
|     ) | ||||
|       throw new Error("Cannot edit other users' messages") | ||||
|     return this.channel.editMessage(this.id, text, option) | ||||
|   } | ||||
| 
 | ||||
|   /** Create a Reply to this Message. */ | ||||
|   async reply( | ||||
|     text?: string | AllMessageOptions, | ||||
|     option?: AllMessageOptions | ||||
|   ): Promise<Message> { | ||||
|     return this.channel.send(text, option, this) | ||||
|   } | ||||
| 
 | ||||
|   /** Delete the Message. */ | ||||
|   async delete(): Promise<void> { | ||||
|     return this.client.rest.delete(CHANNEL_MESSAGE(this.channelID, this.id)) | ||||
|   } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										28
									
								
								src/structures/messageReaction.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/structures/messageReaction.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | |||
| import { ReactionUsersManager } from '../managers/reactionUsers.ts' | ||||
| import { Client } from '../models/client.ts' | ||||
| import { Reaction } from '../types/channel.ts' | ||||
| import { Base } from './base.ts' | ||||
| import { Emoji } from './emoji.ts' | ||||
| import { Message } from './message.ts' | ||||
| 
 | ||||
| export class MessageReaction extends Base { | ||||
|   message: Message | ||||
|   count: number = 0 | ||||
|   emoji: Emoji | ||||
|   me: boolean = false | ||||
|   users: ReactionUsersManager | ||||
| 
 | ||||
|   constructor(client: Client, data: Reaction, message: Message, emoji: Emoji) { | ||||
|     super(client, data) | ||||
|     this.message = message | ||||
|     this.emoji = emoji | ||||
|     this.count = data.count | ||||
|     this.me = data.me | ||||
|     this.users = new ReactionUsersManager(client, this) | ||||
|   } | ||||
| 
 | ||||
|   fromPayload(data: Reaction): void { | ||||
|     this.count = data.count | ||||
|     this.me = data.me | ||||
|   } | ||||
| } | ||||
|  | @ -118,6 +118,22 @@ client.on('voiceStateRemove', (state) => { | |||
|   console.log('VC Leave', state) | ||||
| }) | ||||
| 
 | ||||
| client.on('messageReactionAdd', (reaction, user) => { | ||||
|   console.log(`${user.tag} reacted with ${reaction.emoji.name}`) | ||||
| }) | ||||
| 
 | ||||
| client.on('messageReactionRemove', (reaction, user) => { | ||||
|   console.log(`${user.tag} removed reaction ${reaction.emoji.name}`) | ||||
| }) | ||||
| 
 | ||||
| client.on('messageReactionRemoveEmoji', (message, emoji) => { | ||||
|   console.log(`All ${emoji.name} emoji reactions removed from ${message.id}`) | ||||
| }) | ||||
| 
 | ||||
| client.on('messageReactionRemoveAll', (message) => { | ||||
|   console.log(`All reactions remove from Message: ${message.id}`) | ||||
| }) | ||||
| 
 | ||||
| // client.on('raw', (evt: string) => console.log(`EVENT: ${evt}`))
 | ||||
| 
 | ||||
| const files = Deno.readDirSync('./src/test/cmds') | ||||
|  |  | |||
|  | @ -1,14 +1,14 @@ | |||
| // https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway
 | ||||
| // 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 { Guild } from '../structures/guild.ts' | ||||
| import { Member } from '../structures/member.ts' | ||||
| import { EmojiPayload } from './emoji.ts' | ||||
| import { MemberPayload } from './guild.ts' | ||||
| import { | ||||
|   ActivityGame, | ||||
|   ActivityPayload, | ||||
|   StatusType, | ||||
|   ClientStatus | ||||
|   ClientStatus, | ||||
| } from './presence.ts' | ||||
| import { RolePayload } from './role.ts' | ||||
| import { UserPayload } from './user.ts' | ||||
|  | @ -27,7 +27,7 @@ export enum GatewayOpcodes { // 문서를 확인해본 결과 Opcode 5번은 비 | |||
|   REQUEST_GUILD_MEMBERS = 8, | ||||
|   INVALID_SESSION = 9, | ||||
|   HELLO = 10, | ||||
|   HEARTBEAT_ACK = 11 | ||||
|   HEARTBEAT_ACK = 11, | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  | @ -47,7 +47,7 @@ export enum GatewayCloseCodes { | |||
|   SHARDING_REQUIRED = 4011, | ||||
|   INVALID_API_VERSION = 4012, | ||||
|   INVALID_INTENTS = 4013, | ||||
|   DISALLOWED_INTENTS = 4014 | ||||
|   DISALLOWED_INTENTS = 4014, | ||||
| } | ||||
| 
 | ||||
| export enum GatewayIntents { | ||||
|  | @ -65,7 +65,7 @@ export enum GatewayIntents { | |||
|   GUILD_MESSAGE_TYPING = 1 << 11, | ||||
|   DIRECT_MESSAGES = 1 << 12, | ||||
|   DIRECT_MESSAGE_REACTIONS = 1 << 13, | ||||
|   DIRECT_MESSAGE_TYPING = 1 << 13 | ||||
|   DIRECT_MESSAGE_TYPING = 1 << 13, | ||||
| } | ||||
| 
 | ||||
| export enum GatewayEvents { | ||||
|  | @ -105,7 +105,7 @@ export enum GatewayEvents { | |||
|   User_Update = 'USER_UPDATE', | ||||
|   Voice_Server_Update = 'VOICE_SERVER_UPDATE', | ||||
|   Voice_State_Update = 'VOICE_STATE_UPDATE', | ||||
|   Webhooks_Update = 'WEBHOOKS_UPDATE' | ||||
|   Webhooks_Update = 'WEBHOOKS_UPDATE', | ||||
| } | ||||
| 
 | ||||
| export interface IdentityPayload { | ||||
|  | @ -290,6 +290,13 @@ export interface MessageReactionRemoveAllPayload { | |||
|   message_id: string | ||||
| } | ||||
| 
 | ||||
| export interface MessageReactionRemoveEmojiPayload { | ||||
|   channel_id: string | ||||
|   message_id: string | ||||
|   guild_id?: string | ||||
|   emoji: EmojiPayload | ||||
| } | ||||
| 
 | ||||
| export interface PresenceUpdatePayload { | ||||
|   user: UserPayload | ||||
|   guild_id: string | ||||
|  | @ -335,4 +342,4 @@ export interface TypingStartPayload { | |||
| export interface TypingStartGuildData { | ||||
|   guild: Guild | ||||
|   member: Member | ||||
| } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue