-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
143 lines (119 loc) · 4.5 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
const baseURL = "https://disstat-api.tomatenkuchen.com/v1/"
const autopostInterval = 90000
const { EventEmitter } = require("node:events")
const os = require("node:os")
class DisStat extends EventEmitter {
constructor(apiKeyInput = "", botInput = "") {
super()
this.apiKey = ""
this.botId = ""
this.bot = {}
this.autoposting = false
this.noManualWarningSent = false
this.unpostedCustom = []
if (!apiKeyInput) throw new TypeError("No DisStat API key provided as first argument. You can find the API key on the Manage Bot page of your bot.")
if (!apiKeyInput.startsWith("DS-")) console.warn("[DisStat " + new Date().toLocaleTimeString() + "] The provided API key as first argument doesn't start with \"DS-\".")
this.botId = typeof botInput == "object" ? botInput.user.id : botInput
if (!this.botId) throw new TypeError("Missing (falsy) Discord bot ID provided, but a discord.js bot client or ID is required as second argument")
this.apiKey = apiKeyInput
if (typeof botInput == "object") {
this.startUsage = process.cpuUsage()
this.startTime = Date.now()
this.prevUsage = {}
this.autoposting = true
this.bot = botInput
setTimeout(() => this.autopost(), 30000)
}
}
async autopost() {
this.emit("autopostStart")
const data = {}
if (this.unpostedCustom.length > 0) data.custom = this.unpostedCustom
if (this.bot) {
data.guilds = this.bot.guilds.cache.size
data.shards = this.bot.shard ? this.bot.shard.count : 0
data.users = this.bot.guilds.cache.filter(guild => guild.available).reduce((acc, cur) => acc + cur.memberCount, 0)
data.apiPing = this.bot.ws && this.bot.ws.ping > 0 ? this.bot.ws.ping : null
}
data.ramUsage = process.memoryUsage.rss()
const endUsage = process.cpuUsage()
const elapTime = endUsage.user - this.startUsage.user + endUsage.system - this.startUsage.system
const elapTimeMS = Date.now() - this.startTime
this.startUsage = process.cpuUsage()
this.startTime = Date.now()
data.cpu = parseFloat((100 * elapTime / (1000 * elapTimeMS * os.cpus().length)).toFixed(2))
// TODO: Bandwidth usage
this.noManualWarningSent = true
let result = {}
try {
result = await this.postData(data)
} catch (e) {
this.emit("autopostError", result, data)
console.warn("[DisStat " + new Date().toLocaleTimeString() + "] Failed to post data to DisStat API. Error: " + e.message, result)
setTimeout(() => this.autopost(), autopostInterval)
return
}
setTimeout(() => this.autopost(), autopostInterval)
this.unpostedCustom = []
this.emit("autopostSuccess", data)
}
async getBot(botIdInput = "") {
const response = await fetch(baseURL + "bot/" + (botIdInput || this.botId), {
headers: {
Authorization: this.apiKey,
Accept: "application/json"
}
})
return await response.json()
}
async postData(data = {}) {
if (this.autoposting && !this.noManualWarningSent) {
console.warn("[DisStat " + new Date().toLocaleTimeString() +
"] You are using autoposting, but still manually posting data. This is not recommended, as it can cause duplication and data loss due to overwriting.")
this.noManualWarningSent = true
}
if (!data || typeof data != "object" || Object.keys(data).length == 0) throw new TypeError("No data object provided to postData().")
const response = await fetch(baseURL + "bot/" + this.botId, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: this.apiKey
},
body: JSON.stringify(data)
}).catch(e => {
this.emit("post", e, data)
return e
})
if (response.status == 204) this.emit("post", void 0, data)
else {
const json = await response.json()
this.emit("post", Object.keys(json).length == 0 ? void 0 : json, data)
return json
}
}
postCommand(command = "", userId = void 0, guildId = void 0) {
if (!command || command.trim() == "") return new TypeError("No command name provided to postCommand().")
this.postCustom("command", command, userId, guildId)
}
postCustom(type = "", value1 = void 0, value2 = void 0, value3 = void 0) {
if (!type || type.trim() == "") return new TypeError("No custom graph type provided to postCustom().")
const body = {
type,
value1,
value2,
value3
}
if (this.autoposting) this.unpostedCustom.push(body)
else fetch(baseURL + "bot/" + this.botId + "/custom", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: this.apiKey
},
body: JSON.stringify(body)
})
}
}
module.exports = DisStat