Skip to content
This repository has been archived by the owner on Apr 24, 2024. It is now read-only.

Commit

Permalink
Add metrics tracking for messages in buildInfo function
Browse files Browse the repository at this point in the history
  • Loading branch information
MrlolDev committed Apr 5, 2024
1 parent 2f66b92 commit 5b7086c
Show file tree
Hide file tree
Showing 3 changed files with 284 additions and 185 deletions.
9 changes: 8 additions & 1 deletion src/bot/commands/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { NoCooldown, buttonInfo, createCommand } from "../config/setup.js";
import { gatewayConfig } from "../index.js";
import { OptionResolver } from "../handlers/OptionResolver.js";
import { Environment } from "../../types/other.js";
import { env } from "../utils/db.js";
import { env, getCache, setCache } from "../utils/db.js";
import { LOADING_INDICATORS } from "../../types/models/users.js";
import { CHAT_MODELS } from "../models/index.js";
import EventEmitter from "events";
Expand Down Expand Up @@ -189,6 +189,13 @@ async function buildInfo(
}
try {
const event = await model.run(bot.api, data);
let previousMetrics: any = (await getCache("metrics_shapes")) || {
users: [],
guilds: [],
messages: 0,
};
previousMetrics.messages++;
await setCache("metrics_shapes", previousMetrics);

if (!event || !(event instanceof EventEmitter)) {
return await edit({
Expand Down
247 changes: 149 additions & 98 deletions src/bot/events/interactioncreate.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {
BigString,
Bot,
EventHandlers,
Interaction,
InteractionResponse,
InteractionResponseTypes,
InteractionTypes,
MessageComponentTypes,
MessageFlags,
logger,
BigString,
Bot,
EventHandlers,
Interaction,
InteractionResponse,
InteractionResponseTypes,
InteractionTypes,
MessageComponentTypes,
MessageFlags,
logger,
} from "@discordeno/bot";
import { Environment } from "../../types/other.js";
import { NoCooldown } from "../config/setup.js";
Expand All @@ -17,115 +17,166 @@ import { buttons, commands } from "../index.js";
import { MakeRequired } from "../types/bot.js";
import { Command } from "../types/command.js";
import { checkCooldown } from "../utils/cooldown.js";
import { env, premium, voted } from "../utils/db.js";

export const interactionCreate: EventHandlers["interactionCreate"] = async (interaction) => {
switch (interaction.type) {
case InteractionTypes.ApplicationCommand:
if (!interaction.data) return;
handleCommand(interaction as MakeRequired<Interaction, "data">);
break;
case InteractionTypes.MessageComponent:
if (!interaction.data) return;
if (!interaction.data.customId) return;
switch (interaction.data.componentType) {
case MessageComponentTypes.Button:
handleButton(interaction as MakeRequired<Interaction, "data">);
case MessageComponentTypes.SelectMenu:
handleButton(interaction as MakeRequired<Interaction, "data">);
}
}
import { env, getCache, premium, setCache, voted } from "../utils/db.js";

export const interactionCreate: EventHandlers["interactionCreate"] = async (
interaction
) => {
switch (interaction.type) {
case InteractionTypes.ApplicationCommand:
if (!interaction.data) return;
handleCommand(interaction as MakeRequired<Interaction, "data">);
break;
case InteractionTypes.MessageComponent:
if (!interaction.data) return;
if (!interaction.data.customId) return;
switch (interaction.data.componentType) {
case MessageComponentTypes.Button:
handleButton(interaction as MakeRequired<Interaction, "data">);
case MessageComponentTypes.SelectMenu:
handleButton(interaction as MakeRequired<Interaction, "data">);
}
}
};

export async function handleCommand(interaction: MakeRequired<Interaction, "data">) {
const cmd = commands.get(interaction.data.name);

if (!cmd) {
return logger.error("Command not found (why is the command registered...)");
}

const environment = await env(interaction.user.id.toString(), interaction.guildId?.toString());
if (!environment) return;
const prem = await premium(environment);

await interaction.defer(cmd.isPrivate ?? false);

if (!(await manageCooldown(interaction, environment, cmd))) return;

const options = new OptionResolver(interaction.data.options ?? [], interaction.data.resolved!);

await cmd.interaction({ interaction, options, env: environment, premium: prem }).catch((err) => errorCallback(interaction, err));
export async function handleCommand(
interaction: MakeRequired<Interaction, "data">
) {
const cmd = commands.get(interaction.data.name);

if (!cmd) {
return logger.error("Command not found (why is the command registered...)");
}

const environment = await env(
interaction.user.id.toString(),
interaction.guildId?.toString()
);
if (!environment) return;
const prem = await premium(environment);

await interaction.defer(cmd.isPrivate ?? false);

if (!(await manageCooldown(interaction, environment, cmd))) return;

const options = new OptionResolver(
interaction.data.options ?? [],
interaction.data.resolved!
);
let previousMetrics: any = (await getCache("metrics_shapes")) || {
users: [],
guilds: [],
messages: 0,
};
let userIsThere = previousMetrics?.users.find(
(u: string) => u === interaction.user.id
);
if (!userIsThere) {
previousMetrics?.users.push(interaction.user.id);
}
let guildIsThere = previousMetrics?.guilds.find(
(g: string) => g === interaction.guildId
);
if (!guildIsThere) {
previousMetrics?.guilds.push(interaction.guildId);
}
await setCache("metrics_shapes", previousMetrics);
await cmd
.interaction({ interaction, options, env: environment, premium: prem })
.catch((err) => errorCallback(interaction, err));
}

export async function handleButton(interaction: MakeRequired<Interaction, "data">) {
const name = interaction.data.customId!.split("_");
const button = buttons.get(name.shift()!);
if (!button) {
return logger.error("ButtonResponse not found (why this button was sent...)");
}
let deferType = button.deferType;
if (button.id === "settings" && interaction.data.values?.length) {
deferType = InteractionResponseTypes.DeferredUpdateMessage;
}
await deferInteraction(interaction.bot, interaction.id, interaction.token, deferType, button.isPrivate);
interaction.acknowledged = true;
const args = name.reduce((prev, acc, i) => {
prev[button.args[i]] = acc;
return prev;
}, {} as Record<string, string>);

await button.run(interaction, args);
export async function handleButton(
interaction: MakeRequired<Interaction, "data">
) {
const name = interaction.data.customId!.split("_");
const button = buttons.get(name.shift()!);
if (!button) {
return logger.error(
"ButtonResponse not found (why this button was sent...)"
);
}
let deferType = button.deferType;
if (button.id === "settings" && interaction.data.values?.length) {
deferType = InteractionResponseTypes.DeferredUpdateMessage;
}
await deferInteraction(
interaction.bot,
interaction.id,
interaction.token,
deferType,
button.isPrivate
);
interaction.acknowledged = true;
const args = name.reduce(
(prev, acc, i) => {
prev[button.args[i]] = acc;
return prev;
},
{} as Record<string, string>
);

await button.run(interaction, args);
}

export async function checkStatus(environment: Environment) {
let status: keyof typeof NoCooldown | "plan" = "user";
let status: keyof typeof NoCooldown | "plan" = "user";

const hasVote = voted(environment.user);
const hasVote = voted(environment.user);

if (hasVote) status = "voter";
if (hasVote) status = "voter";

const prem = await premium(environment);
if (prem) status = prem.type;
const prem = await premium(environment);
if (prem) status = prem.type;

return status;
return status;
}

export function errorCallback(interaction: Interaction, err: NonNullable<unknown>) {
interaction.bot.logger.error(`There was an error trying to execute the command ${interaction.data?.name}`);
interaction.bot.logger.error("A detailed walkthrough is provided below.");
interaction.bot.logger.error(err);
export function errorCallback(
interaction: Interaction,
err: NonNullable<unknown>
) {
interaction.bot.logger.error(
`There was an error trying to execute the command ${interaction.data?.name}`
);
interaction.bot.logger.error("A detailed walkthrough is provided below.");
interaction.bot.logger.error(err);
}

export async function manageCooldown(interaction: Interaction, environment: Environment, cmd: Command) {
const status = await checkStatus(environment);
if (status === "plan") return true;
export async function manageCooldown(
interaction: Interaction,
environment: Environment,
cmd: Command
) {
const status = await checkStatus(environment);
if (status === "plan") return true;

const hasCooldown = await checkCooldown(interaction.user.id, cmd, status);
const hasCooldown = await checkCooldown(interaction.user.id, cmd, status);

if (hasCooldown) {
await interaction.edit(hasCooldown);
return;
}
if (hasCooldown) {
await interaction.edit(hasCooldown);
return;
}

return true;
return true;
}

// discordeno for no reason has a bad handle about defers
export async function deferInteraction(
bot: Bot,
id: BigString,
token: string,
type:
| InteractionResponseTypes.DeferredChannelMessageWithSource
| InteractionResponseTypes.DeferredUpdateMessage = InteractionResponseTypes.DeferredChannelMessageWithSource,
isPrivate = false,
bot: Bot,
id: BigString,
token: string,
type:
| InteractionResponseTypes.DeferredChannelMessageWithSource
| InteractionResponseTypes.DeferredUpdateMessage = InteractionResponseTypes.DeferredChannelMessageWithSource,
isPrivate = false
) {
const data: Partial<InteractionResponse["data"]> = {};
if (isPrivate) data.flags = MessageFlags.Ephemeral;
return await bot.rest.sendInteractionResponse(id, token, {
type: type,
data: {
flags: isPrivate ? 64 : undefined,
},
});
const data: Partial<InteractionResponse["data"]> = {};
if (isPrivate) data.flags = MessageFlags.Ephemeral;
return await bot.rest.sendInteractionResponse(id, token, {
type: type,
data: {
flags: isPrivate ? 64 : undefined,
},
});
}
Loading

0 comments on commit 5b7086c

Please sign in to comment.