Change names and format codes

This commit is contained in:
Helloyunho 2020-11-08 16:58:24 +09:00
parent 0950279282
commit 5256f05f04
15 changed files with 303 additions and 232 deletions

View File

@ -1,41 +1,43 @@
import { Client, Message, Intents } from '../mod.ts' import { Client, Message, Intents } from '../mod.ts'
const client = new Client(); const client = new Client()
client.on("ready", () => { client.on('ready', () => {
console.log(`Logged in as ${client.user?.tag}!`); console.log(`Logged in as ${client.user?.tag}!`)
}); })
client.on("messageCreate", (msg: Message) => { client.on('messageCreate', (msg: Message) => {
if (msg.content === "!ping") { if (msg.content === '!ping') {
console.log("Command Used: Ping"); console.log('Command Used: Ping')
msg.reply("pong!"); msg.reply('pong!')
} }
}); })
console.log("discord.deno - ping example"); console.log('harmony - ping example')
const token = prompt("Input Bot Token:"); const token = prompt('Input Bot Token:')
if (token === null) { if (token === null) {
console.log("No token provided"); console.log('No token provided')
Deno.exit(); Deno.exit()
} }
const intents = prompt("Input Intents (0 = All, 1 = Presence, 2 = Server Members, 3 = None):"); const intents = prompt(
if (intents === null || !["0", "1", "2", "3"].includes(intents)) { 'Input Intents (0 = All, 1 = Presence, 2 = Server Members, 3 = None):'
console.log("No intents provided"); )
Deno.exit(); if (intents === null || !['0', '1', '2', '3'].includes(intents)) {
console.log('No intents provided')
Deno.exit()
} }
let ints; let ints
if (intents === "0") { if (intents === '0') {
ints = Intents.All; ints = Intents.All
} else if (intents === "1") { } else if (intents === '1') {
ints = Intents.Presence; ints = Intents.Presence
} else if (intents === "2") { } else if (intents === '2') {
ints = Intents.GuildMembers; ints = Intents.GuildMembers
} else { } else {
ints = Intents.None; ints = Intents.None
} }
client.connect(token, ints); client.connect(token, ints)

View File

