Finally got somewhat working 👍

Co-Authored-By: Aki <71239005+AkiaCode@users.noreply.github.com>
Co-Authored-By: Lee Hyun <ink0416@naver.com>
Co-Authored-By: khk4912 <30457148+khk4912@users.noreply.github.com>
Co-Authored-By: Choi Minseo <minseo0388@outlook.com>
Co-Authored-By: Junseo Park <wonderlandpark@callisto.team>
Co-Authored-By: Y <8479056+yky4589@users.noreply.github.com>
This commit is contained in:
Helloyunho 2020-10-23 00:50:47 +09:00
parent b7896756cd
commit ca7d143ddc
32 changed files with 1355 additions and 428 deletions

View File

@ -1,6 +1,6 @@
export const DISCORD_API_URL = 'https://discord.com/api' export const DISCORD_API_URL = 'https://discord.com/api'
export const DISCORD_GATEWAY_URL = 'wss://gateway.discord.com' export const DISCORD_GATEWAY_URL = 'wss://gateway.discord.gg'
export const DISCORD_CDN_URL = 'https://cdn.discordapp.com' export const DISCORD_CDN_URL = 'https://cdn.discordapp.com'

23
src/models/client.ts Normal file
View File

@ -0,0 +1,23 @@
import { User } from '../structures/user.ts'
import { GatewayIntents } from '../types/gatewayTypes.ts'
import { Gateway } from './gateway.ts'
/**
* Discord Client.
*/
export class Client {
gateway?: Gateway
user?: User
ping = 0
constructor () {}
/**
* This function is used for connect to discord.
* @param token Your token. This is required.
* @param intents Gateway intents in array. This is required.
*/
connect (token: string, intents: GatewayIntents[]) {
this.gateway = new Gateway(this, token, intents)
}
}

View File

