Added Presence
This commit is contained in:
parent
99630d74cf
commit
04056a7f9c
4 changed files with 217 additions and 64 deletions
|
@ -10,6 +10,7 @@ import { gatewayHandlers } from './handlers/index.ts'
|
||||||
import { GATEWAY_BOT } from '../types/endpoint.ts'
|
import { GATEWAY_BOT } from '../types/endpoint.ts'
|
||||||
import { GatewayBotPayload } from "../types/gatewayBot.ts"
|
import { GatewayBotPayload } from "../types/gatewayBot.ts"
|
||||||
import { GatewayCache } from "../managers/GatewayCache.ts"
|
import { GatewayCache } from "../managers/GatewayCache.ts"
|
||||||
|
import { ClientActivityPayload } from "../structures/presence.ts"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles Discord gateway connection.
|
* Handles Discord gateway connection.
|
||||||
|
@ -32,7 +33,7 @@ class Gateway {
|
||||||
client: Client
|
client: Client
|
||||||
cache: GatewayCache
|
cache: GatewayCache
|
||||||
|
|
||||||
constructor (client: Client, token: string, intents: GatewayIntents[]) {
|
constructor(client: Client, token: string, intents: GatewayIntents[]) {
|
||||||
this.token = token
|
this.token = token
|
||||||
this.intents = intents
|
this.intents = intents
|
||||||
this.client = client
|
this.client = client
|
||||||
|
@ -49,12 +50,12 @@ class Gateway {
|
||||||
this.websocket.onerror = this.onerror.bind(this)
|
this.websocket.onerror = this.onerror.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private onopen (): void {
|
private onopen(): void {
|
||||||
this.connected = true
|
this.connected = true
|
||||||
this.debug("Connected to Gateway!")
|
this.debug("Connected to Gateway!")
|
||||||
}
|
}
|
||||||
|
|
||||||
private async onmessage (event: MessageEvent): Promise<void> {
|
private async onmessage(event: MessageEvent): Promise<void> {
|
||||||
let data = event.data
|
let data = event.data
|
||||||
if (data instanceof ArrayBuffer) {
|
if (data instanceof ArrayBuffer) {
|
||||||
data = new Uint8Array(data)
|
data = new Uint8Array(data)
|
||||||
|
@ -79,12 +80,10 @@ class Gateway {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.websocket.send(
|
this.send({
|
||||||
JSON.stringify({
|
|
||||||
op: GatewayOpcodes.HEARTBEAT,
|
op: GatewayOpcodes.HEARTBEAT,
|
||||||
d: this.sequenceID ?? null
|
d: this.sequenceID ?? null
|
||||||
})
|
})
|
||||||
)
|
|
||||||
this.lastPingTimestamp = Date.now()
|
this.lastPingTimestamp = Date.now()
|
||||||
}, this.heartbeatInterval)
|
}, this.heartbeatInterval)
|
||||||
|
|
||||||
|
@ -142,38 +141,38 @@ class Gateway {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onclose (event: CloseEvent): void {
|
private onclose(event: CloseEvent): void {
|
||||||
this.debug("Connection Closed with code: " + event.code)
|
this.debug("Connection Closed with code: " + event.code)
|
||||||
|
|
||||||
if(event.code == GatewayCloseCodes.UNKNOWN_ERROR) {
|
if (event.code == GatewayCloseCodes.UNKNOWN_ERROR) {
|
||||||
this.debug("API has encountered Unknown Error. Reconnecting...")
|
this.debug("API has encountered Unknown Error. Reconnecting...")
|
||||||
this.reconnect()
|
this.reconnect()
|
||||||
} else if(event.code == GatewayCloseCodes.UNKNOWN_OPCODE) {
|
} else if (event.code == GatewayCloseCodes.UNKNOWN_OPCODE) {
|
||||||
throw new Error("Unknown OP Code was sent. This shouldn't happen!")
|
throw new Error("Unknown OP Code was sent. This shouldn't happen!")
|
||||||
} else if(event.code == GatewayCloseCodes.DECODE_ERROR) {
|
} else if (event.code == GatewayCloseCodes.DECODE_ERROR) {
|
||||||
throw new Error("Invalid Payload was sent. This shouldn't happen!")
|
throw new Error("Invalid Payload was sent. This shouldn't happen!")
|
||||||
} else if(event.code == GatewayCloseCodes.NOT_AUTHENTICATED) {
|
} else if (event.code == GatewayCloseCodes.NOT_AUTHENTICATED) {
|
||||||
throw new Error("Not Authorized: Payload was sent before Identifying.")
|
throw new Error("Not Authorized: Payload was sent before Identifying.")
|
||||||
} else if(event.code == GatewayCloseCodes.AUTHENTICATION_FAILED) {
|
} else if (event.code == GatewayCloseCodes.AUTHENTICATION_FAILED) {
|
||||||
throw new Error("Invalid Token provided!")
|
throw new Error("Invalid Token provided!")
|
||||||
} else if(event.code == GatewayCloseCodes.INVALID_SEQ) {
|
} else if (event.code == GatewayCloseCodes.INVALID_SEQ) {
|
||||||
this.debug("Invalid Seq was sent. Reconnecting.")
|
this.debug("Invalid Seq was sent. Reconnecting.")
|
||||||
this.reconnect()
|
this.reconnect()
|
||||||
} else if(event.code == GatewayCloseCodes.RATE_LIMITED) {
|
} else if (event.code == GatewayCloseCodes.RATE_LIMITED) {
|
||||||
throw new Error("You're ratelimited. Calm down.")
|
throw new Error("You're ratelimited. Calm down.")
|
||||||
} else if(event.code == GatewayCloseCodes.SESSION_TIMED_OUT) {
|
} else if (event.code == GatewayCloseCodes.SESSION_TIMED_OUT) {
|
||||||
this.debug("Session Timeout. Reconnecting.")
|
this.debug("Session Timeout. Reconnecting.")
|
||||||
this.reconnect(true)
|
this.reconnect(true)
|
||||||
} else if(event.code == GatewayCloseCodes.INVALID_SHARD) {
|
} else if (event.code == GatewayCloseCodes.INVALID_SHARD) {
|
||||||
this.debug("Invalid Shard was sent. Reconnecting.")
|
this.debug("Invalid Shard was sent. Reconnecting.")
|
||||||
this.reconnect()
|
this.reconnect()
|
||||||
} else if(event.code == GatewayCloseCodes.SHARDING_REQUIRED) {
|
} else if (event.code == GatewayCloseCodes.SHARDING_REQUIRED) {
|
||||||
throw new Error("Couldn't connect. Sharding is requried!")
|
throw new Error("Couldn't connect. Sharding is requried!")
|
||||||
} else if(event.code == GatewayCloseCodes.INVALID_API_VERSION) {
|
} else if (event.code == GatewayCloseCodes.INVALID_API_VERSION) {
|
||||||
throw new Error("Invalid API Version was used. This shouldn't happen!")
|
throw new Error("Invalid API Version was used. This shouldn't happen!")
|
||||||
} else if(event.code == GatewayCloseCodes.INVALID_INTENTS) {
|
} else if (event.code == GatewayCloseCodes.INVALID_INTENTS) {
|
||||||
throw new Error("Invalid Intents")
|
throw new Error("Invalid Intents")
|
||||||
} else if(event.code == GatewayCloseCodes.DISALLOWED_INTENTS) {
|
} else if (event.code == GatewayCloseCodes.DISALLOWED_INTENTS) {
|
||||||
throw new Error("Given Intents aren't allowed")
|
throw new Error("Given Intents aren't allowed")
|
||||||
} else {
|
} else {
|
||||||
this.debug("Unknown Close code, probably connection error. Reconnecting.")
|
this.debug("Unknown Close code, probably connection error. Reconnecting.")
|
||||||
|
@ -181,29 +180,28 @@ class Gateway {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onerror (event: Event | ErrorEvent): void {
|
private onerror(event: Event | ErrorEvent): void {
|
||||||
const eventError = event as ErrorEvent
|
const eventError = event as ErrorEvent
|
||||||
console.log(eventError)
|
console.log(eventError)
|
||||||
}
|
}
|
||||||
|
|
||||||
private async sendIdentify (forceNewSession?: boolean) {
|
private async sendIdentify(forceNewSession?: boolean) {
|
||||||
this.debug("Fetching /gateway/bot...")
|
this.debug("Fetching /gateway/bot...")
|
||||||
const info = await this.client.rest.get(GATEWAY_BOT()) as GatewayBotPayload
|
const info = await this.client.rest.get(GATEWAY_BOT()) as GatewayBotPayload
|
||||||
if(info.session_start_limit.remaining == 0) throw new Error("Session Limit Reached. Retry After " + info.session_start_limit.reset_after + "ms")
|
if (info.session_start_limit.remaining == 0) throw new Error("Session Limit Reached. Retry After " + info.session_start_limit.reset_after + "ms")
|
||||||
this.debug("Recommended Shards: " + info.shards)
|
this.debug("Recommended Shards: " + info.shards)
|
||||||
this.debug("=== Session Limit Info ===")
|
this.debug("=== Session Limit Info ===")
|
||||||
this.debug(`Remaining: ${info.session_start_limit.remaining}/${info.session_start_limit.total}`)
|
this.debug(`Remaining: ${info.session_start_limit.remaining}/${info.session_start_limit.total}`)
|
||||||
this.debug(`Reset After: ${info.session_start_limit.reset_after}ms`)
|
this.debug(`Reset After: ${info.session_start_limit.reset_after}ms`)
|
||||||
if(!forceNewSession) {
|
if (!forceNewSession) {
|
||||||
let sessionIDCached = await this.cache.get("session_id")
|
let sessionIDCached = await this.cache.get("session_id")
|
||||||
if(sessionIDCached) {
|
if (sessionIDCached) {
|
||||||
this.debug("Found Cached SessionID: " + sessionIDCached)
|
this.debug("Found Cached SessionID: " + sessionIDCached)
|
||||||
this.sessionID = sessionIDCached
|
this.sessionID = sessionIDCached
|
||||||
return this.sendResume()
|
return this.sendResume()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.websocket.send(
|
this.send({
|
||||||
JSON.stringify({
|
|
||||||
op: GatewayOpcodes.IDENTIFY,
|
op: GatewayOpcodes.IDENTIFY,
|
||||||
d: {
|
d: {
|
||||||
token: this.token,
|
token: this.token,
|
||||||
|
@ -218,22 +216,16 @@ class Gateway {
|
||||||
(previous, current) => previous | current,
|
(previous, current) => previous | current,
|
||||||
0
|
0
|
||||||
),
|
),
|
||||||
presence: {
|
presence: this.client.presence.create()
|
||||||
// TODO: User should can customize this
|
|
||||||
status: 'online',
|
|
||||||
since: null,
|
|
||||||
afk: false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async sendResume (): Promise<void> {
|
private async sendResume(): Promise<void> {
|
||||||
this.debug(`Preparing to resume with Session: ${this.sessionID}`)
|
this.debug(`Preparing to resume with Session: ${this.sessionID}`)
|
||||||
if(this.sequenceID === undefined) {
|
if (this.sequenceID === undefined) {
|
||||||
let cached = await this.cache.get("seq")
|
let cached = await this.cache.get("seq")
|
||||||
if(cached) this.sequenceID = typeof cached == "string" ? parseInt(cached) : cached
|
if (cached) this.sequenceID = typeof cached == "string" ? parseInt(cached) : cached
|
||||||
}
|
}
|
||||||
const resumePayload = {
|
const resumePayload = {
|
||||||
op: GatewayOpcodes.RESUME,
|
op: GatewayOpcodes.RESUME,
|
||||||
|
@ -243,9 +235,7 @@ class Gateway {
|
||||||
seq: this.sequenceID || null
|
seq: this.sequenceID || null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.websocket.send(
|
this.send(resumePayload)
|
||||||
JSON.stringify(resumePayload)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(msg: string) {
|
debug(msg: string) {
|
||||||
|
@ -254,12 +244,12 @@ class Gateway {
|
||||||
|
|
||||||
async reconnect(forceNew?: boolean) {
|
async reconnect(forceNew?: boolean) {
|
||||||
clearInterval(this.heartbeatIntervalID)
|
clearInterval(this.heartbeatIntervalID)
|
||||||
if(forceNew) await this.cache.delete("session_id")
|
if (forceNew) await this.cache.delete("session_id")
|
||||||
this.close()
|
this.close()
|
||||||
this.initWebsocket()
|
this.initWebsocket()
|
||||||
}
|
}
|
||||||
|
|
||||||
initWebsocket (): void {
|
initWebsocket(): void {
|
||||||
this.websocket = new WebSocket(
|
this.websocket = new WebSocket(
|
||||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||||
`${DISCORD_GATEWAY_URL}/?v=${DISCORD_API_VERSION}&encoding=json`,
|
`${DISCORD_GATEWAY_URL}/?v=${DISCORD_API_VERSION}&encoding=json`,
|
||||||
|
@ -272,9 +262,27 @@ class Gateway {
|
||||||
this.websocket.onerror = this.onerror.bind(this)
|
this.websocket.onerror = this.onerror.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
close (): void {
|
close(): void {
|
||||||
this.websocket.close(1000)
|
this.websocket.close(1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
send(data: GatewayResponse) {
|
||||||
|
if (this.websocket.readyState != this.websocket.OPEN) return false
|
||||||
|
this.websocket.send(JSON.stringify({
|
||||||
|
op: data.op,
|
||||||
|
d: data.d,
|
||||||
|
s: typeof data.s == "number" ? data.s : null,
|
||||||
|
t: data.t || null,
|
||||||
|
}))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
sendPresence(data: ClientActivityPayload) {
|
||||||
|
this.send({
|
||||||
|
op: GatewayOpcodes.PRESENCE_UPDATE,
|
||||||
|
d: data
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GatewayEventHandler = (gateway: Gateway, d: any) => void
|
export type GatewayEventHandler = (gateway: Gateway, d: any) => void
|
||||||
|
|
|
@ -9,13 +9,15 @@ import { GuildManager } from "../managers/GuildsManager.ts"
|
||||||
import { EmojisManager } from "../managers/EmojisManager.ts"
|
import { EmojisManager } from "../managers/EmojisManager.ts"
|
||||||
import { ChannelsManager } from "../managers/ChannelsManager.ts"
|
import { ChannelsManager } from "../managers/ChannelsManager.ts"
|
||||||
import { MessagesManager } from "../managers/MessagesManager.ts"
|
import { MessagesManager } from "../managers/MessagesManager.ts"
|
||||||
|
import { ActivityGame, ClientActivity, ClientActivityPayload, ClientPresence } from "../structures/presence.ts"
|
||||||
|
|
||||||
/** Some Client Options to modify behaviour */
|
/** Some Client Options to modify behaviour */
|
||||||
export interface ClientOptions {
|
export interface ClientOptions {
|
||||||
token?: string
|
token?: string
|
||||||
intents?: GatewayIntents[]
|
intents?: GatewayIntents[]
|
||||||
cache?: ICacheAdapter,
|
cache?: ICacheAdapter,
|
||||||
forceNewSession?: boolean
|
forceNewSession?: boolean,
|
||||||
|
presence?: ClientPresence | ClientActivity | ActivityGame
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,12 +39,15 @@ export class Client extends EventEmitter {
|
||||||
messages: MessagesManager = new MessagesManager(this)
|
messages: MessagesManager = new MessagesManager(this)
|
||||||
emojis: EmojisManager = new EmojisManager(this)
|
emojis: EmojisManager = new EmojisManager(this)
|
||||||
|
|
||||||
|
presence: ClientPresence = new ClientPresence()
|
||||||
|
|
||||||
constructor (options: ClientOptions = {}) {
|
constructor (options: ClientOptions = {}) {
|
||||||
super()
|
super()
|
||||||
this.token = options.token
|
this.token = options.token
|
||||||
this.intents = options.intents
|
this.intents = options.intents
|
||||||
this.forceNewSession = options.forceNewSession
|
this.forceNewSession = options.forceNewSession
|
||||||
if(options.cache) this.cache = options.cache
|
if(options.cache) this.cache = options.cache
|
||||||
|
if(options.presence) this.presence = options.presence instanceof ClientPresence ? options.presence : new ClientPresence(options.presence)
|
||||||
}
|
}
|
||||||
|
|
||||||
setAdapter(adapter: ICacheAdapter) {
|
setAdapter(adapter: ICacheAdapter) {
|
||||||
|
@ -50,6 +55,13 @@ export class Client extends EventEmitter {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setPresence(presence: ClientPresence | ClientActivity | ActivityGame) {
|
||||||
|
if(presence instanceof ClientPresence) {
|
||||||
|
this.presence = presence
|
||||||
|
} else this.presence = new ClientPresence(presence)
|
||||||
|
this.gateway?.sendPresence(this.presence.create())
|
||||||
|
}
|
||||||
|
|
||||||
debug(tag: string, msg: string) {
|
debug(tag: string, msg: string) {
|
||||||
this.emit("debug", `[${tag}] ${msg}`)
|
this.emit("debug", `[${tag}] ${msg}`)
|
||||||
}
|
}
|
||||||
|
|
120
src/structures/presence.ts
Normal file
120
src/structures/presence.ts
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
export type ActivityType = 'PLAYING' | 'STREAMING' | 'LISTENING' | 'WATCHING' | 'CUSTOM_STATUS' | 'COMPETING';
|
||||||
|
export type StatusType = 'online' | 'invisible' | 'offline' | 'idle' | 'dnd';
|
||||||
|
|
||||||
|
export enum ActivityTypes {
|
||||||
|
PLAYING = 0,
|
||||||
|
STREAMING = 1,
|
||||||
|
LISTENING = 2,
|
||||||
|
WATCHING = 3,
|
||||||
|
CUSTOM_STATUS = 4,
|
||||||
|
COMPETING = 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ActivityGame {
|
||||||
|
name: string;
|
||||||
|
type: 0 | 1 | 2 | 3 | 4 | 5 | ActivityType;
|
||||||
|
url?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClientActivity {
|
||||||
|
status?: StatusType
|
||||||
|
activity?: ActivityGame | ActivityGame[]
|
||||||
|
since?: number | null
|
||||||
|
afk?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClientActivityPayload {
|
||||||
|
status: StatusType
|
||||||
|
activities: ActivityGame[] | null
|
||||||
|
since: number | null
|
||||||
|
afk: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ClientPresence {
|
||||||
|
status: StatusType = 'online'
|
||||||
|
activity?: ActivityGame | ActivityGame[]
|
||||||
|
since?: number | null
|
||||||
|
afk?: boolean
|
||||||
|
|
||||||
|
constructor(data?: ClientActivity | ClientActivityPayload | ActivityGame) {
|
||||||
|
if (data) {
|
||||||
|
if((data as ClientActivity).activity !== undefined) {
|
||||||
|
Object.assign(this, data)
|
||||||
|
} else if((data as ClientActivityPayload).activities !== undefined) {
|
||||||
|
|
||||||
|
} else if((data as ActivityGame).name !== undefined) {
|
||||||
|
if(!this.activity) {
|
||||||
|
this.activity = data as ActivityGame
|
||||||
|
} else if(this.activity instanceof Array) {
|
||||||
|
this.activity.push(data as ActivityGame)
|
||||||
|
} else this.activity = [ this.activity, data as ActivityGame ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parse(payload: ClientActivityPayload) {
|
||||||
|
this.afk = payload.afk
|
||||||
|
this.activity = payload.activities ?? undefined
|
||||||
|
this.since = payload.since
|
||||||
|
this.status = payload.status
|
||||||
|
}
|
||||||
|
|
||||||
|
static parse(payload: ClientActivityPayload) {
|
||||||
|
return new ClientPresence().parse(payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
create(): ClientActivityPayload {
|
||||||
|
return {
|
||||||
|
afk: this.afk || false,
|
||||||
|
activities: this.createActivity(),
|
||||||
|
since: this.since || null,
|
||||||
|
status: this.status || 'online'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createActivity() {
|
||||||
|
let activity = this.activity == undefined ? null : (this.activity instanceof Array ? this.activity : [this.activity]) || null
|
||||||
|
if(activity == null) return activity
|
||||||
|
else {
|
||||||
|
activity.map(e => {
|
||||||
|
if(typeof e.type == "string") e.type = ActivityTypes[e.type]
|
||||||
|
return e
|
||||||
|
})
|
||||||
|
return activity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setStatus(status: StatusType) {
|
||||||
|
this.status = status
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setActivity(activity: ActivityGame) {
|
||||||
|
this.activity = activity
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setActivities(activities: ActivityGame[]) {
|
||||||
|
this.activity = activities
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setAFK(afk: boolean) {
|
||||||
|
this.afk = afk
|
||||||
|
}
|
||||||
|
|
||||||
|
removeAFK() {
|
||||||
|
this.afk = false
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleAFK() {
|
||||||
|
this.afk = !(this.afk || true)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
setSince(since?: number) {
|
||||||
|
this.since = since
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,8 +8,17 @@ import { Guild } from '../structures/guild.ts'
|
||||||
import { User } from '../structures/user.ts'
|
import { User } from '../structures/user.ts'
|
||||||
import { Message } from "../structures/message.ts"
|
import { Message } from "../structures/message.ts"
|
||||||
import { RedisCacheAdapter } from "../models/CacheAdapter.ts"
|
import { RedisCacheAdapter } from "../models/CacheAdapter.ts"
|
||||||
|
import { ClientPresence } from "../structures/presence.ts"
|
||||||
|
|
||||||
const bot = new Client()
|
const bot = new Client({
|
||||||
|
presence: new ClientPresence({
|
||||||
|
activity: {
|
||||||
|
name: "Testing",
|
||||||
|
type: 'COMPETING'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
forceNewSession: true
|
||||||
|
})
|
||||||
|
|
||||||
bot.setAdapter(new RedisCacheAdapter(bot, {
|
bot.setAdapter(new RedisCacheAdapter(bot, {
|
||||||
hostname: "127.0.0.1",
|
hostname: "127.0.0.1",
|
||||||
|
@ -18,6 +27,10 @@ bot.setAdapter(new RedisCacheAdapter(bot, {
|
||||||
|
|
||||||
bot.on('ready', () => {
|
bot.on('ready', () => {
|
||||||
console.log(`[Login] Logged in as ${bot.user?.tag}!`)
|
console.log(`[Login] Logged in as ${bot.user?.tag}!`)
|
||||||
|
bot.setPresence({
|
||||||
|
name: "Test After Ready",
|
||||||
|
type: 'COMPETING'
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
bot.on('debug', console.log)
|
bot.on('debug', console.log)
|
||||||
|
|
Loading…
Reference in a new issue