@ -1,9 +1,9 @@
{ {
"name": "discord.deno", "name": "harmony",
"version": "1.0.0", "version": "1.0.0",
"description": "Discord Deno API that is easy to use.", "description": "Discord Deno API that is easy to use.",
"main": "index.js", "main": "index.js",
"repository": "https://github.com/Helloyunho/discord.deno.git", "repository": "https://github.com/harmony/harmony.git",
"author": "Helloyunho <yunho050840@gmail.com>", "author": "Helloyunho <yunho050840@gmail.com>",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {

View File

@ -1,16 +1,16 @@
import { Gateway, GatewayEventHandler } from '../index.ts' import { Gateway, GatewayEventHandler } from '../index.ts'
import cache from '../../models/cache.ts'
import { Guild } from '../../structures/guild.ts' import { Guild } from '../../structures/guild.ts'
import { User } from '../../structures/user.ts' import { User } from '../../structures/user.ts'
import { GuildBanRemovePayload } from '../../types/gateway.ts' import { GuildBanRemovePayload } from '../../types/gateway.ts'
export const guildBanRemove: GatewayEventHandler = ( export const guildBanRemove: GatewayEventHandler = async (
gateway: Gateway, gateway: Gateway,
d: GuildBanRemovePayload d: GuildBanRemovePayload
) => { ) => {
const guild: Guild = cache.get('guild', d.guild_id) const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id)
const user: User = const user: User =
cache.get('user', d.user.id) ?? new User(gateway.client, d.user) (await gateway.client.users.get(d.user.id)) ??
new User(gateway.client, d.user)
if (guild !== undefined) { if (guild !== undefined) {
gateway.client.emit('guildBanRemove', guild, user) gateway.client.emit('guildBanRemove', guild, user)

View File

@ -1,52 +1,63 @@
import { Gateway, GatewayEventHandler } from '../index.ts' import { Gateway, GatewayEventHandler } from '../index.ts'
import { Guild } from '../../structures/guild.ts' import { Guild } from '../../structures/guild.ts'
import { GuildPayload, MemberPayload } from "../../types/guild.ts" import { GuildPayload, MemberPayload } from '../../types/guild.ts'
import { MembersManager } from "../../managers/members.ts" import { MembersManager } from '../../managers/members.ts'
import { GuildChannelPayload } from "../../types/channel.ts" import { GuildChannelPayload } from '../../types/channel.ts'
import { RolePayload } from "../../types/role.ts" import { RolePayload } from '../../types/role.ts'
import { RolesManager } from "../../managers/roles.ts" import { RolesManager } from '../../managers/roles.ts'
export const guildCreate: GatewayEventHandler = async(gateway: Gateway, d: GuildPayload) => { export const guildCreate: GatewayEventHandler = async (
gateway: Gateway,
d: GuildPayload
) => {
let guild: Guild | undefined = await gateway.client.guilds.get(d.id) let guild: Guild | undefined = await gateway.client.guilds.get(d.id)
if (guild !== undefined) { if (guild !== undefined) {
// It was just lazy load, so we don't fire the event as its gonna fire for every guild bot is in // It was just lazy load, so we don't fire the event as its gonna fire for every guild bot is in
await gateway.client.guilds.set(d.id, d) await gateway.client.guilds.set(d.id, d)
if (d.members !== undefined) { if (d.members !== undefined) {
const members = new MembersManager(gateway.client, guild) const members = new MembersManager(gateway.client, guild)
await members.fromPayload(d.members as MemberPayload[]) await members.fromPayload(d.members as MemberPayload[])
guild.members = members guild.members = members
} }
if (d.channels !== undefined) { if (d.channels !== undefined) {
for (const ch of d.channels as GuildChannelPayload[]) { for (const ch of d.channels as GuildChannelPayload[]) {
ch.guild_id = d.id ch.guild_id = d.id
await gateway.client.channels.set(ch.id, ch) await gateway.client.channels.set(ch.id, ch)
} }
} }
if (d.roles !== undefined) { if (d.roles !== undefined) {
const roles = new RolesManager(gateway.client, guild) const roles = new RolesManager(gateway.client, guild)
await roles.fromPayload(d.roles as RolePayload[]) await roles.fromPayload(d.roles as RolePayload[])
guild.roles = roles guild.roles = roles
} }
guild.refreshFromData(d) guild.refreshFromData(d)
} else { } else {
await gateway.client.guilds.set(d.id, d) await gateway.client.guilds.set(d.id, d)
guild = new Guild(gateway.client, d) guild = new Guild(gateway.client, d)
if ((d as any).members !== undefined) { if ((d as any).members !== undefined) {
const members = new MembersManager(gateway.client, guild) const members = new MembersManager(gateway.client, guild)
await members.fromPayload(d.members as MemberPayload[]) await members.fromPayload(d.members as MemberPayload[])
guild.members = members guild.members = members
} }
if (d.channels !== undefined) { if (d.channels !== undefined) {
for (const ch of d.channels as GuildChannelPayload[]) { for (const ch of d.channels as GuildChannelPayload[]) {
(ch as any).guild_id = d.id ;(ch as any).guild_id = d.id
await gateway.client.channels.set(ch.id, ch) await gateway.client.channels.set(ch.id, ch)
} }
} }
if (d.roles !== undefined) { if (d.roles !== undefined) {
const roles = new RolesManager(gateway.client, guild) const roles = new RolesManager(gateway.client, guild)
await roles.fromPayload(d.roles) await roles.fromPayload(d.roles)
guild.roles = roles guild.roles = roles
} }
await guild.roles.fromPayload(d.roles) await guild.roles.fromPayload(d.roles)
guild = new Guild(gateway.client, d) guild = new Guild(gateway.client, d)
gateway.client.emit('guildCreate', guild) gateway.client.emit('guildCreate', guild)

View File

@ -10,10 +10,12 @@ export const guildDelte: GatewayEventHandler = async (
if (guild !== undefined) { if (guild !== undefined) {
guild.refreshFromData(d) guild.refreshFromData(d)
await guild.members.flush() await guild.members.flush()
await guild.channels.flush() await guild.channels.flush()
await guild.roles.flush() await guild.roles.flush()
await gateway.client.guilds.delete(d.id) await gateway.client.guilds.delete(d.id)
gateway.client.emit('guildDelete', guild) gateway.client.emit('guildDelete', guild)
} }
} }

View File

@ -1,18 +1,22 @@
import { Client } from '../models/client.ts' import { Client } from '../models/client.ts'
import { Emoji } from '../structures/emoji.ts' import { Emoji } from '../structures/emoji.ts'
import { Guild } from '../structures/guild.ts'
import { EmojiPayload } from '../types/emoji.ts' import { EmojiPayload } from '../types/emoji.ts'
import { CHANNEL } from '../types/endpoint.ts' import { GUILD_EMOJI } from '../types/endpoint.ts'
import { BaseManager } from './base.ts' import { BaseManager } from './base.ts'
export class EmojisManager extends BaseManager<EmojiPayload, Emoji> { export class EmojisManager extends BaseManager<EmojiPayload, Emoji> {
constructor (client: Client) { guild: Guild
super(client, 'emojis', Emoji)
constructor (client: Client, guild: Guild) {
super(client, `emojis:${guild.id}`, Emoji)
this.guild = guild
} }
async fetch (id: string): Promise<Emoji> { async fetch (id: string): Promise<Emoji> {
return await new Promise((resolve, reject) => { return await new Promise((resolve, reject) => {
this.client.rest this.client.rest
.get(CHANNEL(id)) .get(GUILD_EMOJI(this.guild.id, id))
.then(data => { .then(data => {
this.set(id, data as EmojiPayload) this.set(id, data as EmojiPayload)
resolve(new Emoji(this.client, data as EmojiPayload)) resolve(new Emoji(this.client, data as EmojiPayload))

View File

@ -1,45 +1,53 @@
import { Client } from "../models/client.ts"; import { Client } from '../models/client.ts'
import { Channel } from "../structures/channel.ts"; import { Channel } from '../structures/channel.ts'
import { Guild } from "../structures/guild.ts"; import { Guild } from '../structures/guild.ts'
import { CategoryChannel } from "../structures/guildCategoryChannel.ts"; import { CategoryChannel } from '../structures/guildCategoryChannel.ts'
import { GuildTextChannel } from "../structures/guildTextChannel.ts"; import { GuildTextChannel } from '../structures/guildTextChannel.ts'
import { VoiceChannel } from "../structures/guildVoiceChannel.ts"; import { VoiceChannel } from '../structures/guildVoiceChannel.ts'
import { GuildChannelCategoryPayload, GuildTextChannelPayload, GuildVoiceChannelPayload } from "../types/channel.ts"; import {
import { CHANNEL } from "../types/endpoint.ts"; GuildChannelCategoryPayload,
import { BaseChildManager } from "./baseChild.ts"; GuildTextChannelPayload,
import { ChannelsManager } from "./channels.ts"; GuildVoiceChannelPayload
} from '../types/channel.ts'
import { CHANNEL } from '../types/endpoint.ts'
import { BaseChildManager } from './baseChild.ts'
import { ChannelsManager } from './channels.ts'
export type GuildChannelPayloads = GuildTextChannelPayload | GuildVoiceChannelPayload | GuildChannelCategoryPayload export type GuildChannelPayloads =
| GuildTextChannelPayload
| GuildVoiceChannelPayload
| GuildChannelCategoryPayload
export type GuildChannel = GuildTextChannel | VoiceChannel | CategoryChannel export type GuildChannel = GuildTextChannel | VoiceChannel | CategoryChannel
export class GuildChannelsManager extends BaseChildManager<GuildChannelPayloads, GuildChannel> { export class GuildChannelsManager extends BaseChildManager<
GuildChannelPayloads,
GuildChannel
> {
guild: Guild guild: Guild
constructor(client: Client, parent: ChannelsManager, guild: Guild) { constructor (client: Client, parent: ChannelsManager, guild: Guild) {
super(client, parent as any) super(client, parent as any)
this.guild = guild this.guild = guild
} }
async get(id: string): Promise<GuildChannel | undefined> { async get (id: string): Promise<GuildChannel | undefined> {
const res = await this.parent.get(id) const res = await this.parent.get(id)
if (res !== undefined && res.guild.id === this.guild.id) return res if (res !== undefined && res.guild.id === this.guild.id) return res
else return undefined else return undefined
} }
async delete(id: string): Promise<boolean> { async array (): Promise<GuildChannel[]> {
return this.client.rest.delete(CHANNEL(id)) const arr = (await this.parent.array()) as Channel[]
return arr.filter(
(c: any) => c.guild !== undefined && c.guild.id === this.guild.id
) as any
} }
async array(): Promise<GuildChannel[]> { async flush (): Promise<boolean> {
const arr = await this.parent.array() as Channel[]
return arr.filter((c: any) => c.guild !== undefined && c.guild.id === this.guild.id) as any
}
async flush(): Promise<boolean> {
const arr = await this.array() const arr = await this.array()
for (const elem of arr) { for (const elem of arr) {
this.parent.delete(elem.id) this.parent.delete(elem.id)
} }
return true return true
} }
} }

View File

@ -1,27 +1,35 @@
import { Client } from "../models/client.ts"; import { Client } from '../models/client.ts'
import { Guild } from "../structures/guild.ts"; import { Guild } from '../structures/guild.ts'
import { GUILD } from "../types/endpoint.ts"; import { GUILD } from '../types/endpoint.ts'
import { GuildPayload, MemberPayload } from "../types/guild.ts"; import { GuildPayload, MemberPayload } from '../types/guild.ts'
import { BaseManager } from "./base.ts"; import { BaseManager } from './base.ts'
import { MembersManager } from "./members.ts"; import { MembersManager } from './members.ts'
export class GuildManager extends BaseManager<GuildPayload, Guild> { export class GuildManager extends BaseManager<GuildPayload, Guild> {
constructor (client: Client) { constructor (client: Client) {
super(client, 'guilds', Guild) super(client, 'guilds', Guild)
} }
async fetch(id: string): Promise<Guild> { async fetch (id: string): Promise<Guild> {
return await new Promise((resolve, reject) => { return await new Promise((resolve, reject) => {
this.client.rest.get(GUILD(id)).then(async (data: any) => { this.client.rest
this.set(id, data) .get(GUILD(id))
const guild = new Guild(this.client, data) .then(async (data: any) => {
if ((data as GuildPayload).members !== undefined) { this.set(id, data)
const members = new MembersManager(this.client, guild)
await members.fromPayload((data as GuildPayload).members as MemberPayload[]) const guild = new Guild(this.client, data)
guild.members = members
} if ((data as GuildPayload).members !== undefined) {
resolve(guild) const members = new MembersManager(this.client, guild)
}).catch(e => reject(e)) await members.fromPayload(
(data as GuildPayload).members as MemberPayload[]
)
guild.members = members
}
resolve(guild)
})
.catch(e => reject(e))
}) })
} }
} }

View File

@ -1,40 +1,64 @@
import { Client } from "../models/client.ts"; import { Client } from '../models/client.ts'
import { Message } from "../structures/message.ts"; import { Message } from '../structures/message.ts'
import { MessageMentions } from "../structures/messageMentions.ts"; import { MessageMentions } from '../structures/messageMentions.ts'
import { TextChannel } from "../structures/textChannel.ts"; import { TextChannel } from '../structures/textChannel.ts'
import { User } from "../structures/user.ts"; import { User } from '../structures/user.ts'
import { MessagePayload } from "../types/channel.ts"; import { MessagePayload } from '../types/channel.ts'
import { CHANNEL_MESSAGE } from "../types/endpoint.ts"; import { CHANNEL_MESSAGE } from '../types/endpoint.ts'
import { BaseManager } from "./base.ts"; import { BaseManager } from './base.ts'
export class MessagesManager extends BaseManager<MessagePayload, Message> { export class MessagesManager extends BaseManager<MessagePayload, Message> {
constructor (client: Client) { constructor (client: Client) {
super(client, 'messages', Message) super(client, 'messages', Message)
} }
async get(key: string): Promise<Message | undefined> { async get (key: string): Promise<Message | undefined> {
const raw = await this._get(key) const raw = await this._get(key)
if (raw === undefined) return if (raw === undefined) return
let channel = await this.client.channels.get(raw.channel_id) let channel = await this.client.channels.get(raw.channel_id)
if (channel === undefined) channel = await this.client.channels.fetch(raw.channel_id) if (channel === undefined)
if (channel === undefined) return channel = await this.client.channels.fetch(raw.channel_id)
const author = new User(this.client, raw.author) const author = new User(this.client, raw.author)
const mentions = new MessageMentions() const mentions = new MessageMentions()
return new this.DataType(this.client, raw, channel, author, mentions) as any return new this.DataType(this.client, raw, channel, author, mentions) as any
} }
async fetch(channelID: string, id: string): Promise<Message> { async fetch (channelID: string, id: string): Promise<Message> {
return await new Promise((resolve, reject) => { return await new Promise((resolve, reject) => {
this.client.rest.get(CHANNEL_MESSAGE(channelID, id)).then(async data => { this.client.rest
this.set(id, data as MessagePayload) .get(CHANNEL_MESSAGE(channelID, id))
let channel: any = await this.client.channels.get<TextChannel>(channelID) .then(async data => {
if (channel === undefined) channel = await this.client.channels.fetch(channelID) this.set(id, data as MessagePayload)
const author = new User(this.client, (data as MessagePayload).author)
await this.client.users.set(author.id, (data as MessagePayload).author) let channel: any = await this.client.channels.get<TextChannel>(
// TODO: Make this thing work (MessageMentions) channelID
const mentions = new MessageMentions() )
resolve(new Message(this.client, data as MessagePayload, channel as TextChannel, author, mentions)) if (channel === undefined)
}).catch(e => reject(e)) channel = await this.client.channels.fetch(channelID)
const author = new User(this.client, (data as MessagePayload).author)
await this.client.users.set(
author.id,
(data as MessagePayload).author
)
// TODO: Make this thing work (MessageMentions)
const mentions = new MessageMentions()
resolve(
new Message(
this.client,
data as MessagePayload,
channel as TextChannel,
author,
mentions
)
)
})
.catch(e => reject(e))
}) })
} }
} }

View File

@ -3,20 +3,24 @@ import { GatewayIntents } from '../types/gateway.ts'
import { Gateway } from '../gateway/index.ts' import { Gateway } from '../gateway/index.ts'
import { RESTManager } from './rest.ts' import { RESTManager } from './rest.ts'
import EventEmitter from 'https://deno.land/std@0.74.0/node/events.ts' import EventEmitter from 'https://deno.land/std@0.74.0/node/events.ts'
import { DefaultCacheAdapter, ICacheAdapter } from "./cacheAdapter.ts" import { DefaultCacheAdapter, ICacheAdapter } from './cacheAdapter.ts'
import { UserManager } from "../managers/users.ts" import { UserManager } from '../managers/users.ts'
import { GuildManager } from "../managers/guilds.ts" import { GuildManager } from '../managers/guilds.ts'
import { EmojisManager } from "../managers/emojis.ts" import { EmojisManager } from '../managers/emojis.ts'
import { ChannelsManager } from "../managers/channels.ts" import { ChannelsManager } from '../managers/channels.ts'
import { MessagesManager } from "../managers/messages.ts" import { MessagesManager } from '../managers/messages.ts'
import { ActivityGame, ClientActivity, ClientPresence } from "../structures/presence.ts" import {
ActivityGame,
ClientActivity,
ClientPresence
} from '../structures/presence.ts'
/** Some Client Options to modify behaviour */ /** Some Client Options to modify behaviour */
export interface ClientOptions { export interface ClientOptions {
token?: string token?: string
intents?: GatewayIntents[] intents?: GatewayIntents[]
cache?: ICacheAdapter, cache?: ICacheAdapter
forceNewSession?: boolean, forceNewSession?: boolean
presence?: ClientPresence | ClientActivity | ActivityGame presence?: ClientPresence | ClientActivity | ActivityGame
bot?: boolean bot?: boolean
canary?: boolean canary?: boolean
@ -31,7 +35,7 @@ export class Client extends EventEmitter {
user?: User user?: User
ping = 0 ping = 0
token?: string token?: string
cache: ICacheAdapter = new DefaultCacheAdapter() cache: ICacheAdapter = new DefaultCacheAdapter(this)
intents?: GatewayIntents[] intents?: GatewayIntents[]
forceNewSession?: boolean forceNewSession?: boolean
users: UserManager = new UserManager(this) users: UserManager = new UserManager(this)
@ -50,7 +54,11 @@ export class Client extends EventEmitter {
this.intents = options.intents this.intents = options.intents
this.forceNewSession = options.forceNewSession this.forceNewSession = options.forceNewSession
if (options.cache !== undefined) this.cache = options.cache if (options.cache !== undefined) this.cache = options.cache
if (options.presence !== undefined) this.presence = options.presence instanceof ClientPresence ? options.presence : new ClientPresence(options.presence) if (options.presence !== undefined)
this.presence =
options.presence instanceof ClientPresence
? options.presence
: new ClientPresence(options.presence)
if (options.bot === false) this.bot = false if (options.bot === false) this.bot = false
if (options.canary === true) this.canary = true if (options.canary === true) this.canary = true
} }
@ -68,7 +76,7 @@ export class Client extends EventEmitter {
} }
debug (tag: string, msg: string): void { debug (tag: string, msg: string): void {
this.emit("debug", `[${tag}] ${msg}`) this.emit('debug', `[${tag}] ${msg}`)
} }
/** /**

View File

@ -29,7 +29,7 @@ export interface CommandTexts {
export const DefaultCommandTexts: CommandTexts = { export const DefaultCommandTexts: CommandTexts = {
GUILD_ONLY: 'This command can only be used in a Server!', GUILD_ONLY: 'This command can only be used in a Server!',
OWNER_ONLY: 'This command can only be used by Bot Owners!', OWNER_ONLY: 'This command can only be used by Bot Owners!',
DMS_ONLY: 'This command can only be used in Bot\'s DMs!', DMS_ONLY: "This command can only be used in Bot's DMs!",
ERROR: 'An error occured while executing command!' ERROR: 'An error occured while executing command!'
} }
@ -44,7 +44,7 @@ export const massReplace = (text: string, replaces: Replaces): string => {
return text return text
} }
export class CommandClient extends Client { export class CommandClient extends Client implements CommandClientOptions {
prefix: string | string[] prefix: string | string[]
mentionPrefix: boolean mentionPrefix: boolean
getGuildPrefix: (guildID: string) => PrefixReturnType getGuildPrefix: (guildID: string) => PrefixReturnType
@ -58,23 +58,38 @@ export class CommandClient extends Client {
commands: CommandsManager = new CommandsManager(this) commands: CommandsManager = new CommandsManager(this)
texts: CommandTexts = DefaultCommandTexts texts: CommandTexts = DefaultCommandTexts
constructor(options: CommandClientOptions) { constructor (options: CommandClientOptions) {
super(options) super(options)
this.prefix = options.prefix this.prefix = options.prefix
this.mentionPrefix = options.mentionPrefix === undefined ? false : options.mentionPrefix this.mentionPrefix =
this.getGuildPrefix = options.getGuildPrefix === undefined ? (id: string) => this.prefix : options.getGuildPrefix options.mentionPrefix === undefined ? false : options.mentionPrefix
this.getUserPrefix = options.getUserPrefix === undefined ? (id: string) => this.prefix : options.getUserPrefix this.getGuildPrefix =
this.spacesAfterPrefix = options.spacesAfterPrefix === undefined ? false : options.spacesAfterPrefix options.getGuildPrefix === undefined
this.betterArgs = options.betterArgs === undefined ? false : options.betterArgs ? (id: string) => this.prefix
: options.getGuildPrefix
this.getUserPrefix =
options.getUserPrefix === undefined
? (id: string) => this.prefix
: options.getUserPrefix
this.spacesAfterPrefix =
options.spacesAfterPrefix === undefined
? false
: options.spacesAfterPrefix
this.betterArgs =
options.betterArgs === undefined ? false : options.betterArgs
this.owners = options.owners === undefined ? [] : options.owners this.owners = options.owners === undefined ? [] : options.owners
this.allowBots = options.allowBots === undefined ? false : options.allowBots this.allowBots = options.allowBots === undefined ? false : options.allowBots
this.allowDMs = options.allowDMs === undefined ? true : options.allowDMs this.allowDMs = options.allowDMs === undefined ? true : options.allowDMs
this.caseSensitive = options.caseSensitive === undefined ? false : options.caseSensitive this.caseSensitive =
options.caseSensitive === undefined ? false : options.caseSensitive
this.on('messageCreate', async (msg: Message) => await this.processMessage(msg)) this.on(
'messageCreate',
async (msg: Message) => await this.processMessage(msg)
)
} }
async processMessage(msg: Message): Promise<any> { async processMessage (msg: Message): Promise<any> {
if (!this.allowBots && msg.author.bot === true) return if (!this.allowBots && msg.author.bot === true) return
let prefix: string | string[] = this.prefix let prefix: string | string[] = this.prefix
@ -113,15 +128,18 @@ export class CommandClient extends Client {
} }
if (command.guildOnly === true && msg.guild === undefined) { if (command.guildOnly === true && msg.guild === undefined) {
if (this.texts.GUILD_ONLY !== undefined) return this.sendProcessedText(msg, this.texts.GUILD_ONLY, baseReplaces) if (this.texts.GUILD_ONLY !== undefined)
return this.sendProcessedText(msg, this.texts.GUILD_ONLY, baseReplaces)
return return
} }
if (command.dmOnly === true && msg.guild !== undefined) { if (command.dmOnly === true && msg.guild !== undefined) {
if (this.texts.DMS_ONLY !== undefined) return this.sendProcessedText(msg, this.texts.DMS_ONLY, baseReplaces) if (this.texts.DMS_ONLY !== undefined)
return this.sendProcessedText(msg, this.texts.DMS_ONLY, baseReplaces)
return return
} }
if (command.ownerOnly === true && !this.owners.includes(msg.author.id)) { if (command.ownerOnly === true && !this.owners.includes(msg.author.id)) {
if (this.texts.OWNER_ONLY !== undefined) return this.sendProcessedText(msg, this.texts.OWNER_ONLY, baseReplaces) if (this.texts.OWNER_ONLY !== undefined)
return this.sendProcessedText(msg, this.texts.OWNER_ONLY, baseReplaces)
return return
} }
@ -141,21 +159,30 @@ export class CommandClient extends Client {
this.emit('commandUsed', { context: ctx }) this.emit('commandUsed', { context: ctx })
command.execute(ctx) command.execute(ctx)
} catch (e) { } catch (e) {
if (this.texts.ERROR !== undefined) return this.sendProcessedText(msg, this.texts.ERROR, Object.assign(baseReplaces, { error: e.message })) if (this.texts.ERROR !== undefined)
return this.sendProcessedText(
msg,
this.texts.ERROR,
Object.assign(baseReplaces, { error: e.message })
)
this.emit('commandError', { command, parsed, error: e }) this.emit('commandError', { command, parsed, error: e })
} }
} }
sendProcessedText(msg: Message, text: CommandText, replaces: Replaces): any { sendProcessedText (msg: Message, text: CommandText, replaces: Replaces): any {
if (typeof text === "string") { if (typeof text === 'string') {
text = massReplace(text, replaces) text = massReplace(text, replaces)
return msg.channel.send(text) return msg.channel.send(text)
} else { } else {
if (text.description !== undefined) text.description = massReplace(text.description, replaces) if (text.description !== undefined)
if (text.title !== undefined) text.description = massReplace(text.title, replaces) text.description = massReplace(text.description, replaces)
if (text.author?.name !== undefined) text.description = massReplace(text.author.name, replaces) if (text.title !== undefined)
if (text.footer?.text !== undefined) text.description = massReplace(text.footer.text, replaces) text.description = massReplace(text.title, replaces)
if (text.author?.name !== undefined)
text.description = massReplace(text.author.name, replaces)
if (text.footer?.text !== undefined)
text.description = massReplace(text.footer.text, replaces)
return msg.channel.send(text) return msg.channel.send(text)
} }
} }
} }

View File

@ -1,7 +1,7 @@
import { delay } from '../utils/index.ts' import { delay } from '../utils/index.ts'
import * as baseEndpoints from '../consts/urlsAndVersions.ts' import * as baseEndpoints from '../consts/urlsAndVersions.ts'
import { Client } from './client.ts' import { Client } from './client.ts'
import { getBuildInfo } from "../utils/buildInfo.ts" import { getBuildInfo } from '../utils/buildInfo.ts'
export enum HttpResponseCode { export enum HttpResponseCode {
Ok = 200, Ok = 200,
@ -156,7 +156,7 @@ export class RESTManager {
): { [key: string]: any } { ): { [key: string]: any } {
const headers: { [key: string]: string } = { const headers: { [key: string]: string } = {
Authorization: `Bot ${this.client.token}`, Authorization: `Bot ${this.client.token}`,
'User-Agent': `DiscordBot (discord.deno)` 'User-Agent': `DiscordBot (harmony)`
} }
if (this.client.token === undefined) delete headers.Authorization if (this.client.token === undefined) delete headers.Authorization
@ -190,7 +190,9 @@ export class RESTManager {
data.headers['sec-fetch-dest'] = 'empty' data.headers['sec-fetch-dest'] = 'empty'
data.headers['sec-fetch-mode'] = 'cors' data.headers['sec-fetch-mode'] = 'cors'
data.headers['sec-fetch-site'] = 'same-origin' data.headers['sec-fetch-site'] = 'same-origin'
data.headers['x-super-properties'] = btoa(JSON.stringify(getBuildInfo(this.client))) data.headers['x-super-properties'] = btoa(
JSON.stringify(getBuildInfo(this.client))
)
delete data.headers['User-Agent'] delete data.headers['User-Agent']
delete data.headers.Authorization delete data.headers.Authorization
headers.credentials = 'include' headers.credentials = 'include'
@ -259,10 +261,7 @@ export class RESTManager {
const requestData = this.createRequestBody(body, method) const requestData = this.createRequestBody(body, method)
const response = await fetch( const response = await fetch(urlToUse, requestData)
urlToUse,
requestData
)
const bucketIDFromHeaders = this.processHeaders(url, response.headers) const bucketIDFromHeaders = this.processHeaders(url, response.headers)
this.handleStatusCode(response, errorStack) this.handleStatusCode(response, errorStack)
@ -328,7 +327,8 @@ export class RESTManager {
// eslint-disable-next-line @typescript-eslint/no-floating-promises // eslint-disable-next-line @typescript-eslint/no-floating-promises
this.logErrors(response, errorStack) this.logErrors(response, errorStack)
if (status === HttpResponseCode.Unauthorized) throw new Error("Request was not successful. Invalid Token.") if (status === HttpResponseCode.Unauthorized)
throw new Error('Request was not successful. Invalid Token.')
switch (status) { switch (status) {
case HttpResponseCode.BadRequest: case HttpResponseCode.BadRequest:

View File

@ -1,6 +1,6 @@
// https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway // https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway
// https://discord.com/developers/docs/topics/gateway#commands-and-events-gateway-events // https://discord.com/developers/docs/topics/gateway#commands-and-events-gateway-events
import { StatusType } from "../../mod.ts" import { StatusType } from '../../mod.ts'
import { EmojiPayload } from './emoji.ts' import { EmojiPayload } from './emoji.ts'
import { MemberPayload } from './guild.ts' import { MemberPayload } from './guild.ts'
import { ActivityPayload } from './presence.ts' import { ActivityPayload } from './presence.ts'
@ -122,8 +122,8 @@ export enum UpdateStatus {
export interface IdentityConnection { export interface IdentityConnection {
$os: 'darwin' | 'windows' | 'linux' | 'custom os' $os: 'darwin' | 'windows' | 'linux' | 'custom os'
$browser: 'discord.deno' $browser: 'harmony'
$device: 'discord.deno' $device: 'harmony'
} }
export interface Resume { export interface Resume {
@ -314,4 +314,4 @@ export interface VoiceServerUpdatePayload {
export interface WebhooksUpdatePayload { export interface WebhooksUpdatePayload {
guild_id: string guild_id: string
channel_id: string channel_id: string
} }

View File

@ -1,40 +1,53 @@
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
import { Client } from "../models/client.ts"; import { Client } from '../models/client.ts'
export const getBuildInfo = (client: Client): { export const getBuildInfo = (
os: string client: Client
os_version: string ): {
browser: string os: string
browser_version: string os_version: string
browser_user_agent: string browser: string
client_build_number: number browser_version: string
client_event_source: null browser_user_agent: string
release_channel: string client_build_number: number
client_event_source: null
release_channel: string
} => { } => {
const os = 'Windows' let os = 'Windows'
const os_version = '10' let os_version = '10'
let client_build_number = 71073 let client_build_number = 71073
const client_event_source = null const client_event_source = null
let release_channel = 'stable' let release_channel = 'stable'
if (client.canary === true) { if (client.canary === true) {
release_channel = 'canary' release_channel = 'canary'
client_build_number = 71076 client_build_number = 71076
} }
const browser = 'Firefox' let browser = 'Firefox'
const browser_version = '83.0' let browser_version = '83.0'
const browser_user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 ' + browser + '/' + browser_version let browser_user_agent =
// TODO: Use current OS properties, but also browser_user_agent accordingly 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 ' +
// if (Deno.build.os === 'darwin') os = 'MacOS' browser +
// else if (Deno.build.os === 'linux') os = 'Ubuntu' '/' +
browser_version
// TODO: Use current OS properties, but also browser_user_agent accordingly
if (Deno.build.os === 'darwin') {
os = 'MacOS'
os_version = '10.15.6'
browser = 'Safari'
browser_version = '14.0.1'
browser_user_agent =
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Safari/605.1.15'
}
// else if (Deno.build.os === 'linux') os = 'Ubuntu'
return { return {
os, os,
os_version, os_version,
browser, browser,
browser_version, browser_version,
browser_user_agent, browser_user_agent,
client_build_number, client_build_number,
client_event_source, client_event_source,
release_channel, release_channel
} }
}; }

View File

@ -1,4 +1,4 @@
import { GatewayIntents } from "../types/gateway.ts"; import { GatewayIntents } from '../types/gateway.ts'
// eslint-disable-next-line @typescript-eslint/no-extraneous-class // eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class Intents { export class Intents {
@ -18,55 +18,19 @@ export class Intents {
GatewayIntents.GUILD_MESSAGE_TYPING, GatewayIntents.GUILD_MESSAGE_TYPING,
GatewayIntents.GUILD_VOICE_STATES, GatewayIntents.GUILD_VOICE_STATES,
GatewayIntents.GUILD_WEBHOOKS GatewayIntents.GUILD_WEBHOOKS
]; ]
static Presence: number[] = [ static Presence: number[] = [
GatewayIntents.GUILD_PRESENCES, GatewayIntents.GUILD_PRESENCES,
GatewayIntents.GUILD_MESSAGES, GatewayIntents.GUILDS
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 GuildMembers: number[] = [ static GuildMembers: number[] = [
GatewayIntents.GUILD_MEMBERS, GatewayIntents.GUILD_MEMBERS,
GatewayIntents.GUILD_MESSAGES,
GatewayIntents.DIRECT_MESSAGES,
GatewayIntents.DIRECT_MESSAGE_REACTIONS,
GatewayIntents.DIRECT_MESSAGE_TYPING,
GatewayIntents.GUILDS, GatewayIntents.GUILDS,
GatewayIntents.GUILD_BANS, GatewayIntents.GUILD_BANS,
GatewayIntents.GUILD_EMOJIS, GatewayIntents.GUILD_VOICE_STATES
GatewayIntents.GUILD_INTEGRATIONS,
GatewayIntents.GUILD_INVITES,
GatewayIntents.GUILD_MESSAGE_REACTIONS,
GatewayIntents.GUILD_MESSAGE_TYPING,
GatewayIntents.GUILD_VOICE_STATES,
GatewayIntents.GUILD_WEBHOOKS
];
static None: 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 None: number[] = []
}