@ -1,10 +1,16 @@
import { inflate } from 'https://deno.land/x/denoflate/mod.ts' import { unzlib } from 'https://deno.land/x/denoflate/mod.ts'
import { Client } from './client.ts'
import { import {
DISCORD_GATEWAY_URL, DISCORD_GATEWAY_URL,
DISCORD_API_VERSION DISCORD_API_VERSION
} from '../consts/urlsAndVersions.ts' } from '../consts/urlsAndVersions.ts'
import { GatewayResponse } from '../types/gatewayResponse.ts' import { GatewayResponse } from '../types/gatewayResponse.ts'
import { GatewayOpcodes, GatewayIntents } from '../types/gatewayTypes.ts' import {
GatewayOpcodes,
GatewayIntents,
GatewayEvents
} from '../types/gatewayTypes.ts'
import { User } from '../structures/user.ts'
/** /**
* Handles Discord gateway connection. * Handles Discord gateway connection.
@ -15,20 +21,31 @@ import { GatewayOpcodes, GatewayIntents } from '../types/gatewayTypes.ts'
class Gateway { class Gateway {
websocket: WebSocket websocket: WebSocket
token: string token: string
intents: [GatewayIntents] intents: GatewayIntents[]
connected = false connected = false
initialized = false initialized = false
heartbeatInterval = 0 heartbeatInterval = 0
heartbeatIntervalID?: number heartbeatIntervalID?: number
heartbeatCheckerIntervalID?: number
sequenceID?: number sequenceID?: number
sessionID?: string
lastPingTimestemp = 0
heartbeatServerResponded = false heartbeatServerResponded = false
client: Client
constructor (token: string, intents: [GatewayIntents]) { constructor (client: Client, token: string, intents: GatewayIntents[]) {
this.websocket = new WebSocket(
`${DISCORD_GATEWAY_URL}/?v=${DISCORD_API_VERSION}&encoding=json`
)
this.token = token this.token = token
this.intents = intents this.intents = intents
this.client = client
this.websocket = new WebSocket(
`${DISCORD_GATEWAY_URL}/?v=${DISCORD_API_VERSION}&encoding=json`,
[]
)
this.websocket.binaryType = 'arraybuffer'
this.websocket.onopen = this.onopen.bind(this)
this.websocket.onmessage = this.onmessage.bind(this)
this.websocket.onclose = this.onclose.bind(this)
this.websocket.onerror = this.onerror.bind(this)
} }
onopen () { onopen () {
@ -41,16 +58,8 @@ class Gateway {
data = new Uint8Array(data) data = new Uint8Array(data)
} }
if (data instanceof Uint8Array) { if (data instanceof Uint8Array) {
const dataSuffix = data.slice(-4) data = unzlib(data)
data = new TextDecoder('utf-8').decode(data)
if (
dataSuffix[0] === 0 &&
dataSuffix[1] === 0 &&
dataSuffix[2] === 0xff &&
dataSuffix[3] === 0xff
) {
data = inflate(data)
}
} }
const { op, d, s, t }: GatewayResponse = JSON.parse(data) const { op, d, s, t }: GatewayResponse = JSON.parse(data)
@ -59,56 +68,118 @@ class Gateway {
case GatewayOpcodes.HELLO: case GatewayOpcodes.HELLO:
this.heartbeatInterval = d.heartbeat_interval this.heartbeatInterval = d.heartbeat_interval
this.heartbeatIntervalID = setInterval(() => { this.heartbeatIntervalID = setInterval(() => {
if (this.heartbeatServerResponded) {
this.heartbeatServerResponded = false
} else {
clearInterval(this.heartbeatIntervalID)
clearInterval(this.heartbeatCheckerIntervalID)
this.websocket.close()
this.initWebsocket()
return
}
this.websocket.send( this.websocket.send(
JSON.stringify({ JSON.stringify({
op: GatewayOpcodes.HEARTBEAT, op: GatewayOpcodes.HEARTBEAT,
d: this.sequenceID ?? null d: this.sequenceID ?? null
}) })
) )
this.lastPingTimestemp = Date.now()
if (this.heartbeatServerResponded) {
this.heartbeatServerResponded = false
} else {
// TODO: Add heartbeat failed error
}
}, this.heartbeatInterval) }, this.heartbeatInterval)
this.websocket.send( if (!this.initialized) {
JSON.stringify({ this.sendIdentify()
token: this.token, this.initialized = true
properties: { } else {
$os: Deno.build.os, this.websocket.send(
$browser: 'discord.deno', JSON.stringify({
$device: 'discord.deno' op: GatewayOpcodes.RESUME,
}, d: {
compress: true, token: this.token,
shard: [0, 1], // TODO: Make sharding possible session_id: this.sessionID,
intents: this.intents.reduce( seq: this.sequenceID
(previous, current) => previous | current, }
0 })
), )
presence: { }
// TODO: User should can customize this
status: 'online',
since: null,
afk: false
}
})
)
break break
case GatewayOpcodes.HEARTBEAT_ACK: case GatewayOpcodes.HEARTBEAT_ACK:
this.heartbeatServerResponded = true this.heartbeatServerResponded = true
this.client.ping = Date.now() - this.lastPingTimestemp
break
case GatewayOpcodes.INVALID_SESSION:
setTimeout(this.sendIdentify, 3000)
break break
case GatewayOpcodes.DISPATCH: case GatewayOpcodes.DISPATCH:
switch (t) { if (s !== null) {
this.sequenceID = s
} }
switch (t) {
case GatewayEvents.Ready:
this.client.user = new User(this.client, d.user)
this.sessionID = d.session_id
break
default:
break
}
break
default: default:
return break
} }
} }
onclose (event: CloseEvent) {
// TODO: Handle close event codes.
}
onerror (event: Event | ErrorEvent) {
const eventError = event as ErrorEvent
console.log(eventError)
}
sendIdentify () {
this.websocket.send(
JSON.stringify({
op: GatewayOpcodes.IDENTIFY,
d: {
token: this.token,
properties: {
$os: Deno.build.os,
$browser: 'discord.deno',
$device: 'discord.deno'
},
compress: true,
shard: [0, 1], // TODO: Make sharding possible
intents: this.intents.reduce(
(previous, current) => previous | current,
0
),
presence: {
// TODO: User should can customize this
status: 'online',
since: null,
afk: false
}
}
})
)
}
initWebsocket () {
this.websocket = new WebSocket(
`${DISCORD_GATEWAY_URL}/?v=${DISCORD_API_VERSION}&encoding=json`,
[]
)
this.websocket.binaryType = 'arraybuffer'
this.websocket.onopen = this.onopen.bind(this)
this.websocket.onmessage = this.onmessage.bind(this)
this.websocket.onclose = this.onclose.bind(this)
this.websocket.onerror = this.onerror.bind(this)
}
} }
export { Gateway } export { Gateway }

View File

@ -1,10 +1,11 @@
// 일단 대충 여러 봇 라이브러리에서 본 구조 가져오는 중.. // 일단 대충 여러 봇 라이브러리에서 본 구조 가져오는 중..
import { Client } from '../models/client.ts'
class Base { export class Base {
id?: string // property 읍
constructor (id: string | undefined) { client: Client
if (id) { constructor (client: Client) {
this.id = id this.client = client
}
} }
} }
// discord.js 보는중

View File

@ -0,0 +1,29 @@
import { Client } from '../models/client.ts'
import { ChannelPayload, ChannelTypes } from '../types/channelTypes.ts'
import { Base } from './base.ts'
import { PrivateChannel } from './dm.ts'
import { TextChannel } from './textChannel.ts'
export class Channel extends Base {
type: ChannelTypes
id: string
constructor (client: Client, data: ChannelPayload) {
super(client)
this.type = data.type
this.id = data.id
}
get mention () {
return `<#${this.id}>`
}
static from (data: ChannelPayload, client: Client) {
switch (data.type) {
case ChannelTypes.GUILD_TEXT:
return new TextChannel(client, data)
case ChannelTypes.DM:
return new PrivateChannel(client, data)
}
}
}

9
src/structures/dm.ts Normal file
View File

@ -0,0 +1,9 @@
import { Client } from '../models/client.ts'
import { ChannelPayload } from '../types/channelTypes.ts'
import { Channel } from './channel.ts'
export class PrivateChannel extends Channel implements ChannelPayload {
constructor (client: Client, data: ChannelPayload) {
super(client, data)
}
}

View File

@ -0,0 +1,32 @@
import { Client } from '../models/client.ts'
import {
EmbedAuthor,
EmbedField,
EmbedFooter,
EmbedImage,
EmbedPayload,
EmbedProvider,
EmbedThumbnail,
EmbedTypes,
EmbedVideo
} from '../types/channelTypes.ts'
import { Base } from './base.ts'
export class Embed extends Base implements EmbedPayload {
title?: string
type?: EmbedTypes
description?: string
url?: string
timestamp?: string
color?: number
footer?: EmbedFooter
image?: EmbedImage
thumbnail?: EmbedThumbnail
video?: EmbedVideo
provider?: EmbedProvider
author?: EmbedAuthor
fields?: EmbedField[]
constructor (client: Client, data: EmbedPayload) {
super(client)
}
}

26
src/structures/emoji.ts Normal file
View File

@ -0,0 +1,26 @@
import { Client } from '../models/client.ts'
import { EmojiPayload } from '../types/emojiTypes.ts'
import { Base } from './base.ts'
import { User } from './user.ts'
export class Emoji extends Base implements EmojiPayload {
id: string
name: string
roles?: []
user?: User
require_colons?: boolean
managed?: boolean
animated?: boolean
available?: boolean
constructor (client: Client, data: EmojiPayload) {
super(client)
this.id = data.id
this.name = data.name
this.roles = data.roles
this.user = data.user
this.require_colons = data.require_colons
this.managed = data.managed
this.animated = data.animated
this.available = data.available
}
}

View File

@ -0,0 +1,106 @@
import { Client } from '../models/client.ts'
import { EmojiPayload } from '../types/emojiTypes.ts'
import { GuildFeatures, GuildPayload } from '../types/guildTypes.ts'
import { PresenceUpdatePayload } from '../types/presenceTypes.ts'
import { VoiceStatePayload } from '../types/voiceTypes.ts'
import { Base } from './base.ts'
import { Channel } from './channel.ts'
import { Emoji } from './emoji.ts'
import { Member } from './member.ts'
import { Role } from './role.ts'
export class Guild extends Base implements GuildPayload {
id: string
name: string
icon: string | undefined
icon_hash?: string | undefined
splash: string | undefined
discovery_splash: string | undefined
owner?: boolean | undefined
owner_id: string
permissions?: string | undefined
region: string
afk_channel_id: string | undefined
afk_timeout: number
widget_enabled?: boolean | undefined
widge_channel_id?: string | undefined
verification_level: string
default_message_notifications: string
explicit_content_filter: string
roles: Role[]
emojis: Emoji[]
features: GuildFeatures[]
mfa_level: string
application_id: string | undefined
system_channel_id: string | undefined
system_channel_flags: string
rules_channel_id: string | undefined
joined_at?: string | undefined
large?: boolean | undefined
unavailable: boolean
member_count?: number | undefined
voice_states?: VoiceStatePayload[] | undefined
members?: Member[] | undefined
channels?: Channel[] | undefined
presences?: PresenceUpdatePayload[] | undefined
max_presences?: number | undefined
max_members?: number | undefined
vanity_url_code: string | undefined
description: string | undefined
banner: string | undefined
premium_tier: number
premium_subscription_count?: number | undefined
preferred_locale: string
public_updates_channel_id: string | undefined
max_video_channel_users?: number | undefined
approximate_number_count?: number | undefined
approximate_presence_count?: number | undefined
constructor (client: Client, data: GuildPayload) {
super(client)
this.id = data.id
this.name = data.name
this.icon = data.icon
this.icon_hash = data.icon_hash
this.splash = data.splash
this.discovery_splash = data.discovery_splash
this.owner = data.owner
this.owner_id = data.owner_id
this.permissions = data.permissions
this.region = data.region
this.afk_timeout = data.afk_timeout
this.afk_channel_id = data.afk_channel_id
this.widget_enabled = data.widget_enabled
this.widge_channel_id = data.widge_channel_id
this.verification_level = data.verification_level
this.default_message_notifications = data.default_message_notifications
this.explicit_content_filter = data.explicit_content_filter
this.roles = data.roles
this.emojis = data.emojis
this.features = data.features
this.mfa_level = data.mfa_level
this.system_channel_id = data.system_channel_id
this.system_channel_flags = data.system_channel_flags
this.rules_channel_id = data.rules_channel_id
this.joined_at = data.joined_at
this.large = data.large
this.unavailable = data.unavailable
this.member_count = data.member_count
this.voice_states = data.voice_states
this.members = data.members
this.channels = data.channels
this.presences = data.presences
this.max_presences = data.max_presences
this.max_members = data.max_members
this.vanity_url_code = data.vanity_url_code
this.description = data.description
this.banner = data.banner
this.premium_tier = data.premium_tier
this.premium_subscription_count = data.premium_subscription_count
this.preferred_locale = data.preferred_locale
this.public_updates_channel_id = data.public_updates_channel_id
this.max_video_channel_users = data.max_video_channel_users
this.approximate_number_count = data.approximate_number_count
this.approximate_presence_count = data.approximate_presence_count
}
}

View File

@ -0,0 +1,9 @@
import { Client } from '../models/client.ts'
import { ChannelPayload } from '../types/channelTypes.ts'
import { Channel } from './channel.ts'
export class GuildChannel extends Channel {
constructor (client: Client, data: ChannelPayload) {
super(client, data)
}
}

29
src/structures/invite.ts Normal file
View File

@ -0,0 +1,29 @@
import { Client } from '../models/client.ts'
import { Channel } from '../structures/channel.ts'
import { Guild } from '../structures/guild.ts'
import { User } from '../structures/user.ts'
import { InvitePayload } from '../types/inviteTypes.ts'
import { Base } from './base.ts'
export class Invite extends Base implements InvitePayload {
code: string
guild?: Guild
channel: Channel
inviter?: User
target_user?: User
target_user_type?: number
approximate_presence_count?: number
approximate_member_count?: number
constructor (client: Client, data: InvitePayload) {
super(client)
this.code = data.code
this.guild = data.guild
this.channel = data.channel
this.inviter = data.inviter
this.target_user = data.target_user
this.target_user_type = data.target_user_type
this.approximate_member_count = data.approximate_member_count
this.approximate_presence_count = data.approximate_presence_count
}
}

28
src/structures/member.ts Normal file
View File

@ -0,0 +1,28 @@
import { Client } from '../models/client.ts'
import { MemberPayload } from '../types/guildTypes.ts'
import { UserPayload } from '../types/userTypes.ts'
import { Base } from './base.ts'
import { Guild } from './guild.ts'
import { Role } from './role.ts'
import { User } from './user.ts'
export class Member extends Base implements MemberPayload {
user: User
nick: string | undefined
roles: Role[]
joined_at: string
premium_since?: string | undefined
deaf: boolean
mute: boolean
constructor (client: Client, data: MemberPayload) {
super(client)
this.user = data.user
this.nick = data.nick
this.roles = data.roles
this.joined_at = data.joined_at
this.premium_since = data.premium_since
this.deaf = data.deaf
this.mute = data.mute
}
}

View File

@ -1 +1,69 @@
// 여긴가 import { Base } from './base.ts'
import {
Attachment,
ChannelMention,
EmbedPayload,
MessageActivity,
MessageApplication,
MessagePayload,
MessageReference,
Reaction
} from '../types/channelTypes.ts'
import { Client } from '../models/client.ts'
import { User } from './user.ts'
import { Role } from './role.ts'
import { Embed } from './embed.ts'
class Message extends Base implements MessagePayload {
id: string
channel_id: string
guild_id?: string | undefined
author: User
member?: any
content: string
timestamp: string
edited_timestamp: string | undefined
tts: boolean
mention_everyone: boolean
mentions: User[]
mention_roles: Role[]
mention_channels?: ChannelMention[] | undefined
attachments: Attachment[]
embeds: EmbedPayload[]
reactions?: Reaction[] | undefined
nonce?: string | number | undefined
pinned: boolean
webhook_id?: string | undefined
type: number
activity?: MessageActivity
application?: MessageApplication
message_reference?: MessageReference
flags?: number | undefined
constructor (client: Client, data: MessagePayload) {
super(client)
this.id = data.id
this.channel_id = data.channel_id
this.guild_id = data.guild_id
this.author = data.author
this.member = data.member
this.content = data.content
this.timestamp = data.timestamp
this.edited_timestamp = data.edited_timestamp
this.tts = data.tts
this.mention_everyone = data.mention_everyone
this.mentions = data.mentions
this.mention_roles = data.mention_roles
this.attachments = data.attachments
this.embeds = data.embeds
this.reactions = data.reactions
this.nonce = data.nonce
this.pinned = data.pinned
this.webhook_id = data.webhook_id
this.type = data.type
this.activity = data.activity
this.application = data.application
this.message_reference = data.message_reference
this.flags = data.flags
}
}

26
src/structures/role.ts Normal file
View File

@ -0,0 +1,26 @@
import { Client } from '../models/client.ts'
import { Base } from './base.ts'
import { RolePayload } from '../types/roleTypes.ts'
export class Role extends Base implements RolePayload {
id: string
name: string
color: number
hoist: boolean
position: number
permissions: string
managed: boolean
mentionable: boolean
constructor (client: Client, data: RolePayload) {
super(client)
this.id = data.id
this.name = data.name
this.color = data.color
this.hoist = data.hoist
this.position = data.position
this.permissions = data.permissions
this.managed = data.managed
this.mentionable = data.mentionable
}
}

View File

@ -0,0 +1,31 @@
import { Client } from '../models/client.ts'
import { GuildChannel } from './guildChannel.ts'
import { ChannelPayload } from '../types/channelTypes.ts'
import { User } from './user.ts'
export class TextChannel extends GuildChannel implements ChannelPayload {
id: string
type: number
guild_id?: string | undefined
position?: number | undefined
approximate_member_count?: any
name?: string | undefined
topic?: string | undefined
nsfw?: boolean | undefined
last_message_id?: string | undefined
bitrate?: number | undefined
user_limit?: number | undefined
rate_limit_per_user?: number | undefined
recipients?: User
icon?: string | undefined
owner_id?: string | undefined
application_id?: string | undefined
parent_id?: string | undefined
last_pin_timestamp?: string | undefined
constructor (client: Client, data: ChannelPayload) {
super(client, data)
this.id = data.id
this.type = data.type
}
}

36
src/structures/user.ts Normal file
View File

@ -0,0 +1,36 @@
import { Client } from '../models/client.ts'
import { UserPayload } from '../types/userTypes.ts'
import { Base } from './base.ts'
export class User extends Base implements UserPayload {
id: string
username: string
discriminator: string
avatar?: string
bot?: boolean
system?: boolean
mfa_enabled?: boolean
locale?: string
verified?: boolean
email?: string
flags?: number
premium_type?: 0 | 1 | 2
public_flags?: number
constructor (client: Client, data: UserPayload) {
super(client)
this.id = data.id
this.username = data.username
this.discriminator = data.discriminator
this.avatar = data.avatar
this.bot = data.bot
this.system = data.system
this.mfa_enabled = data.mfa_enabled
this.locale = data.locale
this.verified = data.verified
this.email = data.email
this.flags = data.flags
this.premium_type = data.premium_type
this.public_flags = data.public_flags
}
}

8
src/test/index.ts Normal file
View File

@ -0,0 +1,8 @@
import { Client } from '../models/client.ts'
import { GatewayIntents } from '../types/gatewayTypes.ts'
const bot = new Client()
bot.connect('NDMzMjc2NDAyOTM1MjY3MzI4.WszOGA.KlnMe_LImd1DxcurGvj_x0HOEmc', [
GatewayIntents.GUILD_MESSAGES
])

25
src/test/test.ts Normal file
View File

@ -0,0 +1,25 @@
// How to run:
// deno run --allow-net=echo.websocket.org https://deno.land/posts/whats-new-in-deno-1-4/websocket.js
// Start the connection to the WebSocket server at echo.websocket.org
const ws = new WebSocket('ws://echo.websocket.org/')
// Register event listeners for the open, close, and message events
ws.onopen = () => {
console.log('WebSocket ready!')
// Send a message over the WebSocket to the server
ws.send('Hello World!')
}
ws.onmessage = message => {
// Log the message we recieve:
console.log('Received data:', message.data)
}
ws.onclose = () => console.log('WebSocket closed!')
ws.onerror = err => console.log('WebSocket error:', err)
// When running this the following is logged to the console:
//
// WebSocket ready!
// Received data: Hello World!
// WebSocket closed!

View File

@ -1,231 +1,251 @@
interface Channel { import { Member } from '../structures/member.ts'
id: string import { Role } from '../structures/role.ts'
type: number import { User } from '../structures/user.ts'
guild_id?: string import { EmojiPayload } from './emojiTypes.ts'
position?: number
approximate_member_count?: Overwrite interface ChannelPayload {
name?: string id: string
topic?: string | undefined type: ChannelTypes
nsfw?: boolean guild_id?: string
last_message_id?: string position?: number
bitrate?: number approximate_member_count?: Overwrite
user_limit?: number name?: string
rate_limit_per_user?: number topic?: string
recipients?: User nsfw?: boolean
icon?: string | undefined last_message_id?: string
owner_id?: string bitrate?: number
application_id?: string user_limit?: number
parent_id?: string | undefined rate_limit_per_user?: number
last_pin_timestamp?: string recipients?: User
icon?: string
owner_id?: string
application_id?: string
parent_id?: string
last_pin_timestamp?: string
} }
interface Overwrite { interface Overwrite {
id: string id: string
type: number type: number
allow: string allow: string
deny: string deny: string
} }
enum ChannelTypes { enum ChannelTypes {
GUILD_TEXT = 0, GUILD_TEXT = 0,
DM = 1, DM = 1,
GUILD_VOICE = 2, GUILD_VOICE = 2,
GROUP_DM = 3, GROUP_DM = 3,
GUILD_CATEGORY = 4, GUILD_CATEGORY = 4,
GUILD_NEWS = 5, GUILD_NEWS = 5,
GUILD_STORE = 6 GUILD_STORE = 6
} }
interface Message { interface MessagePayload {
id: string id: string
channel_id: string channel_id: string
guild_id?: string guild_id?: string
suthor: User author: User
member?: GuildMember member?: Member
content: string content: string
timestamp: string timestamp: string
edited_timestamp: string | undefined edited_timestamp: string | undefined
tts: boolean tts: boolean
mention_everyone: boolean mention_everyone: boolean
mentions: User[] mentions: User[]
mention_roles: Role[] mention_roles: Role[]
mention_channels?: ChannelMention[] mention_channels?: ChannelMention[]
attachments: Attachment[] attachments: Attachment[]
embeds: Embed[] embeds: EmbedPayload[]
reactions?: Reaction[] reactions?: Reaction[]
nonce?: number | string nonce?: number | string
pinned: boolean pinned: boolean
webhook_id?: string webhook_id?: string
type: number type: number
activity?: MessageActivity activity?: MessageActivity
application?: MessageApplication application?: MessageApplication
message_reference?: MessageReference message_reference?: MessageReference
flags?: number flags?: number
} }
interface ChannelMention { interface ChannelMention {
id: string id: string
guild_id: string guild_id: string
type: ChannelTypes type: ChannelTypes
name: string name: string
} }
interface Attachment { interface Attachment {
id: string id: string
filename: string filename: string
size: number size: number
url: string url: string
proxy_url: string proxy_url: string
height: number | undefined height: number | undefined
width: number | undefined width: number | undefined
} }
interface Embed { interface EmbedPayload {
title?: string title?: string
type?: EmbedTypes type?: EmbedTypes
description?: string description?: string
url?: string url?: string
timestamp?: string timestamp?: string
color?: number color?: number
footer?: EmbedFooter footer?: EmbedFooter
image?: EmbedImage image?: EmbedImage
thumbnail?: EmbedThumbnail thumbnail?: EmbedThumbnail
video?: EmbedVideo video?: EmbedVideo
provider?: EmbedProvider provider?: EmbedProvider
author?: EmbedAuthor author?: EmbedAuthor
fields?: EmbedField[] fields?: EmbedField[]
} }
type EmbedTypes = type EmbedTypes = 'rich' | 'image' | 'video' | 'gifv' | 'article' | 'link'
| "rich"
| "image"
| "video"
| "gifv"
| "article"
| "link"
interface EmbedField { interface EmbedField {
name: string name: string
value: string value: string
inline?: boolean inline?: boolean
} }
interface EmbedAuthor { interface EmbedAuthor {
name?: string name?: string
url?: string url?: string
icon_url?: string icon_url?: string
proxy_icon_url?: string proxy_icon_url?: string
} }
interface EmbedFooter { interface EmbedFooter {
text: string text: string
icon_url?: string icon_url?: string
proxy_icon_url?: string proxy_icon_url?: string
} }
interface EmbedImage { interface EmbedImage {
url?: string url?: string
proxy_url?: string proxy_url?: string
height?: number height?: number
width?: number width?: number
} }
interface EmbedProvider { interface EmbedProvider {
name?: string name?: string
url?: string url?: string
} }
interface EmbedVideo { interface EmbedVideo {
url?: string url?: string
height?: number height?: number
width?: number width?: number
} }
interface EmbedThumbnail { interface EmbedThumbnail {
url?: string url?: string
proxy_url?: string proxy_url?: string
height?: number height?: number
width?: number width?: number
} }
interface Reaction { interface Reaction {
count: number count: number
me: boolean me: boolean
emoji: Emoji emoji: EmojiPayload
} }
interface MessageActivity { interface MessageActivity {
type: MessageTypes type: MessageTypes
party_id?: string party_id?: string
} }
interface MessageApplication { interface MessageApplication {
id: string id: string
cover_image?: string cover_image?: string
desription: string desription: string
icon: string | undefined icon: string | undefined
name: string name: string
} }
interface MessageReference { interface MessageReference {
message_id?: string message_id?: string
channel_id?: string channel_id?: string
guild_id?: string guild_id?: string
} }
enum MessageTypes { enum MessageTypes {
DEFAULT = 0, DEFAULT = 0,
RECIPIENT_ADD = 1, RECIPIENT_ADD = 1,
RECIPIENT_REMOVE = 2, RECIPIENT_REMOVE = 2,
CALL = 3, CALL = 3,
CHANNEL_NAME_CHANGE = 4, CHANNEL_NAME_CHANGE = 4,
CHANNEL_ICON_CHANGE = 5, CHANNEL_ICON_CHANGE = 5,
CHANNEL_PINNED_MESSAGE = 6, CHANNEL_PINNED_MESSAGE = 6,
GUILD_MEMBER_JOIN = 7, GUILD_MEMBER_JOIN = 7,
USER_PREMIUM_GUILD_SUBSCRIPTION = 8, USER_PREMIUM_GUILD_SUBSCRIPTION = 8,
USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1 = 9, USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1 = 9,
USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 10, USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 10,
USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 11, USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 11,
CHANNEL_FOLLOW_ADD = 12, CHANNEL_FOLLOW_ADD = 12,
GUILD_DISCOVERY_DISQUALIFIED = 14, GUILD_DISCOVERY_DISQUALIFIED = 14,
GUILD_DISCOVERY_REQUALIFIED = 15 GUILD_DISCOVERY_REQUALIFIED = 15
} }
enum MessageActivityTypes { enum MessageActivityTypes {
JOIN = 1, JOIN = 1,
SPECTATE = 2, SPECTATE = 2,
LISTEN = 3, LISTEN = 3,
JOIN_REQUEST = 4 JOIN_REQUEST = 4
} }
enum MessageFlags { enum MessageFlags {
CROSSPOSTED = 1 << 0, CROSSPOSTED = 1 << 0,
IS_CROSSPOST = 1 << 1, IS_CROSSPOST = 1 << 1,
SUPPRESS_EMBEDS = 1 << 2, SUPPRESS_EMBEDS = 1 << 2,
SOURCE_MESSAGE_DELETED = 1 << 3, SOURCE_MESSAGE_DELETED = 1 << 3,
URGENT = 1 << 4 URGENT = 1 << 4
} }
interface FollowedChannel { interface FollowedChannel {
channel_id: string, channel_id: string
webhook_id: string webhook_id: string
} }
interface Reaction { interface Reaction {
count: number, count: number
me: boolean me: boolean
emoji: Emoji emoji: EmojiPayload
} }
interface Overwrite { interface Overwrite {
id: string, id: string
type: number type: number
allow: string allow: string
deny: string deny: string
} }
interface ChannelMention { interface ChannelMention {
id: string id: string
guild_id: string guild_id: string
type: ChannelTypes type: ChannelTypes
name: string name: string
} }
export {
ChannelPayload,
ChannelTypes,
ChannelMention,
Attachment,
Reaction,
MessageActivity,
MessageApplication,
MessageReference,
MessagePayload,
EmbedPayload,
EmbedTypes,
EmbedFooter,
EmbedImage,
EmbedThumbnail,
EmbedVideo,
EmbedProvider,
EmbedAuthor,
EmbedField
}

View File

@ -1,10 +1,12 @@
interface Emoji { import { User } from '../structures/user.ts'
id: string
name: string | undefined export interface EmojiPayload {
roles?: [] id: string
user?: User name: string
require_colons?: boolean roles?: []
managed?: boolean user?: User
animated?: boolean require_colons?: boolean
available?: boolean managed?: boolean
} animated?: boolean
available?: boolean
}

View File

@ -4,7 +4,7 @@ import {
DISCORD_API_URL, DISCORD_API_URL,
DISCORD_API_VERSION, DISCORD_API_VERSION,
DISCORD_CDN_URL DISCORD_CDN_URL
} from "../consts/urlsAndVersions" } from '../consts/urlsAndVersions.ts'
//Guild Endpoints //Guild Endpoints
const GUILDS = `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/guilds` const GUILDS = `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/guilds`
@ -71,20 +71,20 @@ const MESSAGE_REACTIONS = (channelID: string, messageID: string) =>
const MESSAGE_REACTION = ( const MESSAGE_REACTION = (
channelID: string, channelID: string,
messageID: string, messageID: string,
emoji: string, emoji: string
) => ) =>
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/channels/${channelID}/messages/${messageID}/reactions/${emoji}` `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/channels/${channelID}/messages/${messageID}/reactions/${emoji}`
const MESSAGE_REACTION_ME = ( const MESSAGE_REACTION_ME = (
channelID: string, channelID: string,
messageID: string, messageID: string,
emojiID: string, emojiID: string
) => ) =>
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/channels/${channelID}/messages/${messageID}/reactions/${emojiID}/@me` `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/channels/${channelID}/messages/${messageID}/reactions/${emojiID}/@me`
const MESSAGE_REACTION_USER = ( const MESSAGE_REACTION_USER = (
channelID: string, channelID: string,
messageID: string, messageID: string,
emojiID: string, emojiID: string,
userID: string, userID: string
) => ) =>
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/channels/${channelID}/messages/${messageID}/reactions/${emojiID}/${userID}` `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/channels/${channelID}/messages/${messageID}/reactions/${emojiID}/${userID}`
const CHANNEL_BULK_DELETE = (channelID: string) => const CHANNEL_BULK_DELETE = (channelID: string) =>
@ -106,11 +106,9 @@ const GROUP_RECIPIENT = (channelID: string, userID: string) =>
//User Endpoints //User Endpoints
const CURRENT_USER = `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/users/@me` const CURRENT_USER = `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/users/@me`
const CURRENT_USER_GUILDS = const CURRENT_USER_GUILDS = `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/users/@me/guilds`
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/users/@me/guilds`
const USER_DM = `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/users/@me/channels` const USER_DM = `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/users/@me/channels`
const USER_CONNECTIONS = const USER_CONNECTIONS = `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/users/@me/connections`
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/users/@me/connections`
const LEAVE_GUILD = (guildID: string) => const LEAVE_GUILD = (guildID: string) =>
`${DISCORD_API_URL}/v${DISCORD_API_VERSION}/users/@me/guilds/${guildID}` `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/users/@me/guilds/${guildID}`
const USER = (userID: string) => const USER = (userID: string) =>
@ -143,7 +141,7 @@ const GUILD_SPLASH = (guildID: string, guildSPLASH: string) =>
`${DISCORD_CDN_URL}/splashes/${guildID}/${guildSPLASH}.png` `${DISCORD_CDN_URL}/splashes/${guildID}/${guildSPLASH}.png`
const GUILD_DISCOVERY_SPLASH = ( const GUILD_DISCOVERY_SPLASH = (
guildID: string, guildID: string,
guildDiscoverySplash: string, guildDiscoverySplash: string
) => ) =>
`${DISCORD_CDN_URL}/discovery-splashes/${guildID}/${guildDiscoverySplash}.png ` `${DISCORD_CDN_URL}/discovery-splashes/${guildID}/${guildDiscoverySplash}.png `
const GUILD_BANNER = (guildID: string, guildBANNER: string) => const GUILD_BANNER = (guildID: string, guildBANNER: string) =>
@ -157,7 +155,7 @@ const APPLICATION_ASSET = (applicationID: string, assetID: number) =>
const ACHIEVEMENT_ICON = ( const ACHIEVEMENT_ICON = (
applicationID: string, applicationID: string,
achievementID: string, achievementID: string,
iconHASH: string, iconHASH: string
) => ) =>
`${DISCORD_CDN_URL}/app-assets/${applicationID}/achievements/${achievementID}/icons/${iconHASH}.png` `${DISCORD_CDN_URL}/app-assets/${applicationID}/achievements/${achievementID}/icons/${iconHASH}.png`
const TEAM_ICON = (teamID: string, iconID: string) => const TEAM_ICON = (teamID: string, iconID: string) =>

View File

@ -1,4 +1,4 @@
import { GatewayOpcodes } from '../types/gatewayTypes' import { GatewayOpcodes, GatewayEvents } from '../types/gatewayTypes.ts'
/** /**
* Gateway response from Discord. * Gateway response from Discord.
@ -8,7 +8,7 @@ interface GatewayResponse {
op: GatewayOpcodes op: GatewayOpcodes
d: any d: any
s?: number s?: number
t?: string t?: GatewayEvents
} }
export { GatewayResponse } export { GatewayResponse }

View File

@ -1,4 +1,10 @@
// 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
import { Emoji } from '../structures/emoji.ts'
import { Role } from '../structures/role.ts'
import { User } from '../structures/user.ts'
import { MemberPayload } from './guildTypes.ts'
import { ActivityPayload, PresenceUpdatePayload } from './presenceTypes.ts'
/** /**
* Gateway OPcodes from Discord docs. * Gateway OPcodes from Discord docs.
@ -55,4 +61,319 @@ enum GatewayIntents {
DIRECT_MESSAGE_TYPING = 1 << 13 DIRECT_MESSAGE_TYPING = 1 << 13
} }
export { GatewayCloseCodes, GatewayOpcodes, GatewayIntents } enum GatewayEvents {
Hello = 'HELLO',
Ready = 'READY',
Resumed = 'RESUMED',
Reconnect = 'RECONNECT',
Invalid_Session = 'INVALID_SESSION',
Channel_Create = 'CHANNEL_CREATE',
Channel_Update = 'CHANNEL_UPDATE',
Channel_Delete = 'CHANNEL_DELETE',
Channel_Pins_Update = 'CHANNEL_PIN_UPDATE',
Guild_Create = 'GUILD_CREATE',
Guild_Update = 'GUILD_UPDATE',
Guild_Delete = 'GUILD_DELETE',
Guild_Ban_Add = 'GUILD_BAN_ADD',
Guild_Ban_Remove = 'GUILD_BAN_REMOVE',
Guild_Emojis_Update = 'GUILD_EMOJIS_UPDATE',
Guild_Integrations_Update = 'GUILD_INTEGRATIONS_UPDATE',
Guild_Member_Add = 'GUILD_MEMBER_ADD',
Guild_Member_Remove = 'GUILD_MEMBER_REMOVE',
Guild_Member_Update = 'GUILD_MEMBER_UPDATE',
Guild_Members_Chunk = 'GUILD_MEMBERS_CHUNK',
Guild_Role_Create = 'GUILD_ROLE_CREATE',
Guild_Role_Update = 'GUILD_ROLE_UPDATE',
Guild_Role_Delete = 'GUILD_ROLE_DELETE',
Invite_Create = 'INVITE_CREATE',
Invite_Delete = 'INVITE_DELETE',
Message_Create = 'MESSAGE_CREATE',
Message_Update = 'MESSAGE_UPDATE',
Message_Delete = 'MESSAG_DELETE',
Message_Delete_Bulk = 'MESSAGE_DELETE_BULK',
Message_Reaction_Add = 'MESSAGE_REACTION_ADD',
Message_Reaction_Remove = 'MESSAGE_REACTION_REMOVE',
Message_Reaction_Remove_All = 'MESSAGE_REACTION_REMOVE_ALL',
Message_Reaction_Remove_Emoji = 'MESSAGE_REACTION_REMOVE_EMOJI',
Presence_Update = 'PRESENCE_UPDATE',
Typing_Start = 'TYPING_START',
User_Update = 'USER_UPDATE',
Voice_State_Update = 'VOICE_STATE_UPDATE',
Voice_Server_Update = 'VOICE_SERVER_UPDATE',
Webhooks_Update = 'WEBHOOKS_UPDATE'
}
interface IdentityPayload {
token: string
properties: IdentityConnection
compress?: boolean
large_threshold?: number
shard?: number[]
presence?: UpdateStatus
guildSubscriptions?: boolean
intents: number
}
enum UpdateStatus {
online = 'online',
dnd = 'dnd',
afk = 'idle',
invisible = 'invisible',
offline = 'offline'
}
interface IdentityConnection {
$os: 'linux'
$browser: 'discord.deno'
$device: 'discord.deno'
}
interface Resume {
token: string
session_id: string
seq: number
}
interface GuildRequestMembers {
guild_id: string | string[]
query?: string
limit: number
presences?: boolean //do you have any problems? tell me! i am so handsome
user_ids?: string | string[]
nonce?: string
}
interface GatewayVoiceStateUpdate {
guild_id: string
channel_id: string
self_mute: boolean
self_deaf: boolean
}
interface GatewayStatusUpdate {
since: number | undefined
activities: ActivityPayload[]
status: string
afk: boolean
}
interface Hello {
heartbeat_interval: number
}
interface ReadyEvent {
v: number
user: User
privateChannels: []
guilds: []
session_id: string
shard?: number[]
}
interface ChannelPinsUpdate {
guild_id?: string
channel_id: string
last_pin_timestamp?: string
}
interface GuildBanAdd {
guild_id: string
user: User
}
interface GuildBanRemove {
guild_id: string
user: User
}
interface GuildEmojiUpdate {
guild_id: string
emojis: []
}
interface GuildIntegrationsUpdate {
guild_id: string
}
interface GuildMemberAddExtra {
guild_id: string
}
interface GuildMemberRemove {
guild_id: string
user: User
}
interface GuildMemberUpdate {
guild_id: string
roles: string[]
user: User
nick?: string | undefined
joined_at: string
premium_since?: string | undefined
}
interface GuildMemberChunk {
guild_id: string
members: MemberPayload[]
chunk_index: number
chunk_count: number
not_found?: []
presences?: PresenceUpdatePayload[]
nonce?: string
}
interface GuildRoleCreate {
guild_id: string
role: Role
}
interface GuildRoleUpdate {
guild_id: string
role: Role
}
interface GuildRoleDelete {
guild_id: string
role_id: string
}
interface InviteCreate {
channel_id: string
code: string
created_at: string
guild_id?: string
inviter?: User
max_age: number
max_uses: number
target_user?: User
target_user_type?: number
temporary: boolean
uses: number
}
interface InviteDelete {
channel_id: string
guild_id?: string
code: string
}
interface MessageDelete {
id: string
channel_id: string
guild_id?: string
}
interface MessageDeleteBulk {
ids: string[]
channel_id: string
guild_id: string
}
interface MessageReactionAdd {
user_id: string
channel_id: string
message_id: string
guild_id?: string
emoji: Emoji
}
interface MessageReactionRemove {
user_id: string
channel_id: string
message_id: string
guild_id?: string
emoji: Emoji
}
interface MessageReactionRemoveAll {
channel_id: string
guild_id?: string
message_id: string
emoji: Emoji
}
interface MessageReactionRemove {
channel_id: string
guild_id?: string
message_id: string
emoji: Emoji
}
interface PresenceUpdate {
user: User
guild_id: string
status: string
activities: ActivityPayload[]
client_status: UpdateStatus[]
}
interface CilentStatus {
desktop?: string
moblie?: string
web?: string
}
interface Activity {
name: string
type: number
url?: string | undefined
created_at: number
timestamps?: string
application_id: string
details?: string | undefined
state?: string | undefined
emoji?: Emoji | undefined
party?: ActivityParty
assets?: ActivityAssets
secrets?: ActivitySecrets
instance?: boolean
flags?: number
}
enum ActivityTypes {
GAME = 0,
STREAMING = 1,
LISTENING = 2,
CUSTOM = 4,
COMPETING = 5
}
interface ActivityTimestamps {
start?: number
end?: number
}
interface ActivityEmoji {
name: string
id?: string
animated?: boolean
}
interface ActivityParty {
id?: string
size?: number[]
}
interface ActivityAssets {
large_image?: string
large_text?: string
small_image?: string
small_text?: string
}
interface ActivitySecrets {
join?: string
spectate?: string
match?: string
}
enum ActivityFlags {
INSTANCE = 1 << 0,
JOIN = 1 << 1,
SPECTATE = 1 << 2,
JOIN_REQUEST = 1 << 3,
SYNC = 1 << 4,
PLAY = 1 << 5
}
//https://discord.com/developers/docs/topics/gateway#typing-start-typing-start-event-fields
export { GatewayCloseCodes, GatewayOpcodes, GatewayIntents, GatewayEvents }

View File

@ -1,107 +1,117 @@
interface Guild { import { Channel } from '../structures/channel.ts'
id: string import { Emoji } from '../structures/emoji.ts'
name: string import { Member } from '../structures/member.ts'
icon: string | undefined import { Role } from '../structures/role.ts'
icon_hash?: string | undefined import { User } from '../structures/user.ts'
splash: string | undefined import { PresenceUpdatePayload } from './presenceTypes.ts'
discovery_splash: string | undefined import { VoiceStatePayload } from './voiceTypes.ts'
owner?: boolean
owner_id: string interface GuildPayload {
permissions?: string id: string
region: string name: string
afk_channel_id: string | undefined icon: string | undefined
afk_timeout: number icon_hash?: string | undefined
widget_enabled?: boolean splash: string | undefined
widge_channel_id?: string | undefined discovery_splash: string | undefined
verification_level: string owner?: boolean
default_message_notifications: string owner_id: string
explicit_content_filter: string permissions?: string
roles: Role[] region: string
emojis: Emoji[] afk_channel_id: string | undefined
features: GuildFeatures[] afk_timeout: number
mfa_level: string widget_enabled?: boolean
application_id: string | undefined widge_channel_id?: string | undefined
system_channel_id: string | undefined verification_level: string
system_channel_flags: string default_message_notifications: string
rules_channel_id: string | undefined explicit_content_filter: string
joined_at?: string roles: Role[]
large?: boolean emojis: Emoji[]
unavailable: boolean features: GuildFeatures[]
member_count?: number mfa_level: string
voice_states?: VoiceState[] application_id: string | undefined
members?: GuildMember[] system_channel_id: string | undefined
channels?: Channel[] system_channel_flags: string
presences?: PresenceUpdate[] rules_channel_id: string | undefined
max_presences?: number | undefined joined_at?: string
max_members?: number large?: boolean
vanity_url_code: string | undefined unavailable: boolean
description: string | undefined member_count?: number
banner: string | undefined voice_states?: VoiceStatePayload[]
premium_tier: number members?: Member[]
premium_subscription_count?: number channels?: Channel[]
preferred_locale: string presences?: PresenceUpdatePayload[]
public_updates_channel_id: string | undefined max_presences?: number | undefined
max_video_channel_users?: number max_members?: number
approximate_number_count?: number vanity_url_code: string | undefined
approximate_presence_count?: number description: string | undefined
banner: string | undefined
premium_tier: number
premium_subscription_count?: number
preferred_locale: string
public_updates_channel_id: string | undefined
max_video_channel_users?: number
approximate_number_count?: number
approximate_presence_count?: number
} }
interface GuildMember { interface MemberPayload {
user?: User user: User
nick: string | undefined nick: string | undefined
roles: Role[] roles: Role[]
joined_at: string joined_at: string
premium_since?: string | undefined premium_since?: string | undefined
deaf: boolean deaf: boolean
mute: boolean mute: boolean
} }
enum MessageNotification { enum MessageNotification {
ALL_MESSAGES = 0, ALL_MESSAGES = 0,
ONLY_MENTIONS = 1 ONLY_MENTIONS = 1
} }
enum ContentFilter { enum ContentFilter {
DISABLED = 0, DISABLED = 0,
MEMBERS_WITHOUT_ROLES = 1, MEMBERS_WITHOUT_ROLES = 1,
ALL_MEMBERS = 3, ALL_MEMBERS = 3
} }
enum MFA { enum MFA {
NONE = 0, NONE = 0,
ELEVATED = 1 ELEVATED = 1
} }
enum Verification { enum Verification {
NONE = 0, NONE = 0,
LOW = 1, LOW = 1,
MEDIUM = 2, MEDIUM = 2,
HIGH = 3, HIGH = 3,
VERY_HIGH = 4 VERY_HIGH = 4
} }
enum PremiumTier { enum PremiumTier {
NONE = 0, NONE = 0,
TIER_1 = 1, TIER_1 = 1,
TIER_2 = 2, TIER_2 = 2,
TIER_3 = 3 TIER_3 = 3
} }
enum SystemChannelFlags { enum SystemChannelFlags {
SUPPRESS_JOIN_NOTIFICATIONS = 1 << 0, SUPPRESS_JOIN_NOTIFICATIONS = 1 << 0,
SUPPRESS_PREMIUM_SUBSCRIPTIONS = 1 << 1 SUPPRESS_PREMIUM_SUBSCRIPTIONS = 1 << 1
} }
type GuildFeatures = type GuildFeatures =
| "INVITE_SPLASH" | 'INVITE_SPLASH'
| "VIP_REGIONS" | 'VIP_REGIONS'
| "VANITY_URL" | 'VANITY_URL'
| "VERIFIED" | 'VERIFIED'
| "PARTNERED" | 'PARTNERED'
| "PUBLIC" | 'PUBLIC'
| "COMMERCE" | 'COMMERCE'
| "NEWS" | 'NEWS'
| "DISCOVERABLE" | 'DISCOVERABLE'
| "FEATURABLE" | 'FEATURABLE'
| "ANIMATED_ICON" | 'ANIMATED_ICON'
| "BANNER" | 'BANNER'
export { MemberPayload, GuildPayload, GuildFeatures }

View File

@ -1,10 +1,14 @@
interface Invite { import { Channel } from '../structures/channel.ts'
code: string import { Guild } from '../structures/guild.ts'
guild?: Guild import { User } from '../structures/user.ts'
channel: Channel
inviter?: User export interface InvitePayload {
target_user?: User code: string
target_user_type?: number guild?: Guild
approximate_presence_count?: number channel: Channel
approximate_member_count?: number inviter?: User
} target_user?: User
target_user_type?: number
approximate_presence_count?: number
approximate_member_count?: number
}

View File

@ -1,68 +1,72 @@
interface PresenceUpdate { import { User } from '../structures/user.ts'
user: User
guild_id: string interface PresenceUpdatePayload {
status: string user: User
activities: Activity guild_id: string
client_status: ClientStatus status: string
activities: ActivityPayload
client_status: ClientStatus
} }
interface ClientStatus { interface ClientStatus {
desktop?: string desktop?: string
mobile?: string mobile?: string
web?: string web?: string
} }
interface Activity { interface ActivityPayload {
name: string name: string
type: 0 | 1 | 2 | 3 | 4 | 5 type: 0 | 1 | 2 | 3 | 4 | 5
url?: string | undefined url?: string | undefined
created_at: number created_at: number
timestamps?: ActivityTimestamps timestamps?: ActivityTimestamps
application_id?: string application_id?: string
details?: string | undefined details?: string | undefined
state?: string | undefined state?: string | undefined
emoji?: ActivityEmoji emoji?: ActivityEmoji
party?: ActivityParty party?: ActivityParty
assets?: ActivityAssets assets?: ActivityAssets
secrets?: ActivitySecrets secrets?: ActivitySecrets
instance?: boolean instance?: boolean
flags?: number flags?: number
} }
interface ActivityTimestamps { interface ActivityTimestamps {
start?: number start?: number
end?: number end?: number
} }
interface ActivityEmoji { interface ActivityEmoji {
name: string name: string
id?: string id?: string
animated?: boolean animated?: boolean
} }
interface ActivityParty { interface ActivityParty {
id?: string id?: string
size?: number[] size?: number[]
} }
interface ActivityAssets { interface ActivityAssets {
large_image?: string large_image?: string
large_text?: string large_text?: string
small_image?: string small_image?: string
small_text?: string small_text?: string
} }
interface ActivitySecrets { interface ActivitySecrets {
join?: string join?: string
spectate?: string spectate?: string
match?: string match?: string
} }
enum ActivityFlags { enum ActivityFlags {
INSTANCE = 1 << 0, INSTANCE = 1 << 0,
JOIN = 1 << 1, JOIN = 1 << 1,
SPECTATE = 1 << 2, SPECTATE = 1 << 2,
JOIN_REQUEST = 1 << 3, JOIN_REQUEST = 1 << 3,
SYNC = 1 << 4, SYNC = 1 << 4,
PLAY = 1 << 5 PLAY = 1 << 5
} }
export { ActivityPayload, PresenceUpdatePayload }

View File

@ -1,10 +1,10 @@
interface Role { export interface RolePayload {
id: string id: string
name: string name: string
color: number color: number
hoist: boolean hoist: boolean
position: number position: number
permissions: string permissions: string
managed: boolean managed: boolean
mentionable: boolean mentionable: boolean
} }

View File

@ -1,17 +1,22 @@
export class Snowflake { export class Snowflake {
id: string id: string
constructor(id: string) { constructor (id: string) {
this.id = id this.id = id
} }
deconstruct() { deconstruct () {
const snowflake = BigInt.asUintN(64, BigInt(this.id)); const snowflake = BigInt.asUintN(64, BigInt(this.id))
const res = { const res = {
timestamp: (snowflake << BigInt(22)) + BigInt(1420070400000), timestamp: ((snowflake << BigInt(22)) + BigInt(1420070400000)).toString(),
workerId: (snowflake & BigInt(0x3E0000)) >> BigInt(17), workerId: ((snowflake & BigInt(0x3e0000)) >> BigInt(17)).toString(),
processId: (snowflake & BigInt(0x1F000)) >> BigInt(12), processId: ((snowflake & BigInt(0x1f000)) >> BigInt(12)).toString(),
increment: snowflake & BigInt(0xFFF), increment: (snowflake & BigInt(0xfff)).toString()
} }
return res return res
} }
} }
// BigInt라서 이걸 어케 할까 고심끝에 나온게 toString 읍
// 엄...
// deconstruct가 소멸자임? 색 봐서는 아닌거같은데

View File

@ -1,13 +1,16 @@
interface Template { import { Guild } from '../structures/guild.ts'
code: string import { User } from '../structures/user.ts'
name: string
description: string | undefined export interface TemplatePayload {
usage_count: number code: string
creator_id: string name: string
creator: User description: string | undefined
created_at: string usage_count: number
updated_at: string creator_id: string
source_guild_id: string creator: User
serialized_source_guild: Guild created_at: string
is_dirty: boolean | undefined updated_at: string
} source_guild_id: string
serialized_source_guild: Guild
is_dirty: boolean | undefined
}

View File

@ -1,14 +1,14 @@
interface User { export interface UserPayload {
id: string id: string
username: string username: string
discriminator: string discriminator: string
avatar: string | undefined avatar?: string
bot?: boolean bot?: boolean
system?: boolean system?: boolean
mfa_enabled?: boolean mfa_enabled?: boolean
locale?: string locale?: string
verified?: boolean verified?: boolean
email?: string | undefined email?: string
flags?: number flags?: number
premium_type?: 0 | 1 | 2 premium_type?: 0 | 1 | 2
public_flags?: number public_flags?: number

View File

@ -1,4 +1,5 @@
// https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice // https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice
import { Member } from '../structures/member.ts'
enum VoiceOpcodes { // VoiceOpcodes 추가 - UnderC - enum VoiceOpcodes { // VoiceOpcodes 추가 - UnderC -
IDENTIFY = 0, IDENTIFY = 0,
@ -11,7 +12,7 @@ enum VoiceOpcodes { // VoiceOpcodes 추가 - UnderC -
RESUME = 7, RESUME = 7,
HELLO = 8, HELLO = 8,
RESUMED = 9, RESUMED = 9,
CLIENT_DISCONNECT = 13, CLIENT_DISCONNECT = 13
} }
enum VoiceCloseCodes { enum VoiceCloseCodes {
@ -25,14 +26,14 @@ enum VoiceCloseCodes {
UNKNOWN_PROTOCOL = 4012, UNKNOWN_PROTOCOL = 4012,
DISCONNECTED = 4014, DISCONNECTED = 4014,
VOICE_SERVER_CRASHED = 4015, VOICE_SERVER_CRASHED = 4015,
UNKNOWN_ENCRYPTION_MODE = 4016, UNKNOWN_ENCRYPTION_MODE = 4016
} }
interface VoiceState { export interface VoiceStatePayload {
guild_id?: string guild_id?: string
channel_id: string | undefined channel_id: string | undefined
user_id: string user_id: string
member?: GuildMember member?: Member
session_id: string session_id: string
deaf: boolean deaf: boolean
mute: boolean mute: boolean
@ -41,4 +42,4 @@ interface VoiceState {
self_stream?: boolean self_stream?: boolean
self_video: boolean self_video: boolean
suppress: boolean suppress: boolean
} }

View File

@ -1,11 +1,13 @@
interface Webhook { import { User } from '../structures/user.ts'
id: string
type: 1 | 2 export interface WebhookPayload {
guild_id?: string id: string
channel_id: string type: 1 | 2
user?: User guild_id?: string
name: string | undefined channel_id: string
avatar: string | undefined user?: User
token?: string name: string | undefined
application_id: string | undefined avatar: string | undefined
} token?: string
application_id: string | undefined
}