i18n waterMe
This commit is contained in:
@@ -1,4 +1,9 @@
|
|||||||
import { WaterMeService } from "@avocadi/bot-core/features/water-me/water-me.service";
|
import { WaterMeService } from "@avocadi/bot-core/features/water-me/water-me.service";
|
||||||
|
import { i18nService } from "@avocadi/bot-core/lib/i18n";
|
||||||
import { messagesService } from "entitites/messages/messages.service";
|
import { messagesService } from "entitites/messages/messages.service";
|
||||||
|
|
||||||
export const waterMeService = new WaterMeService(messagesService);
|
export const waterMeService = new WaterMeService(
|
||||||
|
messagesService,
|
||||||
|
i18nService,
|
||||||
|
"de",
|
||||||
|
);
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ import { logger } from "lib/common-logger";
|
|||||||
|
|
||||||
export const handleShutdown = async () => {
|
export const handleShutdown = async () => {
|
||||||
logger.info("bot is shutting down...");
|
logger.info("bot is shutting down...");
|
||||||
await logChannelService.sendLogMessage("ich geh schlafen...");
|
await logChannelService.sendLogMessage("**S H U T T I N G D O W N**");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
import { WaterMeService } from "@avocadi/bot-core/features/water-me/water-me.service";
|
import { WaterMeService } from "@avocadi/bot-core/features/water-me/water-me.service";
|
||||||
|
import { i18nService } from "@avocadi/bot-core/lib/i18n";
|
||||||
import { messagesService } from "entities/messages/messages.service";
|
import { messagesService } from "entities/messages/messages.service";
|
||||||
|
|
||||||
export const waterMeService = new WaterMeService(messagesService);
|
export const waterMeService = new WaterMeService(
|
||||||
|
messagesService,
|
||||||
|
i18nService,
|
||||||
|
"en",
|
||||||
|
);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import client from "lib/client";
|
|||||||
import { logger } from "lib/common-logger";
|
import { logger } from "lib/common-logger";
|
||||||
|
|
||||||
client.on(Events.Ready, async () => {
|
client.on(Events.Ready, async () => {
|
||||||
await logChannelService.sendLogMessage("wieder online!!!");
|
await logChannelService.sendLogMessage("**O N L I N E**");
|
||||||
|
|
||||||
logger.info("bot is online");
|
logger.info("bot is online");
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
"discord.js": "^14.16.3",
|
"discord.js": "^14.16.3",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"drizzle-orm": "^0.38.3",
|
"drizzle-orm": "^0.38.3",
|
||||||
|
"i18next": "^25.8.11",
|
||||||
"tslog": "^4.10.2",
|
"tslog": "^4.10.2",
|
||||||
"zod": "catalog:"
|
"zod": "catalog:"
|
||||||
},
|
},
|
||||||
@@ -46,6 +47,8 @@
|
|||||||
"./features/greeting/greeting.service": "./dist/features/greeting/greeting.service.js",
|
"./features/greeting/greeting.service": "./dist/features/greeting/greeting.service.js",
|
||||||
"./features/water-me/water-me.service": "./dist/features/water-me/water-me.service.js",
|
"./features/water-me/water-me.service": "./dist/features/water-me/water-me.service.js",
|
||||||
"./lib/common": "./dist/lib/common.js",
|
"./lib/common": "./dist/lib/common.js",
|
||||||
|
"./lib/i18n": "./dist/lib/i18n/index.js",
|
||||||
|
"./lib/i18n/i18n.service": "./dist/lib/i18n/i18n.service.js",
|
||||||
"./lib/logger": "./dist/lib/logger.js",
|
"./lib/logger": "./dist/lib/logger.js",
|
||||||
"./lib/utils": "./dist/lib/utils.js",
|
"./lib/utils": "./dist/lib/utils.js",
|
||||||
"./lib/utils.test": "./dist/lib/utils.test.js",
|
"./lib/utils.test": "./dist/lib/utils.test.js",
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
export default {
|
|
||||||
discord: {
|
|
||||||
version: 251218,
|
|
||||||
// avocadi
|
|
||||||
serverID: process.env.DISCORD_SERVER_ID || "",
|
|
||||||
// text channel
|
|
||||||
channelIdBump: process.env.DISCORD_CHANNEL_ID_BUMP || "",
|
|
||||||
channelIdBot: process.env.DISCORD_CHANNEL_ID_BOT || "",
|
|
||||||
channelIdFeedback: process.env.DISCORD_CHANNEL_ID_FEEDBACK || "",
|
|
||||||
channelIdLog: process.env.DISCORD_CHANNEL_ID_NOTIFICATION || "",
|
|
||||||
channelIdWelcome: process.env.DISCORD_CHANNEL_ID_WELCOME || "",
|
|
||||||
channelIdRules: process.env.DISCORD_CHANNEL_ID_RULE || "",
|
|
||||||
channelIdNews: process.env.DISCORD_CHANNEL_ID_NEWS || "",
|
|
||||||
channelIdIntroduction: process.env.DISCORD_CHANNEL_ID_INTRODUCTION || "",
|
|
||||||
channelIdOffTopic: process.env.DISCORD_CHANNEL_ID_OFF_TOPIC || "",
|
|
||||||
channelIdHelp: process.env.DISCORD_CHANNEL_ID_HELP || "",
|
|
||||||
channelIdPomodoro: process.env.DISCORD_CHANNEL_ID_POMODORO || "",
|
|
||||||
// voice channel
|
|
||||||
vchannelIdForTwo: process.env.DISCORD_VCHANNEL_ID_FOR_TWO || "",
|
|
||||||
vchannelIdForThree: process.env.DISCORD_VCHANNEL_ID_FOR_THREE || "",
|
|
||||||
vchannelIdForFour: process.env.DISCORD_VCHANNEL_ID_FOR_FOUR || "",
|
|
||||||
vchannelIdForGroup: process.env.DISCORD_VCHANNEL_ID_FOR_GROUP || "",
|
|
||||||
vchannelIdPomodoro25: process.env.DISCORD_VCHANNEL_ID_POMODORO_25_5 || "",
|
|
||||||
vchannelIdPomodoro50: process.env.DISCORD_VCHANNEL_ID_POMODORO_50_10 || "",
|
|
||||||
// roles
|
|
||||||
roleBot: process.env.BOT || "",
|
|
||||||
roleStudy: process.env.PEOPLE || "",
|
|
||||||
roleMod: process.env.MOD || "",
|
|
||||||
roleAdmin: process.env.ADMIN || "",
|
|
||||||
roleMention: process.env.MENTION || "",
|
|
||||||
|
|
||||||
rolesMsg: process.env.ROLES_NOTIFICATION_MSG || "",
|
|
||||||
rolesMsgTest: process.env.ROLES_MSG_TEST || "",
|
|
||||||
// other
|
|
||||||
applicationId: process.env.DISCORD_APPLICATION_ID || "",
|
|
||||||
token: process.env.DISCORD_TOKEN || "",
|
|
||||||
|
|
||||||
botId: process.env.BOT_ID || "",
|
|
||||||
myId: process.env.MY_ID || "",
|
|
||||||
enricoId: process.env.ENRICO_ID || "",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import type { MessagesServiceInterface } from "entities/messages/messages.service";
|
import type { MessagesServiceInterface } from "entities/messages/messages.service";
|
||||||
|
import type { ParseKeys } from "i18next";
|
||||||
|
import type { I18nService } from "lib/i18n/i18n.service";
|
||||||
import { createLogger } from "lib/logger";
|
import { createLogger } from "lib/logger";
|
||||||
import { getRandomInt } from "lib/utils";
|
|
||||||
|
|
||||||
export class WaterMeService {
|
export class WaterMeService {
|
||||||
waterLevel: number;
|
waterLevel: number;
|
||||||
@@ -8,48 +9,45 @@ export class WaterMeService {
|
|||||||
private logger = createLogger("WaterMeService");
|
private logger = createLogger("WaterMeService");
|
||||||
|
|
||||||
private thirsty = 3 as const;
|
private thirsty = 3 as const;
|
||||||
private enough = 10 as const;
|
private full = 10 as const;
|
||||||
messagesService: MessagesServiceInterface;
|
messagesService: MessagesServiceInterface;
|
||||||
|
i18nService: I18nService;
|
||||||
|
lang: "en" | "de";
|
||||||
|
|
||||||
constructor(messagesService: MessagesServiceInterface) {
|
constructor(
|
||||||
|
messagesService: MessagesServiceInterface,
|
||||||
|
i18nService: I18nService,
|
||||||
|
lang: "en" | "de",
|
||||||
|
) {
|
||||||
this.waterLevel = 0;
|
this.waterLevel = 0;
|
||||||
this.messagesService = messagesService;
|
this.messagesService = messagesService;
|
||||||
|
this.i18nService = i18nService;
|
||||||
|
this.lang = lang;
|
||||||
}
|
}
|
||||||
|
|
||||||
getReply() {
|
async getReply() {
|
||||||
const thirstyReplies = [
|
// const key = (
|
||||||
"... wow das wars schon??? ich brauche noch mehr wasser :(",
|
// this.waterLevel <= this.thirsty
|
||||||
"dankeeeee!!!! ich waer fast verdurstet :(((",
|
// ? "water-me.needMoreWater"
|
||||||
"*roelpssssss*",
|
// : this.waterLevel <= this.full
|
||||||
];
|
// ? "water-me.enoughWater"
|
||||||
|
// : "water-me.tooMuchWater"
|
||||||
|
// ) as ParseKeys;
|
||||||
|
|
||||||
const fullReplies = [
|
// return await this.i18nService.t(key, this.lang);
|
||||||
"langsam reicht es :o",
|
|
||||||
"poah, das hat gut getan",
|
|
||||||
"das ist krass :3",
|
|
||||||
];
|
|
||||||
|
|
||||||
const tooMuchReplies = [
|
if (this.waterLevel <= this.thirsty)
|
||||||
"ES REICHT!!!!",
|
return this.i18nService.t("needMoreWater", this.lang, "waterMe");
|
||||||
"bitte hoer auf, ich platze gleich :(",
|
if (this.waterLevel <= this.full)
|
||||||
];
|
return this.i18nService.t("enoughWater", this.lang, "waterMe");
|
||||||
|
return this.i18nService.t("tooMuchWater", this.lang, "waterMe");
|
||||||
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() {
|
async notifyIfThirsty() {
|
||||||
if (this.waterLevel <= this.thirsty) {
|
if (this.waterLevel <= this.thirsty) {
|
||||||
await this.messagesService.sendToChannel(
|
await this.messagesService.sendToChannel(
|
||||||
{ id: "channelId" },
|
{ id: "channelId" },
|
||||||
{ content: "ich brauche wasser :(" },
|
{ content: await this.i18nService.t("waterMe.thirsty", this.lang) },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,11 +64,11 @@ export class WaterMeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async handleCommand(channelId: string) {
|
async handleCommand(channelId: string) {
|
||||||
const result = this.waterMe();
|
const result = this.waterMe(); // muss hier await weil promise rueckgabe?
|
||||||
|
|
||||||
this.messagesService.sendToChannel(
|
this.messagesService.sendToChannel(
|
||||||
{ id: channelId },
|
{ id: channelId },
|
||||||
{ content: result.reply },
|
{ content: await result.reply },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
64
core/src/lib/i18n/i18n.service.ts
Normal file
64
core/src/lib/i18n/i18n.service.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import i18next, { type ParseKeys } from "i18next";
|
||||||
|
// import { createLogger } from "lib/logger";
|
||||||
|
import waterMeDe from "locales/de/water-me";
|
||||||
|
import waterMeEn from "locales/en/water-me";
|
||||||
|
|
||||||
|
export class I18nService {
|
||||||
|
// private logger = createLogger("I18nService");
|
||||||
|
private initialized: Promise<void>;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.initialized = this.init();
|
||||||
|
// this.logger.debug(`language ${lang}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
randomVariantPlugin = {
|
||||||
|
type: "postProcessor" as const,
|
||||||
|
name: "randomVariant",
|
||||||
|
process(value: string) {
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
await i18next.init({
|
||||||
|
lng: "en",
|
||||||
|
fallbackLng: "en",
|
||||||
|
resources: {
|
||||||
|
en: { waterMe: waterMeEn },
|
||||||
|
de: { waterMe: waterMeDe },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
randomItem<T>(arr: T[]): T {
|
||||||
|
return arr[Math.floor(Math.random() * arr.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
async t(
|
||||||
|
key: ParseKeys,
|
||||||
|
locale: string,
|
||||||
|
ns: string,
|
||||||
|
interpolations?: Record<string, string | number>,
|
||||||
|
): Promise<string> {
|
||||||
|
await this.initialized; // wait for init before translating
|
||||||
|
const fixedT = i18next.getFixedT(
|
||||||
|
locale.startsWith("de") ? "de" : "en",
|
||||||
|
ns ?? "waterMe",
|
||||||
|
);
|
||||||
|
const value = fixedT(key, { returnObjects: true, ...interpolations });
|
||||||
|
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
// pick random variant and interpolate manually if needed
|
||||||
|
const picked = this.randomItem(value as string[]);
|
||||||
|
// i18next won't interpolate when returnObjects is true, so we do it here
|
||||||
|
return picked.replace(/\{\{(\w+)\}\}/g, (_, k) =>
|
||||||
|
interpolations?.[k] !== undefined
|
||||||
|
? String(interpolations[k])
|
||||||
|
: `{{${k}}}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value as unknown as string;
|
||||||
|
}
|
||||||
|
}
|
||||||
3
core/src/lib/i18n/index.ts
Normal file
3
core/src/lib/i18n/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { I18nService } from "lib/i18n/i18n.service";
|
||||||
|
|
||||||
|
export const i18nService = new I18nService();
|
||||||
10
core/src/locales/de/water-me.ts
Normal file
10
core/src/locales/de/water-me.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export default {
|
||||||
|
needMoreWater: [
|
||||||
|
"... wow, das wars??? ich brauche noch mehr wasser :(",
|
||||||
|
"danke!!!! ich bin schon fast verdurstet :(((",
|
||||||
|
"*roooeeeelps*",
|
||||||
|
],
|
||||||
|
enoughWater: ["wow, das hat gut getan", "das ist krass :3"],
|
||||||
|
tooMuchWater: ["ES REICHT!!!!", "bitte hoer auf, ich platze gleich :("],
|
||||||
|
thirsty: "ich brauche wasser :c",
|
||||||
|
} as const;
|
||||||
10
core/src/locales/en/water-me.ts
Normal file
10
core/src/locales/en/water-me.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export default {
|
||||||
|
needMoreWater: [
|
||||||
|
"... wow, thats all??? i need more water :(",
|
||||||
|
"thank you!!!! i was almost dying of thirst :(((",
|
||||||
|
"*buuuurrrrp*",
|
||||||
|
],
|
||||||
|
enoughWater: ["wow, that felt good", "that's crazy :3"],
|
||||||
|
tooMuchWater: ["THATS ENOUGH!!!!", "please stop, i'm about to explode :("],
|
||||||
|
thirsty: "i need some water :c",
|
||||||
|
} as const;
|
||||||
9
core/src/locales/index.ts
Normal file
9
core/src/locales/index.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import de from "./de";
|
||||||
|
import en from "./en";
|
||||||
|
|
||||||
|
const locales = {
|
||||||
|
de,
|
||||||
|
en,
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export default locales;
|
||||||
@@ -17,11 +17,12 @@
|
|||||||
// Best practices
|
// Best practices
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
"strictNullChecks": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
|
||||||
// Some stricter flags (disabled by default)
|
// Some stricter flags (disabled by default)
|
||||||
"noUnusedLocals": false,
|
"noUnusedLocals": false,
|
||||||
"noUnusedParameters": false,
|
"noUnusedParameters": false,
|
||||||
"noPropertyAccessFromIndexSignature": false
|
"noPropertyAccessFromIndexSignature": false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user