Merge pull request #38 from DjDeveloperr/main
feat: Gateway Events, Webhooks, and other structures
This commit is contained in:
commit
214a1065ee
32 changed files with 1368 additions and 869 deletions
17
.vscode/settings.json
vendored
17
.vscode/settings.json
vendored
|
@ -1,9 +1,10 @@
|
|||
{
|
||||
"deno.enable": true,
|
||||
"deno.lint": false,
|
||||
"deno.unstable": false,
|
||||
"deepscan.enable": true,
|
||||
"deno.import_intellisense_origins": {
|
||||
"https://deno.land": true
|
||||
}
|
||||
{
|
||||
"deno.enable": true,
|
||||
"deno.lint": false,
|
||||
"deno.unstable": false,
|
||||
"deepscan.enable": true,
|
||||
"deno.import_intellisense_origins": {
|
||||
"https://deno.land": true
|
||||
},
|
||||
"editor.tabSize": 2
|
||||
}
|
124
mod.ts
124
mod.ts
|
@ -1,57 +1,67 @@
|
|||
export * from './src/gateway/index.ts'
|
||||
export * from './src/models/client.ts'
|
||||
export * from './src/models/rest.ts'
|
||||
export * from './src/models/cacheAdapter.ts'
|
||||
export * from './src/models/shard.ts'
|
||||
export * from './src/models/command.ts'
|
||||
export * from './src/models/commandClient.ts'
|
||||
export * from './src/managers/base.ts'
|
||||
export * from './src/managers/baseChild.ts'
|
||||
export * from './src/managers/channels.ts'
|
||||
export * from './src/managers/emojis.ts'
|
||||
export * from './src/managers/gatewayCache.ts'
|
||||
export * from './src/managers/guildChannels.ts'
|
||||
export * from './src/managers/guilds.ts'
|
||||
export * from './src/managers/members.ts'
|
||||
export * from './src/managers/messages.ts'
|
||||
export * from './src/managers/roles.ts'
|
||||
export * from './src/managers/users.ts'
|
||||
export * from './src/structures/base.ts'
|
||||
export * from './src/structures/cdn.ts'
|
||||
export * from './src/structures/channel.ts'
|
||||
export * from './src/structures/dmChannel.ts'
|
||||
export * from './src/structures/embed.ts'
|
||||
export * from './src/structures/emoji.ts'
|
||||
export * from './src/structures/groupChannel.ts'
|
||||
export * from './src/structures/guild.ts'
|
||||
export * from './src/structures/guildCategoryChannel.ts'
|
||||
export * from './src/structures/guildNewsChannel.ts'
|
||||
export * from './src/structures/guildVoiceChannel.ts'
|
||||
export * from './src/structures/invite.ts'
|
||||
export * from './src/structures/member.ts'
|
||||
export * from './src/structures/message.ts'
|
||||
export * from './src/structures/messageMentions.ts'
|
||||
export * from './src/structures/presence.ts'
|
||||
export * from './src/structures/role.ts'
|
||||
export * from './src/structures/snowflake.ts'
|
||||
export * from './src/structures/textChannel.ts'
|
||||
export * from './src/structures/user.ts'
|
||||
export * from './src/structures/webhook.ts'
|
||||
export * from './src/types/cdn.ts'
|
||||
export * from './src/types/channel.ts'
|
||||
export * from './src/types/emoji.ts'
|
||||
export * from './src/types/endpoint.ts'
|
||||
export * from './src/types/gateway.ts'
|
||||
export * from './src/types/gatewayBot.ts'
|
||||
export * from './src/types/gatewayResponse.ts'
|
||||
export * from './src/types/guild.ts'
|
||||
export * from './src/types/invite.ts'
|
||||
export * from './src/types/permissionFlags.ts'
|
||||
export * from './src/types/presence.ts'
|
||||
export * from './src/types/role.ts'
|
||||
export * from './src/types/template.ts'
|
||||
export * from './src/types/user.ts'
|
||||
export * from './src/types/voice.ts'
|
||||
export * from './src/types/webhook.ts'
|
||||
export * from './src/utils/collection.ts'
|
||||
export * from './src/utils/intents.ts'
|
||||
export * from './src/gateway/index.ts'
|
||||
export * from './src/models/client.ts'
|
||||
export * from './src/models/rest.ts'
|
||||
export * from './src/models/cacheAdapter.ts'
|
||||
export * from './src/models/shard.ts'
|
||||
export * from './src/models/command.ts'
|
||||
export * from './src/models/extensions.ts'
|
||||
export * from './src/models/commandClient.ts'
|
||||
export * from './src/managers/base.ts'
|
||||
export * from './src/managers/baseChild.ts'
|
||||
export * from './src/managers/channels.ts'
|
||||
export * from './src/managers/emojis.ts'
|
||||
export * from './src/managers/gatewayCache.ts'
|
||||
export * from './src/managers/guildChannels.ts'
|
||||
export * from './src/managers/guilds.ts'
|
||||
export * from './src/managers/guildChannels.ts'
|
||||
export * from './src/managers/guildEmojis.ts'
|
||||
export * from './src/managers/members.ts'
|
||||
export * from './src/managers/messages.ts'
|
||||
export * from './src/managers/roles.ts'
|
||||
export * from './src/managers/users.ts'
|
||||
export * from './src/structures/application.ts'
|
||||
export * from './src/structures/base.ts'
|
||||
export * from './src/structures/cdn.ts'
|
||||
export * from './src/structures/channel.ts'
|
||||
export * from './src/structures/dmChannel.ts'
|
||||
export * from './src/structures/embed.ts'
|
||||
export * from './src/structures/emoji.ts'
|
||||
export * from './src/structures/groupChannel.ts'
|
||||
export * from './src/structures/guild.ts'
|
||||
export * from './src/structures/guildCategoryChannel.ts'
|
||||
export * from './src/structures/guildNewsChannel.ts'
|
||||
export * from './src/structures/guildVoiceChannel.ts'
|
||||
export * from './src/structures/invite.ts'
|
||||
export * from './src/structures/member.ts'
|
||||
export * from './src/structures/message.ts'
|
||||
export * from './src/structures/messageMentions.ts'
|
||||
export * from './src/structures/presence.ts'
|
||||
export * from './src/structures/role.ts'
|
||||
export * from './src/structures/snowflake.ts'
|
||||
export * from './src/structures/textChannel.ts'
|
||||
export * from './src/structures/user.ts'
|
||||
export * from './src/structures/webhook.ts'
|
||||
export * from './src/types/application.ts'
|
||||
export * from './src/types/cdn.ts'
|
||||
export * from './src/types/channel.ts'
|
||||
export * from './src/types/emoji.ts'
|
||||
export * from './src/types/endpoint.ts'
|
||||
export * from './src/types/gateway.ts'
|
||||
export * from './src/types/gatewayBot.ts'
|
||||
export * from './src/types/gatewayResponse.ts'
|
||||
export * from './src/types/guild.ts'
|
||||
export * from './src/types/invite.ts'
|
||||
export * from './src/types/permissionFlags.ts'
|
||||
export * from './src/types/presence.ts'
|
||||
export * from './src/types/role.ts'
|
||||
export * from './src/types/template.ts'
|
||||
export * from './src/types/user.ts'
|
||||
export * from './src/types/voice.ts'
|
||||
export * from './src/types/webhook.ts'
|
||||
export * from './src/utils/collection.ts'
|
||||
export * from './src/utils/intents.ts'
|
||||
export * from './src/utils/buildInfo.ts'
|
||||
export * from './src/utils/permissions.ts'
|
||||
export * from './src/utils/userFlags.ts'
|
||||
export * from './src/utils/bitfield.ts'
|
||||
export * from './src/utils/getChannelByType.ts'
|
|
@ -1,21 +1,21 @@
|
|||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
import { TextChannel } from '../../structures/textChannel.ts'
|
||||
import { ChannelPinsUpdatePayload } from '../../types/gateway.ts'
|
||||
|
||||
export const channelPinsUpdate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: ChannelPinsUpdatePayload
|
||||
) => {
|
||||
const after: TextChannel | undefined = await gateway.client.channels.get<TextChannel>(d.channel_id)
|
||||
if (after !== undefined) {
|
||||
const before = after.refreshFromData({
|
||||
last_pin_timestamp: d.last_pin_timestamp
|
||||
})
|
||||
const raw = await gateway.client.channels._get(d.channel_id)
|
||||
await gateway.client.channels.set(
|
||||
after.id,
|
||||
Object.assign(raw, { last_pin_timestamp: d.last_pin_timestamp })
|
||||
)
|
||||
gateway.client.emit('channelPinsUpdate', before, after)
|
||||
}
|
||||
}
|
||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
import { TextChannel } from '../../structures/textChannel.ts'
|
||||
import { ChannelPinsUpdatePayload } from '../../types/gateway.ts'
|
||||
|
||||
export const channelPinsUpdate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: ChannelPinsUpdatePayload
|
||||
) => {
|
||||
const after: TextChannel | undefined = await gateway.client.channels.get<TextChannel>(d.channel_id)
|
||||
if (after !== undefined) {
|
||||
const before = after.refreshFromData({
|
||||
last_pin_timestamp: d.last_pin_timestamp
|
||||
})
|
||||
const raw = await gateway.client.channels._get(d.channel_id)
|
||||
await gateway.client.channels.set(
|
||||
after.id,
|
||||
Object.assign(raw, { last_pin_timestamp: d.last_pin_timestamp })
|
||||
)
|
||||
gateway.client.emit('channelPinsUpdate', before, after)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,21 @@
|
|||
import { Channel } from '../../structures/channel.ts'
|
||||
import { Guild } from '../../structures/guild.ts'
|
||||
import { ChannelPayload, GuildChannelPayload } from '../../types/channel.ts'
|
||||
import getChannelByType from '../../utils/getChannelByType.ts'
|
||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
|
||||
export const channelUpdate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: ChannelPayload
|
||||
) => {
|
||||
const oldChannel: Channel | undefined = await gateway.client.channels.get(d.id)
|
||||
|
||||
if (oldChannel !== undefined) {
|
||||
await gateway.client.channels.set(d.id, d)
|
||||
let guild: undefined | Guild;
|
||||
if ('guild_id' in d) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
guild = await gateway.client.guilds.get((d as GuildChannelPayload).guild_id) as Guild | undefined
|
||||
}
|
||||
if (oldChannel.type !== d.type) {
|
||||
const channel: Channel = getChannelByType(gateway.client, d, guild) ?? oldChannel
|
||||
gateway.client.emit('channelUpdate', oldChannel, channel)
|
||||
} else {
|
||||
const before = oldChannel.refreshFromData(d)
|
||||
gateway.client.emit('channelUpdate', before, oldChannel)
|
||||
}
|
||||
}
|
||||
}
|
||||
import { Channel } from '../../structures/channel.ts'
|
||||
import { ChannelPayload } from "../../types/channel.ts"
|
||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
|
||||
export const channelUpdate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: ChannelPayload
|
||||
) => {
|
||||
const oldChannel: Channel | undefined = await gateway.client.channels.get(d.id)
|
||||
await gateway.client.channels.set(d.id, d)
|
||||
const newChannel: Channel = (await gateway.client.channels.get(d.id) as unknown) as Channel
|
||||
|
||||
if (oldChannel !== undefined) {
|
||||
// (DjDeveloperr): Already done by ChannelsManager. I'll recheck later
|
||||
// if ('guild_id' in d) {
|
||||
// // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
// (newChannel as GuildChannel).guild = await gateway.client.guilds.get((d as GuildChannelPayload).guild_id) as Guild
|
||||
// }
|
||||
gateway.client.emit('channelUpdate', oldChannel, newChannel)
|
||||
} else gateway.client.emit('channelUpdateUncached', newChannel)
|
||||
}
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
import { Emoji } from "../../structures/emoji.ts"
|
||||
import { Guild } from '../../structures/guild.ts'
|
||||
import { EmojiPayload } from "../../types/emoji.ts"
|
||||
import { GuildEmojiUpdatePayload } from '../../types/gateway.ts'
|
||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
|
||||
export const guildEmojiUpdate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: GuildEmojiUpdatePayload
|
||||
) => {
|
||||
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
||||
if (guild !== undefined) {
|
||||
const emojis = await guild.emojis.collection()
|
||||
const deleted: Emoji[] = []
|
||||
const added: Emoji[] = []
|
||||
const updated: Array<{ before: Emoji, after: Emoji }> = []
|
||||
const _updated: EmojiPayload[] = []
|
||||
|
||||
for (const raw of d.emojis) {
|
||||
const has = emojis.get(raw.id)
|
||||
if (has === undefined) {
|
||||
await guild.emojis.set(raw.id, raw)
|
||||
const emoji = await guild.emojis.get(raw.id) as Emoji
|
||||
added.push(emoji)
|
||||
} else _updated.push(raw)
|
||||
}
|
||||
|
||||
for (const emoji of emojis.values()) {
|
||||
const find = _updated.find(e => emoji.id === e.id)
|
||||
if (find === undefined) {
|
||||
await guild.emojis.delete(emoji.id)
|
||||
deleted.push(emoji)
|
||||
} else {
|
||||
const before = await guild.emojis.get(find.id) as Emoji
|
||||
await guild.emojis.set(find.id, find)
|
||||
const after = await guild.emojis.get(find.id) as Emoji
|
||||
updated.push({ before, after })
|
||||
}
|
||||
}
|
||||
|
||||
for (const emoji of deleted) {
|
||||
gateway.client.emit('guildEmojiDelete', emoji)
|
||||
}
|
||||
|
||||
for (const emoji of added) {
|
||||
gateway.client.emit('guildEmojiAdd', emoji)
|
||||
}
|
||||
|
||||
for (const emoji of updated) {
|
||||
gateway.client.emit('guildEmojiUpdate', emoji.before, emoji.after)
|
||||
}
|
||||
}
|
||||
}
|
||||
import { Emoji } from "../../structures/emoji.ts"
|
||||
import { Guild } from '../../structures/guild.ts'
|
||||
import { EmojiPayload } from "../../types/emoji.ts"
|
||||
import { GuildEmojiUpdatePayload } from '../../types/gateway.ts'
|
||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
|
||||
export const guildEmojiUpdate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: GuildEmojiUpdatePayload
|
||||
) => {
|
||||
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
||||
if (guild !== undefined) {
|
||||
const emojis = await guild.emojis.collection()
|
||||
const deleted: Emoji[] = []
|
||||
const added: Emoji[] = []
|
||||
const updated: Array<{ before: Emoji, after: Emoji }> = []
|
||||
const _updated: EmojiPayload[] = []
|
||||
|
||||
for (const raw of d.emojis) {
|
||||
const has = emojis.get(raw.id)
|
||||
if (has === undefined) {
|
||||
await guild.emojis.set(raw.id, raw)
|
||||
const emoji = await guild.emojis.get(raw.id) as Emoji
|
||||
added.push(emoji)
|
||||
} else _updated.push(raw)
|
||||
}
|
||||
|
||||
for (const emoji of emojis.values()) {
|
||||
const find = _updated.find(e => emoji.id === e.id)
|
||||
if (find === undefined) {
|
||||
await guild.emojis.delete(emoji.id)
|
||||
deleted.push(emoji)
|
||||
} else {
|
||||
const before = await guild.emojis.get(find.id) as Emoji
|
||||
await guild.emojis.set(find.id, find)
|
||||
const after = await guild.emojis.get(find.id) as Emoji
|
||||
updated.push({ before, after })
|
||||
}
|
||||
}
|
||||
|
||||
for (const emoji of deleted) {
|
||||
gateway.client.emit('guildEmojiDelete', guild, emoji)
|
||||
}
|
||||
|
||||
for (const emoji of added) {
|
||||
gateway.client.emit('guildEmojiAdd', guild, emoji)
|
||||
}
|
||||
|
||||
for (const emoji of updated) {
|
||||
gateway.client.emit('guildEmojiUpdate', guild, emoji.before, emoji.after)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
14
src/gateway/handlers/guildIntegrationsUpdate.ts
Normal file
14
src/gateway/handlers/guildIntegrationsUpdate.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
import { Guild } from '../../structures/guild.ts'
|
||||
import { GuildIntegrationsUpdatePayload } from "../../types/gateway.ts"
|
||||
|
||||
export const guildIntegrationsUpdate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: GuildIntegrationsUpdatePayload
|
||||
) => {
|
||||
console.log(d)
|
||||
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
||||
if (guild === undefined) return
|
||||
|
||||
gateway.client.emit('guildIntegrationsUpdate', guild)
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
import { Guild } from '../../structures/guild.ts'
|
||||
import { GuildMemberAddPayload } from "../../../mod.ts"
|
||||
import { GuildMemberAddPayload } from "../../types/gateway.ts"
|
||||
import { Member } from "../../structures/member.ts"
|
||||
|
||||
export const guildMemberAdd: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
|
@ -11,6 +12,6 @@ export const guildMemberAdd: GatewayEventHandler = async (
|
|||
if (guild === undefined) return
|
||||
|
||||
await guild.members.set(d.user.id, d)
|
||||
const member = await guild.members.get(d.user.id)
|
||||
const member = await guild.members.get(d.user.id) as Member
|
||||
gateway.client.emit('guildMemberAdd', member)
|
||||
}
|
|
@ -2,6 +2,7 @@ import { Gateway, GatewayEventHandler } from '../index.ts'
|
|||
import { Guild } from '../../structures/guild.ts'
|
||||
import { GuildMemberUpdatePayload } from '../../types/gateway.ts'
|
||||
import { MemberPayload } from '../../types/guild.ts'
|
||||
import { Member } from "../../structures/member.ts"
|
||||
|
||||
export const guildMemberUpdate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
|
@ -25,7 +26,7 @@ export const guildMemberUpdate: GatewayEventHandler = async (
|
|||
const newMember = await guild.members.get(d.user.id)
|
||||
|
||||
if (member !== undefined)
|
||||
gateway.client.emit('guildMemberRemove', member, newMember)
|
||||
gateway.client.emit('guildMemberUpdate', member, (newMember as unknown) as Member)
|
||||
else {
|
||||
gateway.client.emit('guildMemberUpdateUncached', newMember)
|
||||
}
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
import { Guild } from '../../structures/guild.ts'
|
||||
import { GuildRoleCreatePayload } from "../../types/gateway.ts"
|
||||
|
||||
export const guildRoleCreate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: GuildRoleCreatePayload
|
||||
) => {
|
||||
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
||||
// Weird case, shouldn't happen
|
||||
if (guild === undefined) return
|
||||
|
||||
await guild.roles.set(d.role.id, d.role)
|
||||
const role = await guild.roles.get(d.role.id)
|
||||
gateway.client.emit('guildRoleCreate', role)
|
||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
import { Guild } from '../../structures/guild.ts'
|
||||
import { GuildRoleCreatePayload } from "../../types/gateway.ts"
|
||||
import { Role } from "../../structures/role.ts"
|
||||
|
||||
export const guildRoleCreate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: GuildRoleCreatePayload
|
||||
) => {
|
||||
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
||||
// Weird case, shouldn't happen
|
||||
if (guild === undefined) return
|
||||
|
||||
await guild.roles.set(d.role.id, d.role)
|
||||
const role = await guild.roles.get(d.role.id)
|
||||
gateway.client.emit('guildRoleCreate', (role as unknown) as Role)
|
||||
}
|
|
@ -1,21 +1,22 @@
|
|||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
import { Guild } from '../../structures/guild.ts'
|
||||
import { GuildRoleUpdatePayload } from "../../types/gateway.ts"
|
||||
|
||||
export const guildRoleUpdate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: GuildRoleUpdatePayload
|
||||
) => {
|
||||
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
||||
// Weird case, shouldn't happen
|
||||
if (guild === undefined) return
|
||||
|
||||
const role = await guild.roles.get(d.role.id)
|
||||
await guild.roles.set(d.role.id, d.role)
|
||||
const newRole = await guild.roles.get(d.role.id)
|
||||
|
||||
// Shouldn't happen either
|
||||
if(role === undefined) return gateway.client.emit('guildRoleUpdateUncached', newRole)
|
||||
|
||||
gateway.client.emit('guildRoleUpdate', role, newRole)
|
||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
import { Guild } from '../../structures/guild.ts'
|
||||
import { GuildRoleUpdatePayload } from "../../types/gateway.ts"
|
||||
import { Role } from "../../structures/role.ts"
|
||||
|
||||
export const guildRoleUpdate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: GuildRoleUpdatePayload
|
||||
) => {
|
||||
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
||||
// Weird case, shouldn't happen
|
||||
if (guild === undefined) return
|
||||
|
||||
const role = await guild.roles.get(d.role.id)
|
||||
await guild.roles.set(d.role.id, d.role)
|
||||
const newRole = await guild.roles.get(d.role.id)
|
||||
|
||||
// Shouldn't happen either
|
||||
if(role === undefined) return gateway.client.emit('guildRoleUpdateUncached', newRole)
|
||||
|
||||
gateway.client.emit('guildRoleUpdate', role, (newRole as unknown) as Role)
|
||||
}
|
|
@ -1,65 +1,115 @@
|
|||
import { GatewayEventHandler } from '../index.ts'
|
||||
import { GatewayEvents } from '../../types/gateway.ts'
|
||||
import { channelCreate } from './channelCreate.ts'
|
||||
import { channelDelete } from './channelDelete.ts'
|
||||
import { channelUpdate } from './channelUpdate.ts'
|
||||
import { channelPinsUpdate } from './channelPinsUpdate.ts'
|
||||
import { guildCreate } from './guildCreate.ts'
|
||||
import { guildDelte as guildDelete } from './guildDelete.ts'
|
||||
import { guildUpdate } from './guildUpdate.ts'
|
||||
import { guildBanAdd } from './guildBanAdd.ts'
|
||||
import { ready } from './ready.ts'
|
||||
import { guildBanRemove } from './guildBanRemove.ts'
|
||||
import { messageCreate } from './messageCreate.ts'
|
||||
import { resume } from './resume.ts'
|
||||
import { reconnect } from './reconnect.ts'
|
||||
import { messageDelete } from "./messageDelete.ts"
|
||||
import { messageUpdate } from "./messageUpdate.ts"
|
||||
import { guildEmojiUpdate } from "./guildEmojiUpdate.ts"
|
||||
import { guildMemberAdd } from "./guildMemberAdd.ts"
|
||||
import { guildMemberRemove } from "./guildMemberRemove.ts"
|
||||
import { guildMemberUpdate } from "./guildMemberUpdate.ts"
|
||||
import { guildRoleCreate } from "./guildRoleCreate.ts"
|
||||
import { guildRoleDelete } from "./guildRoleDelete.ts"
|
||||
import { guildRoleUpdate } from "./guildRoleUpdate.ts"
|
||||
|
||||
export const gatewayHandlers: {
|
||||
[eventCode in GatewayEvents]: GatewayEventHandler | undefined
|
||||
} = {
|
||||
READY: ready,
|
||||
RECONNECT: reconnect,
|
||||
RESUMED: resume,
|
||||
CHANNEL_CREATE: channelCreate,
|
||||
CHANNEL_DELETE: channelDelete,
|
||||
CHANNEL_UPDATE: channelUpdate,
|
||||
CHANNEL_PINS_UPDATE: channelPinsUpdate,
|
||||
GUILD_CREATE: guildCreate,
|
||||
GUILD_DELETE: guildDelete,
|
||||
GUILD_UPDATE: guildUpdate,
|
||||
GUILD_BAN_ADD: guildBanAdd,
|
||||
GUILD_BAN_REMOVE: guildBanRemove,
|
||||
GUILD_EMOJIS_UPDATE: guildEmojiUpdate,
|
||||
GUILD_INTEGRATIONS_UPDATE: undefined,
|
||||
GUILD_MEMBER_ADD: guildMemberAdd,
|
||||
GUILD_MEMBER_REMOVE: guildMemberRemove,
|
||||
GUILD_MEMBER_UPDATE: guildMemberUpdate,
|
||||
GUILD_MEMBERS_CHUNK: undefined,
|
||||
GUILD_ROLE_CREATE: guildRoleCreate,
|
||||
GUILD_ROLE_UPDATE: guildRoleUpdate,
|
||||
GUILD_ROLE_DELETE: guildRoleDelete,
|
||||
INVITE_CREATE: undefined,
|
||||
INVITE_DELETE: undefined,
|
||||
MESSAGE_CREATE: messageCreate,
|
||||
MESSAGE_UPDATE: messageUpdate,
|
||||
MESSAGE_DELETE: messageDelete,
|
||||
MESSAGE_DELETE_BULK: undefined,
|
||||
MESSAGE_REACTION_ADD: undefined,
|
||||
MESSAGE_REACTION_REMOVE: undefined,
|
||||
MESSAGE_REACTION_REMOVE_ALL: undefined,
|
||||
MESSAGE_REACTION_REMOVE_EMOJI: undefined,
|
||||
PRESENCE_UPDATE: undefined,
|
||||
TYPING_START: undefined,
|
||||
USER_UPDATE: undefined,
|
||||
VOICE_SERVER_UPDATE: undefined,
|
||||
WEBHOOKS_UPDATE: undefined
|
||||
}
|
||||
import { GatewayEventHandler } from '../index.ts'
|
||||
import { GatewayEvents, TypingStartGuildData } from '../../types/gateway.ts'
|
||||
import { channelCreate } from './channelCreate.ts'
|
||||
import { channelDelete } from './channelDelete.ts'
|
||||
import { channelUpdate } from './channelUpdate.ts'
|
||||
import { channelPinsUpdate } from './channelPinsUpdate.ts'
|
||||
import { guildCreate } from './guildCreate.ts'
|
||||
import { guildDelte as guildDelete } from './guildDelete.ts'
|
||||
import { guildUpdate } from './guildUpdate.ts'
|
||||
import { guildBanAdd } from './guildBanAdd.ts'
|
||||
import { ready } from './ready.ts'
|
||||
import { guildBanRemove } from './guildBanRemove.ts'
|
||||
import { messageCreate } from './messageCreate.ts'
|
||||
import { resume } from './resume.ts'
|
||||
import { reconnect } from './reconnect.ts'
|
||||
import { messageDelete } from "./messageDelete.ts"
|
||||
import { messageUpdate } from "./messageUpdate.ts"
|
||||
import { guildEmojiUpdate } from "./guildEmojiUpdate.ts"
|
||||
import { guildMemberAdd } from "./guildMemberAdd.ts"
|
||||
import { guildMemberRemove } from "./guildMemberRemove.ts"
|
||||
import { guildMemberUpdate } from "./guildMemberUpdate.ts"
|
||||
import { guildRoleCreate } from "./guildRoleCreate.ts"
|
||||
import { guildRoleDelete } from "./guildRoleDelete.ts"
|
||||
import { guildRoleUpdate } from "./guildRoleUpdate.ts"
|
||||
import { guildIntegrationsUpdate } from "./guildIntegrationsUpdate.ts"
|
||||
import { webhooksUpdate } from "./webhooksUpdate.ts"
|
||||
import { messageDeleteBulk } from "./messageDeleteBulk.ts"
|
||||
import { userUpdate } from "./userUpdate.ts"
|
||||
import { typingStart } from "./typingStart.ts"
|
||||
import { Channel } from "../../structures/channel.ts"
|
||||
import { GuildTextChannel, TextChannel } from "../../structures/textChannel.ts"
|
||||
import { Guild } from "../../structures/guild.ts"
|
||||
import { User } from "../../structures/user.ts"
|
||||
import { Emoji } from "../../structures/emoji.ts"
|
||||
import { Member } from "../../structures/member.ts"
|
||||
import { Role } from "../../structures/role.ts"
|
||||
import { Message } from "../../structures/message.ts"
|
||||
import { Collection } from "../../utils/collection.ts"
|
||||
|
||||
export const gatewayHandlers: {
|
||||
[eventCode in GatewayEvents]: GatewayEventHandler | undefined
|
||||
} = {
|
||||
READY: ready,
|
||||
RECONNECT: reconnect,
|
||||
RESUMED: resume,
|
||||
CHANNEL_CREATE: channelCreate,
|
||||
CHANNEL_DELETE: channelDelete,
|
||||
CHANNEL_UPDATE: channelUpdate,
|
||||
CHANNEL_PINS_UPDATE: channelPinsUpdate,
|
||||
GUILD_CREATE: guildCreate,
|
||||
GUILD_DELETE: guildDelete,
|
||||
GUILD_UPDATE: guildUpdate,
|
||||
GUILD_BAN_ADD: guildBanAdd,
|
||||
GUILD_BAN_REMOVE: guildBanRemove,
|
||||
GUILD_EMOJIS_UPDATE: guildEmojiUpdate,
|
||||
GUILD_INTEGRATIONS_UPDATE: guildIntegrationsUpdate,
|
||||
GUILD_MEMBER_ADD: guildMemberAdd,
|
||||
GUILD_MEMBER_REMOVE: guildMemberRemove,
|
||||
GUILD_MEMBER_UPDATE: guildMemberUpdate,
|
||||
GUILD_MEMBERS_CHUNK: undefined,
|
||||
GUILD_ROLE_CREATE: guildRoleCreate,
|
||||
GUILD_ROLE_UPDATE: guildRoleUpdate,
|
||||
GUILD_ROLE_DELETE: guildRoleDelete,
|
||||
INVITE_CREATE: undefined,
|
||||
INVITE_DELETE: undefined,
|
||||
MESSAGE_CREATE: messageCreate,
|
||||
MESSAGE_UPDATE: messageUpdate,
|
||||
MESSAGE_DELETE: messageDelete,
|
||||
MESSAGE_DELETE_BULK: messageDeleteBulk,
|
||||
MESSAGE_REACTION_ADD: undefined,
|
||||
MESSAGE_REACTION_REMOVE: undefined,
|
||||
MESSAGE_REACTION_REMOVE_ALL: undefined,
|
||||
MESSAGE_REACTION_REMOVE_EMOJI: undefined,
|
||||
PRESENCE_UPDATE: undefined,
|
||||
TYPING_START: typingStart,
|
||||
USER_UPDATE: userUpdate,
|
||||
VOICE_SERVER_UPDATE: undefined,
|
||||
WEBHOOKS_UPDATE: webhooksUpdate
|
||||
}
|
||||
|
||||
export interface EventTypes {
|
||||
[name: string]: (...args: any[]) => void
|
||||
}
|
||||
|
||||
export interface ClientEvents extends EventTypes {
|
||||
'ready': () => void
|
||||
'reconnect': () => void
|
||||
'resumed': () => void
|
||||
'channelCreate': (channel: Channel) => void
|
||||
'channelDelete': (channel: Channel) => void
|
||||
'channelPinsUpdate': (before: TextChannel, after: TextChannel) => void
|
||||
'channelUpdate': (before: Channel, after: Channel) => void
|
||||
'guildBanAdd': (guild: Guild, user: User) => void
|
||||
'guildBanRemove': (guild: Guild, user: User) => void
|
||||
'guildCreate': (guild: Guild) => void
|
||||
'guildDelete': (guild: Guild) => void
|
||||
'guildEmojiAdd': (guild: Guild, emoji: Emoji) => void
|
||||
'guildEmojiDelete': (guild: Guild, emoji: Emoji) => void
|
||||
'guildEmojiUpdate': (guild: Guild, before: Emoji, after: Emoji) => void
|
||||
'guildIntegrationsUpdate': (guild: Guild) => void
|
||||
'guildMemberAdd': (member: Member) => void
|
||||
'guildMemberRemove': (member: Member) => void
|
||||
'guildMemberUpdate': (before: Member, after: Member) => void
|
||||
'guildRoleCreate': (role: Role) => void
|
||||
'guildRoleDelete': (role: Role) => void
|
||||
'guildRoleUpdate': (before: Role, after: Role) => void
|
||||
'guildUpdate': (before: Guild, after: Guild) => void
|
||||
'messageCreate': (message: Message) => void
|
||||
'messageDelete': (message: Message) => void
|
||||
'messageDeleteBulk': (channel: GuildTextChannel, messages: Collection<string, Message>, uncached: Set<string>) => void
|
||||
'messageUpdate': (before: Message, after: Message) => void
|
||||
'typingStart': (user: User, channel: TextChannel, at: Date, guildData?: TypingStartGuildData) => void
|
||||
'userUpdate': (before: User, after: User) => void
|
||||
'webhooksUpdate': (guild: Guild, channel: GuildTextChannel) => void
|
||||
}
|
29
src/gateway/handlers/messageDeleteBulk.ts
Normal file
29
src/gateway/handlers/messageDeleteBulk.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { Message } from "../../structures/message.ts"
|
||||
import { GuildTextChannel } from '../../structures/textChannel.ts'
|
||||
import { MessageDeleteBulkPayload } from "../../types/gateway.ts"
|
||||
import { Collection } from "../../utils/collection.ts"
|
||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
|
||||
export const messageDeleteBulk: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: MessageDeleteBulkPayload
|
||||
) => {
|
||||
let channel = await gateway.client.channels.get<GuildTextChannel>(d.channel_id)
|
||||
// Fetch the channel if not cached
|
||||
if (channel === undefined)
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
channel = (await gateway.client.channels.fetch(d.channel_id)) as GuildTextChannel
|
||||
|
||||
const messages = new Collection<string, Message>()
|
||||
const uncached = new Set<string>()
|
||||
for (const id of d.ids) {
|
||||
const message = await channel.messages.get(id)
|
||||
if (message === undefined) uncached.add(id)
|
||||
else {
|
||||
messages.set(id, message)
|
||||
await channel.messages.delete(id)
|
||||
}
|
||||
}
|
||||
|
||||
gateway.client.emit('messageDeleteBulk', channel, messages, uncached)
|
||||
}
|
23
src/gateway/handlers/typingStart.ts
Normal file
23
src/gateway/handlers/typingStart.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { Member } from "../../structures/member.ts"
|
||||
import { TextChannel } from "../../structures/textChannel.ts"
|
||||
import { TypingStartPayload } from "../../types/gateway.ts"
|
||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
|
||||
// TODO: Do we need to add uncached events here?
|
||||
export const typingStart: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: TypingStartPayload
|
||||
) => {
|
||||
const user = await gateway.client.users.get(d.user_id)
|
||||
if (user === undefined) return console.log('user not cached')
|
||||
|
||||
const channel = await gateway.client.channels.get(d.channel_id)
|
||||
if (channel === undefined) return console.log(`channel not cached`)
|
||||
|
||||
const guild = d.guild_id !== undefined ? await gateway.client.guilds.get(d.guild_id) : undefined
|
||||
if(guild === undefined && d.guild_id !== undefined) return console.log('guild not cached')
|
||||
|
||||
const member = d.member !== undefined && guild !== undefined ? new Member(gateway.client, d.member, user, guild) : undefined
|
||||
|
||||
gateway.client.emit('typingStart', user, (channel as unknown) as TextChannel, new Date(d.timestamp), guild !== undefined && member !== undefined ? { guild, member } : undefined)
|
||||
}
|
16
src/gateway/handlers/userUpdate.ts
Normal file
16
src/gateway/handlers/userUpdate.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { User } from "../../structures/user.ts"
|
||||
import { UserPayload } from "../../types/user.ts"
|
||||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
|
||||
export const userUpdate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: UserPayload
|
||||
) => {
|
||||
const oldUser: User | undefined = await gateway.client.users.get(d.id)
|
||||
await gateway.client.users.set(d.id, d)
|
||||
const newUser: User = (await gateway.client.users.get(d.id) as unknown) as User
|
||||
|
||||
if (oldUser !== undefined) {
|
||||
gateway.client.emit('userUpdate', oldUser, newUser)
|
||||
} else gateway.client.emit('userUpdateUncached', newUser)
|
||||
}
|
16
src/gateway/handlers/webhooksUpdate.ts
Normal file
16
src/gateway/handlers/webhooksUpdate.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { Gateway, GatewayEventHandler } from '../index.ts'
|
||||
import { Guild } from '../../structures/guild.ts'
|
||||
import { WebhooksUpdatePayload } from "../../types/gateway.ts"
|
||||
import { GuildTextChannel } from "../../structures/textChannel.ts"
|
||||
|
||||
export const webhooksUpdate: GatewayEventHandler = async (
|
||||
gateway: Gateway,
|
||||
d: WebhooksUpdatePayload
|
||||
) => {
|
||||
const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
|
||||
if (guild === undefined) return
|
||||
|
||||
const channel: GuildTextChannel | undefined = await guild.channels.get(d.channel_id) as GuildTextChannel
|
||||
if (channel === undefined) gateway.client.emit('webhooksUpdateUncached', guild, d.channel_id)
|
||||
else gateway.client.emit('webhooksUpdate', guild, channel)
|
||||
}
|
|
@ -43,7 +43,7 @@ export class ChannelsManager extends BaseManager<ChannelPayload, Channel> {
|
|||
return result
|
||||
}
|
||||
|
||||
async fetch (id: string): Promise<Channel> {
|
||||
async fetch<T = Channel> (id: string): Promise<T> {
|
||||
return await new Promise((resolve, reject) => {
|
||||
this.client.rest
|
||||
.get(CHANNEL(id))
|
||||
|
@ -53,7 +53,7 @@ export class ChannelsManager extends BaseManager<ChannelPayload, Channel> {
|
|||
if (data.guild_id !== undefined) {
|
||||
guild = await this.client.guilds.get(data.guild_id)
|
||||
}
|
||||
resolve(getChannelByType(this.client, data as ChannelPayload, guild))
|
||||
resolve((getChannelByType(this.client, data as ChannelPayload, guild) as unknown) as T)
|
||||
})
|
||||
.catch(e => reject(e))
|
||||
})
|
||||
|
|
|
@ -20,7 +20,6 @@ export class GatewayCache {
|
|||
}
|
||||
|
||||
async delete (key: string): Promise<boolean> {
|
||||
console.log(`[GatewayCache] DEL ${key}`)
|
||||
const result = await this.client.cache.delete(this.cacheName, key)
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ import {
|
|||
} from '../structures/presence.ts'
|
||||
import { EmojisManager } from '../managers/emojis.ts'
|
||||
import { ActivityGame, ClientActivity } from "../types/presence.ts"
|
||||
import { ClientEvents } from "../gateway/handlers/index.ts"
|
||||
// import { Application } from "../../mod.ts"
|
||||
|
||||
/** Some Client Options to modify behaviour */
|
||||
export interface ClientOptions {
|
||||
|
@ -33,6 +35,17 @@ export interface ClientOptions {
|
|||
messageCacheLifetime?: number
|
||||
}
|
||||
|
||||
export declare interface Client {
|
||||
on: <U extends string>(
|
||||
event: U, listener: ClientEvents[U]
|
||||
) => this
|
||||
|
||||
emit: <U extends string>(
|
||||
event: U, ...args: Parameters<ClientEvents[U]>
|
||||
) => boolean
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Discord Client.
|
||||
*/
|
||||
|
@ -103,6 +116,9 @@ export class Client extends EventEmitter {
|
|||
this.emit('debug', `[${tag}] ${msg}`)
|
||||
}
|
||||
|
||||
// TODO(DjDeveloperr): Implement this
|
||||
// fetchApplication(): Promise<Application>
|
||||
|
||||
/**
|
||||
* This function is used for connect to discord.
|
||||
* @param token Your token. This is required.
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { delay } from '../utils/index.ts'
|
||||
import * as baseEndpoints from '../consts/urlsAndVersions.ts'
|
||||
import { Client } from './client.ts'
|
||||
import { getBuildInfo } from '../utils/buildInfo.ts'
|
||||
|
@ -45,13 +44,13 @@ export interface RateLimit {
|
|||
}
|
||||
|
||||
export class RESTManager {
|
||||
client: Client
|
||||
client?: Client
|
||||
queues: { [key: string]: QueuedItem[] } = {}
|
||||
rateLimits = new Collection<string, RateLimit>()
|
||||
globalRateLimit: boolean = false
|
||||
processing: boolean = false
|
||||
|
||||
constructor(client: Client) {
|
||||
constructor(client?: Client) {
|
||||
this.client = client
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.handleRateLimits()
|
||||
|
@ -125,7 +124,7 @@ export class RESTManager {
|
|||
}
|
||||
|
||||
if (Object.keys(this.queues).length !== 0) {
|
||||
await delay(1000)
|
||||
// await delay(100)
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.processQueue()
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
|
@ -139,11 +138,12 @@ export class RESTManager {
|
|||
): { [key: string]: any } {
|
||||
|
||||
const headers: RequestHeaders = {
|
||||
'Authorization': `Bot ${this.client.token}`,
|
||||
'User-Agent': `DiscordBot (harmony, https://github.com/harmony-org/harmony)`
|
||||
}
|
||||
|
||||
if (this.client.token === undefined) delete headers.Authorization
|
||||
if (this.client !== undefined) headers.Authorization = `Bot ${this.client.token}`
|
||||
|
||||
if (this.client?.token === undefined) delete headers.Authorization
|
||||
|
||||
if (method === 'get' || method === 'head' || method === 'delete') body = undefined
|
||||
|
||||
|
@ -166,7 +166,7 @@ export class RESTManager {
|
|||
method: method.toUpperCase()
|
||||
}
|
||||
|
||||
if (this.client.bot === false) {
|
||||
if (this.client?.bot === false) {
|
||||
// This is a selfbot. Use requests similar to Discord Client
|
||||
data.headers.authorization = this.client.token as string
|
||||
data.headers['accept-language'] = 'en-US'
|
||||
|
@ -259,7 +259,7 @@ export class RESTManager {
|
|||
|
||||
if (
|
||||
(status >= 200 && status < 400)
|
||||
|| status === HttpResponseCode.NoContent
|
||||
|| status === HttpResponseCode.NoContent
|
||||
|| status === HttpResponseCode.TooManyRequests
|
||||
) return
|
||||
|
||||
|
@ -290,7 +290,8 @@ export class RESTManager {
|
|||
url: string,
|
||||
body?: unknown,
|
||||
maxRetries = 0,
|
||||
bucket?: string | null
|
||||
bucket?: string | null,
|
||||
rawResponse?: boolean,
|
||||
): Promise<any> {
|
||||
return await new Promise((resolve, reject) => {
|
||||
const onComplete = async (): Promise<undefined | any> => {
|
||||
|
@ -318,7 +319,7 @@ export class RESTManager {
|
|||
let urlToUse =
|
||||
method === 'get' && query !== '' ? `${url}?${query}` : url
|
||||
|
||||
if (this.client.canary === true) {
|
||||
if (this.client?.canary === true) {
|
||||
const split = urlToUse.split('//')
|
||||
urlToUse = split[0] + '//canary.' + split[1]
|
||||
}
|
||||
|
@ -328,7 +329,7 @@ export class RESTManager {
|
|||
const response = await fetch(urlToUse, requestData)
|
||||
const bucketFromHeaders = this.processHeaders(url, response.headers)
|
||||
|
||||
if (response.status === 204) return resolve(undefined)
|
||||
if (response.status === 204) return resolve(rawResponse === true ? { response, body: null } : undefined)
|
||||
|
||||
const json: any = await response.json()
|
||||
await this.handleStatusCode(response, json, requestData)
|
||||
|
@ -347,7 +348,7 @@ export class RESTManager {
|
|||
bucket: bucketFromHeaders
|
||||
}
|
||||
}
|
||||
return resolve(json)
|
||||
return resolve(rawResponse === true ? { response, body: json } : json)
|
||||
} catch (error) {
|
||||
return reject(error)
|
||||
}
|
||||
|
@ -375,23 +376,23 @@ export class RESTManager {
|
|||
})
|
||||
}
|
||||
|
||||
async get(url: string, body?: unknown): Promise<any> {
|
||||
return await this.make('get', url, body)
|
||||
async get(url: string, body?: unknown, maxRetries = 0, bucket?: string | null, rawResponse?: boolean): Promise<any> {
|
||||
return await this.make('get', url, body, maxRetries, bucket, rawResponse)
|
||||
}
|
||||
|
||||
async post(url: string, body?: unknown): Promise<any> {
|
||||
return await this.make('post', url, body)
|
||||
async post(url: string, body?: unknown, maxRetries = 0, bucket?: string | null, rawResponse?: boolean): Promise<any> {
|
||||
return await this.make('post', url, body, maxRetries, bucket, rawResponse)
|
||||
}
|
||||
|
||||
async delete(url: string, body?: unknown): Promise<any> {
|
||||
return await this.make('delete', url, body)
|
||||
async delete(url: string, body?: unknown, maxRetries = 0, bucket?: string | null, rawResponse?: boolean): Promise<any> {
|
||||
return await this.make('delete', url, body, maxRetries, bucket, rawResponse)
|
||||
}
|
||||
|
||||
async patch(url: string, body?: unknown): Promise<any> {
|
||||
return await this.make('patch', url, body)
|
||||
async patch(url: string, body?: unknown, maxRetries = 0, bucket?: string | null, rawResponse?: boolean): Promise<any> {
|
||||
return await this.make('patch', url, body, maxRetries, bucket, rawResponse)
|
||||
}
|
||||
|
||||
async put(url: string, body?: unknown): Promise<any> {
|
||||
return await this.make('put', url, body)
|
||||
async put(url: string, body?: unknown, maxRetries = 0, bucket?: string | null, rawResponse?: boolean): Promise<any> {
|
||||
return await this.make('put', url, body, maxRetries, bucket, rawResponse)
|
||||
}
|
||||
}
|
||||
|
|
10
src/models/voice.ts
Normal file
10
src/models/voice.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { Client } from './client.ts'
|
||||
|
||||
export class VoiceClient {
|
||||
client: Client
|
||||
|
||||
constructor(client: Client) {
|
||||
this.client = client
|
||||
|
||||
}
|
||||
}
|
24
src/structures/application.ts
Normal file
24
src/structures/application.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { Client } from "../models/client.ts";
|
||||
import { ApplicationPayload } from "../types/application.ts";
|
||||
import { Base } from "./base.ts";
|
||||
import { User } from "./user.ts";
|
||||
|
||||
export class Application extends Base {
|
||||
id: string
|
||||
name: string
|
||||
icon: string
|
||||
description: string
|
||||
summary: string
|
||||
bot?: User
|
||||
|
||||
constructor(client: Client, data: ApplicationPayload) {
|
||||
super(client, data)
|
||||
|
||||
this.id = data.id
|
||||
this.name = data.name
|
||||
this.icon = data.icon
|
||||
this.description = data.description
|
||||
this.summary = data.summary
|
||||
this.bot = data.bot !== undefined ? new User(client, data.bot) : undefined
|
||||
}
|
||||
}
|
|
@ -1,224 +1,270 @@
|
|||
import { Client } from '../models/client.ts'
|
||||
import { GuildFeatures, GuildPayload } from '../types/guild.ts'
|
||||
import { PresenceUpdatePayload } from '../types/gateway.ts'
|
||||
import { Base } from './base.ts'
|
||||
import { VoiceState } from './voiceState.ts'
|
||||
import { RolesManager } from '../managers/roles.ts'
|
||||
import { GuildChannelsManager } from '../managers/guildChannels.ts'
|
||||
import { MembersManager } from '../managers/members.ts'
|
||||
import { Role } from './role.ts'
|
||||
import { GuildEmojisManager } from '../managers/guildEmojis.ts'
|
||||
import { Member } from "./member.ts"
|
||||
|
||||
export class Guild extends Base {
|
||||
id: string
|
||||
name?: string
|
||||
icon?: string
|
||||
iconHash?: string
|
||||
splash?: string
|
||||
discoverySplash?: string
|
||||
owner?: boolean
|
||||
ownerID?: string
|
||||
permissions?: string
|
||||
region?: string
|
||||
afkChannelID?: string
|
||||
afkTimeout?: number
|
||||
widgetEnabled?: boolean
|
||||
widgetChannelID?: string
|
||||
verificationLevel?: string
|
||||
defaultMessageNotifications?: string
|
||||
explicitContentFilter?: string
|
||||
roles: RolesManager
|
||||
emojis: GuildEmojisManager
|
||||
features?: GuildFeatures[]
|
||||
mfaLevel?: string
|
||||
applicationID?: string
|
||||
systemChannelID?: string
|
||||
systemChannelFlags?: string
|
||||
rulesChannelID?: string
|
||||
joinedAt?: string
|
||||
large?: boolean
|
||||
unavailable: boolean
|
||||
memberCount?: number
|
||||
voiceStates?: VoiceState[]
|
||||
members: MembersManager
|
||||
channels: GuildChannelsManager
|
||||
presences?: PresenceUpdatePayload[]
|
||||
maxPresences?: number
|
||||
maxMembers?: number
|
||||
vanityURLCode?: string
|
||||
description?: string
|
||||
banner?: string
|
||||
premiumTier?: number
|
||||
premiumSubscriptionCount?: number
|
||||
preferredLocale?: string
|
||||
publicUpdatesChannelID?: string
|
||||
maxVideoChannelUsers?: number
|
||||
approximateNumberCount?: number
|
||||
approximatePresenceCount?: number
|
||||
|
||||
constructor (client: Client, data: GuildPayload) {
|
||||
super(client, data)
|
||||
this.id = data.id
|
||||
this.unavailable = data.unavailable
|
||||
this.members = new MembersManager(this.client, this)
|
||||
this.channels = new GuildChannelsManager(
|
||||
this.client,
|
||||
this.client.channels,
|
||||
this
|
||||
)
|
||||
this.roles = new RolesManager(this.client, this)
|
||||
this.emojis = new GuildEmojisManager(this.client, this.client.emojis, this)
|
||||
|
||||
if (!this.unavailable) {
|
||||
this.name = data.name
|
||||
this.icon = data.icon
|
||||
this.iconHash = data.icon_hash
|
||||
this.splash = data.splash
|
||||
this.discoverySplash = data.discovery_splash
|
||||
this.owner = data.owner
|
||||
this.ownerID = data.owner_id
|
||||
this.permissions = data.permissions
|
||||
this.region = data.region
|
||||
this.afkTimeout = data.afk_timeout
|
||||
this.afkChannelID = data.afk_channel_id
|
||||
this.widgetEnabled = data.widget_enabled
|
||||
this.widgetChannelID = data.widget_channel_id
|
||||
this.verificationLevel = data.verification_level
|
||||
this.defaultMessageNotifications = data.default_message_notifications
|
||||
this.explicitContentFilter = data.explicit_content_filter
|
||||
// this.roles = data.roles.map(
|
||||
// v => cache.get('role', v.id) ?? new Role(client, v)
|
||||
// )
|
||||
// data.roles.forEach(role => {
|
||||
// this.roles.set(role.id, new Role(client, role))
|
||||
// })
|
||||
// this.emojis = data.emojis.map(
|
||||
// v => cache.get('emoji', v.id) ?? new Emoji(client, v)
|
||||
// )
|
||||
this.features = data.features
|
||||
this.mfaLevel = data.mfa_level
|
||||
this.systemChannelID = data.system_channel_id
|
||||
this.systemChannelFlags = data.system_channel_flags
|
||||
this.rulesChannelID = data.rules_channel_id
|
||||
this.joinedAt = data.joined_at
|
||||
this.large = data.large
|
||||
this.memberCount = data.member_count
|
||||
// TODO: Cache in Gateway Event code
|
||||
// this.voiceStates = data.voice_states?.map(
|
||||
// v =>
|
||||
// cache.get('voiceState', `${v.guild_id}:${v.user_id}`) ??
|
||||
// new VoiceState(client, v)
|
||||
// )
|
||||
// this.members = data.members?.map(
|
||||
// v =>
|
||||
// cache.get('member', `${this.id}:${v.user.id}`) ??
|
||||
// new Member(client, v)
|
||||
// )
|
||||
// this.channels = data.channels?.map(
|
||||
// v => cache.get('channel', v.id) ?? getChannelByType(this.client, v)
|
||||
// )
|
||||
this.presences = data.presences
|
||||
this.maxPresences = data.max_presences
|
||||
this.maxMembers = data.max_members
|
||||
this.vanityURLCode = data.vanity_url_code
|
||||
this.description = data.description
|
||||
this.banner = data.banner
|
||||
this.premiumTier = data.premium_tier
|
||||
this.premiumSubscriptionCount = data.premium_subscription_count
|
||||
this.preferredLocale = data.preferred_locale
|
||||
this.publicUpdatesChannelID = data.public_updates_channel_id
|
||||
this.maxVideoChannelUsers = data.max_video_channel_users
|
||||
this.approximateNumberCount = data.approximate_number_count
|
||||
this.approximatePresenceCount = data.approximate_presence_count
|
||||
}
|
||||
}
|
||||
|
||||
protected readFromData (data: GuildPayload): void {
|
||||
super.readFromData(data)
|
||||
this.id = data.id ?? this.id
|
||||
this.unavailable = data.unavailable ?? this.unavailable
|
||||
|
||||
if (!this.unavailable) {
|
||||
this.name = data.name ?? this.name
|
||||
this.icon = data.icon ?? this.icon
|
||||
this.iconHash = data.icon_hash ?? this.iconHash
|
||||
this.splash = data.splash ?? this.splash
|
||||
this.discoverySplash = data.discovery_splash ?? this.discoverySplash
|
||||
this.owner = data.owner ?? this.owner
|
||||
this.ownerID = data.owner_id ?? this.ownerID
|
||||
this.permissions = data.permissions ?? this.permissions
|
||||
this.region = data.region ?? this.region
|
||||
this.afkTimeout = data.afk_timeout ?? this.afkTimeout
|
||||
this.afkChannelID = data.afk_channel_id ?? this.afkChannelID
|
||||
this.widgetEnabled = data.widget_enabled ?? this.widgetEnabled
|
||||
this.widgetChannelID = data.widget_channel_id ?? this.widgetChannelID
|
||||
this.verificationLevel = data.verification_level ?? this.verificationLevel
|
||||
this.defaultMessageNotifications =
|
||||
data.default_message_notifications ?? this.defaultMessageNotifications
|
||||
this.explicitContentFilter =
|
||||
data.explicit_content_filter ?? this.explicitContentFilter
|
||||
// this.roles =
|
||||
// data.roles.map(
|
||||
// v => cache.get('role', v.id) ?? new Role(this.client, v)
|
||||
// ) ?? this.roles
|
||||
// this.emojis =
|
||||
// data.emojis.map(
|
||||
// v => cache.get('emoji', v.id) ?? new Emoji(this.client, v)
|
||||
// ) ?? this.emojis
|
||||
this.features = data.features ?? this.features
|
||||
this.mfaLevel = data.mfa_level ?? this.mfaLevel
|
||||
this.systemChannelID = data.system_channel_id ?? this.systemChannelID
|
||||
this.systemChannelFlags =
|
||||
data.system_channel_flags ?? this.systemChannelFlags
|
||||
this.rulesChannelID = data.rules_channel_id ?? this.rulesChannelID
|
||||
this.joinedAt = data.joined_at ?? this.joinedAt
|
||||
this.large = data.large ?? this.large
|
||||
this.memberCount = data.member_count ?? this.memberCount
|
||||
// this.voiceStates =
|
||||
// data.voice_states?.map(
|
||||
// v =>
|
||||
// cache.get('voiceState', `${v.guild_id}:${v.user_id}`) ??
|
||||
// new VoiceState(this.client, v)
|
||||
// ) ?? this.voiceStates
|
||||
// this.members =
|
||||
// data.members?.map(
|
||||
// v =>
|
||||
// cache.get('member', `${this.id}:${v.user.id}`) ??
|
||||
// new Member(this.client, v)
|
||||
// ) ?? this.members
|
||||
// this.channels =
|
||||
// data.channels?.map(
|
||||
// v => cache.get('channel', v.id) ?? getChannelByType(this.client, v, this)
|
||||
// ) ?? this.members
|
||||
this.presences = data.presences ?? this.presences
|
||||
this.maxPresences = data.max_presences ?? this.maxPresences
|
||||
this.maxMembers = data.max_members ?? this.maxMembers
|
||||
this.vanityURLCode = data.vanity_url_code ?? this.vanityURLCode
|
||||
this.description = data.description ?? this.description
|
||||
this.banner = data.banner ?? this.banner
|
||||
this.premiumTier = data.premium_tier ?? this.premiumTier
|
||||
this.premiumSubscriptionCount =
|
||||
data.premium_subscription_count ?? this.premiumSubscriptionCount
|
||||
this.preferredLocale = data.preferred_locale ?? this.preferredLocale
|
||||
this.publicUpdatesChannelID =
|
||||
data.public_updates_channel_id ?? this.publicUpdatesChannelID
|
||||
this.maxVideoChannelUsers =
|
||||
data.max_video_channel_users ?? this.maxVideoChannelUsers
|
||||
this.approximateNumberCount =
|
||||
data.approximate_number_count ?? this.approximateNumberCount
|
||||
this.approximatePresenceCount =
|
||||
data.approximate_presence_count ?? this.approximatePresenceCount
|
||||
}
|
||||
}
|
||||
|
||||
async getEveryoneRole (): Promise<Role> {
|
||||
return (await this.roles.array().then(arr => arr?.sort((b, a) => a.position - b.position)[0]) as any) as Role
|
||||
}
|
||||
|
||||
async me(): Promise<Member> {
|
||||
const get = await this.members.get(this.client.user?.id as string)
|
||||
if (get === undefined) throw new Error('Guild#me is not cached')
|
||||
return get
|
||||
}
|
||||
}
|
||||
import { Client } from '../models/client.ts'
|
||||
import { GuildFeatures, GuildIntegrationPayload, GuildPayload, IntegrationAccountPayload, IntegrationExpireBehavior } from '../types/guild.ts'
|
||||
import { PresenceUpdatePayload } from '../types/gateway.ts'
|
||||
import { Base } from './base.ts'
|
||||
import { VoiceState } from './voiceState.ts'
|
||||
import { RolesManager } from '../managers/roles.ts'
|
||||
import { GuildChannelsManager } from '../managers/guildChannels.ts'
|
||||
import { MembersManager } from '../managers/members.ts'
|
||||
import { Role } from './role.ts'
|
||||
import { GuildEmojisManager } from '../managers/guildEmojis.ts'
|
||||
import { Member } from "./member.ts"
|
||||
import { User } from "./user.ts"
|
||||
import { Application } from "./application.ts"
|
||||
import { GUILD_INTEGRATIONS } from "../types/endpoint.ts"
|
||||
|
||||
export class Guild extends Base {
|
||||
id: string
|
||||
name?: string
|
||||
icon?: string
|
||||
iconHash?: string
|
||||
splash?: string
|
||||
discoverySplash?: string
|
||||
owner?: boolean
|
||||
ownerID?: string
|
||||
permissions?: string
|
||||
region?: string
|
||||
afkChannelID?: string
|
||||
afkTimeout?: number
|
||||
widgetEnabled?: boolean
|
||||
widgetChannelID?: string
|
||||
verificationLevel?: string
|
||||
defaultMessageNotifications?: string
|
||||
explicitContentFilter?: string
|
||||
roles: RolesManager
|
||||
emojis: GuildEmojisManager
|
||||
features?: GuildFeatures[]
|
||||
mfaLevel?: string
|
||||
applicationID?: string
|
||||
systemChannelID?: string
|
||||
systemChannelFlags?: string
|
||||
rulesChannelID?: string
|
||||
joinedAt?: string
|
||||
large?: boolean
|
||||
unavailable: boolean
|
||||
memberCount?: number
|
||||
voiceStates?: VoiceState[]
|
||||
members: MembersManager
|
||||
channels: GuildChannelsManager
|
||||
presences?: PresenceUpdatePayload[]
|
||||
maxPresences?: number
|
||||
maxMembers?: number
|
||||
vanityURLCode?: string
|
||||
description?: string
|
||||
banner?: string
|
||||
premiumTier?: number
|
||||
premiumSubscriptionCount?: number
|
||||
preferredLocale?: string
|
||||
publicUpdatesChannelID?: string
|
||||
maxVideoChannelUsers?: number
|
||||
approximateNumberCount?: number
|
||||
approximatePresenceCount?: number
|
||||
|
||||
constructor (client: Client, data: GuildPayload) {
|
||||
super(client, data)
|
||||
this.id = data.id
|
||||
this.unavailable = data.unavailable
|
||||
this.members = new MembersManager(this.client, this)
|
||||
this.channels = new GuildChannelsManager(
|
||||
this.client,
|
||||
this.client.channels,
|
||||
this
|
||||
)
|
||||
this.roles = new RolesManager(this.client, this)
|
||||
this.emojis = new GuildEmojisManager(this.client, this.client.emojis, this)
|
||||
|
||||
if (!this.unavailable) {
|
||||
this.name = data.name
|
||||
this.icon = data.icon
|
||||
this.iconHash = data.icon_hash
|
||||
this.splash = data.splash
|
||||
this.discoverySplash = data.discovery_splash
|
||||
this.owner = data.owner
|
||||
this.ownerID = data.owner_id
|
||||
this.permissions = data.permissions
|
||||
this.region = data.region
|
||||
this.afkTimeout = data.afk_timeout
|
||||
this.afkChannelID = data.afk_channel_id
|
||||
this.widgetEnabled = data.widget_enabled
|
||||
this.widgetChannelID = data.widget_channel_id
|
||||
this.verificationLevel = data.verification_level
|
||||
this.defaultMessageNotifications = data.default_message_notifications
|
||||
this.explicitContentFilter = data.explicit_content_filter
|
||||
// this.roles = data.roles.map(
|
||||
// v => cache.get('role', v.id) ?? new Role(client, v)
|
||||
// )
|
||||
// data.roles.forEach(role => {
|
||||
// this.roles.set(role.id, new Role(client, role))
|
||||
// })
|
||||
// this.emojis = data.emojis.map(
|
||||
// v => cache.get('emoji', v.id) ?? new Emoji(client, v)
|
||||
// )
|
||||
this.features = data.features
|
||||
this.mfaLevel = data.mfa_level
|
||||
this.systemChannelID = data.system_channel_id
|
||||
this.systemChannelFlags = data.system_channel_flags
|
||||
this.rulesChannelID = data.rules_channel_id
|
||||
this.joinedAt = data.joined_at
|
||||
this.large = data.large
|
||||
this.memberCount = data.member_count
|
||||
// TODO: Cache in Gateway Event code
|
||||
// this.voiceStates = data.voice_states?.map(
|
||||
// v =>
|
||||
// cache.get('voiceState', `${v.guild_id}:${v.user_id}`) ??
|
||||
// new VoiceState(client, v)
|
||||
// )
|
||||
// this.members = data.members?.map(
|
||||
// v =>
|
||||
// cache.get('member', `${this.id}:${v.user.id}`) ??
|
||||
// new Member(client, v)
|
||||
// )
|
||||
// this.channels = data.channels?.map(
|
||||
// v => cache.get('channel', v.id) ?? getChannelByType(this.client, v)
|
||||
// )
|
||||
this.presences = data.presences
|
||||
this.maxPresences = data.max_presences
|
||||
this.maxMembers = data.max_members
|
||||
this.vanityURLCode = data.vanity_url_code
|
||||
this.description = data.description
|
||||
this.banner = data.banner
|
||||
this.premiumTier = data.premium_tier
|
||||
this.premiumSubscriptionCount = data.premium_subscription_count
|
||||
this.preferredLocale = data.preferred_locale
|
||||
this.publicUpdatesChannelID = data.public_updates_channel_id
|
||||
this.maxVideoChannelUsers = data.max_video_channel_users
|
||||
this.approximateNumberCount = data.approximate_number_count
|
||||
this.approximatePresenceCount = data.approximate_presence_count
|
||||
}
|
||||
}
|
||||
|
||||
protected readFromData (data: GuildPayload): void {
|
||||
super.readFromData(data)
|
||||
this.id = data.id ?? this.id
|
||||
this.unavailable = data.unavailable ?? this.unavailable
|
||||
|
||||
if (!this.unavailable) {
|
||||
this.name = data.name ?? this.name
|
||||
this.icon = data.icon ?? this.icon
|
||||
this.iconHash = data.icon_hash ?? this.iconHash
|
||||
this.splash = data.splash ?? this.splash
|
||||
this.discoverySplash = data.discovery_splash ?? this.discoverySplash
|
||||
this.owner = data.owner ?? this.owner
|
||||
this.ownerID = data.owner_id ?? this.ownerID
|
||||
this.permissions = data.permissions ?? this.permissions
|
||||
this.region = data.region ?? this.region
|
||||
this.afkTimeout = data.afk_timeout ?? this.afkTimeout
|
||||
this.afkChannelID = data.afk_channel_id ?? this.afkChannelID
|
||||
this.widgetEnabled = data.widget_enabled ?? this.widgetEnabled
|
||||
this.widgetChannelID = data.widget_channel_id ?? this.widgetChannelID
|
||||
this.verificationLevel = data.verification_level ?? this.verificationLevel
|
||||
this.defaultMessageNotifications =
|
||||
data.default_message_notifications ?? this.defaultMessageNotifications
|
||||
this.explicitContentFilter =
|
||||
data.explicit_content_filter ?? this.explicitContentFilter
|
||||
// this.roles =
|
||||
// data.roles.map(
|
||||
// v => cache.get('role', v.id) ?? new Role(this.client, v)
|
||||
// ) ?? this.roles
|
||||
// this.emojis =
|
||||
// data.emojis.map(
|
||||
// v => cache.get('emoji', v.id) ?? new Emoji(this.client, v)
|
||||
// ) ?? this.emojis
|
||||
this.features = data.features ?? this.features
|
||||
this.mfaLevel = data.mfa_level ?? this.mfaLevel
|
||||
this.systemChannelID = data.system_channel_id ?? this.systemChannelID
|
||||
this.systemChannelFlags =
|
||||
data.system_channel_flags ?? this.systemChannelFlags
|
||||
this.rulesChannelID = data.rules_channel_id ?? this.rulesChannelID
|
||||
this.joinedAt = data.joined_at ?? this.joinedAt
|
||||
this.large = data.large ?? this.large
|
||||
this.memberCount = data.member_count ?? this.memberCount
|
||||
// this.voiceStates =
|
||||
// data.voice_states?.map(
|
||||
// v =>
|
||||
// cache.get('voiceState', `${v.guild_id}:${v.user_id}`) ??
|
||||
// new VoiceState(this.client, v)
|
||||
// ) ?? this.voiceStates
|
||||
// this.members =
|
||||
// data.members?.map(
|
||||
// v =>
|
||||
// cache.get('member', `${this.id}:${v.user.id}`) ??
|
||||
// new Member(this.client, v)
|
||||
// ) ?? this.members
|
||||
// this.channels =
|
||||
// data.channels?.map(
|
||||
// v => cache.get('channel', v.id) ?? getChannelByType(this.client, v, this)
|
||||
// ) ?? this.members
|
||||
this.presences = data.presences ?? this.presences
|
||||
this.maxPresences = data.max_presences ?? this.maxPresences
|
||||
this.maxMembers = data.max_members ?? this.maxMembers
|
||||
this.vanityURLCode = data.vanity_url_code ?? this.vanityURLCode
|
||||
this.description = data.description ?? this.description
|
||||
this.banner = data.banner ?? this.banner
|
||||
this.premiumTier = data.premium_tier ?? this.premiumTier
|
||||
this.premiumSubscriptionCount =
|
||||
data.premium_subscription_count ?? this.premiumSubscriptionCount
|
||||
this.preferredLocale = data.preferred_locale ?? this.preferredLocale
|
||||
this.publicUpdatesChannelID =
|
||||
data.public_updates_channel_id ?? this.publicUpdatesChannelID
|
||||
this.maxVideoChannelUsers =
|
||||
data.max_video_channel_users ?? this.maxVideoChannelUsers
|
||||
this.approximateNumberCount =
|
||||
data.approximate_number_count ?? this.approximateNumberCount
|
||||
this.approximatePresenceCount =
|
||||
data.approximate_presence_count ?? this.approximatePresenceCount
|
||||
}
|
||||
}
|
||||
|
||||
async getEveryoneRole (): Promise<Role> {
|
||||
return (await this.roles.get(this.id) as unknown) as Role
|
||||
}
|
||||
|
||||
async me(): Promise<Member> {
|
||||
const get = await this.members.get(this.client.user?.id as string)
|
||||
if (get === undefined) throw new Error('Guild#me is not cached')
|
||||
return get
|
||||
}
|
||||
|
||||
async fetchIntegrations(): Promise<GuildIntegration[]> {
|
||||
const raw = await this.client.rest.get(GUILD_INTEGRATIONS(this.id)) as GuildIntegrationPayload[]
|
||||
return raw.map(e => new GuildIntegration(this.client, e))
|
||||
}
|
||||
}
|
||||
|
||||
export class GuildIntegration extends Base {
|
||||
id: string
|
||||
name: string
|
||||
type: string
|
||||
enabled: boolean
|
||||
syncing?: boolean
|
||||
roleID?: string
|
||||
enableEmoticons?: boolean
|
||||
expireBehaviour?: IntegrationExpireBehavior
|
||||
expireGracePeriod?: number
|
||||
user?: User
|
||||
account: IntegrationAccountPayload
|
||||
syncedAt?: string // Actually a ISO Timestamp, but we parse in constructor'
|
||||
subscriberCount?: number
|
||||
revoked?: boolean
|
||||
application?: Application
|
||||
|
||||
constructor(client: Client, data: GuildIntegrationPayload) {
|
||||
super(client, data)
|
||||
|
||||
this.id = data.id
|
||||
this.name= data.name
|
||||
this.type = data.type
|
||||
this.enabled = data.enabled
|
||||
this.syncing = data.syncing
|
||||
this.roleID = data.role_id
|
||||
this.enableEmoticons = data.enable_emoticons
|
||||
this.expireBehaviour = data.expire_behaviour
|
||||
this.expireGracePeriod = data.expire_grace_period
|
||||
this.user = data.user !== undefined ? new User(client, data.user) : undefined
|
||||
this.account = data.account
|
||||
this.syncedAt = data.synced_at
|
||||
this.subscriberCount = data.subscriber_count
|
||||
this.revoked = data.revoked
|
||||
this.application = data.application !== undefined ? new Application(client, data.application) : undefined
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ import { Embed } from './embed.ts'
|
|||
import { Guild } from "./guild.ts"
|
||||
import { Message } from './message.ts'
|
||||
|
||||
type AllMessageOptions = MessageOption | Embed
|
||||
export type AllMessageOptions = MessageOption | Embed
|
||||
|
||||
export class TextChannel extends Channel {
|
||||
lastMessageID?: string
|
||||
|
@ -27,6 +27,12 @@ export class TextChannel extends Channel {
|
|||
this.lastPinTimestamp = data.last_pin_timestamp ?? this.lastPinTimestamp
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param text Text content of the Message to send.
|
||||
* @param option Various other Message options.
|
||||
* @param reply Reference to a Message object to reply-to.
|
||||
*/
|
||||
async send(text?: string | AllMessageOptions, option?: AllMessageOptions, reply?: Message): Promise<Message> {
|
||||
if (typeof text === "object") {
|
||||
option = text
|
||||
|
@ -44,7 +50,7 @@ export class TextChannel extends Channel {
|
|||
embed: option?.embed,
|
||||
file: option?.file,
|
||||
tts: option?.tts,
|
||||
allowed_mentions: option?.allowedMention
|
||||
allowed_mentions: option?.allowedMentions
|
||||
}
|
||||
|
||||
if (reply !== undefined) {
|
||||
|
@ -63,6 +69,12 @@ export class TextChannel extends Channel {
|
|||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param message Message to edit. ID or the Message object itself.
|
||||
* @param text New text contents of the Message.
|
||||
* @param option Other options to edit the message.
|
||||
*/
|
||||
async editMessage(
|
||||
message: Message | string,
|
||||
text?: string,
|
||||
|
@ -84,9 +96,10 @@ export class TextChannel extends Channel {
|
|||
{
|
||||
content: text,
|
||||
embed: option?.embed !== undefined ? option.embed.toJSON() : undefined,
|
||||
file: option?.file,
|
||||
// Cannot upload new files with Message
|
||||
// file: option?.file,
|
||||
tts: option?.tts,
|
||||
allowed_mentions: option?.allowedMention
|
||||
allowed_mentions: option?.allowedMentions
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -1,69 +1,76 @@
|
|||
import { Client } from '../models/client.ts'
|
||||
import { UserPayload } from '../types/user.ts'
|
||||
import { UserFlagsManager } from "../utils/userFlags.ts"
|
||||
import { Base } from './base.ts'
|
||||
|
||||
export class User extends Base {
|
||||
id: string
|
||||
username: string
|
||||
discriminator: string
|
||||
avatar?: string
|
||||
bot?: boolean
|
||||
system?: boolean
|
||||
mfaEnabled?: boolean
|
||||
locale?: string
|
||||
verified?: boolean
|
||||
email?: string
|
||||
flags?: UserFlagsManager
|
||||
premiumType?: 0 | 1 | 2
|
||||
publicFlags?: UserFlagsManager
|
||||
|
||||
get tag (): string {
|
||||
return `${this.username}#${this.discriminator}`
|
||||
}
|
||||
|
||||
get nickMention (): string {
|
||||
return `<@!${this.id}>`
|
||||
}
|
||||
|
||||
get mention (): string {
|
||||
return `<@${this.id}>`
|
||||
}
|
||||
|
||||
constructor (client: Client, data: UserPayload) {
|
||||
super(client, data)
|
||||
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.mfaEnabled = data.mfa_enabled
|
||||
this.locale = data.locale
|
||||
this.verified = data.verified
|
||||
this.email = data.email
|
||||
this.flags = new UserFlagsManager(data.flags)
|
||||
this.premiumType = data.premium_type
|
||||
this.publicFlags = new UserFlagsManager(data.public_flags)
|
||||
}
|
||||
|
||||
protected readFromData (data: UserPayload): void {
|
||||
super.readFromData(data)
|
||||
this.username = data.username ?? this.username
|
||||
this.discriminator = data.discriminator ?? this.discriminator
|
||||
this.avatar = data.avatar ?? this.avatar
|
||||
this.bot = data.bot ?? this.bot
|
||||
this.system = data.system ?? this.system
|
||||
this.mfaEnabled = data.mfa_enabled ?? this.mfaEnabled
|
||||
this.locale = data.locale ?? this.locale
|
||||
this.verified = data.verified ?? this.verified
|
||||
this.email = data.email ?? this.email
|
||||
this.flags = new UserFlagsManager(data.flags) ?? this.flags
|
||||
this.premiumType = data.premium_type ?? this.premiumType
|
||||
this.publicFlags = new UserFlagsManager(data.public_flags) ?? this.publicFlags
|
||||
}
|
||||
|
||||
toString (): string {
|
||||
return this.mention
|
||||
}
|
||||
}
|
||||
import { Client } from '../models/client.ts'
|
||||
import { UserPayload } from '../types/user.ts'
|
||||
import { UserFlagsManager } from "../utils/userFlags.ts"
|
||||
import { Base } from './base.ts'
|
||||
|
||||
export class User extends Base {
|
||||
id: string
|
||||
username: string
|
||||
discriminator: string
|
||||
avatar?: string
|
||||
bot?: boolean
|
||||
system?: boolean
|
||||
mfaEnabled?: boolean
|
||||
locale?: string
|
||||
verified?: boolean
|
||||
email?: string
|
||||
flags?: UserFlagsManager
|
||||
/**
|
||||
* Nitro type of the User.
|
||||
*
|
||||
* 0 = No Nitro
|
||||
* 1 = Classic Nitro
|
||||
* 2 = Regular Nitro
|
||||
*/
|
||||
premiumType?: 0 | 1 | 2
|
||||
publicFlags?: UserFlagsManager
|
||||
|
||||
get tag (): string {
|
||||
return `${this.username}#${this.discriminator}`
|
||||
}
|
||||
|
||||
get nickMention (): string {
|
||||
return `<@!${this.id}>`
|
||||
}
|
||||
|
||||
get mention (): string {
|
||||
return `<@${this.id}>`
|
||||
}
|
||||
|
||||
constructor (client: Client, data: UserPayload) {
|
||||
super(client, data)
|
||||
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.mfaEnabled = data.mfa_enabled
|
||||
this.locale = data.locale
|
||||
this.verified = data.verified
|
||||
this.email = data.email
|
||||
this.flags = new UserFlagsManager(data.flags)
|
||||
this.premiumType = data.premium_type
|
||||
this.publicFlags = new UserFlagsManager(data.public_flags)
|
||||
}
|
||||
|
||||
protected readFromData (data: UserPayload): void {
|
||||
super.readFromData(data)
|
||||
this.username = data.username ?? this.username
|
||||
this.discriminator = data.discriminator ?? this.discriminator
|
||||
this.avatar = data.avatar ?? this.avatar
|
||||
this.bot = data.bot ?? this.bot
|
||||
this.system = data.system ?? this.system
|
||||
this.mfaEnabled = data.mfa_enabled ?? this.mfaEnabled
|
||||
this.locale = data.locale ?? this.locale
|
||||
this.verified = data.verified ?? this.verified
|
||||
this.email = data.email ?? this.email
|
||||
this.flags = new UserFlagsManager(data.flags) ?? this.flags
|
||||
this.premiumType = data.premium_type ?? this.premiumType
|
||||
this.publicFlags = new UserFlagsManager(data.public_flags) ?? this.publicFlags
|
||||
}
|
||||
|
||||
toString (): string {
|
||||
return this.mention
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,158 @@
|
|||
import { Client } from '../models/client.ts'
|
||||
import { UserPayload } from '../types/user.ts'
|
||||
import { WebhookPayload } from '../types/webhook.ts'
|
||||
import { Base } from './base.ts'
|
||||
|
||||
export class Webhook extends Base {
|
||||
id: string
|
||||
type: 1 | 2
|
||||
guildID?: string
|
||||
channelID: string
|
||||
user?: UserPayload
|
||||
name?: string
|
||||
avatar?: string
|
||||
token?: string
|
||||
applicationID?: string
|
||||
|
||||
constructor (client: Client, data: WebhookPayload) {
|
||||
super(client)
|
||||
this.id = data.id
|
||||
this.type = data.type
|
||||
this.channelID = data.channel_id
|
||||
}
|
||||
}
|
||||
import { DISCORD_API_URL, DISCORD_API_VERSION } from "../consts/urlsAndVersions.ts"
|
||||
import { Client } from '../models/client.ts'
|
||||
import { RESTManager } from "../models/rest.ts"
|
||||
import { MessageOption } from "../types/channel.ts"
|
||||
import { UserPayload } from '../types/user.ts'
|
||||
import { WebhookPayload } from '../types/webhook.ts'
|
||||
import { Embed } from "./embed.ts"
|
||||
import { Message } from "./message.ts"
|
||||
import { TextChannel } from "./textChannel.ts"
|
||||
import { User } from "./user.ts"
|
||||
import { fetchAuto } from 'https://raw.githubusercontent.com/DjDeveloperr/fetch-base64/main/mod.ts'
|
||||
|
||||
export interface WebhookMessageOptions extends MessageOption {
|
||||
embeds?: Embed[]
|
||||
name?: string
|
||||
avatar?: string
|
||||
}
|
||||
|
||||
export type AllWebhookMessageOptions = string | WebhookMessageOptions
|
||||
|
||||
export interface WebhookEditOptions {
|
||||
/** New name to set for Webhook. */
|
||||
name?: string
|
||||
/** New avatar to set for Webhook. URL of image or base64 encoded data. */
|
||||
avatar?: string
|
||||
/** New channel for Webhook. Requires authentication. */
|
||||
channelID?: string
|
||||
}
|
||||
|
||||
/** Webhook follows different way of instantiation */
|
||||
export class Webhook {
|
||||
client?: Client
|
||||
id: string
|
||||
type: 1 | 2
|
||||
guildID?: string
|
||||
channelID: string
|
||||
user?: User
|
||||
userRaw?: UserPayload
|
||||
name?: string
|
||||
avatar?: string
|
||||
token?: string
|
||||
applicationID?: string
|
||||
rest: RESTManager
|
||||
|
||||
get url(): string {
|
||||
return `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/webhooks/${this.id}/${this.token}`
|
||||
}
|
||||
|
||||
constructor(data: WebhookPayload, client?: Client, rest?: RESTManager) {
|
||||
this.id = data.id
|
||||
this.type = data.type
|
||||
this.channelID = data.channel_id
|
||||
this.guildID = data.guild_id
|
||||
this.user = data.user === undefined || client === undefined ? undefined : new User(client, data.user)
|
||||
if (data.user !== undefined && client === undefined) this.userRaw = data.user
|
||||
this.name = data.name
|
||||
this.avatar = data.avatar
|
||||
this.token = data.token
|
||||
this.applicationID = data.application_id
|
||||
|
||||
if (rest !== undefined) this.rest = rest
|
||||
else if (client !== undefined) this.rest = client.rest
|
||||
else this.rest = new RESTManager()
|
||||
}
|
||||
|
||||
private fromPayload(data: WebhookPayload): Webhook {
|
||||
this.id = data.id
|
||||
this.type = data.type
|
||||
this.channelID = data.channel_id
|
||||
this.guildID = data.guild_id
|
||||
this.user = data.user === undefined || this.client === undefined ? undefined : new User(this.client, data.user)
|
||||
if (data.user !== undefined && this.client === undefined) this.userRaw = data.user
|
||||
this.name = data.name
|
||||
this.avatar = data.avatar
|
||||
this.token = data.token
|
||||
this.applicationID = data.application_id
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/** Send a Message through Webhook. */
|
||||
async send(text?: string | AllWebhookMessageOptions, option?: AllWebhookMessageOptions): Promise<Message> {
|
||||
if (typeof text === "object") {
|
||||
option = text
|
||||
text = undefined
|
||||
}
|
||||
|
||||
if (text === undefined && option === undefined) {
|
||||
throw new Error('Either text or option is necessary.')
|
||||
}
|
||||
|
||||
if (option instanceof Embed) option = {
|
||||
embeds: [ option ],
|
||||
}
|
||||
|
||||
const payload: any = {
|
||||
content: text,
|
||||
embeds: (option as WebhookMessageOptions)?.embed !== undefined ? [ (option as WebhookMessageOptions).embed ] : ((option as WebhookMessageOptions)?.embeds !== undefined ? (option as WebhookMessageOptions).embeds : undefined),
|
||||
file: (option as WebhookMessageOptions)?.file,
|
||||
tts: (option as WebhookMessageOptions)?.tts,
|
||||
allowed_mentions: (option as WebhookMessageOptions)?.allowedMentions
|
||||
}
|
||||
|
||||
if ((option as WebhookMessageOptions).name !== undefined) {
|
||||
payload.username = (option as WebhookMessageOptions)?.name
|
||||
}
|
||||
|
||||
if ((option as WebhookMessageOptions).avatar !== undefined) {
|
||||
payload.avatar = (option as WebhookMessageOptions)?.avatar
|
||||
}
|
||||
|
||||
if (payload.embeds !== undefined && payload.embeds instanceof Array && payload.embeds.length > 10) throw new Error(`Cannot send more than 10 embeds through Webhook`)
|
||||
|
||||
const resp = await this.rest.post(this.url + '?wait=true', payload)
|
||||
|
||||
const res = new Message(this.client as Client, resp, (this as unknown) as TextChannel, (this as unknown) as User)
|
||||
await res.mentions.fromPayload(resp)
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Webhook object from URL
|
||||
* @param url URL of the Webhook
|
||||
* @param client Client (bot) object, if any.
|
||||
*/
|
||||
static async fromURL(url: string | URL, client?: Client): Promise<Webhook> {
|
||||
const rest = client !== undefined ? client.rest : new RESTManager()
|
||||
|
||||
const raw = await rest.get(typeof url === 'string' ? url : url.toString())
|
||||
if (typeof raw !== 'object') throw new Error(`Failed to load Webhook from URL: ${url}`)
|
||||
|
||||
const webhook = new Webhook(raw, client, rest)
|
||||
return webhook
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit the Webhook name, avatar, or channel (requires authentication).
|
||||
* @param options Options to edit the Webhook.
|
||||
*/
|
||||
async edit(options: WebhookEditOptions): Promise<Webhook> {
|
||||
if (options.channelID !== undefined && this.rest.client === undefined) throw new Error('Authentication is required for editing Webhook Channel')
|
||||
if (options.avatar !== undefined && (options.avatar.startsWith('http:') || options.avatar.startsWith('https:'))) {
|
||||
options.avatar = await fetchAuto(options.avatar)
|
||||
}
|
||||
|
||||
const data = await this.rest.patch(this.url, options)
|
||||
this.fromPayload(data)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/** Delete the Webhook. */
|
||||
async delete(): Promise<boolean> {
|
||||
const resp = await this.rest.delete(this.url, undefined, 0, undefined, true)
|
||||
if (resp.response.status !== 204) return false
|
||||
else return true
|
||||
}
|
||||
}
|
||||
|
|
212
src/test/cmd.ts
212
src/test/cmd.ts
|
@ -1,103 +1,109 @@
|
|||
import { Command, CommandClient, Intents } from '../../mod.ts'
|
||||
import { GuildChannel } from "../managers/guildChannels.ts"
|
||||
import { CommandContext } from "../models/command.ts"
|
||||
import { Extension } from "../models/extensions.ts"
|
||||
import { Member } from "../structures/member.ts"
|
||||
import { Message } from "../structures/message.ts"
|
||||
import { Role } from "../structures/role.ts"
|
||||
import { MessageDeletePayload } from "../types/gateway.ts"
|
||||
import { TOKEN } from './config.ts'
|
||||
|
||||
const client = new CommandClient({
|
||||
prefix: ["pls", "!"],
|
||||
spacesAfterPrefix: true,
|
||||
mentionPrefix: true
|
||||
})
|
||||
|
||||
client.on('debug', console.log)
|
||||
|
||||
client.on('ready', () => {
|
||||
console.log(`[Login] Logged in as ${client.user?.tag}!`)
|
||||
})
|
||||
|
||||
client.on('messageDelete', (msg: Message) => {
|
||||
console.log(`Message Deleted: ${msg.id}, ${msg.author.tag}, ${msg.content}`)
|
||||
})
|
||||
|
||||
client.on('messageDeleteUncached', (d: MessageDeletePayload) => {
|
||||
console.log(`Uncached Message Deleted: ${d.id} in ${d.channel_id}`)
|
||||
})
|
||||
|
||||
client.on('messageUpdate', (before: Message, after: Message) => {
|
||||
console.log('Message Update')
|
||||
console.log(`Before: ${before.author.tag}: ${before.content}`)
|
||||
console.log(`After: ${after.author.tag}: ${after.content}`)
|
||||
})
|
||||
|
||||
client.on('messageUpdateUncached', (msg: Message) => {
|
||||
console.log(`Message: ${msg.author.tag}: ${msg.content}`)
|
||||
})
|
||||
|
||||
client.on('guildMemberAdd', (member: Member) => {
|
||||
console.log(`Member Join: ${member.user.tag}`)
|
||||
})
|
||||
|
||||
client.on('guildMemberRemove', (member: Member) => {
|
||||
console.log(`Member Leave: ${member.user.tag}`)
|
||||
})
|
||||
|
||||
client.on('guildRoleCreate', (role: Role) => {
|
||||
console.log(`Role Create: ${role.name}`)
|
||||
})
|
||||
|
||||
client.on('guildRoleDelete', (role: Role) => {
|
||||
console.log(`Role Delete: ${role.name}`)
|
||||
})
|
||||
|
||||
client.on('guildRoleUpdate', (role: Role, after: Role) => {
|
||||
console.log(`Role Update: ${role.name}, ${after.name}`)
|
||||
})
|
||||
|
||||
// client.on('messageCreate', msg => console.log(`${msg.author.tag}: ${msg.content}`))
|
||||
|
||||
client.on("commandError", console.error)
|
||||
|
||||
class ChannelLog extends Extension {
|
||||
|
||||
onChannelCreate(ext: Extension, channel: GuildChannel): void {
|
||||
console.log(`Channel Created: ${channel.name}`)
|
||||
}
|
||||
|
||||
load(): void {
|
||||
this.listen('channelCreate', this.onChannelCreate)
|
||||
|
||||
class Pong extends Command {
|
||||
name = 'Pong'
|
||||
|
||||
execute(ctx: CommandContext): any {
|
||||
ctx.message.reply('Ping!')
|
||||
}
|
||||
}
|
||||
|
||||
this.commands.add(Pong)
|
||||
}
|
||||
}
|
||||
|
||||
client.extensions.load(ChannelLog)
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
;(async() => {
|
||||
const files = Deno.readDirSync('./src/test/cmds')
|
||||
|
||||
for (const file of files) {
|
||||
const module = await import(`./cmds/${file.name}`)
|
||||
// eslint-disable-next-line new-cap
|
||||
const cmd = new module.default()
|
||||
client.commands.add(cmd)
|
||||
console.log(`Loaded command ${cmd.name}!`)
|
||||
}
|
||||
|
||||
console.log(`Loaded ${client.commands.count} commands!`)
|
||||
|
||||
client.connect(TOKEN, Intents.All)
|
||||
})()
|
||||
import { Command, CommandClient, Intents, GuildChannel, CommandContext, Extension } from '../../mod.ts'
|
||||
import { TOKEN } from './config.ts'
|
||||
|
||||
const client = new CommandClient({
|
||||
prefix: ["pls", "!"],
|
||||
spacesAfterPrefix: true,
|
||||
mentionPrefix: true
|
||||
})
|
||||
|
||||
client.on('debug', console.log)
|
||||
|
||||
client.on('ready', () => {
|
||||
console.log(`[Login] Logged in as ${client.user?.tag}!`)
|
||||
})
|
||||
|
||||
client.on('messageDelete', (msg) => {
|
||||
console.log(`Message Deleted: ${msg.id}, ${msg.author.tag}, ${msg.content}`)
|
||||
})
|
||||
|
||||
client.on('messageUpdate', (before, after) => {
|
||||
console.log('Message Update')
|
||||
console.log(`Before: ${before.author.tag}: ${before.content}`)
|
||||
console.log(`After: ${after.author.tag}: ${after.content}`)
|
||||
})
|
||||
|
||||
client.on('messageUpdateUncached', (msg) => {
|
||||
console.log(`Message: ${msg.author.tag}: ${msg.content}`)
|
||||
})
|
||||
|
||||
client.on('guildMemberAdd', (member) => {
|
||||
console.log(`Member Join: ${member.user.tag}`)
|
||||
})
|
||||
|
||||
client.on('guildMemberRemove', (member) => {
|
||||
console.log(`Member Leave: ${member.user.tag}`)
|
||||
})
|
||||
|
||||
client.on('guildRoleCreate', (role) => {
|
||||
console.log(`Role Create: ${role.name}`)
|
||||
})
|
||||
|
||||
client.on('guildRoleDelete', (role) => {
|
||||
console.log(`Role Delete: ${role.name}`)
|
||||
})
|
||||
|
||||
client.on('guildRoleUpdate', (role, after) => {
|
||||
console.log(`Role Update: ${role.name}, ${after.name}`)
|
||||
})
|
||||
|
||||
client.on('guildIntegrationsUpdate', (guild) => {
|
||||
console.log(`Guild Integrations Update: ${guild.name}`)
|
||||
})
|
||||
|
||||
client.on('webhooksUpdate', (guild, channel) => {
|
||||
console.log(`Webhooks Updated in #${channel.name} from ${guild.name}`)
|
||||
})
|
||||
|
||||
client.on("commandError", console.error)
|
||||
|
||||
class ChannelLog extends Extension {
|
||||
|
||||
onChannelCreate(ext: Extension, channel: GuildChannel): void {
|
||||
console.log(`Channel Created: ${channel.name}`)
|
||||
}
|
||||
|
||||
load(): void {
|
||||
this.listen('channelCreate', this.onChannelCreate)
|
||||
|
||||
class Pong extends Command {
|
||||
name = 'Pong'
|
||||
|
||||
execute(ctx: CommandContext): any {
|
||||
ctx.message.reply('Ping!')
|
||||
}
|
||||
}
|
||||
|
||||
this.commands.add(Pong)
|
||||
}
|
||||
}
|
||||
|
||||
client.extensions.load(ChannelLog)
|
||||
|
||||
client.on('messageDeleteBulk', (channel, messages, uncached) => {
|
||||
console.log(`=== Message Delete Bulk ===\nMessages: ${messages.map(m => m.id).join(', ')}\nUncached: ${[...uncached.values()].join(', ')}`)
|
||||
})
|
||||
|
||||
client.on('channelUpdate', (before, after) => {
|
||||
console.log(`Channel Update: ${(before as GuildChannel).name}, ${(after as GuildChannel).name}`)
|
||||
})
|
||||
|
||||
client.on('typingStart', (user, channel, at, guildData) => {
|
||||
console.log(`${user.tag} started typing in ${channel.id} at ${at}${guildData !== undefined ? `\nGuild: ${guildData.guild.name}` : ''}`)
|
||||
})
|
||||
|
||||
// client.on('raw', (evt: string) => console.log(`EVENT: ${evt}`))
|
||||
|
||||
const files = Deno.readDirSync('./src/test/cmds')
|
||||
|
||||
for (const file of files) {
|
||||
const module = await import(`./cmds/${file.name}`)
|
||||
// eslint-disable-next-line new-cap
|
||||
const cmd = new module.default()
|
||||
client.commands.add(cmd)
|
||||
console.log(`Loaded command ${cmd.name}!`)
|
||||
}
|
||||
|
||||
console.log(`Loaded ${client.commands.count} commands!`)
|
||||
|
||||
client.connect(TOKEN, Intents.create(['GUILD_MEMBERS', 'GUILD_PRESENCES']))
|
9
src/test/hook.ts
Normal file
9
src/test/hook.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { Webhook } from '../../mod.ts'
|
||||
import { WEBHOOK } from "./config.ts"
|
||||
|
||||
const webhook = await Webhook.fromURL(WEBHOOK)
|
||||
console.log('Fetched webhook!')
|
||||
|
||||
webhook.send('Hello World', {
|
||||
name: 'OwO'
|
||||
}).then(() => 'Sent message!')
|
10
src/types/application.ts
Normal file
10
src/types/application.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { UserPayload } from "./user.ts";
|
||||
|
||||
export interface ApplicationPayload {
|
||||
id: string
|
||||
name: string
|
||||
icon: string
|
||||
description: string
|
||||
summary: string
|
||||
bot?: UserPayload
|
||||
}
|
|
@ -102,7 +102,7 @@ export interface MessageOption {
|
|||
tts?: boolean
|
||||
embed?: Embed
|
||||
file?: Attachment
|
||||
allowedMention?: {
|
||||
allowedMentions?: {
|
||||
parse: 'everyone' | 'users' | 'roles'
|
||||
roles: string[]
|
||||
users: string[]
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway
|
||||
// https://discord.com/developers/docs/topics/gateway#commands-and-events-gateway-events
|
||||
import { Guild } from "../structures/guild.ts"
|
||||
import { Member } from "../structures/member.ts"
|
||||
import { EmojiPayload } from './emoji.ts'
|
||||
import { MemberPayload } from './guild.ts'
|
||||
import {
|
||||
|
@ -320,3 +322,16 @@ export interface WebhooksUpdatePayload {
|
|||
guild_id: string
|
||||
channel_id: string
|
||||
}
|
||||
|
||||
export interface TypingStartPayload {
|
||||
channel_id: string
|
||||
user_id: string
|
||||
guild_id?: string
|
||||
timestamp: number
|
||||
member?: MemberPayload
|
||||
}
|
||||
|
||||
export interface TypingStartGuildData {
|
||||
guild: Guild
|
||||
member: Member
|
||||
}
|
|
@ -1,114 +1,143 @@
|
|||
import { ChannelPayload } from './channel.ts'
|
||||
import { EmojiPayload } from './emoji.ts'
|
||||
import { PresenceUpdatePayload } from './gateway.ts'
|
||||
import { RolePayload } from './role.ts'
|
||||
import { UserPayload } from './user.ts'
|
||||
import { VoiceStatePayload } from './voice.ts'
|
||||
|
||||
export interface GuildPayload {
|
||||
id: string
|
||||
name: string
|
||||
icon?: string
|
||||
icon_hash?: string
|
||||
splash?: string
|
||||
discovery_splash?: string
|
||||
owner?: boolean
|
||||
owner_id: string
|
||||
permissions?: string
|
||||
region: string
|
||||
afk_channel_id?: string
|
||||
afk_timeout: number
|
||||
widget_enabled?: boolean
|
||||
widget_channel_id?: string
|
||||
verification_level: string
|
||||
default_message_notifications: string
|
||||
explicit_content_filter: string
|
||||
roles: RolePayload[]
|
||||
emojis: EmojiPayload[]
|
||||
features: GuildFeatures[]
|
||||
mfa_level: string
|
||||
application_id?: string
|
||||
system_channel_id?: string
|
||||
system_channel_flags: string
|
||||
rules_channel_id?: string
|
||||
joined_at?: string
|
||||
large?: boolean
|
||||
unavailable: boolean
|
||||
member_count?: number
|
||||
voice_states?: VoiceStatePayload[]
|
||||
members?: MemberPayload[]
|
||||
channels?: ChannelPayload[]
|
||||
presences?: PresenceUpdatePayload[]
|
||||
max_presences?: number
|
||||
max_members?: number
|
||||
vanity_url_code?: string
|
||||
description?: string
|
||||
banner?: string
|
||||
premium_tier: number
|
||||
premium_subscription_count?: number
|
||||
preferred_locale: string
|
||||
public_updates_channel_id?: string
|
||||
max_video_channel_users?: number
|
||||
approximate_number_count?: number
|
||||
approximate_presence_count?: number
|
||||
}
|
||||
|
||||
export interface MemberPayload {
|
||||
user: UserPayload
|
||||
nick?: string
|
||||
roles: string[]
|
||||
joined_at: string
|
||||
premium_since?: string
|
||||
deaf: boolean
|
||||
mute: boolean
|
||||
}
|
||||
|
||||
export enum MessageNotification {
|
||||
ALL_MESSAGES = 0,
|
||||
ONLY_MENTIONS = 1
|
||||
}
|
||||
|
||||
export enum ContentFilter {
|
||||
DISABLED = 0,
|
||||
MEMBERS_WITHOUT_ROLES = 1,
|
||||
ALL_MEMBERS = 3
|
||||
}
|
||||
|
||||
export enum MFA {
|
||||
NONE = 0,
|
||||
ELEVATED = 1
|
||||
}
|
||||
|
||||
export enum Verification {
|
||||
NONE = 0,
|
||||
LOW = 1,
|
||||
MEDIUM = 2,
|
||||
HIGH = 3,
|
||||
VERY_HIGH = 4
|
||||
}
|
||||
|
||||
export enum PremiumTier {
|
||||
NONE = 0,
|
||||
TIER_1 = 1,
|
||||
TIER_2 = 2,
|
||||
TIER_3 = 3
|
||||
}
|
||||
|
||||
export enum SystemChannelFlags {
|
||||
SUPPRESS_JOIN_NOTIFICATIONS = 1 << 0,
|
||||
SUPPRESS_PREMIUM_SUBSCRIPTIONS = 1 << 1
|
||||
}
|
||||
|
||||
export type GuildFeatures =
|
||||
| 'INVITE_SPLASH'
|
||||
| 'VIP_REGIONS'
|
||||
| 'VANITY_URL'
|
||||
| 'VERIFIED'
|
||||
| 'PARTNERED'
|
||||
| 'PUBLIC'
|
||||
| 'COMMERCE'
|
||||
| 'NEWS'
|
||||
| 'DISCOVERABLE'
|
||||
| 'FEATURABLE'
|
||||
| 'ANIMATED_ICON'
|
||||
| 'BANNER'
|
||||
import { ApplicationPayload } from "./application.ts"
|
||||
import { ChannelPayload } from './channel.ts'
|
||||
import { EmojiPayload } from './emoji.ts'
|
||||
import { PresenceUpdatePayload } from './gateway.ts'
|
||||
import { RolePayload } from './role.ts'
|
||||
import { UserPayload } from './user.ts'
|
||||
import { VoiceStatePayload } from './voice.ts'
|
||||
|
||||
export interface GuildPayload {
|
||||
id: string
|
||||
name: string
|
||||
icon?: string
|
||||
icon_hash?: string
|
||||
splash?: string
|
||||
discovery_splash?: string
|
||||
owner?: boolean
|
||||
owner_id: string
|
||||
permissions?: string
|
||||
region: string
|
||||
afk_channel_id?: string
|
||||
afk_timeout: number
|
||||
widget_enabled?: boolean
|
||||
widget_channel_id?: string
|
||||
verification_level: string
|
||||
default_message_notifications: string
|
||||
explicit_content_filter: string
|
||||
roles: RolePayload[]
|
||||
emojis: EmojiPayload[]
|
||||
features: GuildFeatures[]
|
||||
mfa_level: string
|
||||
application_id?: string
|
||||
system_channel_id?: string
|
||||
system_channel_flags: string
|
||||
rules_channel_id?: string
|
||||
joined_at?: string
|
||||
large?: boolean
|
||||
unavailable: boolean
|
||||
member_count?: number
|
||||
voice_states?: VoiceStatePayload[]
|
||||
members?: MemberPayload[]
|
||||
channels?: ChannelPayload[]
|
||||
presences?: PresenceUpdatePayload[]
|
||||
max_presences?: number
|
||||
max_members?: number
|
||||
vanity_url_code?: string
|
||||
description?: string
|
||||
banner?: string
|
||||
premium_tier: number
|
||||
premium_subscription_count?: number
|
||||
preferred_locale: string
|
||||
public_updates_channel_id?: string
|
||||
max_video_channel_users?: number
|
||||
approximate_number_count?: number
|
||||
approximate_presence_count?: number
|
||||
}
|
||||
|
||||
export interface MemberPayload {
|
||||
user: UserPayload
|
||||
nick?: string
|
||||
roles: string[]
|
||||
joined_at: string
|
||||
premium_since?: string
|
||||
deaf: boolean
|
||||
mute: boolean
|
||||
}
|
||||
|
||||
export enum MessageNotification {
|
||||
ALL_MESSAGES = 0,
|
||||
ONLY_MENTIONS = 1
|
||||
}
|
||||
|
||||
export enum ContentFilter {
|
||||
DISABLED = 0,
|
||||
MEMBERS_WITHOUT_ROLES = 1,
|
||||
ALL_MEMBERS = 3
|
||||
}
|
||||
|
||||
export enum MFA {
|
||||
NONE = 0,
|
||||
ELEVATED = 1
|
||||
}
|
||||
|
||||
export enum Verification {
|
||||
NONE = 0,
|
||||
LOW = 1,
|
||||
MEDIUM = 2,
|
||||
HIGH = 3,
|
||||
VERY_HIGH = 4
|
||||
}
|
||||
|
||||
export enum PremiumTier {
|
||||
NONE = 0,
|
||||
TIER_1 = 1,
|
||||
TIER_2 = 2,
|
||||
TIER_3 = 3
|
||||
}
|
||||
|
||||
export enum SystemChannelFlags {
|
||||
SUPPRESS_JOIN_NOTIFICATIONS = 1 << 0,
|
||||
SUPPRESS_PREMIUM_SUBSCRIPTIONS = 1 << 1
|
||||
}
|
||||
|
||||
export type GuildFeatures =
|
||||
| 'INVITE_SPLASH'
|
||||
| 'VIP_REGIONS'
|
||||
| 'VANITY_URL'
|
||||
| 'VERIFIED'
|
||||
| 'PARTNERED'
|
||||
| 'PUBLIC'
|
||||
| 'COMMERCE'
|
||||
| 'NEWS'
|
||||
| 'DISCOVERABLE'
|
||||
| 'FEATURABLE'
|
||||
| 'ANIMATED_ICON'
|
||||
| 'BANNER'
|
||||
|
||||
export enum IntegrationExpireBehavior {
|
||||
REMOVE_ROLE = 0,
|
||||
KICK = 1
|
||||
}
|
||||
|
||||
export interface IntegrationAccountPayload {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface GuildIntegrationPayload {
|
||||
id: string
|
||||
name: string
|
||||
type: string
|
||||
enabled: boolean
|
||||
syncing?: boolean
|
||||
role_id?: string
|
||||
enable_emoticons?: boolean
|
||||
expire_behaviour?: IntegrationExpireBehavior
|
||||
expire_grace_period?: number
|
||||
user?: UserPayload
|
||||
account: IntegrationAccountPayload
|
||||
synced_at?: string // Actually a ISO Timestamp, but we parse in constructor'
|
||||
subscriber_count?: number
|
||||
revoked?: boolean
|
||||
application?: ApplicationPayload
|
||||
}
|
|
@ -1,36 +1,59 @@
|
|||
import { GatewayIntents } from '../types/gateway.ts'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
||||
export class Intents {
|
||||
static All: number[] = [
|
||||
GatewayIntents.GUILD_MEMBERS,
|
||||
GatewayIntents.GUILD_PRESENCES,
|
||||
GatewayIntents.GUILD_MESSAGES,
|
||||
GatewayIntents.DIRECT_MESSAGES,
|
||||
GatewayIntents.DIRECT_MESSAGE_REACTIONS,
|
||||
GatewayIntents.DIRECT_MESSAGE_TYPING,
|
||||
GatewayIntents.GUILDS,
|
||||
GatewayIntents.GUILD_BANS,
|
||||
GatewayIntents.GUILD_EMOJIS,
|
||||
GatewayIntents.GUILD_INTEGRATIONS,
|
||||
GatewayIntents.GUILD_INVITES,
|
||||
GatewayIntents.GUILD_MESSAGE_REACTIONS,
|
||||
GatewayIntents.GUILD_MESSAGE_TYPING,
|
||||
GatewayIntents.GUILD_VOICE_STATES,
|
||||
GatewayIntents.GUILD_WEBHOOKS
|
||||
]
|
||||
|
||||
static Presence: number[] = [
|
||||
GatewayIntents.GUILD_PRESENCES,
|
||||
GatewayIntents.GUILDS
|
||||
]
|
||||
|
||||
static GuildMembers: number[] = [
|
||||
GatewayIntents.GUILD_MEMBERS,
|
||||
GatewayIntents.GUILDS,
|
||||
GatewayIntents.GUILD_BANS,
|
||||
GatewayIntents.GUILD_VOICE_STATES
|
||||
]
|
||||
|
||||
static None: number[] = []
|
||||
}
|
||||
import { GatewayIntents } from '../types/gateway.ts'
|
||||
|
||||
export type PriviligedIntents = 'GUILD_MEMBERS' | 'GUILD_PRESENCES'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
||||
export class Intents {
|
||||
static NonPriviliged: number[] = [
|
||||
GatewayIntents.GUILD_MESSAGES,
|
||||
GatewayIntents.DIRECT_MESSAGES,
|
||||
GatewayIntents.DIRECT_MESSAGE_REACTIONS,
|
||||
GatewayIntents.DIRECT_MESSAGE_TYPING,
|
||||
GatewayIntents.GUILDS,
|
||||
GatewayIntents.GUILD_BANS,
|
||||
GatewayIntents.GUILD_EMOJIS,
|
||||
GatewayIntents.GUILD_INTEGRATIONS,
|
||||
GatewayIntents.GUILD_INVITES,
|
||||
GatewayIntents.GUILD_MESSAGE_REACTIONS,
|
||||
GatewayIntents.GUILD_MESSAGE_TYPING,
|
||||
GatewayIntents.GUILD_VOICE_STATES,
|
||||
GatewayIntents.GUILD_WEBHOOKS
|
||||
]
|
||||
|
||||
static All: number[] = [
|
||||
GatewayIntents.GUILD_MEMBERS,
|
||||
GatewayIntents.GUILD_PRESENCES,
|
||||
...Intents.NonPriviliged
|
||||
]
|
||||
|
||||
static Presence: number[] = [
|
||||
GatewayIntents.GUILD_PRESENCES,
|
||||
...Intents.NonPriviliged
|
||||
]
|
||||
|
||||
static GuildMembers: number[] = [
|
||||
GatewayIntents.GUILD_MEMBERS,
|
||||
...Intents.NonPriviliged
|
||||
]
|
||||
|
||||
static None: number[] = [
|
||||
...Intents.NonPriviliged
|
||||
]
|
||||
|
||||
static create(priviliged?: PriviligedIntents[], disable?: number[]): number[] {
|
||||
let intents: number[] = [
|
||||
...Intents.NonPriviliged
|
||||
]
|
||||
|
||||
if (priviliged !== undefined && priviliged.length !== 0) {
|
||||
if (priviliged.includes('GUILD_MEMBERS')) intents.push(GatewayIntents.GUILD_MEMBERS)
|
||||
if (priviliged.includes('GUILD_PRESENCES')) intents.push(GatewayIntents.GUILD_PRESENCES)
|
||||
}
|
||||
|
||||
if (disable !== undefined) {
|
||||
intents = intents.filter(intent => !disable.includes(intent))
|
||||
}
|
||||
|
||||
return intents
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue