Fixed Member Caching, Message#member, Member#roles
This commit is contained in:
		
							parent
							
								
									71c1499c1d
								
							
						
					
					
						commit
						70824135a7
					
				
					 13 changed files with 103 additions and 85 deletions
				
			
		|  | @ -1,16 +1,15 @@ | ||||||
| import { Gateway, GatewayEventHandler } from '../index.ts' | import { Gateway, GatewayEventHandler } from '../index.ts' | ||||||
| import cache from '../../models/cache.ts' |  | ||||||
| import { Guild } from '../../structures/guild.ts' | import { Guild } from '../../structures/guild.ts' | ||||||
| import { User } from '../../structures/user.ts' | import { User } from '../../structures/user.ts' | ||||||
| import { GuildBanRemovePayload } from '../../types/gateway.ts' | import { GuildBanRemovePayload } from '../../types/gateway.ts' | ||||||
| 
 | 
 | ||||||
| export const guildBanRemove: GatewayEventHandler = ( | export const guildBanRemove: GatewayEventHandler = async ( | ||||||
|   gateway: Gateway, |   gateway: Gateway, | ||||||
|   d: GuildBanRemovePayload |   d: GuildBanRemovePayload | ||||||
| ) => { | ) => { | ||||||
|   const guild: Guild = cache.get('guild', d.guild_id) |   const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id) | ||||||
|   const user: User = |   const user: User = | ||||||
|     cache.get('user', d.user.id) ?? new User(gateway.client, d.user) |     await gateway.client.users.get(d.user.id) ?? new User(gateway.client, d.user) | ||||||
| 
 | 
 | ||||||
|   if (guild !== undefined) { |   if (guild !== undefined) { | ||||||
|     gateway.client.emit('guildBanRemove', guild, user) |     gateway.client.emit('guildBanRemove', guild, user) | ||||||
|  |  | ||||||
|  | @ -17,11 +17,26 @@ export const messageCreate: GatewayEventHandler = async ( | ||||||
|   const user = new User(gateway.client, d.author) |   const user = new User(gateway.client, d.author) | ||||||
|   await gateway.client.users.set(d.author.id, d.author) |   await gateway.client.users.set(d.author.id, d.author) | ||||||
|   let guild |   let guild | ||||||
|  |   let member | ||||||
|   if (d.guild_id !== undefined) { |   if (d.guild_id !== undefined) { | ||||||
|     guild = await gateway.client.guilds.get(d.guild_id) |     guild = await gateway.client.guilds.get(d.guild_id) | ||||||
|   } |   } | ||||||
|  |   if (guild !== undefined && d.member !== undefined) { | ||||||
|  |     d.member.user = d.author | ||||||
|  |     await guild.members.set(d.author.id, d.member) | ||||||
|  |     member = await guild.members.get(d.author.id) | ||||||
|  |   } | ||||||
|   const mentions = new MessageMentions() |   const mentions = new MessageMentions() | ||||||
|   const message = new Message(gateway.client, d, channel as any, user, mentions) |   const message = new Message(gateway.client, d, channel as any, user, mentions) | ||||||
|  |   message.member = member | ||||||
|   if (guild !== undefined) message.guild = guild |   if (guild !== undefined) message.guild = guild | ||||||
|  |   if (message.member !== undefined) { | ||||||
|  |     if(message.member.user === undefined) { | ||||||
|  |       const user = await gateway.client.users.get(message.member.id) | ||||||
|  |       if(user !== undefined) { | ||||||
|  |         message.member.user = user | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|   gateway.client.emit('messageCreate', message) |   gateway.client.emit('messageCreate', message) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,7 +3,9 @@ import { Collection } from "../utils/collection.ts"; | ||||||
| 
 | 
 | ||||||
| export class BaseManager<T, T2> { | export class BaseManager<T, T2> { | ||||||
|   client: Client |   client: Client | ||||||
|  |   /** Cache Name or Key used to differentiate caches */ | ||||||
|   cacheName: string |   cacheName: string | ||||||
|  |   /** Which data type does this cache have */ | ||||||
|   DataType: any |   DataType: any | ||||||
| 
 | 
 | ||||||
|   constructor (client: Client, cacheName: string, DataType: any) { |   constructor (client: Client, cacheName: string, DataType: any) { | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | import { User } from "../structures/user.ts"; | ||||||
| import { Client } from "../models/client.ts"; | import { Client } from "../models/client.ts"; | ||||||
| import { Guild } from "../structures/guild.ts"; | import { Guild } from "../structures/guild.ts"; | ||||||
| import { Member } from "../structures/member.ts"; | import { Member } from "../structures/member.ts"; | ||||||
|  | @ -13,11 +14,29 @@ export class MembersManager extends BaseManager<MemberPayload, Member> { | ||||||
|     this.guild = guild |     this.guild = guild | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   async get (key: string): Promise<Member | undefined> { | ||||||
|  |     const raw = await this._get(key) | ||||||
|  |     if (raw === undefined) return | ||||||
|  |     const user = new User(this.client, raw.user) | ||||||
|  |     const res = new this.DataType(this.client, raw, user) | ||||||
|  |     for (const roleid of res.roleIDs as string[]) { | ||||||
|  |       const role = await this.guild.roles.get(roleid) | ||||||
|  |       if(role !== undefined) res.roles.push(role) | ||||||
|  |     } | ||||||
|  |     return res | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   async fetch(id: string): Promise<Member> { |   async fetch(id: string): Promise<Member> { | ||||||
|     return await new Promise((resolve, reject) => { |     return await new Promise((resolve, reject) => { | ||||||
|       this.client.rest.get(GUILD_MEMBER(this.guild.id, id)).then(data => { |       this.client.rest.get(GUILD_MEMBER(this.guild.id, id)).then(async data => { | ||||||
|         this.set(id, data as MemberPayload) |         await this.set(id, data as MemberPayload) | ||||||
|         resolve(new Member(this.client, data as MemberPayload)) |         const user: User = new User(this.client, data.user) | ||||||
|  |         const res = new Member(this.client, data as MemberPayload, user) | ||||||
|  |         for (const roleid of res.roleIDs as string[]) { | ||||||
|  |           const role = await this.guild.roles.get(roleid) | ||||||
|  |           if(role !== undefined) res.roles.push(role) | ||||||
|  |         } | ||||||
|  |         resolve(res) | ||||||
|       }).catch(e => reject(e)) |       }).catch(e => reject(e)) | ||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -1,48 +0,0 @@ | ||||||
| let caches: any = {} |  | ||||||
| 
 |  | ||||||
| const get = (cacheName: string, key: string): any => { |  | ||||||
|   const gotCache: Map<string, any> = caches[cacheName] |  | ||||||
|   if (gotCache === undefined || !(gotCache instanceof Map)) { |  | ||||||
|     return undefined |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   const gotMap = gotCache.get(key) |  | ||||||
|   return gotMap |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| const set = (cacheName: string, key: string, value: any): any => { |  | ||||||
|   let gotCache: Map<string, any> = caches[cacheName] |  | ||||||
|   if (gotCache === undefined || !(gotCache instanceof Map)) { |  | ||||||
|     gotCache = caches[cacheName] = new Map<string, any>() |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   gotCache.set(key, value) |  | ||||||
| 
 |  | ||||||
|   return value |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| const del = (cacheName: string, key: string): boolean | undefined => { |  | ||||||
|   const gotCache: Map<string, any> = caches[cacheName] |  | ||||||
|   if (gotCache === undefined || !(gotCache instanceof Map)) { |  | ||||||
|     return |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   return gotCache.delete(key) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| const deleteCache = (cacheName: string): void => { |  | ||||||
|   const gotCache = caches[cacheName] |  | ||||||
|   if (gotCache === undefined) { |  | ||||||
|     return |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
 |  | ||||||
|   delete caches[cacheName] |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| const resetCaches = (): void => { |  | ||||||
|   caches = {} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| export default { get, set, del, deleteCache, resetCaches } |  | ||||||
| export { get, set, del, deleteCache, resetCaches } |  | ||||||
|  | @ -13,12 +13,19 @@ import { ActivityGame, ClientActivity, ClientPresence } from "../structures/pres | ||||||
| 
 | 
 | ||||||
| /** Some Client Options to modify behaviour */ | /** Some Client Options to modify behaviour */ | ||||||
| export interface ClientOptions { | export interface ClientOptions { | ||||||
|  |   /** Token of the Bot/User */ | ||||||
|   token?: string |   token?: string | ||||||
|  |   /** Gateway Intents */ | ||||||
|   intents?: GatewayIntents[] |   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 |   presence?: ClientPresence | ClientActivity | ActivityGame | ||||||
|  |   /** Whether it's a bot user or not? Use this if selfbot! */ | ||||||
|   bot?: boolean |   bot?: boolean | ||||||
|  |   /** Force all requests to Canary API */ | ||||||
|   canary?: boolean |   canary?: boolean | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -26,22 +33,34 @@ export interface ClientOptions { | ||||||
|  * Discord Client. |  * Discord Client. | ||||||
|  */ |  */ | ||||||
| export class Client extends EventEmitter { | export class Client extends EventEmitter { | ||||||
|  |   /** Gateway object */ | ||||||
|   gateway?: Gateway |   gateway?: Gateway | ||||||
|  |   /** REST Manager - used to make all requests */ | ||||||
|   rest: RESTManager = new RESTManager(this) |   rest: RESTManager = new RESTManager(this) | ||||||
|  |   /** User which Client logs in to, undefined until logs in */ | ||||||
|   user?: User |   user?: User | ||||||
|  |   /** WebSocket ping of Client */ | ||||||
|   ping = 0 |   ping = 0 | ||||||
|  |   /** Token of the Bot/User */ | ||||||
|   token?: string |   token?: string | ||||||
|  |   /** Cache Adapter */ | ||||||
|   cache: ICacheAdapter = new DefaultCacheAdapter() |   cache: ICacheAdapter = new DefaultCacheAdapter() | ||||||
|  |   /** Gateway Intents */ | ||||||
|   intents?: GatewayIntents[] |   intents?: GatewayIntents[] | ||||||
|  |   /** Whether to force new session or not */ | ||||||
|   forceNewSession?: boolean |   forceNewSession?: boolean | ||||||
|  | 
 | ||||||
|   users: UserManager = new UserManager(this) |   users: UserManager = new UserManager(this) | ||||||
|   guilds: GuildManager = new GuildManager(this) |   guilds: GuildManager = new GuildManager(this) | ||||||
|   channels: ChannelsManager = new ChannelsManager(this) |   channels: ChannelsManager = new ChannelsManager(this) | ||||||
|   messages: MessagesManager = new MessagesManager(this) |   messages: MessagesManager = new MessagesManager(this) | ||||||
|   emojis: EmojisManager = new EmojisManager(this) |   emojis: EmojisManager = new EmojisManager(this) | ||||||
|  |    | ||||||
|  |   /** Whether this client will login as bot user or not */ | ||||||
|   bot: boolean = true |   bot: boolean = true | ||||||
|  |   /** Whether the REST Manager will use Canary API or not */ | ||||||
|   canary: boolean = false |   canary: boolean = false | ||||||
| 
 |   /** Client's presence. Startup one if set before connecting */ | ||||||
|   presence: ClientPresence = new ClientPresence() |   presence: ClientPresence = new ClientPresence() | ||||||
| 
 | 
 | ||||||
|   constructor (options: ClientOptions = {}) { |   constructor (options: ClientOptions = {}) { | ||||||
|  | @ -55,11 +74,13 @@ export class Client extends EventEmitter { | ||||||
|     if (options.canary === true) this.canary = true |     if (options.canary === true) this.canary = true | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /** Set Cache Adapter */ | ||||||
|   setAdapter (adapter: ICacheAdapter): Client { |   setAdapter (adapter: ICacheAdapter): Client { | ||||||
|     this.cache = adapter |     this.cache = adapter | ||||||
|     return this |     return this | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /** Change Presence of Client */ | ||||||
|   setPresence (presence: ClientPresence | ClientActivity | ActivityGame): void { |   setPresence (presence: ClientPresence | ClientActivity | ActivityGame): void { | ||||||
|     if (presence instanceof ClientPresence) { |     if (presence instanceof ClientPresence) { | ||||||
|       this.presence = presence |       this.presence = presence | ||||||
|  | @ -67,6 +88,7 @@ export class Client extends EventEmitter { | ||||||
|     this.gateway?.sendPresence(this.presence.create()) |     this.gateway?.sendPresence(this.presence.create()) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   /** Emit debug event */ | ||||||
|   debug (tag: string, msg: string): void { |   debug (tag: string, msg: string): void { | ||||||
|     this.emit("debug", `[${tag}] ${msg}`) |     this.emit("debug", `[${tag}] ${msg}`) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -141,7 +141,7 @@ export class CommandClient extends Client { | ||||||
|       this.emit('commandUsed', { context: ctx }) |       this.emit('commandUsed', { context: ctx }) | ||||||
|       command.execute(ctx) |       command.execute(ctx) | ||||||
|     } catch (e) { |     } catch (e) { | ||||||
|       if (this.texts.ERROR !== undefined) return this.sendProcessedText(msg, this.texts.ERROR, Object.assign(baseReplaces, { error: e.message })) |       if (this.texts.ERROR !== undefined) this.sendProcessedText(msg, this.texts.ERROR, Object.assign(baseReplaces, { error: e.message })) | ||||||
|       this.emit('commandError', { command, parsed, error: e }) |       this.emit('commandError', { command, parsed, error: e }) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,4 @@ | ||||||
| import { Client } from '../models/client.ts' | import { Client } from '../models/client.ts' | ||||||
| import * as cache from '../models/cache.ts' |  | ||||||
| 
 | 
 | ||||||
| interface IInit { | interface IInit { | ||||||
|   useCache?: boolean |   useCache?: boolean | ||||||
|  | @ -25,18 +24,13 @@ export class Base { | ||||||
|     this.useCache = useCache |     this.useCache = useCache | ||||||
|     const cacheID = restURLfuncArgs.join(':') |     const cacheID = restURLfuncArgs.join(':') | ||||||
|     if (this.useCache !== undefined) { |     if (this.useCache !== undefined) { | ||||||
|       const cached = cache.get(this.cacheName ?? this.name, cacheID) |       const cached = await client.cache.get(this.cacheName ?? this.name, cacheID) | ||||||
|       if (cached !== undefined) { |       if (cached !== undefined) { | ||||||
|         return cached |         return cached | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const resp = await fetch(endpoint(...restURLfuncArgs), { |     const jsonParsed = await client.rest.get(endpoint(...restURLfuncArgs)) | ||||||
|       headers: { |  | ||||||
|         Authorization: `Bot ${client.token}` |  | ||||||
|       } |  | ||||||
|     }) |  | ||||||
|     const jsonParsed = await resp.json() |  | ||||||
| 
 | 
 | ||||||
|     return new this(client, jsonParsed) |     return new this(client, jsonParsed) | ||||||
|   } |   } | ||||||
|  | @ -47,12 +41,7 @@ export class Base { | ||||||
|   ): Promise<this> { |   ): Promise<this> { | ||||||
|     const oldOne = Object.assign(Object.create(this), this) |     const oldOne = Object.assign(Object.create(this), this) | ||||||
| 
 | 
 | ||||||
|     const resp = await fetch(endpoint(...restURLfuncArgs), { |     const jsonParsed = await client.rest.get(endpoint(...restURLfuncArgs)) | ||||||
|       headers: { |  | ||||||
|         Authorization: `Bot ${client.token}` |  | ||||||
|       } |  | ||||||
|     }) |  | ||||||
|     const jsonParsed = await resp.json() |  | ||||||
| 
 | 
 | ||||||
|     this.readFromData(jsonParsed) |     this.readFromData(jsonParsed) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,7 +4,6 @@ import { PresenceUpdatePayload } from '../types/gateway.ts' | ||||||
| import { Base } from './base.ts' | import { Base } from './base.ts' | ||||||
| import { Emoji } from './emoji.ts' | import { Emoji } from './emoji.ts' | ||||||
| import { VoiceState } from './voiceState.ts' | import { VoiceState } from './voiceState.ts' | ||||||
| import cache from '../models/cache.ts' |  | ||||||
| import { RolesManager } from "../managers/roles.ts" | import { RolesManager } from "../managers/roles.ts" | ||||||
| import { GuildChannelsManager } from "../managers/guildChannels.ts" | import { GuildChannelsManager } from "../managers/guildChannels.ts" | ||||||
| import { MembersManager } from "../managers/members.ts" | import { MembersManager } from "../managers/members.ts" | ||||||
|  | @ -156,10 +155,10 @@ export class Guild extends Base { | ||||||
|       //   data.roles.map(
 |       //   data.roles.map(
 | ||||||
|       //     v => cache.get('role', v.id) ?? new Role(this.client, v)
 |       //     v => cache.get('role', v.id) ?? new Role(this.client, v)
 | ||||||
|       //   ) ?? this.roles
 |       //   ) ?? this.roles
 | ||||||
|       this.emojis = |       // this.emojis =
 | ||||||
|         data.emojis.map( |       //   data.emojis.map(
 | ||||||
|           v => cache.get('emoji', v.id) ?? new Emoji(this.client, v) |       //     v => cache.get('emoji', v.id) ?? new Emoji(this.client, v)
 | ||||||
|         ) ?? this.emojis |       //   ) ?? this.emojis
 | ||||||
|       this.features = data.features ?? this.features |       this.features = data.features ?? this.features | ||||||
|       this.mfaLevel = data.mfa_level ?? this.mfaLevel |       this.mfaLevel = data.mfa_level ?? this.mfaLevel | ||||||
|       this.systemChannelID = data.system_channel_id ?? this.systemChannelID |       this.systemChannelID = data.system_channel_id ?? this.systemChannelID | ||||||
|  |  | ||||||
|  | @ -1,26 +1,28 @@ | ||||||
| import cache from '../models/cache.ts' |  | ||||||
| import { Client } from '../models/client.ts' | import { Client } from '../models/client.ts' | ||||||
| import { MemberPayload } from '../types/guild.ts' | import { MemberPayload } from '../types/guild.ts' | ||||||
| import { Base } from './base.ts' | import { Base } from './base.ts' | ||||||
|  | import { Role } from "./role.ts" | ||||||
| import { User } from './user.ts' | import { User } from './user.ts' | ||||||
| 
 | 
 | ||||||
| export class Member extends Base { | export class Member extends Base { | ||||||
|   id: string |   id: string | ||||||
|   user: User |   user: User | ||||||
|   nick?: string |   nick?: string | ||||||
|   roles: string[] |   roleIDs: string[] | ||||||
|  |   roles: Role[] = [] | ||||||
|   joinedAt: string |   joinedAt: string | ||||||
|   premiumSince?: string |   premiumSince?: string | ||||||
|   deaf: boolean |   deaf: boolean | ||||||
|   mute: boolean |   mute: boolean | ||||||
| 
 | 
 | ||||||
|   constructor (client: Client, data: MemberPayload) { |   constructor (client: Client, data: MemberPayload, user: User) { | ||||||
|     super(client) |     super(client) | ||||||
|     this.id = data.user.id |     this.id = data.user.id | ||||||
|     this.user = |     this.user = user | ||||||
|       cache.get('user', data.user.id) ?? new User(this.client, data.user) |     // this.user =
 | ||||||
|  |     //   cache.get('user', data.user.id) ?? new User(this.client, data.user)
 | ||||||
|     this.nick = data.nick |     this.nick = data.nick | ||||||
|     this.roles = data.roles |     this.roleIDs = data.roles | ||||||
|     this.joinedAt = data.joined_at |     this.joinedAt = data.joined_at | ||||||
|     this.premiumSince = data.premium_since |     this.premiumSince = data.premium_since | ||||||
|     this.deaf = data.deaf |     this.deaf = data.deaf | ||||||
|  | @ -32,7 +34,7 @@ export class Member extends Base { | ||||||
|   protected readFromData (data: MemberPayload): void { |   protected readFromData (data: MemberPayload): void { | ||||||
|     super.readFromData(data.user) |     super.readFromData(data.user) | ||||||
|     this.nick = data.nick ?? this.nick |     this.nick = data.nick ?? this.nick | ||||||
|     this.roles = data.roles ?? this.roles |     this.roleIDs = data.roles ?? this.roles | ||||||
|     this.joinedAt = data.joined_at ?? this.joinedAt |     this.joinedAt = data.joined_at ?? this.joinedAt | ||||||
|     this.premiumSince = data.premium_since ?? this.premiumSince |     this.premiumSince = data.premium_since ?? this.premiumSince | ||||||
|     this.deaf = data.deaf ?? this.deaf |     this.deaf = data.deaf ?? this.deaf | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| import { CommandClient, Intents } from '../../mod.ts'; | import { CommandClient, Intents } from '../../mod.ts'; | ||||||
| import PingCommand from "./cmds/ping.ts"; | import PingCommand from "./cmds/ping.ts"; | ||||||
|  | import UserinfoCommand from "./cmds/userinfo.ts"; | ||||||
| import { TOKEN } from './config.ts' | import { TOKEN } from './config.ts' | ||||||
| 
 | 
 | ||||||
| const client = new CommandClient({ | const client = new CommandClient({ | ||||||
|  | @ -13,6 +14,9 @@ client.on('ready', () => { | ||||||
|   console.log(`[Login] Logged in as ${client.user?.tag}!`) |   console.log(`[Login] Logged in as ${client.user?.tag}!`) | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
|  | client.on("commandError", console.log) | ||||||
|  | 
 | ||||||
| client.commands.add(PingCommand) | client.commands.add(PingCommand) | ||||||
|  | client.commands.add(UserinfoCommand) | ||||||
| 
 | 
 | ||||||
| client.connect(TOKEN, Intents.All) | client.connect(TOKEN, Intents.All) | ||||||
|  | @ -3,9 +3,8 @@ import { CommandContext } from "../../models/command.ts"; | ||||||
| 
 | 
 | ||||||
| export default class PingCommand extends Command { | export default class PingCommand extends Command { | ||||||
|   name = "ping" |   name = "ping" | ||||||
|   dmOnly = true |  | ||||||
| 
 | 
 | ||||||
|   execute(ctx: CommandContext): void { |   execute(ctx: CommandContext): void { | ||||||
|     ctx.message.reply(`pong! Latency: ${ctx.client.ping}ms`) |     ctx.message.reply(`Pong! Latency: ${ctx.client.ping}ms`) | ||||||
|   } |   } | ||||||
| } | } | ||||||
							
								
								
									
										16
									
								
								src/test/cmds/userinfo.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/test/cmds/userinfo.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | ||||||
|  | import { Command, Member, CommandContext, Embed } from "../../../mod.ts"; | ||||||
|  | 
 | ||||||
|  | export default class UserinfoCommand extends Command { | ||||||
|  |     name = "userinfo" | ||||||
|  |     guildOnly = true | ||||||
|  | 
 | ||||||
|  |     execute(ctx: CommandContext): void { | ||||||
|  |         const member: Member = ctx.message.member as any | ||||||
|  |         const embed = new Embed() | ||||||
|  |         .setTitle(`User Info`) | ||||||
|  |         .setAuthor({ name: member.user.tag }) | ||||||
|  |         .addField("ID", member.id) | ||||||
|  |         .addField("Roles", member.roles.map(r => r.name).join(", ")) | ||||||
|  |         ctx.channel.send(embed) | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue