import { CronJob } from "cron"; import { getRandomInt } from "lib/utils"; import config from "config"; import client from "lib/client"; import { ActionRowBuilder, ButtonBuilder, type ButtonInteraction, ButtonStyle, type ChatInputCommandInteraction, type ModalSubmitInteraction, type CacheType, type Interaction, } from "discord.js"; import { yesButton, noButton } from "./medication.components"; import { db } from "db"; import { usersTable } from "db/schema"; import { eq } from "drizzle-orm"; export class MedicationService { medication: string; tookMedication: boolean; constructor() { this.medication = ""; this.tookMedication = false; } async askMedication() { const channels = client.channels; const channel = channels.cache.get(config.discord.channelIdBot); // funkt noch nicht, beides const row = new ActionRowBuilder().addComponents(yesButton); row.addComponents(noButton); if ( channel?.isTextBased && channel?.isSendable() && this.tookMedication === false ) { await channel.send({ content: "hast du schon deine medis genommen? :)", // biome-ignore lint/suspicious/noExplicitAny: components: [row as any], }); } } getMedication() { // todo } setMedication() { const reply = this.getReply(); console.log("medication"); // this.medication = input von user:in hier rein; return { reply, }; } getReply() { return "medication reminder"; } async handleInteraction(interaction: Interaction) { if (interaction.isModalSubmit()) { await this.handleModalSubmit(interaction); return; } if (interaction.isChatInputCommand()) { await this.handleChatInputCommand(interaction); return; } if (interaction.isButton()) { await this.handleButton(interaction); return; } } async handleModalSubmit(interaction: ModalSubmitInteraction) { switch (interaction.customId) { default: break; } } async handleButton(interaction: ButtonInteraction) { console.log("button interaction"); const discordId = Number.parseInt(interaction.user.id); const name = interaction.user.displayName; console.log(`userid: ${discordId}`); try { const userId = await this.ensureUserExists(discordId, name); console.log(`userid: ${userId}`); const tookMedication = interaction.customId === "yesMedication"; await interaction.reply({ content: tookMedication ? "das hast du toll gemacht <3 mach weiter so :3" : "das passiert mal... aber versuch sie heute noch zu nehmen, oki? :)", }); await this.logMedication(userId, tookMedication); } catch (error) { console.error("error ensuring user exists:", error); await interaction.reply({ content: "es gab einen fehler beim verarbeiten deiner anfrage :( versuch es bitte spaeter nochmal, oki? c:", ephemeral: true, }); return; } } async handleChatInputCommand( interaction: ChatInputCommandInteraction, ) { const result = this.setMedication(); const row = new ActionRowBuilder().addComponents(yesButton); row.addComponents(noButton); await interaction.reply({ content: result.reply, // biome-ignore lint/suspicious/noExplicitAny: components: [row as any], }); } /**, um die Benutzerdaten in die Datenbank zu schreiben. * @param discordId unique user id * @param name name how the user wants to get called by avocadi * @param tookMedication if user took medication */ async logMedication(id: number, tookMedication: boolean) { try { await db .update(usersTable) .set({ took_medication_today: Number(tookMedication), }) .where(eq(usersTable.id, id)); /* await db.insert(usersTable).values({ name: name, discord_id: discordId, took_medication_today: Number(tookMedication), }); */ console.log(`user with id ${id} saved`); } catch (error) { console.error("error while saving in db:", error); } } async getNameByDiscordId(discordId: number): Promise { const result = await db .select({ name: usersTable.name, }) .from(usersTable) .where(eq(usersTable.discord_id, discordId)) .limit(1); if (result.length > 0) { console.log("user found"); return result[0].name; } console.log("name not found"); return ""; } async findUserIdByDiscordId(discordId: number): Promise { try { const result = await db .select({ id: usersTable.id, }) .from(usersTable) .where(eq(usersTable.discord_id, discordId)) .limit(1); if (result.length > 0) { console.log(`ID für Discord-ID ${discordId} gefunden: ${result[0].id}`); return result[0].id; } console.log(`no id for discordId ${discordId} found`); return null; } catch (error) { console.error( `error while calling id for discordId ${discordId}:`, error, ); return null; } } async ensureUserExists(discordId: number, name: string): Promise { try { const userId = await this.findUserIdByDiscordId(discordId); if (userId !== null) { console.log(`entry for discordID ${discordId} already exists`); return userId; } console.log( `found no entry for discordID ${discordId}. creating new entry`, ); const result = await db .insert(usersTable) .values({ name: name, discord_id: discordId, }) .onConflictDoNothing() .returning({ id: usersTable.id, }); if (result.length > 0) { const newUserId = result[0].id; console.log( `new user with discordId ${discordId} and name ${name} created. id: ${newUserId}`, ); return newUserId; } // check again if user is now existing const newUserId = await this.findUserIdByDiscordId(discordId); if (newUserId !== null) { console.log(`user created in parallel. fetched id: ${newUserId}`); return newUserId; } throw new Error(`creating a new user for discordId ${discordId} failed`); } catch (error) { console.error("error while creating or calling the user:", error); throw error; } } }