diff --git a/bun.lockb b/bun.lockb index 95e0258..0dfbcb6 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 09391f7..e500e56 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "dev": "bun --watch src/index.ts" }, "devDependencies": { - "@types/bun": "latest" + "@types/bun": "^1.1.14", + "drizzle-kit": "^0.30.1" }, "peerDependencies": { "typescript": "^5.0.0" @@ -15,6 +16,8 @@ "@discordjs/rest": "^2.4.0", "cron": "^3.3.1", "discord.js": "^14.16.3", + "dotenv": "^16.4.7", + "drizzle-orm": "^0.38.3", "zod": "^3.24.1" } } \ No newline at end of file diff --git a/process.env b/process.env new file mode 100644 index 0000000..d7e2499 --- /dev/null +++ b/process.env @@ -0,0 +1 @@ +DB_FILE_NAME=mydb.sqlite diff --git a/src/services/drink.service.ts b/src/actions/drink/drink.service.ts similarity index 100% rename from src/services/drink.service.ts rename to src/actions/drink/drink.service.ts diff --git a/src/tasks/drink.task.ts b/src/actions/drink/drink.task.ts similarity index 100% rename from src/tasks/drink.task.ts rename to src/actions/drink/drink.task.ts diff --git a/src/actions/greeting/greeting.components.ts b/src/actions/greeting/greeting.components.ts new file mode 100644 index 0000000..89dacf9 --- /dev/null +++ b/src/actions/greeting/greeting.components.ts @@ -0,0 +1,2 @@ +export const greetContent = ["HALLOOOO", "guten morgen! ich hoffe es geht euch gut <3"]; +export const sleepContent = ["gute nacht! ich muss jetzt schlafen gehen :c", "zzzzZZ..", "*schnarch*"]; diff --git a/src/services/greeting.service.ts b/src/actions/greeting/greeting.service.ts similarity index 66% rename from src/services/greeting.service.ts rename to src/actions/greeting/greeting.service.ts index e800ab6..b2f411d 100644 --- a/src/services/greeting.service.ts +++ b/src/actions/greeting/greeting.service.ts @@ -1,17 +1,9 @@ import config from "config"; import client from "lib/client"; import { getRandomInt } from "lib/utils"; +import { greetContent, sleepContent } from "./greeting.components.ts"; export class GreetingService { - private greetContent = ["HALLOOOO"] as const; - private sleepContent = ["zzzzZZ..", "*schnarch*"] as const; - getContent(asleep: boolean) { - if (asleep) { - return this.sleepContent[getRandomInt(0, this.sleepContent.length - 1)]; - } - - return this.greetContent[getRandomInt(0, this.greetContent.length - 1)]; - } async greet() { const channels = client.channels; @@ -19,7 +11,7 @@ export class GreetingService { const channel = channels.cache.get(config.discord.channelId); if (channel?.isTextBased && channel?.isSendable()) { - await channel.send({ content: "HALLOOOO" }); + await channel.send({ content: this.getContent(false) }); } } @@ -32,4 +24,11 @@ export class GreetingService { await channel.send({ content: this.getContent(true) }); } } + + getContent(asleep: boolean) { + if (asleep) { + return sleepContent[getRandomInt(0, sleepContent.length - 1)]; + } + return greetContent[getRandomInt(0, greetContent.length - 1)]; + } } diff --git a/src/actions/greeting/greeting.task.ts b/src/actions/greeting/greeting.task.ts new file mode 100644 index 0000000..38a42a0 --- /dev/null +++ b/src/actions/greeting/greeting.task.ts @@ -0,0 +1,26 @@ +import { CronJob } from "cron"; +import { GreetingService } from "actions/greeting/greeting.service"; + +const greetingService = new GreetingService(); + +new CronJob( + "0 30 6 * * *", // cronTime + async () => { + console.log("good morning"); + await greetingService.greet(); + }, // onTick + null, // onComplete + true, // start + "Europe/Berlin", // timeZone +); + +new CronJob( + "0 30 22 * * *", + async () => { + console.log("good night"); + await greetingService.sleep(); + }, + null, + true, + "Europe/Berlin", +); \ No newline at end of file diff --git a/src/actions/medication/medication.components.ts b/src/actions/medication/medication.components.ts new file mode 100644 index 0000000..ef4c52d --- /dev/null +++ b/src/actions/medication/medication.components.ts @@ -0,0 +1,10 @@ +import { ButtonBuilder, ButtonStyle } from "discord.js"; + +export const yesButton = new ButtonBuilder() + .setCustomId("yesMedication") + .setLabel("ja") + .setStyle(ButtonStyle.Primary); +export const noButton = new ButtonBuilder() + .setCustomId("noMedication") + .setLabel("noch nicht") + .setStyle(ButtonStyle.Secondary); diff --git a/src/actions/medication/medication.service.ts b/src/actions/medication/medication.service.ts new file mode 100644 index 0000000..7abab37 --- /dev/null +++ b/src/actions/medication/medication.service.ts @@ -0,0 +1,94 @@ +import { CronJob } from "cron"; +import { getRandomInt } from "lib/utils"; +import config from "config"; +import client from "lib/client"; +import { + ActionRowBuilder, + ButtonBuilder, + ButtonStyle, + type CacheType, + type Interaction, +} from "discord.js"; +import { yesButton, noButton } from "./medication.components"; + +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.channelId); + + // 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? :)", components: [row as any] }); + } + + } + + getMedication() { + throw new Error("Method not implemented."); + } + + 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) { + const result = this.setMedication(); + + const yesButton = new ButtonBuilder() + .setCustomId("yesMedication") + .setLabel("ja") + .setStyle(ButtonStyle.Primary); + const noButton = new ButtonBuilder() + .setCustomId("noMedication") + .setLabel("noch nicht") + .setStyle(ButtonStyle.Secondary); + + const row = new ActionRowBuilder().addComponents(yesButton); + row.addComponents(noButton); + + if (interaction.isChatInputCommand()) { + await interaction.reply({ + content: result.reply, + // biome-ignore lint/suspicious/noExplicitAny: + components: [row as any], + }); + } else if (interaction.isButton()) { + console.log("button interaction"); + if (interaction.customId == "yesMedication") { + interaction.reply({ + content: "das hast du toll gemacht <3 mach weiter so :3", + }); + } else if (interaction.customId == "noMedication") { + interaction.reply({ + content: "das passiert mal... aber versuch sie heute noch zu nehmen, oki? :)", + }); + } + + } + } +} \ No newline at end of file diff --git a/src/actions/medication/medication.task.ts b/src/actions/medication/medication.task.ts new file mode 100644 index 0000000..cff5e6f --- /dev/null +++ b/src/actions/medication/medication.task.ts @@ -0,0 +1,15 @@ +import { CronJob } from "cron"; +import { MedicationService } from "actions/medication/medication.service"; + +const medicationService = new MedicationService(); + +new CronJob( + "0 0 19 * * *", // cronTime + async () => { + console.log("askMedication()"); + await medicationService.askMedication(); + }, // onTick + null, // onComplete + true, // start + "Europe/Berlin", // timeZone +); \ No newline at end of file diff --git a/src/services/water-me.service.ts b/src/actions/waterMe/waterMe.service.ts similarity index 100% rename from src/services/water-me.service.ts rename to src/actions/waterMe/waterMe.service.ts diff --git a/src/tasks/water-me.task.ts b/src/actions/waterMe/waterMe.task.ts similarity index 84% rename from src/tasks/water-me.task.ts rename to src/actions/waterMe/waterMe.task.ts index 73b8e8a..62e1dc6 100644 --- a/src/tasks/water-me.task.ts +++ b/src/actions/waterMe/waterMe.task.ts @@ -1,5 +1,5 @@ import { CronJob } from "cron"; -import { WaterMeService } from "services/water-me.service"; +import { WaterMeService } from "actions/waterMe/waterMe.service"; const waterMeService = new WaterMeService(); diff --git a/src/components/commands.component.ts b/src/components/commands.component.ts index e7f16c7..cc0e802 100644 --- a/src/components/commands.component.ts +++ b/src/components/commands.component.ts @@ -1,14 +1,18 @@ import { SlashCommandBuilder } from "discord.js"; import { z } from "zod"; -export const Commands = z.enum(["water-me"]); +export const Commands = z.enum(["giessen", "medikamente"]); export type CommandsType = z.output; export default function getCommands() { const commands = [ new SlashCommandBuilder() - .setName(Commands.Enum["water-me"]) + .setName(Commands.Enum.giessen) .setDescription("giess mich mit etwas wasser :3"), + + new SlashCommandBuilder() + .setName(Commands.Enum.medikamente) + .setDescription("ich erinnere dich gerne daran, deine medikamente zu nehmen! :)"), ].map((command) => command.toJSON()); return commands; diff --git a/src/controllers/discord.controller.ts b/src/controllers/discord.controller.ts index 507f297..d926b09 100644 --- a/src/controllers/discord.controller.ts +++ b/src/controllers/discord.controller.ts @@ -9,17 +9,20 @@ import type { import client from "lib/client"; import EventEmitter from "node:events"; import DiscordService from "services/discord.service"; -import { WaterMeService } from "services/water-me.service"; +import { WaterMeService } from "actions/waterMe/waterMe.service"; import config from "config"; +import { MedicationService } from "actions/medication/medication.service"; export default class DiscordController extends EventEmitter { private discordService!: DiscordService; waterMeService: WaterMeService; + medicationService: MedicationService; constructor() { super(); this.discordService = new DiscordService(); this.waterMeService = new WaterMeService(); + this.medicationService = new MedicationService(); // log when running client.once("ready", async () => { console.log("hello :)"); @@ -64,6 +67,9 @@ export default class DiscordController extends EventEmitter { if (customId === "moreWater") { await this.waterMeService.handleInteraction(interaction); } + if (customId.toLowerCase().includes("medication")) { + await this.medicationService.handleInteraction(interaction); + } } async handleChatInputCommand( @@ -73,9 +79,12 @@ export default class DiscordController extends EventEmitter { // add commands switch (commandName) { - case Commands.Enum["water-me"]: + case Commands.Enum.giessen: await this.waterMeService.handleInteraction(interaction); return; + case Commands.Enum.medikamente: + await this.medicationService.handleInteraction(interaction); + return; default: break; } diff --git a/src/services/medication.service.ts b/src/db/schema.ts similarity index 100% rename from src/services/medication.service.ts rename to src/db/schema.ts diff --git a/src/index.ts b/src/index.ts index 059bbf8..84aedfe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,17 @@ -import "tasks/water-me.task"; -import "tasks/greeting.task"; -import "tasks/drink.task"; +import "actions/waterMe/waterMe.task"; +import "actions/greeting/greeting.task"; +import "actions/medication/medication.task" +import "actions/drink/drink.task"; import DiscordController from "controllers/discord.controller"; +import 'dotenv/config'; +import { drizzle } from 'drizzle-orm/bun-sqlite'; +import { Database } from 'bun:sqlite'; + +const sqlite = new Database(process.env.DB_FILE_NAME!); +const db = drizzle({ client: sqlite }); + + // = main file // bootstrap application diff --git a/src/tasks/greeting.task.ts b/src/tasks/greeting.task.ts deleted file mode 100644 index 1abd451..0000000 --- a/src/tasks/greeting.task.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { CronJob } from "cron"; -import { GreetingService } from "services/greeting.service"; - -const greetingService = new GreetingService(); - -new CronJob( - "0 */30 7-23 * * *", // cronTime - async () => { - console.log("called greeting"); - await greetingService.greet(); - }, // onTick - null, // onComplete - true, // start - "Europe/Berlin", // timeZone -); - -new CronJob( - "0 */30 0-6 * * *", // cronTime - async () => { - console.log("called greeting"); - await greetingService.sleep(); - }, // onTick - null, // onComplete - true, // start - "Europe/Berlin", // timeZone -); -// job.start() is optional here because of the fourth parameter set to true. diff --git a/src/tasks/medication.task.ts b/src/tasks/medication.task.ts deleted file mode 100644 index e69de29..0000000