refactor water me service

remove "text-based-feature"
improve messages service interface
implement more features for fluxer
This commit is contained in:
2026-02-18 18:38:09 +01:00
parent 84b851f60f
commit 0a460800b6
20 changed files with 202 additions and 56 deletions

View File

@@ -3,5 +3,5 @@ import { logger } from "lib/common-logger";
export const handleShutdown = async () => {
logger.info("bot is shutting down...");
await logChannelService.sendLogMessage("bot is shutting down...");
await logChannelService.sendLogMessage("ich geh schlafen...");
};

View File

@@ -1,9 +1,11 @@
import type { MessagesServiceInterface } from "@avocadi/bot-core/entities/messages/messages.service";
import { createLogger } from "@avocadi/bot-core/lib/logger";
import {
type Channel,
ChannelType,
type DMChannel,
type Message,
type MessagePayload,
type PartialDMChannel,
type User,
} from "discord.js";
@@ -11,11 +13,11 @@ import { logChannelService } from "features/log-channel/log-channel.service";
import client from "lib/client";
export class MessagesService
implements MessagesServiceInterface<User, Message>
implements MessagesServiceInterface<User, Message, Channel, MessagePayload>
{
private logger = createLogger("MessagesService");
async sendToUser(userInput: User, message: string): Promise<void> {
async sendToUser(userInput: User, message: MessagePayload): Promise<void> {
const user = await client.users.fetch(userInput.id);
if (user) {
@@ -47,6 +49,23 @@ export class MessagesService
await logChannelService.sendLogMessage(logMessage);
}
async sendToChannel(
channel: Channel,
createMessageInput: MessagePayload,
): Promise<void> {
const fetchedChannel = await client.channels.fetch(channel.id);
if (fetchedChannel?.isTextBased() && fetchedChannel.isSendable()) {
await fetchedChannel.send(createMessageInput);
} else {
this.logger.error(
`Channel with ID ${channel.id} not found or is not text-based.`,
);
throw new Error("Channel not found or is not text-based.");
}
}
}
export const messagesService = new MessagesService();

View File

@@ -4,9 +4,7 @@ import {
ButtonBuilder,
type ButtonInteraction,
ButtonStyle,
type CacheType,
type ChatInputCommandInteraction,
type Interaction,
} from "discord.js";
import { waterMeService } from "./water-me.service";

View File

@@ -1,8 +1,4 @@
import { WaterMeService } from "@avocadi/bot-core/features/water-me/water-me.service";
import { messagesService } from "entitites/messages/messages.service";
export const waterMeService = new WaterMeService({
channelId: "123",
handleMessageSend: async (message, channelId) => {
console.log(`Sending message to channel ${channelId}: ${message}`);
},
});
export const waterMeService = new WaterMeService(messagesService);

View File

@@ -0,0 +1,7 @@
import { logChannelService } from "features/log-channel/log-channel.service";
import { logger } from "lib/common-logger";
export const handleShutdown = async () => {
logger.info("bot is shutting down...");
await logChannelService.sendLogMessage("ich geh schlafen...");
};

View File

@@ -13,6 +13,7 @@ export const ConfigSchema = z.object({
roleMapping: z.record(Roles, z.string()),
serverId: z.string(),
version: z.number(),
commandPrefix: z.string().default("!"),
fluxer: z.object({
token: z.string(),
applicationId: z.string(),

View File

@@ -1,8 +1,8 @@
import type z from "zod";
import type { ConfigSchema } from "./config.schema";
import { ConfigSchema } from "./config.schema";
import env from "./env";
export const config: z.output<typeof ConfigSchema> = {
const configInput: z.input<typeof ConfigSchema> = {
channelMapping: {
text: {
bot: "1473270893617315899",
@@ -42,3 +42,5 @@ export const config: z.output<typeof ConfigSchema> = {
applicationId: env.FLUXER_APPLICATION_ID,
},
};
export const config = ConfigSchema.parse(configInput);

View File

@@ -0,0 +1,56 @@
import type { MessagesServiceInterface } from "@avocadi/bot-core/entities/messages/messages.service";
import { createLogger } from "@avocadi/bot-core/lib/logger";
import type {
Channel,
Message,
MessageSendOptions,
User,
} from "@fluxerjs/core";
import { logChannelService } from "features/log-channel/log-channel.service";
import client from "lib/client";
export class MessagesService
implements
MessagesServiceInterface<User, Message, Channel, MessageSendOptions>
{
private logger = createLogger("MessagesService");
async sendToUser(
userInput: User,
createMessageInput: MessageSendOptions,
): Promise<void> {
const user = await client.users.fetch(userInput.id);
if (user) {
await user.send(createMessageInput);
} else {
this.logger.error(`User with ID ${userInput.id} not found.`);
}
}
async sendToChannel(
channel: Channel,
createMessageInput: MessageSendOptions,
): Promise<void> {
const fetchedChannel = await client.channels.fetch(channel.id);
if (fetchedChannel?.isSendable()) {
await fetchedChannel.send(createMessageInput);
} else {
this.logger.error(
`Channel with ID ${channel.id} not found or is not text-based.`,
);
throw new Error("Channel not found or is not text-based.");
}
}
async logMessage(message: Message): Promise<void> {
const logMessage = `<@${message.author.id}> sent a message:\n"${message.content}"`;
await logChannelService.sendLogMessage(logMessage);
}
}
export const messagesService = new MessagesService();

View File

@@ -1,18 +1,22 @@
import { createLogger } from "@avocadi/bot-core/lib/logger";
import { config } from "config";
import client from "lib/client";
import { logger } from "lib/common-logger";
export class LogChannelService {
private logger = createLogger("LogChannelService");
private logChannelId = config.channelMapping.text.log;
async getLogChannel() {
this.logger.debug(`fetching log channel with ID: ${this.logChannelId}`);
const logChannel = await client.channels.fetch(this.logChannelId);
if (logChannel.isSendable()) {
return logChannel;
} else {
logger.fatal("Log channel not found or is not text-based.");
throw new Error("Log channel not found or is not text-based");
this.logger.fatal("log channel not found or is not text-based.");
throw new Error("log channel not found or is not text-based");
}
}

View File

@@ -0,0 +1,4 @@
import { WaterMeService } from "@avocadi/bot-core/features/water-me/water-me.service";
import { messagesService } from "entities/messages/messages.service";
export const waterMeService = new WaterMeService(messagesService);

View File

View File

@@ -1,2 +1,3 @@
import "./ready.listener";
import "./stop.listener";
import "./messages/messages.listener";

View File

@@ -0,0 +1,37 @@
import { CommandKeys } from "@avocadi/bot-core/entities/commands/commands.schema";
import { Events, type Message } from "@fluxerjs/core";
import { config } from "config";
import { messagesService } from "entities/messages/messages.service";
import client from "lib/client";
import { logger } from "lib/common-logger";
client.on(Events.MessageCreate, async (message: Message) => {
if (
message.channel?.id !== config.channelMapping.text.log &&
message.channel?.id !== config.channelMapping.text.bot
) {
await messagesService.logMessage(message);
}
if (message.content?.startsWith(config.commandPrefix)) {
await messagesService.logMessage(message);
logger.info(
`Command received: ${message.content} from user ${message.author.id}`,
);
const command = message.content
.slice(config.commandPrefix.length)
.trim()
.split(" ")[0];
logger.info(`Parsed command: ${command}`);
const result = CommandKeys.safeParse(command);
if (result.success) {
logger.info(`Command ${command} is valid.`);
} else {
logger.warn(`Command ${command} is not recognized.`);
}
}
});

View File

@@ -1,3 +1,15 @@
import { Events } from "@fluxerjs/core";
import client from "lib/client";
import { logger } from "lib/common-logger";
import { handleShutdown } from "actions/shutdown";
process.on("exit", async () => {
await handleShutdown();
});
process.on("SIGINT", async () => {
await handleShutdown();
process.exit(0);
});
process.on("SIGTERM", async () => {
await handleShutdown();
process.exit(0);
});