begin rewriting first services to be domain agnostic
more rewrites
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
"discord.js": "^14.16.3",
|
||||
"dotenv": "^16.4.7",
|
||||
"drizzle-orm": "^0.38.3",
|
||||
"tslog": "^4.10.2",
|
||||
"zod": "catalog:"
|
||||
},
|
||||
"trustedDependencies": [
|
||||
@@ -32,8 +33,17 @@
|
||||
"./db": "./dist/db/index.js",
|
||||
"./db/schema": "./dist/db/schema.js",
|
||||
"./entities/channels/channels.schema": "./dist/entities/channels/channels.schema.js",
|
||||
"./entities/commands/commands.entity": "./dist/entities/commands/commands.entity.js",
|
||||
"./entities/commands/commands.schema": "./dist/entities/commands/commands.schema.js",
|
||||
"./entities/interactions/interactions.schema": "./dist/entities/interactions/interactions.schema.js",
|
||||
"./entities/messages/messages.service": "./dist/entities/messages/messages.service.js",
|
||||
"./entities/roles/roles.schema": "./dist/entities/roles/roles.schema.js",
|
||||
"./lib/client": "./dist/lib/client.js",
|
||||
"./entities/roles/roles.service": "./dist/entities/roles/roles.service.js",
|
||||
"./features/greeting/greeting.service": "./dist/features/greeting/greeting.service.js",
|
||||
"./features/text-based-feature/text-based-feature": "./dist/features/text-based-feature/text-based-feature.js",
|
||||
"./features/text-based-feature/text-based-feature.schema": "./dist/features/text-based-feature/text-based-feature.schema.js",
|
||||
"./features/water-me/water-me.service": "./dist/features/water-me/water-me.service.js",
|
||||
"./lib/logger": "./dist/lib/logger.js",
|
||||
"./lib/utils": "./dist/lib/utils.js",
|
||||
"./lib/utils.test": "./dist/lib/utils.test.js",
|
||||
"./package.json": "./package.json"
|
||||
|
||||
@@ -1,104 +1,110 @@
|
||||
import config from "config";
|
||||
import {
|
||||
type CacheType,
|
||||
Client,
|
||||
EmbedBuilder,
|
||||
type GuildMember,
|
||||
type Interaction,
|
||||
type Message,
|
||||
type OmitPartialGroupDMChannel,
|
||||
} from "discord.js";
|
||||
import client from "lib/client";
|
||||
import { getRandomInt } from "lib/utils";
|
||||
import { dmWelcomeContent, dmAcceptedContent } from "./dm.components.ts";
|
||||
import {
|
||||
Client,
|
||||
EmbedBuilder,
|
||||
type Message,
|
||||
type CacheType,
|
||||
type GuildMember,
|
||||
type Interaction,
|
||||
type OmitPartialGroupDMChannel,
|
||||
} from "discord.js";
|
||||
import { dmAcceptedContent, dmWelcomeContent } from "./dm.components.ts";
|
||||
|
||||
export class DmService {
|
||||
async handleInteraction(interaction: Interaction<CacheType>) {
|
||||
// todo
|
||||
}
|
||||
|
||||
async handleInteraction(interaction: Interaction<CacheType>) {
|
||||
// todo
|
||||
}
|
||||
async reminderPrivate(member: GuildMember) {
|
||||
console.log("reminder");
|
||||
try {
|
||||
const content = `hey, kleine erinnerung :)\nbitte stelle dich auf <#${config.discord.channelIdIntroduction}> vor, damit du alle kanaele ansehen und nutzen kannst! <3`;
|
||||
await client.users.send(member, content);
|
||||
} catch (error) {
|
||||
const channels = client.channels;
|
||||
const channel = channels.cache.get(config.discord.channelIdLog);
|
||||
if (channel?.isTextBased() && channel?.isSendable()) {
|
||||
await channel.send(
|
||||
`konnte keine private nachricht an <@${member.user.id}> senden`,
|
||||
);
|
||||
}
|
||||
console.error("error while sending a welcome msg:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async reminderPrivate(member: GuildMember) {
|
||||
console.log("reminder");
|
||||
try {
|
||||
const content = `hey, kleine erinnerung :)\nbitte stelle dich auf <#${config.discord.channelIdIntroduction}> vor, damit du alle kanaele ansehen und nutzen kannst! <3`
|
||||
await client.users.send(member, content);
|
||||
} catch (error) {
|
||||
const channels = client.channels;
|
||||
const channel = channels.cache.get(config.discord.channelIdLog);
|
||||
if (channel?.isTextBased() && channel?.isSendable()) {
|
||||
await channel.send(`konnte keine private nachricht an <@${member.user.id}> senden`);
|
||||
}
|
||||
console.error("error while sending a welcome msg:", error);
|
||||
}
|
||||
}
|
||||
async welcomePrivate(member: GuildMember) {
|
||||
console.log("welcome private");
|
||||
try {
|
||||
await client.users.send(member, dmWelcomeContent);
|
||||
} catch (error) {
|
||||
const channels = client.channels;
|
||||
const channel = channels.cache.get(config.discord.channelIdLog);
|
||||
if (channel?.isTextBased() && channel?.isSendable()) {
|
||||
await channel.send(
|
||||
`konnte keine private nachricht an <@${member.user.id}> senden`,
|
||||
);
|
||||
}
|
||||
console.error("error while sending a welcome msg:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async welcomePrivate(member: GuildMember) {
|
||||
console.log("welcome private");
|
||||
try {
|
||||
await client.users.send(member, dmWelcomeContent);
|
||||
} catch (error) {
|
||||
const channels = client.channels;
|
||||
const channel = channels.cache.get(config.discord.channelIdLog);
|
||||
if (channel?.isTextBased() && channel?.isSendable()) {
|
||||
await channel.send(`konnte keine private nachricht an <@${member.user.id}> senden`);
|
||||
}
|
||||
console.error("error while sending a welcome msg:", error);
|
||||
}
|
||||
}
|
||||
async forward(message: OmitPartialGroupDMChannel<Message<boolean>>) {
|
||||
if (message.channel.isDMBased()) {
|
||||
const author = message.author.id;
|
||||
const recipient = message.channel.recipient?.id;
|
||||
console.log("forward message");
|
||||
let context = "";
|
||||
|
||||
async forward(message: OmitPartialGroupDMChannel<Message<boolean>>) {
|
||||
if (message.channel.isDMBased()) {
|
||||
const author = message.author.id;
|
||||
const recipient = message.channel.recipient?.id;
|
||||
console.log("forward message");
|
||||
let context = "";
|
||||
if (message.author.bot) {
|
||||
context = `<@${author}> hat an <@${recipient}> geschrieben:\n"${message.content}"`;
|
||||
} else {
|
||||
context = `<@${author}> hat geschrieben:\n"${message.content}"`;
|
||||
}
|
||||
|
||||
if (message.author.bot) {
|
||||
context = `<@${author}> hat an <@${recipient}> geschrieben:\n"${message.content}"`;
|
||||
}
|
||||
else {
|
||||
context = `<@${author}> hat geschrieben:\n"${message.content}"`;
|
||||
}
|
||||
try {
|
||||
const channels = client.channels;
|
||||
const channel = channels.cache.get(config.discord.channelIdLog);
|
||||
if (channel?.isTextBased() && channel?.isSendable()) {
|
||||
await channel.send(context);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("error while forwarding a msg:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const channels = client.channels;
|
||||
const channel = channels.cache.get(config.discord.channelIdLog);
|
||||
if (channel?.isTextBased() && channel?.isSendable()) {
|
||||
await channel.send(context);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("error while forwarding a msg:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
async acceptDm(member: GuildMember) {
|
||||
console.log("accept dm");
|
||||
try {
|
||||
await client.users.send(member, dmAcceptedContent);
|
||||
} catch (error) {
|
||||
const channels = client.channels;
|
||||
const channel = channels.cache.get(config.discord.channelIdLog);
|
||||
if (channel?.isTextBased() && channel?.isSendable()) {
|
||||
await channel.send(
|
||||
`konnte keine private nachricht an <@${member.user.id}> senden`,
|
||||
);
|
||||
}
|
||||
console.error("error while sending a accept msg:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async acceptDm(member: GuildMember) {
|
||||
console.log("accept dm");
|
||||
try {
|
||||
await client.users.send(member, dmAcceptedContent);
|
||||
} catch (error) {
|
||||
const channels = client.channels;
|
||||
const channel = channels.cache.get(config.discord.channelIdLog);
|
||||
if (channel?.isTextBased() && channel?.isSendable()) {
|
||||
await channel.send(`konnte keine private nachricht an <@${member.user.id}> senden`);
|
||||
}
|
||||
console.error("error while sending a accept msg:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async roleMentionDm(member: GuildMember, add: boolean) {
|
||||
console.log("rolementionadd dm");
|
||||
try {
|
||||
const contentRoleMentionDm = `du hast die rolle **streber:in** erfolgreich ** *${(add ? "zugeteilt" : "entfernt")}* ** bekommen :3 <#${config.discord.channelIdOffTopic}> <:avocadi_cute:1321893797138923602>`;
|
||||
client.users.send(member, contentRoleMentionDm);
|
||||
} catch (error) {
|
||||
const channels = client.channels;
|
||||
const channel = channels.cache.get(config.discord.channelIdLog);
|
||||
if (channel?.isTextBased() && channel?.isSendable()) {
|
||||
await channel.send(`konnte keine private nachricht an <@${member.user.id}> senden`);
|
||||
}
|
||||
console.error("error while sending a accept msg:", error);
|
||||
}
|
||||
}
|
||||
async roleMentionDm(member: GuildMember, add: boolean) {
|
||||
console.log("rolementionadd dm");
|
||||
try {
|
||||
const contentRoleMentionDm = `du hast die rolle **streber:in** erfolgreich ** *${add ? "zugeteilt" : "entfernt"}* ** bekommen :3 <#${config.discord.channelIdOffTopic}> <:avocadi_cute:1321893797138923602>`;
|
||||
client.users.send(member, contentRoleMentionDm);
|
||||
} catch (error) {
|
||||
const channels = client.channels;
|
||||
const channel = channels.cache.get(config.discord.channelIdLog);
|
||||
if (channel?.isTextBased() && channel?.isSendable()) {
|
||||
await channel.send(
|
||||
`konnte keine private nachricht an <@${member.user.id}> senden`,
|
||||
);
|
||||
}
|
||||
console.error("error while sending a accept msg:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,21 @@
|
||||
import { DmService } from "actions/dm/dm.service.ts";
|
||||
import { Commands, type CommandsType } from "commands/index.ts";
|
||||
import config from "config";
|
||||
import {
|
||||
type CacheType,
|
||||
type ChatInputCommandInteraction,
|
||||
type GuildMember,
|
||||
GuildMemberRoleManager,
|
||||
type Interaction,
|
||||
} from "discord.js";
|
||||
import client from "lib/client";
|
||||
import { getRandomInt } from "lib/utils";
|
||||
import { checkPermission } from "permissions/index.ts";
|
||||
import {
|
||||
getWelcomeContent,
|
||||
greetContent,
|
||||
sleepContent,
|
||||
} from "./greeting.components.ts";
|
||||
import {
|
||||
type ChatInputCommandInteraction,
|
||||
Client,
|
||||
EmbedBuilder,
|
||||
type CacheType,
|
||||
type GuildMember,
|
||||
type Interaction,
|
||||
GuildMemberRoleManager,
|
||||
type APIInteractionGuildMember,
|
||||
} from "discord.js";
|
||||
import { DmService } from "actions/dm/dm.service.ts";
|
||||
import { Commands, type CommandsType } from "commands/index.ts";
|
||||
import { checkPermission } from "permissions/index.ts";
|
||||
|
||||
export class GreetingService {
|
||||
dmService: DmService;
|
||||
@@ -27,17 +24,15 @@ export class GreetingService {
|
||||
this.dmService = new DmService();
|
||||
}
|
||||
|
||||
async handleInteraction(
|
||||
interaction: Interaction<CacheType>
|
||||
) {
|
||||
|
||||
async handleInteraction(interaction: Interaction<CacheType>) {
|
||||
if (interaction.isChatInputCommand()) {
|
||||
await this.handleChatInputCommand(interaction);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
async handleChatInputCommand(interaction: ChatInputCommandInteraction<CacheType>) {
|
||||
async handleChatInputCommand(
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
) {
|
||||
const commandName = interaction.commandName as CommandsType;
|
||||
switch (commandName) {
|
||||
case Commands.Enum.accept:
|
||||
@@ -72,9 +67,7 @@ export class GreetingService {
|
||||
}
|
||||
}
|
||||
|
||||
async acceptUser(
|
||||
interaction: ChatInputCommandInteraction<CacheType>
|
||||
) {
|
||||
async acceptUser(interaction: ChatInputCommandInteraction<CacheType>) {
|
||||
console.log("accept user");
|
||||
|
||||
// get the string option
|
||||
@@ -83,7 +76,7 @@ export class GreetingService {
|
||||
//console.log(input);
|
||||
|
||||
// permission check
|
||||
if (await checkPermission(interaction.member) !== true) {
|
||||
if ((await checkPermission(interaction.member)) !== true) {
|
||||
await interaction.reply({
|
||||
content: "du hast keine rechte fuer diesen befehl",
|
||||
ephemeral: true,
|
||||
@@ -108,7 +101,7 @@ export class GreetingService {
|
||||
const username = member.user.username;
|
||||
console.log(username);
|
||||
|
||||
if (await this.checkRole(member) === true) {
|
||||
if ((await this.checkRole(member)) === true) {
|
||||
await interaction.reply({
|
||||
content: `${member.user.username} hat die rolle *lernende:r* schon!`,
|
||||
ephemeral: true,
|
||||
@@ -192,8 +185,7 @@ export class GreetingService {
|
||||
return greetContent[getRandomInt(0, greetContent.length - 1)];
|
||||
}
|
||||
|
||||
async reminderCommand(
|
||||
interaction: ChatInputCommandInteraction<CacheType>) {
|
||||
async reminderCommand(interaction: ChatInputCommandInteraction<CacheType>) {
|
||||
console.log("remind user");
|
||||
|
||||
// get the string option
|
||||
@@ -203,7 +195,7 @@ export class GreetingService {
|
||||
|
||||
try {
|
||||
// permission check
|
||||
if (await checkPermission(interaction.member) !== true) {
|
||||
if ((await checkPermission(interaction.member)) !== true) {
|
||||
await interaction.reply({
|
||||
content: "du hast keine rechte fuer diesen befehl",
|
||||
ephemeral: true,
|
||||
@@ -227,7 +219,7 @@ export class GreetingService {
|
||||
const username = member.user.username;
|
||||
console.log(username);
|
||||
|
||||
if (await this.checkRole(member) === true) {
|
||||
if ((await this.checkRole(member)) === true) {
|
||||
await interaction.reply({
|
||||
content: `${member.user.username} hat die rolle *lernende:r* schon!`,
|
||||
ephemeral: true,
|
||||
@@ -252,9 +244,7 @@ export class GreetingService {
|
||||
}
|
||||
}
|
||||
|
||||
async welcomeCommand(
|
||||
interaction: ChatInputCommandInteraction<CacheType>
|
||||
) {
|
||||
async welcomeCommand(interaction: ChatInputCommandInteraction<CacheType>) {
|
||||
console.log("welcome user");
|
||||
|
||||
// get the string option
|
||||
@@ -275,7 +265,7 @@ export class GreetingService {
|
||||
return;
|
||||
}
|
||||
|
||||
if (await checkPermission(interaction.member) !== true) {
|
||||
if ((await checkPermission(interaction.member)) !== true) {
|
||||
await interaction.reply({
|
||||
content: "du hast keine rechte fuer diesen befehl",
|
||||
ephemeral: true,
|
||||
@@ -290,7 +280,7 @@ export class GreetingService {
|
||||
|
||||
const welcomeContent = getWelcomeContent(member);
|
||||
|
||||
if (await this.checkRole(member) === true) {
|
||||
if ((await this.checkRole(member)) === true) {
|
||||
await interaction.reply({
|
||||
content: `${member.user.username} wurde schon begruesst!`,
|
||||
ephemeral: true,
|
||||
@@ -306,7 +296,6 @@ export class GreetingService {
|
||||
}
|
||||
|
||||
await this.dmService.welcomePrivate(member);
|
||||
|
||||
} catch (error) {
|
||||
console.error("error while sending a welcome command msg:", error);
|
||||
}
|
||||
@@ -315,12 +304,10 @@ export class GreetingService {
|
||||
content: `erfolgreich welcome command: ${member.user.username}`,
|
||||
ephemeral: true,
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error("fehler bei welcome command", error);
|
||||
await interaction.reply({
|
||||
content:
|
||||
"fehler bei welcome command",
|
||||
content: "fehler bei welcome command",
|
||||
ephemeral: true,
|
||||
});
|
||||
}
|
||||
@@ -329,7 +316,10 @@ export class GreetingService {
|
||||
async checkRole(member: GuildMember) {
|
||||
let hasRole = false;
|
||||
if (member?.roles instanceof GuildMemberRoleManager) {
|
||||
if (member.roles.cache.has(config.discord.roleAdmin) || member.roles.cache.has(config.discord.roleMod)) {
|
||||
if (
|
||||
member.roles.cache.has(config.discord.roleAdmin) ||
|
||||
member.roles.cache.has(config.discord.roleMod)
|
||||
) {
|
||||
console.log("user has permission");
|
||||
hasRole = true;
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
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";
|
||||
|
||||
export class WaterMeService {
|
||||
waterLevel: number;
|
||||
|
||||
private thirsty = 3 as const;
|
||||
private enough = 10 as const;
|
||||
|
||||
constructor() {
|
||||
this.waterLevel = 0;
|
||||
}
|
||||
|
||||
getReply() {
|
||||
const thirstyReplies = [
|
||||
"... wow das wars schon??? ich brauche noch mehr wasser :(",
|
||||
"dankeeeee!!!! ich waer fast verdurstet :(((",
|
||||
"*roelpssssss*",
|
||||
];
|
||||
|
||||
const fullReplies = [
|
||||
"langsam reicht es :o",
|
||||
"poah, das hat gut getan",
|
||||
"das ist krass :3",
|
||||
];
|
||||
|
||||
const tooMuchReplies = [
|
||||
"ES REICHT!!!!",
|
||||
"bitte hoer auf, ich platze gleich :(",
|
||||
];
|
||||
|
||||
if (this.waterLevel <= this.thirsty) {
|
||||
return thirstyReplies[getRandomInt(0, thirstyReplies.length - 1)];
|
||||
}
|
||||
if (this.waterLevel > this.thirsty && this.waterLevel <= this.enough) {
|
||||
return fullReplies[getRandomInt(0, fullReplies.length - 1)];
|
||||
}
|
||||
if (this.waterLevel > this.enough) {
|
||||
return tooMuchReplies[getRandomInt(0, tooMuchReplies.length - 1)];
|
||||
}
|
||||
}
|
||||
|
||||
async isThirsty() {
|
||||
const channels = client.channels;
|
||||
|
||||
const channel = channels.cache.get(config.discord.channelIdBot);
|
||||
|
||||
if (
|
||||
channel?.isTextBased &&
|
||||
channel?.isSendable() &&
|
||||
this.waterLevel <= this.thirsty
|
||||
) {
|
||||
await channel.send({ content: "ich brauche wasser :(" });
|
||||
}
|
||||
}
|
||||
|
||||
waterMe() {
|
||||
const reply = this.getReply();
|
||||
|
||||
this.waterLevel++;
|
||||
console.log(this.waterLevel);
|
||||
|
||||
return {
|
||||
reply,
|
||||
};
|
||||
}
|
||||
|
||||
async handleInteraction(interaction: Interaction<CacheType>) {
|
||||
const result = this.waterMe();
|
||||
|
||||
const moreButton = new ButtonBuilder()
|
||||
.setCustomId("moreWater")
|
||||
.setLabel("mehr")
|
||||
.setStyle(ButtonStyle.Secondary);
|
||||
|
||||
const row = new ActionRowBuilder().addComponents(moreButton);
|
||||
|
||||
if (interaction.isChatInputCommand()) {
|
||||
await interaction.reply({
|
||||
content: result.reply,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
components: [row as any],
|
||||
});
|
||||
} else if (interaction.isButton()) {
|
||||
await interaction.reply({
|
||||
content: result.reply,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { CronJob } from "cron";
|
||||
import { WaterMeService } from "actions/waterMe/waterMe.service";
|
||||
|
||||
const waterMeService = new WaterMeService();
|
||||
/*
|
||||
new CronJob(
|
||||
"0 0 20 * * *", // cronTime
|
||||
async () => {
|
||||
console.log("isThirsty()");
|
||||
await waterMeService.isThirsty();
|
||||
}, // onTick
|
||||
null, // onComplete
|
||||
true, // start
|
||||
"Europe/Berlin", // timeZone
|
||||
);*/
|
||||
// job.start() is optional here because of the fourth parameter set to true.
|
||||
@@ -1,123 +0,0 @@
|
||||
import { SlashCommandBuilder, userMention } from "discord.js";
|
||||
import { z } from "zod";
|
||||
|
||||
export const Commands = z.enum(["giessen", "medikamente", "hilfe", "support", "kofi", "disboard", "discadia", "accept", "welcome", "embed", "message", "reminder", "version"]);
|
||||
|
||||
export const CommandsMeta: Record<z.output<typeof Commands>, { description: string }> = {
|
||||
giessen: {
|
||||
description: "giess mich mit etwas wasser :3"
|
||||
},
|
||||
medikamente: {
|
||||
description: "ich erinnere dich gerne daran, deine medikamente zu nehmen! :)"
|
||||
},
|
||||
hilfe: {
|
||||
description: "ich schreibe dir auf, was du alles mit mir machen kannst :)"
|
||||
},
|
||||
support: {
|
||||
description: "unterstuetze uns! link zu unserem ko-fi, disboard und discardia c:"
|
||||
},
|
||||
kofi: {
|
||||
description: "link zu unserem ko-fi (spendenportal):"
|
||||
},
|
||||
disboard: {
|
||||
description: "link zu disboard, hier kannst du uns bewerten!"
|
||||
},
|
||||
discadia: {
|
||||
description: "link zu discadia, hier kannst du fuer uns voten!"
|
||||
},
|
||||
accept: {
|
||||
description: "admin use only"
|
||||
},
|
||||
welcome: {
|
||||
description: "admin use only"
|
||||
},
|
||||
embed: {
|
||||
description: "admin use only"
|
||||
},
|
||||
message: {
|
||||
description: "admin use only"
|
||||
},
|
||||
reminder: {
|
||||
description: "admin use only"
|
||||
},
|
||||
version: {
|
||||
description: "admin use only"
|
||||
}
|
||||
}
|
||||
|
||||
export type CommandsType = z.output<typeof Commands>;
|
||||
|
||||
export default function getCommands() {
|
||||
const commands = [
|
||||
new SlashCommandBuilder()
|
||||
.setName(Commands.Enum.giessen)
|
||||
.setDescription(CommandsMeta.giessen.description),
|
||||
new SlashCommandBuilder()
|
||||
.setName(Commands.Enum.medikamente)
|
||||
.setDescription(CommandsMeta.medikamente.description),
|
||||
new SlashCommandBuilder()
|
||||
.setName(Commands.Enum.hilfe)
|
||||
.setDescription(CommandsMeta.hilfe.description),
|
||||
new SlashCommandBuilder()
|
||||
.setName(Commands.Enum.support)
|
||||
.setDescription(CommandsMeta.support.description),
|
||||
new SlashCommandBuilder()
|
||||
.setName(Commands.Enum.kofi)
|
||||
.setDescription(CommandsMeta.kofi.description),
|
||||
new SlashCommandBuilder()
|
||||
.setName(Commands.Enum.disboard)
|
||||
.setDescription(CommandsMeta.disboard.description),
|
||||
new SlashCommandBuilder()
|
||||
.setName(Commands.Enum.discadia)
|
||||
.setDescription(CommandsMeta.discadia.description),
|
||||
new SlashCommandBuilder()
|
||||
.setName(Commands.Enum.accept)
|
||||
.setDescription(CommandsMeta.accept.description)
|
||||
.addStringOption(option =>
|
||||
option.setName('input')
|
||||
.setDescription('input for bot')
|
||||
.setRequired(true)),
|
||||
new SlashCommandBuilder()
|
||||
.setName(Commands.Enum.welcome)
|
||||
.setDescription(CommandsMeta.welcome.description)
|
||||
.addStringOption(option =>
|
||||
option.setName('input')
|
||||
.setDescription('input for bot')
|
||||
.setRequired(true)),
|
||||
new SlashCommandBuilder()
|
||||
.setName(Commands.Enum.embed)
|
||||
.setDescription(CommandsMeta.embed.description)
|
||||
.addStringOption(option =>
|
||||
option.setName('title')
|
||||
.setDescription('title')
|
||||
.setRequired(true))
|
||||
.addStringOption(option =>
|
||||
option.setName('description')
|
||||
.setDescription('description')
|
||||
.setRequired(true))
|
||||
.addBooleanOption(option =>
|
||||
option.setName('timestamp')
|
||||
.setDescription('timestamp bool')
|
||||
.setRequired(false)),
|
||||
new SlashCommandBuilder()
|
||||
.setName(Commands.Enum.message)
|
||||
.setDescription(CommandsMeta.message.description)
|
||||
.addStringOption(option =>
|
||||
option.setName('input')
|
||||
.setDescription('input for bot')
|
||||
.setRequired(true)),
|
||||
new SlashCommandBuilder()
|
||||
.setName(Commands.Enum.reminder)
|
||||
.setDescription(CommandsMeta.reminder.description)
|
||||
.addStringOption(option =>
|
||||
option.setName('input')
|
||||
.setDescription('input for bot')
|
||||
.setRequired(true)),
|
||||
new SlashCommandBuilder()
|
||||
.setName(Commands.Enum.version)
|
||||
.setDescription(CommandsMeta.version.description),
|
||||
|
||||
].map((command) => command.toJSON());
|
||||
|
||||
return commands;
|
||||
}
|
||||
@@ -1,301 +0,0 @@
|
||||
import { Commands, type CommandsType } from "commands";
|
||||
import {
|
||||
ChannelType,
|
||||
Client,
|
||||
Events,
|
||||
IntentsBitField,
|
||||
type VoiceState,
|
||||
type ButtonInteraction,
|
||||
type CacheType,
|
||||
type ChatInputCommandInteraction,
|
||||
type Interaction,
|
||||
type ModalSubmitInteraction,
|
||||
ActivityType,
|
||||
type Channel,
|
||||
} from "discord.js";
|
||||
import client from "lib/client";
|
||||
import EventEmitter from "node:events";
|
||||
import DiscordService from "discord.service";
|
||||
import { WaterMeService } from "actions/waterMe/waterMe.service";
|
||||
import { MedicationService } from "actions/medication/medication.service";
|
||||
import { HelpService } from "actions/help/help.service";
|
||||
import { SupportService } from "actions/support/support.service";
|
||||
import { GreetingService } from "actions/greeting/greeting.service";
|
||||
import { ActivityService } from "actions/activity/activity.service";
|
||||
import { DmService } from "actions/dm/dm.service";
|
||||
import { CustomMessageService } from "actions/customMessage/customMessage.service";
|
||||
import { DynamicVChannelService } from "actions/dynamicVChannel/dynamicVChannel.service";
|
||||
import { DebugService } from "actions/debug/debug.service";
|
||||
import { ReactRolesService } from "actions/reactRole/reactRoles.service";
|
||||
import config from "config";
|
||||
|
||||
export default class DiscordController extends EventEmitter {
|
||||
private discordService: DiscordService;
|
||||
private waterMeService: WaterMeService;
|
||||
private greetingService: GreetingService;
|
||||
private medicationService: MedicationService;
|
||||
private helpService: HelpService;
|
||||
private supportService: SupportService;
|
||||
private activityService: ActivityService;
|
||||
private dmService: DmService;
|
||||
private customMessageService: CustomMessageService;
|
||||
private dynamicVChannelService: DynamicVChannelService;
|
||||
private debugService: DebugService;
|
||||
|
||||
private channelListeners = new Map();
|
||||
private reactRolesService: ReactRolesService;
|
||||
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
let channelListeners = new Map();
|
||||
this.discordService = new DiscordService();
|
||||
this.waterMeService = new WaterMeService();
|
||||
this.greetingService = new GreetingService();
|
||||
this.medicationService = new MedicationService();
|
||||
this.helpService = new HelpService();
|
||||
this.supportService = new SupportService();
|
||||
this.activityService = new ActivityService();
|
||||
this.dmService = new DmService();
|
||||
this.customMessageService = new CustomMessageService();
|
||||
this.dynamicVChannelService = new DynamicVChannelService();
|
||||
this.debugService = new DebugService();
|
||||
this.reactRolesService = new ReactRolesService();
|
||||
|
||||
client.on("messageReactionAdd", async (reaction, user) => {
|
||||
await this.reactRolesService.roleMention(reaction, user, true);
|
||||
});
|
||||
|
||||
client.on("messageReactionRemove", async (reaction, user) => {
|
||||
await this.reactRolesService.roleMention(reaction, user, false);
|
||||
});
|
||||
|
||||
// log when running
|
||||
client.once("ready", async () => {
|
||||
const channels = client.channels;
|
||||
const logChannel = channels.cache.get(config.discord.channelIdLog);
|
||||
|
||||
if (logChannel?.isTextBased() && logChannel?.isSendable()) {
|
||||
try {
|
||||
console.log("bot is online");
|
||||
await logChannel.send("wieder online!!!");
|
||||
} catch (error) {
|
||||
console.error("failed to send online message:", error);
|
||||
}
|
||||
} else {
|
||||
console.error("log channel is not valid or sendable.");
|
||||
}
|
||||
await this.setActivity(100);
|
||||
console.log("ready");
|
||||
});
|
||||
|
||||
process.on("exit", async () => {
|
||||
const channels = client.channels;
|
||||
const logChannel = channels.cache.get(config.discord.channelIdLog);
|
||||
await this.handleShutdown(logChannel);
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
process.on("SIGINT", async () => {
|
||||
const channels = client.channels;
|
||||
const logChannel = channels.cache.get(config.discord.channelIdLog);
|
||||
await this.handleShutdown(logChannel);
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
process.on("SIGTERM", async () => {
|
||||
const channels = client.channels;
|
||||
const logChannel = channels.cache.get(config.discord.channelIdLog);
|
||||
await this.handleShutdown(logChannel);
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
// listen for interactions
|
||||
client.on("interactionCreate", this.handleInteraction.bind(this));
|
||||
|
||||
client.on("messageCreate", async (message) => {
|
||||
console.log(message.id);
|
||||
if (message.channel.type === ChannelType.DM) {
|
||||
console.log("got msg");
|
||||
await this.dmService.forward(message);
|
||||
}
|
||||
});
|
||||
|
||||
client.on("guildMemberAdd", async (member) => {
|
||||
await this.greetingService.welcome(member);
|
||||
});
|
||||
|
||||
client.on(
|
||||
Events.VoiceStateUpdate,
|
||||
async (oldState: VoiceState, newState: VoiceState) => {
|
||||
// check if user joined a vc
|
||||
if (
|
||||
(!oldState.channelId && newState.channelId) ||
|
||||
oldState.channelId !== newState.channelId
|
||||
) {
|
||||
// check if right vc
|
||||
if (
|
||||
newState.channelId === config.discord.vchannelIdForTwo ||
|
||||
newState.channelId === config.discord.vchannelIdForThree ||
|
||||
newState.channelId === config.discord.vchannelIdForFour ||
|
||||
newState.channelId === config.discord.vchannelIdForGroup
|
||||
) {
|
||||
const channel = newState.channel;
|
||||
if (!channel) {
|
||||
console.error("channel not found");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const newChannel = await this.dynamicVChannelService.createVChannel(
|
||||
newState,
|
||||
channel,
|
||||
);
|
||||
// move user in new channel
|
||||
await newState.setChannel(newChannel);
|
||||
// create specific listener for channel
|
||||
const channelListener = async (
|
||||
oldState: VoiceState,
|
||||
newState: VoiceState,
|
||||
) => {
|
||||
channelListeners =
|
||||
await this.dynamicVChannelService.deleteVChannel(
|
||||
oldState,
|
||||
newState,
|
||||
newChannel,
|
||||
channelListeners,
|
||||
channelListener,
|
||||
);
|
||||
};
|
||||
// save listener in map
|
||||
channelListeners.set(newChannel.id, channelListener);
|
||||
// add listener
|
||||
client.on(Events.VoiceStateUpdate, channelListener);
|
||||
} catch (error) {
|
||||
console.error("error while duplicating channel", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
console.log(`----------------\nversion ${config.discord.version}\n----------------`);
|
||||
}
|
||||
|
||||
async setActivity(state: number) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
client.user?.setActivity(" ", { type: 0 });
|
||||
console.log("set activity");
|
||||
client.user?.setPresence({
|
||||
status: "invisible",
|
||||
});
|
||||
break;
|
||||
default:
|
||||
client.user?.setActivity("spielt sudoku", { type: 0 });
|
||||
console.log("set activity");
|
||||
client.user?.setPresence({
|
||||
status: "online",
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async handleShutdown(logChannel: Channel | undefined) {
|
||||
if (logChannel?.isTextBased() && logChannel?.isSendable()) {
|
||||
try {
|
||||
await logChannel.send("bot is going offline...");
|
||||
} catch (error) {
|
||||
console.error("failed to send offline message:", error);
|
||||
}
|
||||
} else {
|
||||
console.error("log channel is not valid or sendable.");
|
||||
}
|
||||
await this.setActivity(0);
|
||||
console.log("bot is offline.");
|
||||
}
|
||||
|
||||
|
||||
async init() {
|
||||
await this.discordService.init();
|
||||
}
|
||||
|
||||
async handleInteraction(interaction: Interaction<CacheType>) {
|
||||
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 handleButton(interaction: ButtonInteraction<CacheType>) {
|
||||
const { customId } = interaction;
|
||||
console.log(interaction.customId);
|
||||
|
||||
if (customId.toLowerCase().includes("moreWater")) {
|
||||
await this.waterMeService.handleInteraction(interaction);
|
||||
}
|
||||
if (customId.toLowerCase().includes("medication")) {
|
||||
await this.medicationService.handleInteraction(interaction);
|
||||
}
|
||||
}
|
||||
|
||||
async handleChatInputCommand(
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
) {
|
||||
const commandName = interaction.commandName as CommandsType;
|
||||
|
||||
// add commands
|
||||
switch (commandName) {
|
||||
case Commands.Enum.giessen:
|
||||
await this.waterMeService.handleInteraction(interaction); // zu chatinputcommand wechseln
|
||||
return;
|
||||
case Commands.Enum.medikamente:
|
||||
await this.medicationService.handleChatInputCommand(interaction);
|
||||
return;
|
||||
case Commands.Enum.hilfe:
|
||||
await this.helpService.handleInteraction(interaction); // zu chatinputcommand wechseln
|
||||
return;
|
||||
case Commands.Enum.support:
|
||||
case Commands.Enum.kofi:
|
||||
case Commands.Enum.disboard:
|
||||
case Commands.Enum.discadia:
|
||||
await this.supportService.handleInteraction(interaction);
|
||||
return;
|
||||
case Commands.Enum.accept:
|
||||
await this.greetingService.handleChatInputCommand(interaction);
|
||||
return;
|
||||
case Commands.Enum.welcome:
|
||||
await this.greetingService.handleChatInputCommand(interaction);
|
||||
return;
|
||||
case Commands.Enum.embed:
|
||||
case Commands.Enum.message:
|
||||
await this.customMessageService.handleChatInputCommand(interaction);
|
||||
return;
|
||||
case Commands.Enum.reminder:
|
||||
await this.greetingService.handleChatInputCommand(interaction);
|
||||
return;
|
||||
case Commands.Enum.version:
|
||||
await this.debugService.handleChatInputCommand(interaction);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// wenn neues fenster durch buttonclick or so
|
||||
async handleModalSubmit(interaction: ModalSubmitInteraction<CacheType>) {
|
||||
const { customId } = interaction;
|
||||
|
||||
switch (customId) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import { Routes } from "discord.js";
|
||||
import { REST } from "@discordjs/rest";
|
||||
import config from "config";
|
||||
import getCommands from "commands";
|
||||
|
||||
export default class DiscordService {
|
||||
rest: REST;
|
||||
|
||||
constructor() {
|
||||
this.rest = new REST({ version: "10" }).setToken(config.discord.token);
|
||||
}
|
||||
|
||||
async init() {
|
||||
try {
|
||||
await this.rest.put(
|
||||
Routes.applicationCommands(config.discord.applicationId),
|
||||
{
|
||||
body: getCommands(),
|
||||
},
|
||||
);
|
||||
console.log("Successfully added commands");
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
84
core/src/entities/commands/commands.entity.ts
Normal file
84
core/src/entities/commands/commands.entity.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import type z from "zod";
|
||||
import type { Commands } from "./commands.schema";
|
||||
|
||||
// TODO: add missing options
|
||||
export const CommandsCollection: z.output<typeof Commands> = {
|
||||
giessen: {
|
||||
description: "giess mich mit etwas wasser :3",
|
||||
},
|
||||
medikamente: {
|
||||
description:
|
||||
"ich erinnere dich gerne daran, deine medikamente zu nehmen! :)",
|
||||
},
|
||||
hilfe: {
|
||||
description: "ich schreibe dir auf, was du alles mit mir machen kannst :)",
|
||||
},
|
||||
support: {
|
||||
description:
|
||||
"unterstuetze uns! link zu unserem ko-fi, disboard und discardia c:",
|
||||
},
|
||||
kofi: {
|
||||
description: "link zu unserem ko-fi (spendenportal):",
|
||||
},
|
||||
disboard: {
|
||||
description: "link zu disboard, hier kannst du uns bewerten!",
|
||||
},
|
||||
discadia: {
|
||||
description: "link zu discadia, hier kannst du fuer uns voten!",
|
||||
},
|
||||
accept: {
|
||||
description: "admin use only",
|
||||
options: [
|
||||
{
|
||||
name: "input",
|
||||
description: "input for bot",
|
||||
required: true,
|
||||
type: "string",
|
||||
},
|
||||
],
|
||||
},
|
||||
welcome: {
|
||||
description: "admin use only",
|
||||
options: [
|
||||
{
|
||||
name: "input",
|
||||
description: "input for bot",
|
||||
required: true,
|
||||
type: "string",
|
||||
},
|
||||
],
|
||||
},
|
||||
embed: {
|
||||
description: "admin use only",
|
||||
options: [
|
||||
{
|
||||
name: "title",
|
||||
description: "title",
|
||||
required: true,
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
name: "description",
|
||||
description: "description",
|
||||
required: true,
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
name: "timestamp",
|
||||
description: "timestamp bool",
|
||||
required: false,
|
||||
type: "boolean",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
message: {
|
||||
description: "admin use only",
|
||||
},
|
||||
reminder: {
|
||||
description: "admin use only",
|
||||
},
|
||||
version: {
|
||||
description: "admin use only",
|
||||
},
|
||||
};
|
||||
59
core/src/entities/commands/commands.schema.ts
Normal file
59
core/src/entities/commands/commands.schema.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import z from "zod";
|
||||
|
||||
export const CommandKeyOptions = [
|
||||
"giessen",
|
||||
"medikamente",
|
||||
"hilfe",
|
||||
"support",
|
||||
"kofi",
|
||||
"disboard",
|
||||
"discadia",
|
||||
"accept",
|
||||
"welcome",
|
||||
"embed",
|
||||
"message",
|
||||
"reminder",
|
||||
"version",
|
||||
] as const;
|
||||
|
||||
export const CommandOptionTypeOptions = [
|
||||
"string",
|
||||
"integer",
|
||||
"boolean",
|
||||
"mentionable",
|
||||
"channel",
|
||||
"role",
|
||||
"user",
|
||||
] as const;
|
||||
|
||||
export const CommandOptionTypes = z.enum(CommandOptionTypeOptions);
|
||||
|
||||
export const CommandOptionCommon = z.object({
|
||||
name: z.string(),
|
||||
description: z.string(),
|
||||
required: z.boolean(),
|
||||
});
|
||||
|
||||
export const CommandOptionString = CommandOptionCommon.extend({
|
||||
type: z.literal(CommandOptionTypes.enum.string),
|
||||
});
|
||||
|
||||
export const CommandOptionBoolean = CommandOptionCommon.extend({
|
||||
type: z.literal(CommandOptionTypes.enum.boolean),
|
||||
});
|
||||
|
||||
// TODO: add other option types
|
||||
export const CommandOption = z.discriminatedUnion("type", [
|
||||
CommandOptionString,
|
||||
CommandOptionBoolean,
|
||||
]);
|
||||
|
||||
export const CommandKeys = z.enum(CommandKeyOptions);
|
||||
|
||||
export const Command = z.object({
|
||||
name: z.string().optional(),
|
||||
description: z.string(),
|
||||
options: z.array(CommandOption).optional(),
|
||||
});
|
||||
|
||||
export const Commands = z.record(CommandKeys, Command);
|
||||
5
core/src/entities/interactions/interactions.schema.ts
Normal file
5
core/src/entities/interactions/interactions.schema.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import z from "zod";
|
||||
|
||||
export const InteractionOptions = ["command", "button"] as const;
|
||||
|
||||
export const Interactions = z.enum(InteractionOptions);
|
||||
3
core/src/entities/messages/messages.service.ts
Normal file
3
core/src/entities/messages/messages.service.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface MessagesServiceInterface<U = unknown> {
|
||||
sendToUser(user: U, message: string): Promise<void>;
|
||||
}
|
||||
6
core/src/entities/roles/roles.service.ts
Normal file
6
core/src/entities/roles/roles.service.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export interface RolesServiceInterface<U = unknown> {
|
||||
assignRole(user: U, role: string): void | Promise<void>;
|
||||
removeRole(user: U, role: string): void | Promise<void>;
|
||||
getRoles(user: U): string[] | Promise<string[]>;
|
||||
hasRole(user: U, role: string): boolean | Promise<boolean>;
|
||||
}
|
||||
14
core/src/features/greeting/greeting.service.ts
Normal file
14
core/src/features/greeting/greeting.service.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import type { MessagesServiceInterface } from "entities/messages/messages.service";
|
||||
|
||||
export class GreetingService<U = unknown> {
|
||||
messagesService: MessagesServiceInterface<U>;
|
||||
|
||||
constructor(messagesService: MessagesServiceInterface<U>) {
|
||||
this.messagesService = messagesService;
|
||||
}
|
||||
|
||||
async sendGreeting(user: U, userName: string) {
|
||||
const greetingMessage = `Hello, ${userName}! Welcome to the server!`;
|
||||
await this.messagesService.sendToUser(user, greetingMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export type TextBasedFeatureHandleMessageSend = (
|
||||
message: string,
|
||||
channelId: string,
|
||||
) => void | Promise<void>;
|
||||
|
||||
export type TextBasedFeatureInput = {
|
||||
channelId: string;
|
||||
handleMessageSend: TextBasedFeatureHandleMessageSend;
|
||||
};
|
||||
18
core/src/features/text-based-feature/text-based-feature.ts
Normal file
18
core/src/features/text-based-feature/text-based-feature.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import type {
|
||||
TextBasedFeatureHandleMessageSend,
|
||||
TextBasedFeatureInput,
|
||||
} from "./text-based-feature.schema";
|
||||
|
||||
export class TextBasedFeature {
|
||||
channelId: string;
|
||||
handleMessageSend: TextBasedFeatureHandleMessageSend;
|
||||
|
||||
constructor(input: TextBasedFeatureInput) {
|
||||
this.channelId = input.channelId;
|
||||
this.handleMessageSend = input.handleMessageSend;
|
||||
}
|
||||
|
||||
async sendMessage(input: { content: string }) {
|
||||
this.handleMessageSend(input.content, this.channelId);
|
||||
}
|
||||
}
|
||||
64
core/src/features/water-me/water-me.service.ts
Normal file
64
core/src/features/water-me/water-me.service.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { TextBasedFeature } from "features/text-based-feature/text-based-feature";
|
||||
import type { TextBasedFeatureInput } from "features/text-based-feature/text-based-feature.schema";
|
||||
import { createLogger } from "lib/logger";
|
||||
import { getRandomInt } from "lib/utils";
|
||||
|
||||
export class WaterMeService extends TextBasedFeature {
|
||||
waterLevel: number;
|
||||
|
||||
private logger = createLogger("WaterMeService");
|
||||
|
||||
private thirsty = 3 as const;
|
||||
private enough = 10 as const;
|
||||
|
||||
constructor(input: TextBasedFeatureInput) {
|
||||
super(input);
|
||||
this.waterLevel = 0;
|
||||
}
|
||||
|
||||
getReply() {
|
||||
const thirstyReplies = [
|
||||
"... wow das wars schon??? ich brauche noch mehr wasser :(",
|
||||
"dankeeeee!!!! ich waer fast verdurstet :(((",
|
||||
"*roelpssssss*",
|
||||
];
|
||||
|
||||
const fullReplies = [
|
||||
"langsam reicht es :o",
|
||||
"poah, das hat gut getan",
|
||||
"das ist krass :3",
|
||||
];
|
||||
|
||||
const tooMuchReplies = [
|
||||
"ES REICHT!!!!",
|
||||
"bitte hoer auf, ich platze gleich :(",
|
||||
];
|
||||
|
||||
if (this.waterLevel <= this.thirsty) {
|
||||
return thirstyReplies[getRandomInt(0, thirstyReplies.length - 1)];
|
||||
}
|
||||
if (this.waterLevel > this.thirsty && this.waterLevel <= this.enough) {
|
||||
return fullReplies[getRandomInt(0, fullReplies.length - 1)];
|
||||
}
|
||||
if (this.waterLevel > this.enough) {
|
||||
return tooMuchReplies[getRandomInt(0, tooMuchReplies.length - 1)];
|
||||
}
|
||||
}
|
||||
|
||||
async notifyIfThirsty() {
|
||||
if (this.waterLevel <= this.thirsty) {
|
||||
await this.sendMessage({ content: "ich brauche wasser :(" });
|
||||
}
|
||||
}
|
||||
|
||||
waterMe() {
|
||||
const reply = this.getReply();
|
||||
|
||||
this.waterLevel++;
|
||||
this.logger.info(`Water level increased to ${this.waterLevel}`);
|
||||
|
||||
return {
|
||||
reply,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import config from "config";
|
||||
import { Client, GatewayIntentBits, Partials, ChannelType, Events, IntentsBitField } from "discord.js";
|
||||
|
||||
const client = new Client({
|
||||
intents: [IntentsBitField.Flags.Guilds,
|
||||
IntentsBitField.Flags.GuildMembers,
|
||||
IntentsBitField.Flags.GuildModeration,
|
||||
IntentsBitField.Flags.GuildMessages,
|
||||
IntentsBitField.Flags.GuildMessageReactions,
|
||||
IntentsBitField.Flags.GuildMessagePolls,
|
||||
IntentsBitField.Flags.GuildVoiceStates,
|
||||
IntentsBitField.Flags.MessageContent,
|
||||
IntentsBitField.Flags.DirectMessages,
|
||||
IntentsBitField.Flags.DirectMessageReactions,
|
||||
IntentsBitField.Flags.DirectMessageTyping,
|
||||
IntentsBitField.Flags.DirectMessagePolls,],
|
||||
partials: [Partials.Channel, Partials.Message, Partials.Reaction]
|
||||
});
|
||||
|
||||
await client.login(config.discord.token);
|
||||
|
||||
export default client;
|
||||
8
core/src/lib/logger.ts
Normal file
8
core/src/lib/logger.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Logger } from "tslog";
|
||||
|
||||
export const createLogger = (name: string) =>
|
||||
new Logger({
|
||||
name,
|
||||
prettyLogTemplate:
|
||||
"{{yyyy}}.{{mm}}.{{dd}} {{hh}}:{{MM}}:{{ss}}:{{ms}}\t{{logLevelName}}\t{{name}}\t",
|
||||
});
|
||||
@@ -4,6 +4,7 @@ export default defineConfig({
|
||||
entry: [
|
||||
"./src/index.ts",
|
||||
"./src/entities/**/*.ts",
|
||||
"./src/features/**/*.ts",
|
||||
"./src/lib/**/*.ts",
|
||||
"./src/api/**/*.ts",
|
||||
"./src/db/**/*.ts",
|
||||
|
||||
Reference in New Issue
Block a user