From a23430f210563acf58c8a5e10c0895bc13b3467c Mon Sep 17 00:00:00 2001 From: Till-JS <101404291+Till-JS@users.noreply.github.com> Date: Sun, 1 Feb 2026 03:26:25 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20KeywordCommandDetecto?= =?UTF-8?q?r=20to=20all=2019=20Matrix=20bots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All bots now support natural language commands via KeywordCommandDetector: - matrix-chat-bot (gespraeche, modelle, verlauf, etc.) - matrix-mana-bot (todo, timer, kalender, summary, etc.) - matrix-manadeck-bot (decks, karten, lernen, mana, etc.) - matrix-planta-bot (pflanzen, giessen, faellig, etc.) - matrix-presi-bot (presis, folien, themes, teilen, etc.) - matrix-project-doc-bot (projekte, generate, export, etc.) - matrix-questions-bot (fragen, recherche, antwort, etc.) - matrix-skilltree-bot (skills, xp, stats, aktivitaeten, etc.) - matrix-stats-bot (stats, heute, woche, realtime, etc.) - matrix-storage-bot (dateien, ordner, teilen, suche, etc.) - matrix-tts-bot (voice, voices, speed, etc.) All bots include COMMON_KEYWORDS (hilfe, help, status). Co-Authored-By: Claude Opus 4.5 --- .../src/db/schema/user-lists.schema.ts | 5 ++- .../apps/backend/src/list/list.service.ts | 2 +- apps/zitare/apps/backend/tsconfig.json | 26 ++++++++++- .../matrix-chat-bot/src/bot/matrix.service.ts | 24 +++++++++- .../src/bot/command-router.service.ts | 44 +++++++------------ .../src/bot/matrix.service.ts | 21 +++++++++ .../src/bot/matrix.service.ts | 25 ++++++++++- .../src/bot/matrix.service.ts | 18 ++++++++ .../src/bot/matrix.service.ts | 25 ++++++++++- .../src/bot/matrix.service.ts | 26 ++++++++++- .../src/bot/matrix.service.ts | 17 +++++++ .../src/bot/matrix.service.ts | 23 +++++++++- .../src/bot/matrix.service.ts | 26 ++++++++++- .../matrix-tts-bot/src/bot/matrix.service.ts | 15 +++++++ 14 files changed, 261 insertions(+), 36 deletions(-) diff --git a/apps/zitare/apps/backend/src/db/schema/user-lists.schema.ts b/apps/zitare/apps/backend/src/db/schema/user-lists.schema.ts index 691e142bb..6cd67869c 100644 --- a/apps/zitare/apps/backend/src/db/schema/user-lists.schema.ts +++ b/apps/zitare/apps/backend/src/db/schema/user-lists.schema.ts @@ -7,7 +7,10 @@ export const userLists = pgTable('user_lists', { description: text('description'), quoteIds: jsonb('quote_ids').$type().default([]), // References static quote IDs from shared package createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), - updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull(), + updatedAt: timestamp('updated_at', { withTimezone: true }) + .defaultNow() + .$onUpdate(() => new Date()) + .notNull(), }); export type UserList = typeof userLists.$inferSelect; diff --git a/apps/zitare/apps/backend/src/list/list.service.ts b/apps/zitare/apps/backend/src/list/list.service.ts index 2aa4a3a96..486f9a8b6 100644 --- a/apps/zitare/apps/backend/src/list/list.service.ts +++ b/apps/zitare/apps/backend/src/list/list.service.ts @@ -37,7 +37,7 @@ export class ListService { ): Promise { const [list] = await this.db .update(userLists) - .set({ ...data, updatedAt: new Date() }) + .set(data) .where(and(eq(userLists.id, listId), eq(userLists.userId, userId))) .returning(); diff --git a/apps/zitare/apps/backend/tsconfig.json b/apps/zitare/apps/backend/tsconfig.json index dd1e616b7..27971033a 100644 --- a/apps/zitare/apps/backend/tsconfig.json +++ b/apps/zitare/apps/backend/tsconfig.json @@ -1,3 +1,27 @@ { - "extends": "@manacore/shared-tsconfig/nestjs" + "compilerOptions": { + "target": "ES2021", + "module": "commonjs", + "moduleResolution": "node", + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "outDir": "./dist", + "baseUrl": "./", + "rootDir": "./src", + "incremental": true, + "skipLibCheck": true, + "strictNullChecks": true, + "noImplicitAny": true, + "strictBindCallApply": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "sourceMap": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] } diff --git a/services/matrix-chat-bot/src/bot/matrix.service.ts b/services/matrix-chat-bot/src/bot/matrix.service.ts index 6dfbcd9a1..f8be71a8c 100644 --- a/services/matrix-chat-bot/src/bot/matrix.service.ts +++ b/services/matrix-chat-bot/src/bot/matrix.service.ts @@ -1,12 +1,28 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent } from '@manacore/matrix-bot-common'; +import { + BaseMatrixService, + MatrixBotConfig, + MatrixRoomEvent, + KeywordCommandDetector, + COMMON_KEYWORDS, +} from '@manacore/matrix-bot-common'; import { ChatService, Conversation } from '../chat/chat.service'; import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE, BRANCH_ICONS } from '../config/configuration'; @Injectable() export class MatrixService extends BaseMatrixService { + private readonly keywordDetector = new KeywordCommandDetector([ + ...COMMON_KEYWORDS, + { keywords: ['gespraeche', 'conversations', 'liste', 'chats'], command: 'gespraeche' }, + { keywords: ['modelle', 'models', 'ki modelle', 'ai models'], command: 'modelle' }, + { keywords: ['neu', 'new', 'neues gespraech', 'new conversation'], command: 'neu' }, + { keywords: ['verlauf', 'history', 'nachrichten', 'messages'], command: 'verlauf' }, + { keywords: ['archiviert', 'archived', 'archiv liste'], command: 'archiviert' }, + { keywords: ['chat', 'fragen', 'ask', 'frage'], command: 'chat' }, + ]); + constructor( configService: ConfigService, private chatService: ChatService, @@ -67,6 +83,12 @@ export class MatrixService extends BaseMatrixService { message: string, sender: string ): Promise { + // Check for keyword commands first + const keywordCommand = this.keywordDetector.detect(message); + if (keywordCommand) { + message = `!${keywordCommand}`; + } + if (!message.startsWith('!')) return; const [command, ...args] = message.slice(1).split(/\s+/); diff --git a/services/matrix-mana-bot/src/bot/command-router.service.ts b/services/matrix-mana-bot/src/bot/command-router.service.ts index 0359f3a08..faa7b8fd2 100644 --- a/services/matrix-mana-bot/src/bot/command-router.service.ts +++ b/services/matrix-mana-bot/src/bot/command-router.service.ts @@ -1,4 +1,5 @@ import { Injectable, Logger, Inject, forwardRef } from '@nestjs/common'; +import { KeywordCommandDetector, COMMON_KEYWORDS } from '@manacore/matrix-bot-common'; import { AiHandler } from '../handlers/ai.handler'; import { TodoHandler } from '../handlers/todo.handler'; import { CalendarHandler } from '../handlers/calendar.handler'; @@ -21,22 +22,20 @@ interface CommandRoute { description: string; } -// Natural language keywords (German + English) -const KEYWORD_COMMANDS: { keywords: string[]; command: string }[] = [ - { keywords: ['hilfe', 'help', 'was kannst du', 'befehle'], command: '!help' }, - { keywords: ['modelle', 'models', 'welche modelle'], command: '!models' }, - { - keywords: ['meine aufgaben', 'zeige aufgaben', 'todo liste', 'was muss ich'], - command: '!list', - }, - { keywords: ['heute', 'was steht heute an'], command: '!today' }, - { keywords: ['termine', 'kalender', 'meine termine'], command: '!cal' }, - { keywords: ['timer', 'stoppuhr'], command: '!timers' }, - { keywords: ['zusammenfassung', 'wie war mein tag', 'tagesrückblick'], command: '!summary' }, -]; - @Injectable() export class CommandRouterService { + private readonly keywordDetector = new KeywordCommandDetector([ + ...COMMON_KEYWORDS, + { keywords: ['modelle', 'models', 'welche modelle', 'ai models'], command: 'models' }, + { keywords: ['meine aufgaben', 'zeige aufgaben', 'todo liste', 'was muss ich', 'aufgaben'], command: 'list' }, + { keywords: ['heute', 'was steht heute an', 'today'], command: 'today' }, + { keywords: ['termine', 'kalender', 'meine termine', 'calendar'], command: 'cal' }, + { keywords: ['timer', 'stoppuhr', 'zeitmesser'], command: 'timers' }, + { keywords: ['zusammenfassung', 'wie war mein tag', 'tagesrueckblick', 'summary'], command: 'summary' }, + { keywords: ['todo', 'aufgabe', 'neue aufgabe', 'task'], command: 'todo' }, + { keywords: ['alarm', 'wecker', 'alarme'], command: 'alarms' }, + { keywords: ['clear', 'loeschen', 'verlauf loeschen', 'reset'], command: 'clear' }, + ]); private readonly logger = new Logger(CommandRouterService.name); private routes: CommandRoute[] = []; @@ -262,20 +261,11 @@ export class CommandRouterService { } private detectKeywordCommand(message: string): string | null { - const lowerMessage = message.toLowerCase().trim(); - - // Only check short messages - if (lowerMessage.length > 60) return null; - - for (const { keywords, command } of KEYWORD_COMMANDS) { - for (const keyword of keywords) { - if (lowerMessage === keyword || lowerMessage.includes(keyword)) { - this.logger.debug(`Detected keyword "${keyword}" -> "${command}"`); - return command; - } - } + const command = this.keywordDetector.detect(message); + if (command) { + this.logger.debug(`Detected keyword -> "!${command}"`); + return `!${command}`; } - return null; } diff --git a/services/matrix-manadeck-bot/src/bot/matrix.service.ts b/services/matrix-manadeck-bot/src/bot/matrix.service.ts index 9a286e7ac..5a227a0a2 100644 --- a/services/matrix-manadeck-bot/src/bot/matrix.service.ts +++ b/services/matrix-manadeck-bot/src/bot/matrix.service.ts @@ -5,6 +5,8 @@ import { MatrixBotConfig, MatrixRoomEvent, UserListMapper, + KeywordCommandDetector, + COMMON_KEYWORDS, } from '@manacore/matrix-bot-common'; import { ManadeckService, Deck, Card } from '../manadeck/manadeck.service'; import { SessionService } from '@manacore/bot-services'; @@ -17,6 +19,19 @@ export class MatrixService extends BaseMatrixService { private cardsMapper = new UserListMapper(); private currentDeckId: Map = new Map(); + private readonly keywordDetector = new KeywordCommandDetector([ + ...COMMON_KEYWORDS, + { keywords: ['decks', 'meine decks', 'kartendecks', 'liste'], command: 'decks' }, + { keywords: ['karten', 'cards', 'meine karten'], command: 'karten' }, + { keywords: ['lernen', 'study', 'ueben', 'wiederholen'], command: 'lernen' }, + { keywords: ['faellig', 'due', 'anstehend', 'zu lernen'], command: 'faellig' }, + { keywords: ['mana', 'credits', 'guthaben', 'punkte'], command: 'mana' }, + { keywords: ['stats', 'statistik', 'fortschritt', 'statistiken'], command: 'stats' }, + { keywords: ['generieren', 'generate', 'erstellen', 'ai'], command: 'generate' }, + { keywords: ['featured', 'empfohlen', 'beliebte decks'], command: 'featured' }, + { keywords: ['rangliste', 'leaderboard', 'bestenliste'], command: 'leaderboard' }, + ]); + constructor( configService: ConfigService, private manadeckService: ManadeckService, @@ -40,6 +55,12 @@ export class MatrixService extends BaseMatrixService { message: string, sender: string ): Promise { + // Check for keyword commands first + const keywordCommand = this.keywordDetector.detect(message); + if (keywordCommand) { + message = `!${keywordCommand}`; + } + if (!message.startsWith('!')) return; const parts = message.slice(1).split(/\s+/); diff --git a/services/matrix-planta-bot/src/bot/matrix.service.ts b/services/matrix-planta-bot/src/bot/matrix.service.ts index 43fc49a0d..b303f887a 100644 --- a/services/matrix-planta-bot/src/bot/matrix.service.ts +++ b/services/matrix-planta-bot/src/bot/matrix.service.ts @@ -1,6 +1,13 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent, UserListMapper } from '@manacore/matrix-bot-common'; +import { + BaseMatrixService, + MatrixBotConfig, + MatrixRoomEvent, + UserListMapper, + KeywordCommandDetector, + COMMON_KEYWORDS, +} from '@manacore/matrix-bot-common'; import { PlantaService, Plant } from '../planta/planta.service'; import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE } from '../config/configuration'; @@ -10,6 +17,16 @@ export class MatrixService extends BaseMatrixService { // Store last shown plants per user for reference by number private plantsMapper = new UserListMapper(); + private readonly keywordDetector = new KeywordCommandDetector([ + ...COMMON_KEYWORDS, + { keywords: ['pflanzen', 'plants', 'meine pflanzen', 'liste'], command: 'pflanzen' }, + { keywords: ['giessen', 'water', 'bewaessern', 'wasser geben'], command: 'giessen' }, + { keywords: ['faellig', 'due', 'anstehend', 'upcoming'], command: 'faellig' }, + { keywords: ['neu', 'new', 'neue pflanze', 'add'], command: 'neu' }, + { keywords: ['historie', 'history', 'verlauf', 'giess historie'], command: 'historie' }, + { keywords: ['intervall', 'interval', 'frequenz', 'wie oft'], command: 'intervall' }, + ]); + // Field mappings for edit command private readonly fieldMappings: Record = { name: 'name', @@ -52,6 +69,12 @@ export class MatrixService extends BaseMatrixService { event: MatrixRoomEvent, body: string ): Promise { + // Check for keyword commands first + const keywordCommand = this.keywordDetector.detect(body); + if (keywordCommand) { + body = `!${keywordCommand}`; + } + if (!body.startsWith('!')) return; const sender = event.sender; diff --git a/services/matrix-presi-bot/src/bot/matrix.service.ts b/services/matrix-presi-bot/src/bot/matrix.service.ts index ee603e86a..167090a32 100644 --- a/services/matrix-presi-bot/src/bot/matrix.service.ts +++ b/services/matrix-presi-bot/src/bot/matrix.service.ts @@ -5,6 +5,8 @@ import { MatrixBotConfig, MatrixRoomEvent, UserListMapper, + KeywordCommandDetector, + COMMON_KEYWORDS, } from '@manacore/matrix-bot-common'; import { PresiService, Deck, Theme, SlideContent } from '../presi/presi.service'; import { SessionService } from '@manacore/bot-services'; @@ -16,6 +18,16 @@ export class MatrixService extends BaseMatrixService { private decksMapper = new UserListMapper(); private themesMapper = new UserListMapper(); + private readonly keywordDetector = new KeywordCommandDetector([ + ...COMMON_KEYWORDS, + { keywords: ['presis', 'decks', 'praesentationen', 'liste'], command: 'presis' }, + { keywords: ['folien', 'slides', 'folie hinzufuegen'], command: 'folie' }, + { keywords: ['themes', 'designs', 'vorlagen', 'stile'], command: 'themes' }, + { keywords: ['teilen', 'share', 'freigeben', 'link'], command: 'teilen' }, + { keywords: ['links', 'shares', 'freigaben', 'geteilte'], command: 'links' }, + { keywords: ['neu', 'new', 'neue praesentation', 'erstellen'], command: 'neu' }, + ]); + constructor( configService: ConfigService, private presiService: PresiService, @@ -40,6 +52,12 @@ export class MatrixService extends BaseMatrixService { event: MatrixRoomEvent, body: string ): Promise { + // Check for keyword commands first + const keywordCommand = this.keywordDetector.detect(body); + if (keywordCommand) { + body = `!${keywordCommand}`; + } + if (!body.startsWith('!')) return; const sender = event.sender; diff --git a/services/matrix-project-doc-bot/src/bot/matrix.service.ts b/services/matrix-project-doc-bot/src/bot/matrix.service.ts index 9fb9154a5..fcb66dd73 100644 --- a/services/matrix-project-doc-bot/src/bot/matrix.service.ts +++ b/services/matrix-project-doc-bot/src/bot/matrix.service.ts @@ -1,6 +1,12 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent } from '@manacore/matrix-bot-common'; +import { + BaseMatrixService, + MatrixBotConfig, + MatrixRoomEvent, + KeywordCommandDetector, + COMMON_KEYWORDS, +} from '@manacore/matrix-bot-common'; import { ProjectService } from '../project/project.service'; import { MediaService } from '../media/media.service'; import { GenerationService } from '../generation/generation.service'; @@ -13,6 +19,17 @@ export class MatrixService extends BaseMatrixService { // Active project per user (matrixUserId -> projectId) private activeProjects: Map = new Map(); + private readonly keywordDetector = new KeywordCommandDetector([ + ...COMMON_KEYWORDS, + { keywords: ['projekte', 'projects', 'meine projekte', 'liste'], command: 'projects' }, + { keywords: ['archiv', 'archive', 'archivieren'], command: 'archive' }, + { keywords: ['generieren', 'generate', 'erstellen', 'blogbeitrag'], command: 'generate' }, + { keywords: ['exportieren', 'export', 'herunterladen', 'download'], command: 'export' }, + { keywords: ['stile', 'styles', 'vorlagen', 'formate'], command: 'styles' }, + { keywords: ['neu', 'new', 'neues projekt', 'projekt starten'], command: 'new' }, + { keywords: ['wechseln', 'switch', 'umschalten'], command: 'switch' }, + ]); + constructor( configService: ConfigService, private projectService: ProjectService, @@ -77,6 +94,12 @@ export class MatrixService extends BaseMatrixService { body: string, sender: string ): Promise { + // Check for keyword commands first + const keywordCommand = this.keywordDetector.detect(body); + if (keywordCommand) { + body = `!${keywordCommand}`; + } + if (body.startsWith('!')) { await this.handleCommand(roomId, sender, body); } else { diff --git a/services/matrix-questions-bot/src/bot/matrix.service.ts b/services/matrix-questions-bot/src/bot/matrix.service.ts index f0fcdb6bd..28b9102cd 100644 --- a/services/matrix-questions-bot/src/bot/matrix.service.ts +++ b/services/matrix-questions-bot/src/bot/matrix.service.ts @@ -1,6 +1,13 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent, UserListMapper } from '@manacore/matrix-bot-common'; +import { + BaseMatrixService, + MatrixBotConfig, + MatrixRoomEvent, + UserListMapper, + KeywordCommandDetector, + COMMON_KEYWORDS, +} from '@manacore/matrix-bot-common'; import { QuestionsService, Question, Collection, Answer } from '../questions/questions.service'; import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE } from '../config/configuration'; @@ -12,6 +19,17 @@ export class MatrixService extends BaseMatrixService { private collectionsMapper = new UserListMapper(); private answersMapper = new UserListMapper(); + private readonly keywordDetector = new KeywordCommandDetector([ + ...COMMON_KEYWORDS, + { keywords: ['fragen', 'questions', 'meine fragen', 'liste'], command: 'fragen' }, + { keywords: ['recherche', 'research', 'suchen', 'untersuchen'], command: 'recherche' }, + { keywords: ['antwort', 'answer', 'antworten', 'ergebnis'], command: 'antwort' }, + { keywords: ['quellen', 'sources', 'referenzen', 'links'], command: 'quellen' }, + { keywords: ['sammlungen', 'collections', 'ordner', 'kategorien'], command: 'sammlungen' }, + { keywords: ['suche', 'search', 'finde', 'durchsuchen'], command: 'suche' }, + { keywords: ['neu', 'new', 'neue frage', 'frage stellen'], command: 'neu' }, + ]); + constructor( configService: ConfigService, private questionsService: QuestionsService, @@ -34,6 +52,12 @@ export class MatrixService extends BaseMatrixService { event: MatrixRoomEvent, body: string ): Promise { + // Check for keyword commands first + const keywordCommand = this.keywordDetector.detect(body); + if (keywordCommand) { + body = `!${keywordCommand}`; + } + if (!body.startsWith('!')) return; const sender = event.sender; diff --git a/services/matrix-skilltree-bot/src/bot/matrix.service.ts b/services/matrix-skilltree-bot/src/bot/matrix.service.ts index fffb1d8e9..6a6879521 100644 --- a/services/matrix-skilltree-bot/src/bot/matrix.service.ts +++ b/services/matrix-skilltree-bot/src/bot/matrix.service.ts @@ -5,6 +5,8 @@ import { MatrixBotConfig, MatrixRoomEvent, UserListMapper, + KeywordCommandDetector, + COMMON_KEYWORDS, } from '@manacore/matrix-bot-common'; import { SkilltreeService, Skill, SkillBranch } from '../skilltree/skilltree.service'; import { SessionService } from '@manacore/bot-services'; @@ -15,6 +17,15 @@ export class MatrixService extends BaseMatrixService { // User list mapper for number-based reference private skillsMapper = new UserListMapper(); + private readonly keywordDetector = new KeywordCommandDetector([ + ...COMMON_KEYWORDS, + { keywords: ['skills', 'faehigkeiten', 'meine skills', 'liste'], command: 'skills' }, + { keywords: ['xp', 'punkte', 'erfahrung', 'erfahrungspunkte'], command: 'xp' }, + { keywords: ['stats', 'statistik', 'statistiken', 'fortschritt'], command: 'stats' }, + { keywords: ['aktivitaeten', 'activities', 'verlauf', 'historie'], command: 'aktivitaeten' }, + { keywords: ['neu', 'new', 'neuer skill', 'skill erstellen'], command: 'neu' }, + ]); + // Branch name mappings (German/English) private readonly branchMappings: Record = { intellect: 'intellect', @@ -64,6 +75,12 @@ export class MatrixService extends BaseMatrixService { event: MatrixRoomEvent, body: string ): Promise { + // Check for keyword commands first + const keywordCommand = this.keywordDetector.detect(body); + if (keywordCommand) { + body = `!${keywordCommand}`; + } + if (!body.startsWith('!')) return; const sender = event.sender; diff --git a/services/matrix-stats-bot/src/bot/matrix.service.ts b/services/matrix-stats-bot/src/bot/matrix.service.ts index fc09fae10..be81a8f48 100644 --- a/services/matrix-stats-bot/src/bot/matrix.service.ts +++ b/services/matrix-stats-bot/src/bot/matrix.service.ts @@ -1,6 +1,12 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent } from '@manacore/matrix-bot-common'; +import { + BaseMatrixService, + MatrixBotConfig, + MatrixRoomEvent, + KeywordCommandDetector, + COMMON_KEYWORDS, +} from '@manacore/matrix-bot-common'; import { AnalyticsService } from '../analytics/analytics.service'; import { UsersService } from '../users/users.service'; @@ -8,6 +14,15 @@ import { UsersService } from '../users/users.service'; export class MatrixService extends BaseMatrixService { private reportRoomId: string = ''; + private readonly keywordDetector = new KeywordCommandDetector([ + ...COMMON_KEYWORDS, + { keywords: ['stats', 'statistik', 'statistiken', 'uebersicht'], command: 'stats' }, + { keywords: ['heute', 'today', 'tagesstatistik'], command: 'today' }, + { keywords: ['woche', 'week', 'wochenstatistik'], command: 'week' }, + { keywords: ['realtime', 'live', 'aktive', 'jetzt'], command: 'realtime' }, + { keywords: ['users', 'benutzer', 'nutzer', 'registrierte'], command: 'users' }, + ]); + constructor( configService: ConfigService, private analyticsService: AnalyticsService, @@ -33,6 +48,12 @@ export class MatrixService extends BaseMatrixService { message: string, _sender: string ): Promise { + // Check for keyword commands first + const keywordCommand = this.keywordDetector.detect(message); + if (keywordCommand) { + message = `!${keywordCommand}`; + } + if (!message.startsWith('!')) return; const [command] = message.slice(1).split(' '); diff --git a/services/matrix-storage-bot/src/bot/matrix.service.ts b/services/matrix-storage-bot/src/bot/matrix.service.ts index a15132351..0412b230e 100644 --- a/services/matrix-storage-bot/src/bot/matrix.service.ts +++ b/services/matrix-storage-bot/src/bot/matrix.service.ts @@ -1,6 +1,13 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent, UserListMapper } from '@manacore/matrix-bot-common'; +import { + BaseMatrixService, + MatrixBotConfig, + MatrixRoomEvent, + UserListMapper, + KeywordCommandDetector, + COMMON_KEYWORDS, +} from '@manacore/matrix-bot-common'; import { StorageService, StorageFile, Folder, ShareLink, TrashItem } from '../storage/storage.service'; import { SessionService } from '@manacore/bot-services'; import { HELP_MESSAGE } from '../config/configuration'; @@ -14,6 +21,17 @@ export class MatrixService extends BaseMatrixService { private trashMapper = new UserListMapper(); private currentFolder: Map = new Map(); + private readonly keywordDetector = new KeywordCommandDetector([ + ...COMMON_KEYWORDS, + { keywords: ['dateien', 'files', 'meine dateien', 'liste'], command: 'dateien' }, + { keywords: ['ordner', 'folders', 'verzeichnisse', 'dirs'], command: 'ordner' }, + { keywords: ['teilen', 'share', 'freigeben', 'link erstellen'], command: 'teilen' }, + { keywords: ['suche', 'search', 'finde', 'durchsuchen'], command: 'suche' }, + { keywords: ['favoriten', 'favorites', 'favs', 'gemerkte'], command: 'favoriten' }, + { keywords: ['papierkorb', 'trash', 'geloeschte', 'muell'], command: 'papierkorb' }, + { keywords: ['links', 'shares', 'freigaben', 'geteilte'], command: 'links' }, + ]); + constructor( configService: ConfigService, private storageService: StorageService, @@ -36,6 +54,12 @@ export class MatrixService extends BaseMatrixService { event: MatrixRoomEvent, body: string ): Promise { + // Check for keyword commands first + const keywordCommand = this.keywordDetector.detect(body); + if (keywordCommand) { + body = `!${keywordCommand}`; + } + if (!body.startsWith('!')) return; const sender = event.sender; diff --git a/services/matrix-tts-bot/src/bot/matrix.service.ts b/services/matrix-tts-bot/src/bot/matrix.service.ts index 2eb6ee5df..5763166c2 100644 --- a/services/matrix-tts-bot/src/bot/matrix.service.ts +++ b/services/matrix-tts-bot/src/bot/matrix.service.ts @@ -4,6 +4,8 @@ import { BaseMatrixService, MatrixBotConfig, MatrixRoomEvent, + KeywordCommandDetector, + COMMON_KEYWORDS, } from '@manacore/matrix-bot-common'; import { TtsService } from '../tts/tts.service'; import { HELP_TEXT, WELCOME_TEXT } from '../config/configuration'; @@ -25,6 +27,13 @@ export class MatrixService extends BaseMatrixService { // Track processed events to prevent duplicates private processedEvents: Set = new Set(); + private readonly keywordDetector = new KeywordCommandDetector([ + ...COMMON_KEYWORDS, + { keywords: ['voice', 'stimme', 'stimme aendern'], command: 'voice' }, + { keywords: ['voices', 'stimmen', 'verfuegbare stimmen'], command: 'voices' }, + { keywords: ['speed', 'geschwindigkeit', 'tempo'], command: 'speed' }, + ]); + constructor( configService: ConfigService, private ttsService: TtsService @@ -93,6 +102,12 @@ export class MatrixService extends BaseMatrixService { const userId = event.sender; try { + // Check for keyword commands first + const keywordCommand = this.keywordDetector.detect(body); + if (keywordCommand) { + body = `!${keywordCommand}`; + } + // Handle ! commands if (body.startsWith('!')) { const [command, ...args] = body.slice(1).split(' ');