diff --git a/.bruno/Authenticated/General Utility/Bot Statistics.bru b/.bruno/Authenticated/General Utility/Bot Statistics.bru new file mode 100644 index 0000000..724b963 --- /dev/null +++ b/.bruno/Authenticated/General Utility/Bot Statistics.bru @@ -0,0 +1,11 @@ +meta { + name: Bot Statistics + type: http + seq: 2 +} + +get { + url: http://localhost:8166/api/stats + body: none + auth: inherit +} diff --git a/src/api.ts b/src/api.ts index 0021394..0e76834 100644 --- a/src/api.ts +++ b/src/api.ts @@ -102,6 +102,9 @@ const start = () => { case '/ping': case '/ping/': return endpoints.get.apiPing(); + case '/stats': + case '/stats/': + return endpoints.get.apiStats(); case '/key': case '/key/': return endpoints.get.apiKeyAdmin(query, apiUserid); diff --git a/src/endpoints/_index.ts b/src/endpoints/_index.ts index a992e36..f9c38f5 100644 --- a/src/endpoints/_index.ts +++ b/src/endpoints/_index.ts @@ -5,6 +5,7 @@ import { apiKey } from 'endpoints/gets/apiKey.ts'; import { apiKeyAdmin } from 'endpoints/gets/apiKeyAdmin.ts'; import { apiPing } from 'endpoints/gets/apiPing.ts'; import { apiRoll } from 'endpoints/gets/apiRoll.ts'; +import { apiStats } from 'endpoints/gets/apiStats.ts'; import { generateWebView } from 'endpoints/gets/webView.ts'; import { heatmapPng } from 'endpoints/gets/heatmapPng.ts'; @@ -24,6 +25,7 @@ export default { apiKeyAdmin, apiPing, apiRoll, + apiStats, generateWebView, heatmapPng, }, diff --git a/src/endpoints/gets/apiStats.ts b/src/endpoints/gets/apiStats.ts new file mode 100644 index 0000000..3ce81c9 --- /dev/null +++ b/src/endpoints/gets/apiStats.ts @@ -0,0 +1,44 @@ +import { cache, cacheHandlers } from '@discordeno'; +import { STATUS_CODE, STATUS_TEXT } from '@std/http/status'; + +import { basicReducer } from 'artigen/utils/reducers.ts'; + +import dbClient from 'db/client.ts'; + +import stdResponses from 'endpoints/stdResponses.ts'; + +import utils from 'utils/utils.ts'; + +export const apiStats = async (): Promise => { + const headers = new Headers(); + headers.append('Content-Type', 'text/json'); + + const memberCount = cache.guilds + .array() + .map((guild) => guild.memberCount) + .reduce(basicReducer); + + const cachedGuilds = await cacheHandlers.size('guilds'); + + const rollQuery = await dbClient + .query(`SELECT count, hourlyRate FROM command_cnt WHERE command = "roll";`) + .catch((e) => utils.commonLoggers.dbError('stats.ts:23', 'query', e)); + const rollCount = BigInt(rollQuery[0].count ?? '0'); + + if (!rollCount) { + return stdResponses.InternalServerError(''); + } + + return new Response( + JSON.stringify({ + guildCount: cachedGuilds + cache.dispatchedGuildIds.size, + memberCount, + rollCount, + }), + { + status: STATUS_CODE.OK, + statusText: STATUS_TEXT[STATUS_CODE.OK], + headers, + } + ); +};