fix(matrix-bots): update all bots for async SessionService methods

Update all Matrix bots to properly await async SessionService methods
after the migration to Redis-backed session storage. This includes:

- Adding await to getSessionData, getSession, getToken, isLoggedIn calls
- Making requireAuth helper methods async and return Promise<string>
- Making session data helper methods async (getCurrentConversation, etc.)
- Fixing handleLogout and other methods that use session operations

Affected bots:
- matrix-chat-bot (extensive changes for session helpers)
- matrix-clock-bot (getToken helper + session calls)
- matrix-contacts-bot, matrix-manadeck-bot, matrix-nutriphi-bot
- matrix-ollama-bot, matrix-picture-bot, matrix-planta-bot
- matrix-presi-bot, matrix-project-doc-bot, matrix-skilltree-bot
- matrix-storage-bot, matrix-zitare-bot, matrix-tts-bot
- matrix-mana-bot (help handler)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Till-JS 2026-02-02 15:04:30 +01:00
parent 0b46d203bb
commit 60d2f6422c
15 changed files with 551 additions and 350 deletions

View file

@ -8,7 +8,12 @@ import {
COMMON_KEYWORDS,
} from '@manacore/matrix-bot-common';
import { ChatService, Conversation } from '../chat/chat.service';
import { SessionService, TranscriptionService, CreditService, CreditErrorCode } from '@manacore/bot-services';
import {
SessionService,
TranscriptionService,
CreditService,
CreditErrorCode,
} from '@manacore/bot-services';
import { HELP_MESSAGE, BRANCH_ICONS } from '../config/configuration';
@Injectable()
@ -59,46 +64,51 @@ export class MatrixService extends BaseMatrixService {
protected getConfig(): MatrixBotConfig {
return {
homeserverUrl: this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
homeserverUrl:
this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
accessToken: this.configService.get<string>('matrix.accessToken') || '',
storagePath: this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
storagePath:
this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
allowedRooms: this.configService.get<string[]>('matrix.allowedRooms') || [],
};
}
// Session data helper methods (wrapping the generic setSessionData/getSessionData)
private getCurrentConversation(sender: string): string | null {
private async getCurrentConversation(sender: string): Promise<string | null> {
return this.sessionService.getSessionData<string>(sender, 'currentConversationId');
}
private setCurrentConversation(sender: string, conversationId: string | null): void {
this.sessionService.setSessionData(sender, 'currentConversationId', conversationId);
private async setCurrentConversation(
sender: string,
conversationId: string | null
): Promise<void> {
await this.sessionService.setSessionData(sender, 'currentConversationId', conversationId);
}
private getSelectedModel(sender: string): string | null {
private async getSelectedModel(sender: string): Promise<string | null> {
return this.sessionService.getSessionData<string>(sender, 'selectedModelId');
}
private setSelectedModel(sender: string, modelId: string): void {
this.sessionService.setSessionData(sender, 'selectedModelId', modelId);
private async setSelectedModel(sender: string, modelId: string): Promise<void> {
await this.sessionService.setSessionData(sender, 'selectedModelId', modelId);
}
private setConversationMapping(sender: string, ids: string[]): void {
this.sessionService.setSessionData(sender, 'conversationMapping', ids);
private async setConversationMapping(sender: string, ids: string[]): Promise<void> {
await this.sessionService.setSessionData(sender, 'conversationMapping', ids);
}
private getConversationId(sender: string, number: number): string | null {
const ids = this.sessionService.getSessionData<string[]>(sender, 'conversationMapping');
private async getConversationId(sender: string, number: number): Promise<string | null> {
const ids = await this.sessionService.getSessionData<string[]>(sender, 'conversationMapping');
if (!ids || number < 1 || number > ids.length) return null;
return ids[number - 1];
}
private setModelMapping(sender: string, ids: string[]): void {
this.sessionService.setSessionData(sender, 'modelMapping', ids);
private async setModelMapping(sender: string, ids: string[]): Promise<void> {
await this.sessionService.setSessionData(sender, 'modelMapping', ids);
}
private getModelId(sender: string, number: number): string | null {
const ids = this.sessionService.getSessionData<string[]>(sender, 'modelMapping');
private async getModelId(sender: string, number: number): Promise<string | null> {
const ids = await this.sessionService.getSessionData<string[]>(sender, 'modelMapping');
if (!ids || number < 1 || number > ids.length) return null;
return ids[number - 1];
}
@ -133,7 +143,7 @@ export class MatrixService extends BaseMatrixService {
break;
case 'logout':
response = this.handleLogout(sender);
response = await this.handleLogout(sender);
break;
case 'status':
@ -244,17 +254,17 @@ export class MatrixService extends BaseMatrixService {
return `Anmeldung fehlgeschlagen: ${result.error}`;
}
private handleLogout(sender: string): string {
this.sessionService.logout(sender);
private async handleLogout(sender: string): Promise<string> {
await this.sessionService.logout(sender);
return 'Erfolgreich abgemeldet.';
}
private async handleStatus(sender: string): Promise<string> {
const isLoggedIn = this.sessionService.isLoggedIn(sender);
const email = this.sessionService.getEmail(sender);
const token = this.sessionService.getToken(sender);
const currentConv = this.getCurrentConversation(sender);
const selectedModel = this.getSelectedModel(sender);
const isLoggedIn = await this.sessionService.isLoggedIn(sender);
const email = await this.sessionService.getEmail(sender);
const token = await this.sessionService.getToken(sender);
const currentConv = await this.getCurrentConversation(sender);
const selectedModel = await this.getSelectedModel(sender);
// Get credit balance if logged in
let creditBalance = { balance: 0, hasCredits: false };
@ -289,7 +299,7 @@ export class MatrixService extends BaseMatrixService {
return 'Verwendung: `!chat [deine nachricht]`';
}
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
return 'Bitte zuerst anmelden mit `!login email passwort`';
}
@ -300,8 +310,9 @@ export class MatrixService extends BaseMatrixService {
return 'Keine AI-Modelle verfuegbar.';
}
const selectedModelId = this.getSelectedModel(sender);
const modelId = selectedModelId || modelsResult.data.find((m) => m.isDefault)?.id || modelsResult.data[0].id;
const selectedModelId = await this.getSelectedModel(sender);
const modelId =
selectedModelId || modelsResult.data.find((m) => m.isDefault)?.id || modelsResult.data[0].id;
const result = await this.chatService.createCompletion(
token,
@ -332,7 +343,7 @@ export class MatrixService extends BaseMatrixService {
// Conversation management
private async handleNewConversation(sender: string, title: string): Promise<string> {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
return 'Bitte zuerst anmelden mit `!login email passwort`';
}
@ -343,8 +354,9 @@ export class MatrixService extends BaseMatrixService {
return 'Keine AI-Modelle verfuegbar.';
}
const selectedModelId = this.getSelectedModel(sender);
const modelId = selectedModelId || modelsResult.data.find((m) => m.isDefault)?.id || modelsResult.data[0].id;
const selectedModelId = await this.getSelectedModel(sender);
const modelId =
selectedModelId || modelsResult.data.find((m) => m.isDefault)?.id || modelsResult.data[0].id;
const convTitle = title || `Matrix Chat ${new Date().toLocaleDateString('de-DE')}`;
const result = await this.chatService.createConversation(token, {
@ -357,12 +369,12 @@ export class MatrixService extends BaseMatrixService {
return `Fehler: ${result.error}`;
}
this.setCurrentConversation(sender, result.data!.id);
await this.setCurrentConversation(sender, result.data!.id);
return `Neues Gespraech erstellt: **${result.data!.title}**\nNutze \`!senden [nachricht]\` um zu chatten.`;
}
private async handleListConversations(sender: string): Promise<string> {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
return 'Bitte zuerst anmelden mit `!login email passwort`';
}
@ -383,12 +395,12 @@ export class MatrixService extends BaseMatrixService {
});
// Store mapping
this.setConversationMapping(
await this.setConversationMapping(
sender,
sorted.map((c) => c.id)
);
const currentId = this.getCurrentConversation(sender);
const currentId = await this.getCurrentConversation(sender);
let response = '**Deine Gespraeche:**\n\n';
sorted.forEach((conv, index) => {
@ -403,14 +415,14 @@ export class MatrixService extends BaseMatrixService {
}
private async handleSelectConversation(sender: string, numberStr: string): Promise<string> {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
return 'Bitte zuerst anmelden mit `!login email passwort`';
}
if (!numberStr) {
// Show current conversation
const currentId = this.getCurrentConversation(sender);
const currentId = await this.getCurrentConversation(sender);
if (!currentId) {
return 'Kein Gespraech ausgewaehlt. Nutze `!gespraeche` und dann `!gespraech [nr]`';
}
@ -428,7 +440,7 @@ export class MatrixService extends BaseMatrixService {
return 'Bitte eine gueltige Nummer angeben.';
}
const conversationId = this.getConversationId(sender, number);
const conversationId = await this.getConversationId(sender, number);
if (!conversationId) {
return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.';
}
@ -438,7 +450,7 @@ export class MatrixService extends BaseMatrixService {
return `Fehler: ${result.error}`;
}
this.setCurrentConversation(sender, conversationId);
await this.setCurrentConversation(sender, conversationId);
return `Gespraech ausgewaehlt: **${result.data!.title}**\n\n${this.formatConversationDetails(result.data!)}`;
}
@ -461,12 +473,12 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
return 'Verwendung: `!senden [deine nachricht]`';
}
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
return 'Bitte zuerst anmelden mit `!login email passwort`';
}
const conversationId = this.getCurrentConversation(sender);
const conversationId = await this.getCurrentConversation(sender);
if (!conversationId) {
return 'Kein Gespraech ausgewaehlt. Nutze `!gespraeche` und `!gespraech [nr]` oder `!neu [titel]`';
}
@ -491,7 +503,11 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
}));
// Get AI response
const completionResult = await this.chatService.createCompletion(token, messages, convResult.data!.modelId);
const completionResult = await this.chatService.createCompletion(
token,
messages,
convResult.data!.modelId
);
if (completionResult.error) {
// Handle 402 Payment Required (insufficient credits)
if (completionResult.statusCode === 402) {
@ -507,7 +523,12 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
}
// Save assistant response
await this.chatService.addMessage(token, conversationId, completionResult.data!.content, 'assistant');
await this.chatService.addMessage(
token,
conversationId,
completionResult.data!.content,
'assistant'
);
let response = completionResult.data!.content;
if (completionResult.data!.usage) {
@ -517,17 +538,17 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
}
private async handleShowHistory(sender: string, numberStr?: string): Promise<string> {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
return 'Bitte zuerst anmelden mit `!login email passwort`';
}
let conversationId = this.getCurrentConversation(sender);
let conversationId = await this.getCurrentConversation(sender);
if (numberStr) {
const number = parseInt(numberStr, 10);
if (!isNaN(number)) {
const id = this.getConversationId(sender, number);
const id = await this.getConversationId(sender, number);
if (id) conversationId = id;
}
}
@ -550,7 +571,8 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
recentMessages.forEach((msg) => {
const icon = msg.sender === 'user' ? '👤' : msg.sender === 'assistant' ? '🤖' : '⚙️';
const text = msg.messageText.length > 200 ? msg.messageText.substring(0, 200) + '...' : msg.messageText;
const text =
msg.messageText.length > 200 ? msg.messageText.substring(0, 200) + '...' : msg.messageText;
response += `${icon} **${msg.sender}:**\n${text}\n\n`;
});
@ -562,8 +584,12 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
}
// Conversation management actions
private async handleUpdateTitle(sender: string, numberStr: string, title: string): Promise<string> {
const token = this.sessionService.getToken(sender);
private async handleUpdateTitle(
sender: string,
numberStr: string,
title: string
): Promise<string> {
const token = await this.sessionService.getToken(sender);
if (!token) {
return 'Bitte zuerst anmelden mit `!login email passwort`';
}
@ -577,7 +603,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
return 'Bitte eine gueltige Nummer angeben.';
}
const conversationId = this.getConversationId(sender, number);
const conversationId = await this.getConversationId(sender, number);
if (!conversationId) {
return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.';
}
@ -591,7 +617,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
}
private async handleArchive(sender: string, numberStr: string): Promise<string> {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
return 'Bitte zuerst anmelden mit `!login email passwort`';
}
@ -605,7 +631,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
return 'Bitte eine gueltige Nummer angeben.';
}
const conversationId = this.getConversationId(sender, number);
const conversationId = await this.getConversationId(sender, number);
if (!conversationId) {
return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.';
}
@ -619,7 +645,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
}
private async handleListArchived(sender: string): Promise<string> {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
return 'Bitte zuerst anmelden mit `!login email passwort`';
}
@ -634,7 +660,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
}
// Store mapping for restore
this.setConversationMapping(
await this.setConversationMapping(
sender,
result.data.map((c) => c.id)
);
@ -650,7 +676,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
}
private async handleUnarchive(sender: string, numberStr: string): Promise<string> {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
return 'Bitte zuerst anmelden mit `!login email passwort`';
}
@ -664,7 +690,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
return 'Bitte eine gueltige Nummer angeben.';
}
const conversationId = this.getConversationId(sender, number);
const conversationId = await this.getConversationId(sender, number);
if (!conversationId) {
return 'Ungueltige Nummer. Nutze `!archiviert` fuer eine aktuelle Liste.';
}
@ -678,7 +704,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
}
private async handlePin(sender: string, numberStr: string): Promise<string> {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
return 'Bitte zuerst anmelden mit `!login email passwort`';
}
@ -692,7 +718,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
return 'Bitte eine gueltige Nummer angeben.';
}
const conversationId = this.getConversationId(sender, number);
const conversationId = await this.getConversationId(sender, number);
if (!conversationId) {
return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.';
}
@ -706,7 +732,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
}
private async handleUnpin(sender: string, numberStr: string): Promise<string> {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
return 'Bitte zuerst anmelden mit `!login email passwort`';
}
@ -720,7 +746,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
return 'Bitte eine gueltige Nummer angeben.';
}
const conversationId = this.getConversationId(sender, number);
const conversationId = await this.getConversationId(sender, number);
if (!conversationId) {
return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.';
}
@ -734,7 +760,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
}
private async handleDelete(sender: string, numberStr: string): Promise<string> {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
return 'Bitte zuerst anmelden mit `!login email passwort`';
}
@ -748,7 +774,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
return 'Bitte eine gueltige Nummer angeben.';
}
const conversationId = this.getConversationId(sender, number);
const conversationId = await this.getConversationId(sender, number);
if (!conversationId) {
return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.';
}
@ -763,8 +789,8 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
}
// Clear current conversation if it was the deleted one
if (this.getCurrentConversation(sender) === conversationId) {
this.setCurrentConversation(sender, null);
if ((await this.getCurrentConversation(sender)) === conversationId) {
await this.setCurrentConversation(sender, null);
}
return `Gespraech **${title}** geloescht.`;
@ -784,12 +810,12 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
const activeModels = result.data.filter((m) => m.isActive);
// Store mapping
this.setModelMapping(
await this.setModelMapping(
sender,
activeModels.map((m) => m.id)
);
const selectedModelId = this.getSelectedModel(sender);
const selectedModelId = await this.getSelectedModel(sender);
let response = '**Verfuegbare AI-Modelle:**\n\n';
activeModels.forEach((model, index) => {
@ -806,7 +832,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
private async handleSelectModel(sender: string, numberStr: string): Promise<string> {
if (!numberStr) {
const selectedModelId = this.getSelectedModel(sender);
const selectedModelId = await this.getSelectedModel(sender);
if (!selectedModelId) {
return 'Kein Modell ausgewaehlt (Standard wird verwendet). Nutze `!modelle` und `!modell [nr]`';
}
@ -825,7 +851,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
return 'Bitte eine gueltige Nummer angeben.';
}
const modelId = this.getModelId(sender, number);
const modelId = await this.getModelId(sender, number);
if (!modelId) {
return 'Ungueltige Nummer. Nutze `!modelle` fuer eine aktuelle Liste.';
}
@ -835,7 +861,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
return `Fehler: ${result.error}`;
}
this.setSelectedModel(sender, modelId);
await this.setSelectedModel(sender, modelId);
const icon = BRANCH_ICONS[result.data!.provider] || BRANCH_ICONS.default;
return `Modell gewaehlt: ${icon} **${result.data!.name}**\nWird fuer neue Gespraeche und Quick-Chat verwendet.`;
}

View file

@ -37,9 +37,11 @@ export class MatrixService extends BaseMatrixService {
protected getConfig(): MatrixBotConfig {
return {
homeserverUrl: this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
homeserverUrl:
this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
accessToken: this.configService.get<string>('matrix.accessToken') || '',
storagePath: this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
storagePath:
this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
allowedRooms: this.configService.get<string[]>('matrix.allowedRooms') || [],
};
}
@ -222,7 +224,12 @@ export class MatrixService extends BaseMatrixService {
}
}
private async handleTimerCommand(roomId: string, event: MatrixRoomEvent, userId: string, args: string) {
private async handleTimerCommand(
roomId: string,
event: MatrixRoomEvent,
userId: string,
args: string
) {
if (!args.trim()) {
await this.sendReply(
roomId,
@ -242,7 +249,7 @@ export class MatrixService extends BaseMatrixService {
const label = args.replace(/[\d\s]*[hms]+/gi, '').trim() || null;
try {
const token = this.getToken(userId);
const token = await this.getToken(userId);
if (!token) {
await this.sendReply(roomId, event, 'Keine Authentifizierung. Bitte zuerst `!login`.');
return;
@ -266,7 +273,7 @@ export class MatrixService extends BaseMatrixService {
private async handleStopCommand(roomId: string, event: MatrixRoomEvent, userId: string) {
try {
const token = this.getToken(userId);
const token = await this.getToken(userId);
if (!token) {
await this.sendReply(roomId, event, 'Keine Authentifizierung.');
return;
@ -303,7 +310,7 @@ export class MatrixService extends BaseMatrixService {
private async handleResumeCommand(roomId: string, event: MatrixRoomEvent, userId: string) {
try {
const token = this.getToken(userId);
const token = await this.getToken(userId);
if (!token) {
await this.sendReply(roomId, event, 'Keine Authentifizierung.');
return;
@ -327,7 +334,7 @@ export class MatrixService extends BaseMatrixService {
private async handleResetCommand(roomId: string, event: MatrixRoomEvent, userId: string) {
try {
const token = this.getToken(userId);
const token = await this.getToken(userId);
if (!token) {
await this.sendReply(roomId, event, 'Keine Authentifizierung.');
return;
@ -357,11 +364,14 @@ export class MatrixService extends BaseMatrixService {
const result = await this.sessionService.login(userId, email, password);
if (result.success) {
const token = this.sessionService.getToken(userId);
const token = await this.sessionService.getToken(userId);
if (token) {
const balance = await this.creditService.getBalance(token);
await this.sendReply(roomId, event,
`✅ Erfolgreich angemeldet als **${email}**\n⚡ Credits: ${balance.balance.toFixed(2)}`);
await this.sendReply(
roomId,
event,
`✅ Erfolgreich angemeldet als **${email}**\n⚡ Credits: ${balance.balance.toFixed(2)}`
);
} else {
await this.sendReply(roomId, event, `✅ Erfolgreich angemeldet als **${email}**`);
}
@ -371,15 +381,15 @@ export class MatrixService extends BaseMatrixService {
}
private async handleLogout(roomId: string, event: MatrixRoomEvent, userId: string) {
this.sessionService.logout(userId);
await this.sessionService.logout(userId);
await this.sendReply(roomId, event, '👋 Erfolgreich abgemeldet.');
}
private async handleStatusCommand(roomId: string, event: MatrixRoomEvent, userId: string) {
// Auth-Status zuerst
const loggedIn = this.sessionService.isLoggedIn(userId);
const session = this.sessionService.getSession(userId);
const token = this.sessionService.getToken(userId);
const loggedIn = await this.sessionService.isLoggedIn(userId);
const session = await this.sessionService.getSession(userId);
const token = await this.sessionService.getToken(userId);
let response = '**🕐 Clock Bot Status**\n\n';
@ -394,7 +404,7 @@ export class MatrixService extends BaseMatrixService {
// Timer-Status
try {
const timerToken = this.getToken(userId);
const timerToken = await this.getToken(userId);
if (timerToken) {
const timer = await this.clockService.getRunningTimer(timerToken);
if (timer) {
@ -421,7 +431,7 @@ export class MatrixService extends BaseMatrixService {
private async handleTimersCommand(roomId: string, event: MatrixRoomEvent, userId: string) {
try {
const token = this.getToken(userId);
const token = await this.getToken(userId);
if (!token) {
await this.sendReply(roomId, event, 'Keine Authentifizierung.');
return;
@ -448,7 +458,12 @@ export class MatrixService extends BaseMatrixService {
}
}
private async handleAlarmCommand(roomId: string, event: MatrixRoomEvent, userId: string, args: string) {
private async handleAlarmCommand(
roomId: string,
event: MatrixRoomEvent,
userId: string,
args: string
) {
const parts = args.trim().split(' ');
// Handle !alarm off/on/delete commands
@ -472,7 +487,7 @@ export class MatrixService extends BaseMatrixService {
const label = args.replace(/[\d:]+\s*(uhr\s*\d*)?/gi, '').trim() || null;
try {
const token = this.getToken(userId);
const token = await this.getToken(userId);
if (!token) {
await this.sendReply(roomId, event, 'Keine Authentifizierung.');
return;
@ -491,7 +506,7 @@ export class MatrixService extends BaseMatrixService {
private async handleAlarmsCommand(roomId: string, event: MatrixRoomEvent, userId: string) {
try {
const token = this.getToken(userId);
const token = await this.getToken(userId);
if (!token) {
await this.sendReply(roomId, event, 'Keine Authentifizierung.');
return;
@ -530,7 +545,7 @@ export class MatrixService extends BaseMatrixService {
let response = `**${timeStr} Uhr**\n${dateStr}`;
try {
const token = this.getToken(userId);
const token = await this.getToken(userId);
if (token) {
const worldClocks = await this.clockService.getWorldClocks(token);
if (worldClocks.length > 0) {
@ -552,7 +567,12 @@ export class MatrixService extends BaseMatrixService {
await this.sendReply(roomId, event, response);
}
private async handleWorldClockCommand(roomId: string, event: MatrixRoomEvent, userId: string, args: string) {
private async handleWorldClockCommand(
roomId: string,
event: MatrixRoomEvent,
userId: string,
args: string
) {
if (!args.trim()) {
await this.sendReply(
roomId,
@ -569,7 +589,7 @@ export class MatrixService extends BaseMatrixService {
return;
}
const token = this.getToken(userId);
const token = await this.getToken(userId);
if (!token) {
await this.sendReply(roomId, event, 'Keine Authentifizierung.');
return;
@ -586,7 +606,7 @@ export class MatrixService extends BaseMatrixService {
private async handleWorldClocksCommand(roomId: string, event: MatrixRoomEvent, userId: string) {
try {
const token = this.getToken(userId);
const token = await this.getToken(userId);
if (!token) {
await this.sendReply(roomId, event, 'Keine Authentifizierung.');
return;
@ -619,7 +639,12 @@ export class MatrixService extends BaseMatrixService {
}
}
private async handleNaturalLanguage(roomId: string, event: MatrixRoomEvent, userId: string, text: string) {
private async handleNaturalLanguage(
roomId: string,
event: MatrixRoomEvent,
userId: string,
text: string
) {
const lower = text.toLowerCase();
// Try to detect timer intent
@ -654,9 +679,9 @@ export class MatrixService extends BaseMatrixService {
// No match - don't respond to random messages
}
private getToken(userId: string): string | null {
private async getToken(userId: string): Promise<string | null> {
// SessionService hat Priorität (Login via mana-core-auth)
const sessionToken = this.sessionService.getToken(userId);
const sessionToken = await this.sessionService.getToken(userId);
if (sessionToken) return sessionToken;
// Fallback auf clockService Token

View file

@ -176,7 +176,7 @@ Sag "hilfe" fur alle Befehle!`;
break;
case 'logout':
this.sessionService.logout(sender);
await this.sessionService.logout(sender);
await this.sendReply(roomId, event, 'Du wurdest abgemeldet.');
break;
@ -198,7 +198,7 @@ Sag "hilfe" fur alle Befehle!`;
}
private async handleListContacts(roomId: string, event: MatrixRoomEvent, sender: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendReply(roomId, event, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -249,7 +249,7 @@ Sag "hilfe" fur alle Befehle!`;
sender: string,
searchTerm: string
) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendReply(roomId, event, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -296,7 +296,7 @@ Sag "hilfe" fur alle Befehle!`;
}
private async handleFavorites(roomId: string, event: MatrixRoomEvent, sender: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendReply(roomId, event, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -339,7 +339,7 @@ Sag "hilfe" fur alle Befehle!`;
sender: string,
args: string[]
) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendReply(roomId, event, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -411,7 +411,7 @@ Sag "hilfe" fur alle Befehle!`;
sender: string,
args: string[]
) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendReply(roomId, event, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -466,7 +466,7 @@ Sag "hilfe" fur alle Befehle!`;
sender: string,
args: string[]
) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendReply(roomId, event, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -561,7 +561,7 @@ Sag "hilfe" fur alle Befehle!`;
sender: string,
args: string[]
) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendReply(roomId, event, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -605,7 +605,7 @@ Sag "hilfe" fur alle Befehle!`;
sender: string,
args: string[]
) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendReply(roomId, event, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -649,7 +649,7 @@ Sag "hilfe" fur alle Befehle!`;
sender: string,
args: string[]
) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendReply(roomId, event, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -709,7 +709,7 @@ Sag "hilfe" fur alle Befehle!`;
const result = await this.sessionService.login(sender, email, password);
if (result.success) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (token) {
const balance = await this.creditService.getBalance(token);
await this.sendReply(
@ -731,10 +731,10 @@ Sag "hilfe" fur alle Befehle!`;
private async handleStatus(roomId: string, event: MatrixRoomEvent, sender: string) {
const backendHealthy = await this.contactsService.checkHealth();
const isLoggedIn = this.sessionService.isLoggedIn(sender);
const isLoggedIn = await this.sessionService.isLoggedIn(sender);
const sessionCount = this.sessionService.getSessionCount();
const session = this.sessionService.getSession(sender);
const token = this.sessionService.getToken(sender);
const session = await this.sessionService.getSession(sender);
const token = await this.sessionService.getToken(sender);
let statusText = `**Contacts Bot Status**\n\n`;
statusText += `**Backend:** ${backendHealthy ? '✅ Online' : '❌ Offline'}\n`;

View file

@ -27,7 +27,7 @@ export class HelpHandler {
const result = await this.sessionService.login(ctx.userId, email, password);
if (result.success) {
const token = this.sessionService.getToken(ctx.userId);
const token = await this.sessionService.getToken(ctx.userId);
if (token) {
const balance = await this.creditService.getBalance(token);
return `✅ Erfolgreich angemeldet als **${email}**\n⚡ Credits: ${balance.balance.toFixed(2)}`;
@ -38,15 +38,15 @@ export class HelpHandler {
}
async handleLogout(ctx: CommandContext): Promise<string> {
this.sessionService.logout(ctx.userId);
await this.sessionService.logout(ctx.userId);
return '👋 Erfolgreich abgemeldet.';
}
async showStatus(ctx: CommandContext): Promise<string> {
// Auth-Status zuerst
const loggedIn = this.sessionService.isLoggedIn(ctx.userId);
const session = this.sessionService.getSession(ctx.userId);
const token = this.sessionService.getToken(ctx.userId);
const loggedIn = await this.sessionService.isLoggedIn(ctx.userId);
const session = await this.sessionService.getSession(ctx.userId);
const token = await this.sessionService.getToken(ctx.userId);
let authSection = '';
if (loggedIn && session && token) {

View file

@ -71,9 +71,11 @@ export class MatrixService extends BaseMatrixService {
protected getConfig(): MatrixBotConfig {
return {
homeserverUrl: this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
homeserverUrl:
this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
accessToken: this.configService.get<string>('matrix.accessToken') || '',
storagePath: this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
storagePath:
this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
allowedRooms: this.configService.get<string[]>('matrix.allowedRooms') || [],
};
}
@ -109,7 +111,7 @@ export class MatrixService extends BaseMatrixService {
break;
case 'logout':
this.sessionService.logout(sender);
await this.sessionService.logout(sender);
await this.sendHtml(roomId, '<p>Erfolgreich abgemeldet.</p>');
break;
@ -206,8 +208,8 @@ export class MatrixService extends BaseMatrixService {
});
}
private requireAuth(sender: string): string {
const token = this.sessionService.getToken(sender);
private async requireAuth(sender: string): Promise<string> {
const token = await this.sessionService.getToken(sender);
if (!token) {
throw new Error('Nicht angemeldet. Nutze <code>!login email passwort</code>');
}
@ -225,12 +227,18 @@ export class MatrixService extends BaseMatrixService {
const result = await this.sessionService.login(sender, email, password);
if (result.success) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (token) {
const balance = await this.creditService.getBalance(token);
await this.sendHtml(roomId, `<p>✅ Erfolgreich angemeldet als <strong>${email}</strong><br/>⚡ Credits: ${balance.balance.toFixed(2)}</p>`);
await this.sendHtml(
roomId,
`<p>✅ Erfolgreich angemeldet als <strong>${email}</strong><br/>⚡ Credits: ${balance.balance.toFixed(2)}</p>`
);
} else {
await this.sendHtml(roomId, `<p>✅ Erfolgreich angemeldet als <strong>${email}</strong></p>`);
await this.sendHtml(
roomId,
`<p>✅ Erfolgreich angemeldet als <strong>${email}</strong></p>`
);
}
} else {
await this.sendHtml(roomId, `<p>❌ Login fehlgeschlagen: ${result.error}</p>`);
@ -239,10 +247,10 @@ export class MatrixService extends BaseMatrixService {
private async handleStatus(roomId: string, sender: string) {
const backendOk = await this.manadeckService.checkHealth();
const loggedIn = this.sessionService.isLoggedIn(sender);
const sessions = this.sessionService.getSessionCount();
const session = this.sessionService.getSession(sender);
const token = this.sessionService.getToken(sender);
const loggedIn = await this.sessionService.isLoggedIn(sender);
const sessions = await this.sessionService.getSessionCount();
const session = await this.sessionService.getSession(sender);
const token = await this.sessionService.getToken(sender);
let statusHtml = `<h3>ManaDeck Bot Status</h3><ul>`;
statusHtml += `<li>Backend: ${backendOk ? '✅ Online' : '❌ Offline'}</li>`;
@ -263,7 +271,7 @@ export class MatrixService extends BaseMatrixService {
// Deck handlers
private async handleListDecks(roomId: string, sender: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.manadeckService.getDecks(token);
if (result.error) {
@ -295,14 +303,11 @@ export class MatrixService extends BaseMatrixService {
}
private async handleDeckDetails(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const deck = this.getDeckByNumber(sender, numberStr);
if (!deck) {
await this.sendHtml(
roomId,
'<p>Ungueltige Nummer. Nutze zuerst <code>!decks</code></p>'
);
await this.sendHtml(roomId, '<p>Ungueltige Nummer. Nutze zuerst <code>!decks</code></p>');
return;
}
@ -332,7 +337,7 @@ export class MatrixService extends BaseMatrixService {
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const parts = title.split('|').map((s) => s.trim());
const deckTitle = parts[0];
const description = parts[1];
@ -351,14 +356,11 @@ export class MatrixService extends BaseMatrixService {
}
private async handleDeleteDeck(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const deck = this.getDeckByNumber(sender, numberStr);
if (!deck) {
await this.sendHtml(
roomId,
'<p>Ungueltige Nummer. Nutze zuerst <code>!decks</code></p>'
);
await this.sendHtml(roomId, '<p>Ungueltige Nummer. Nutze zuerst <code>!decks</code></p>');
return;
}
@ -376,14 +378,11 @@ export class MatrixService extends BaseMatrixService {
// Card handlers
private async handleListCards(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const deck = this.getDeckByNumber(sender, numberStr);
if (!deck) {
await this.sendHtml(
roomId,
'<p>Ungueltige Nummer. Nutze zuerst <code>!decks</code></p>'
);
await this.sendHtml(roomId, '<p>Ungueltige Nummer. Nutze zuerst <code>!decks</code></p>');
return;
}
@ -399,10 +398,7 @@ export class MatrixService extends BaseMatrixService {
this.currentDeckId.set(sender, deck.id);
if (cards.length === 0) {
await this.sendHtml(
roomId,
`<p>Keine Karten in <strong>${deck.title}</strong>.</p>`
);
await this.sendHtml(roomId, `<p>Keine Karten in <strong>${deck.title}</strong>.</p>`);
return;
}
@ -424,7 +420,7 @@ export class MatrixService extends BaseMatrixService {
deckNumStr: string,
cardNumStr: string
) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const deck = this.decksMapper.getByNumber(sender, parseInt(deckNumStr, 10));
if (!deck) {
@ -486,7 +482,7 @@ export class MatrixService extends BaseMatrixService {
// AI generation
private async handleGenerate(roomId: string, sender: string, argString: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
// Parse options from argString
const options: any = {};
@ -540,14 +536,11 @@ export class MatrixService extends BaseMatrixService {
// Study
private async handleStartStudy(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const deck = this.getDeckByNumber(sender, numberStr);
if (!deck) {
await this.sendHtml(
roomId,
'<p>Ungueltige Nummer. Nutze zuerst <code>!decks</code></p>'
);
await this.sendHtml(roomId, '<p>Ungueltige Nummer. Nutze zuerst <code>!decks</code></p>');
return;
}
@ -568,7 +561,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleDueCards(roomId: string, sender: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.manadeckService.getDueCards(token);
if (result.error) {
@ -592,7 +585,7 @@ export class MatrixService extends BaseMatrixService {
// Stats
private async handleStats(roomId: string, sender: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.manadeckService.getStats(token);
if (result.error) {
@ -615,7 +608,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleCredits(roomId: string, sender: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.manadeckService.getCredits(token);
if (result.error) {

View file

@ -101,7 +101,7 @@ Sag "hilfe" fur alle Befehle!`;
event: MatrixRoomEvent,
sender: string
): Promise<void> {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(
roomId,
@ -191,7 +191,7 @@ Sag "hilfe" fur alle Befehle!`;
break;
case 'logout':
this.sessionService.logout(sender);
await this.sessionService.logout(sender);
await this.sendMessage(roomId, 'Du wurdest abgemeldet.');
break;
@ -259,7 +259,7 @@ Sag "hilfe" fur alle Befehle!`;
const result = await this.sessionService.login(sender, email, password);
if (result.success) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (token) {
const balance = await this.creditService.getBalance(token);
await this.sendMessage(
@ -278,7 +278,7 @@ Sag "hilfe" fur alle Befehle!`;
}
private async handleAnalyze(roomId: string, sender: string, description: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(
roomId,
@ -287,10 +287,10 @@ Sag "hilfe" fur alle Befehle!`;
return;
}
const pendingImage = this.sessionService.getSessionData<{ url: string; mimeType: string }>(
sender,
'pendingImage'
);
const pendingImage = await this.sessionService.getSessionData<{
url: string;
mimeType: string;
}>(sender, 'pendingImage');
// If no image and no description, show help
if (!pendingImage && !description.trim()) {
@ -368,7 +368,7 @@ Sag "hilfe" fur alle Befehle!`;
}
private async handleToday(roomId: string, sender: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -428,7 +428,7 @@ Sag "hilfe" fur alle Befehle!`;
}
private async handleWeek(roomId: string, sender: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -481,7 +481,7 @@ Sag "hilfe" fur alle Befehle!`;
}
private async handleGoals(roomId: string, sender: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -512,7 +512,7 @@ Sag "hilfe" fur alle Befehle!`;
}
private async handleSetGoals(roomId: string, sender: string, args: string[]) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -564,7 +564,7 @@ Sag "hilfe" fur alle Befehle!`;
}
private async handleFavorites(roomId: string, sender: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -592,7 +592,7 @@ Sag "hilfe" fur alle Befehle!`;
}
private async handleTips(roomId: string, sender: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -624,10 +624,10 @@ Sag "hilfe" fur alle Befehle!`;
private async handleStatus(roomId: string, sender: string) {
const backendHealthy = await this.nutriphiService.checkHealth();
const isLoggedIn = this.sessionService.isLoggedIn(sender);
const isLoggedIn = await this.sessionService.isLoggedIn(sender);
const sessionCount = this.sessionService.getSessionCount();
const session = this.sessionService.getSession(sender);
const token = this.sessionService.getToken(sender);
const session = await this.sessionService.getSession(sender);
const token = await this.sessionService.getToken(sender);
let statusText = `**NutriPhi Bot Status**\n\n`;
statusText += `**Backend:** ${backendHealthy ? '✅ Online' : '❌ Offline'}\n`;

View file

@ -387,9 +387,9 @@ Schreibe einfach eine Nachricht und ich antworte!
const connected = await this.ollamaService.checkConnection();
const models = await this.ollamaService.listModels();
const session = this.getSession(sender);
const loggedIn = this.sessionService.isLoggedIn(sender);
const authSession = this.sessionService.getSession(sender);
const token = this.sessionService.getToken(sender);
const loggedIn = await this.sessionService.isLoggedIn(sender);
const authSession = await this.sessionService.getSession(sender);
const token = await this.sessionService.getToken(sender);
let statusText = `**Ollama Status**\n\n`;
statusText += `**Verbindung:** ${connected ? 'Online' : 'Offline'}\n`;

View file

@ -73,9 +73,11 @@ export class MatrixService extends BaseMatrixService {
protected getConfig(): MatrixBotConfig {
return {
homeserverUrl: this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
homeserverUrl:
this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
accessToken: this.configService.get<string>('matrix.accessToken') || '',
storagePath: this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
storagePath:
this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
allowedRooms: this.configService.get<string[]>('matrix.allowedRooms') || [],
};
}
@ -161,7 +163,7 @@ Sag "hilfe" fur alle Befehle!`;
break;
case 'logout':
this.sessionService.logout(sender);
await this.sessionService.logout(sender);
await this.sendMessage(roomId, 'Du wurdest abgemeldet.');
break;
@ -234,7 +236,7 @@ Sag "hilfe" fur alle Befehle!`;
}
// Check if user is logged in
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(
roomId,
@ -400,7 +402,7 @@ Sag "hilfe" fur alle Befehle!`;
}
private async handleHistory(roomId: string, sender: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -432,7 +434,7 @@ Sag "hilfe" fur alle Befehle!`;
}
private async handleDelete(roomId: string, sender: string, args: string[]) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -470,7 +472,7 @@ Sag "hilfe" fur alle Befehle!`;
}
private async handleCredits(roomId: string, sender: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -535,9 +537,9 @@ Sag "hilfe" fur alle Befehle!`;
private async handleStatus(roomId: string, sender: string) {
const backendHealthy = await this.pictureService.checkHealth();
const isLoggedIn = this.sessionService.isLoggedIn(sender);
const email = this.sessionService.getEmail(sender);
const token = this.sessionService.getToken(sender);
const isLoggedIn = await this.sessionService.isLoggedIn(sender);
const email = await this.sessionService.getEmail(sender);
const token = await this.sessionService.getToken(sender);
const sessionCount = this.sessionService.getSessionCount();
const currentModel = this.userModels.get(sender);
const hasActiveGeneration = this.activeGenerations.has(sender);

View file

@ -83,9 +83,11 @@ export class MatrixService extends BaseMatrixService {
protected getConfig(): MatrixBotConfig {
return {
homeserverUrl: this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
homeserverUrl:
this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
accessToken: this.configService.get<string>('matrix.accessToken') || '',
storagePath: this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
storagePath:
this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
allowedRooms: this.configService.get<string[]>('matrix.allowedRooms') || [],
};
}
@ -121,7 +123,7 @@ export class MatrixService extends BaseMatrixService {
break;
case 'logout':
this.sessionService.logout(sender);
await this.sessionService.logout(sender);
await this.sendMessage(roomId, '<p>Erfolgreich abgemeldet.</p>');
break;
@ -193,8 +195,8 @@ export class MatrixService extends BaseMatrixService {
}
}
private requireAuth(sender: string): string {
const token = this.sessionService.getToken(sender);
private async requireAuth(sender: string): Promise<string> {
const token = await this.sessionService.getToken(sender);
if (!token) {
throw new Error('Nicht angemeldet. Nutze <code>!login email passwort</code>');
}
@ -212,12 +214,18 @@ export class MatrixService extends BaseMatrixService {
const result = await this.sessionService.login(sender, email, password);
if (result.success) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (token) {
const balance = await this.creditService.getBalance(token);
await this.sendMessage(roomId, `<p>✅ Erfolgreich angemeldet als <strong>${email}</strong><br/>⚡ Credits: ${balance.balance.toFixed(2)}</p>`);
await this.sendMessage(
roomId,
`<p>✅ Erfolgreich angemeldet als <strong>${email}</strong><br/>⚡ Credits: ${balance.balance.toFixed(2)}</p>`
);
} else {
await this.sendMessage(roomId, `<p>✅ Erfolgreich angemeldet als <strong>${email}</strong></p>`);
await this.sendMessage(
roomId,
`<p>✅ Erfolgreich angemeldet als <strong>${email}</strong></p>`
);
}
} else {
await this.sendMessage(roomId, `<p>❌ Login fehlgeschlagen: ${result.error}</p>`);
@ -226,10 +234,10 @@ export class MatrixService extends BaseMatrixService {
private async handleStatus(roomId: string, sender: string) {
const backendOk = await this.plantaService.checkHealth();
const loggedIn = this.sessionService.isLoggedIn(sender);
const sessions = this.sessionService.getSessionCount();
const session = this.sessionService.getSession(sender);
const token = this.sessionService.getToken(sender);
const loggedIn = await this.sessionService.isLoggedIn(sender);
const sessions = await this.sessionService.getSessionCount();
const session = await this.sessionService.getSession(sender);
const token = await this.sessionService.getToken(sender);
let statusHtml = `<h3>Planta Bot Status</h3><ul>`;
statusHtml += `<li>Backend: ${backendOk ? '✅ Online' : '❌ Offline'}</li>`;
@ -250,7 +258,7 @@ export class MatrixService extends BaseMatrixService {
// Plant handlers
private async handleListPlants(roomId: string, sender: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.plantaService.getPlants(token);
if (result.error) {
@ -276,13 +284,14 @@ export class MatrixService extends BaseMatrixService {
html += `<li>${health} <strong>${plant.name}</strong>${scientific}</li>`;
}
html += '</ol>';
html += '<p><em>Nutze <code>!pflanze [nr]</code> fuer Details oder <code>!faellig</code> fuer Giess-Status</em></p>';
html +=
'<p><em>Nutze <code>!pflanze [nr]</code> fuer Details oder <code>!faellig</code> fuer Giess-Status</em></p>';
await this.sendMessage(roomId, html);
}
private async handlePlantDetails(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const plant = this.getPlantByNumber(sender, numberStr);
if (!plant) {
@ -312,7 +321,8 @@ export class MatrixService extends BaseMatrixService {
if (p.temperature) html += `<li>Temperatur: ${p.temperature}</li>`;
if (p.soilType) html += `<li>Erde: ${p.soilType}</li>`;
if (p.healthStatus) html += `<li>Gesundheit: ${this.translateHealth(p.healthStatus)}</li>`;
if (p.acquiredAt) html += `<li>Erworben: ${new Date(p.acquiredAt).toLocaleDateString('de-DE')}</li>`;
if (p.acquiredAt)
html += `<li>Erworben: ${new Date(p.acquiredAt).toLocaleDateString('de-DE')}</li>`;
html += '</ul>';
if (p.careNotes) {
@ -328,7 +338,7 @@ export class MatrixService extends BaseMatrixService {
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.plantaService.createPlant(token, name);
if (result.error) {
@ -346,7 +356,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleDeletePlant(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const plant = this.getPlantByNumber(sender, numberStr);
if (!plant) {
@ -378,7 +388,7 @@ export class MatrixService extends BaseMatrixService {
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const plant = this.getPlantByNumber(sender, args[0]);
if (!plant) {
@ -411,10 +421,17 @@ export class MatrixService extends BaseMatrixService {
}
} else if (field === 'lightRequirements') {
const lightMap: Record<string, string> = {
wenig: 'low', low: 'low', gering: 'low',
mittel: 'medium', medium: 'medium',
hell: 'bright', bright: 'bright', viel: 'bright',
direkt: 'direct', direct: 'direct', sonne: 'direct',
wenig: 'low',
low: 'low',
gering: 'low',
mittel: 'medium',
medium: 'medium',
hell: 'bright',
bright: 'bright',
viel: 'bright',
direkt: 'direct',
direct: 'direct',
sonne: 'direct',
};
updateValue = lightMap[value.toLowerCase()];
if (!updateValue) {
@ -426,9 +443,16 @@ export class MatrixService extends BaseMatrixService {
}
} else if (field === 'humidity') {
const humidityMap: Record<string, string> = {
niedrig: 'low', low: 'low', gering: 'low', trocken: 'low',
mittel: 'medium', medium: 'medium', normal: 'medium',
hoch: 'high', high: 'high', feucht: 'high',
niedrig: 'low',
low: 'low',
gering: 'low',
trocken: 'low',
mittel: 'medium',
medium: 'medium',
normal: 'medium',
hoch: 'high',
high: 'high',
feucht: 'high',
};
updateValue = humidityMap[value.toLowerCase()];
if (!updateValue) {
@ -456,8 +480,13 @@ export class MatrixService extends BaseMatrixService {
}
// Watering handlers
private async handleWaterPlant(roomId: string, sender: string, numberStr: string, notes?: string) {
const token = this.requireAuth(sender);
private async handleWaterPlant(
roomId: string,
sender: string,
numberStr: string,
notes?: string
) {
const token = await this.requireAuth(sender);
const plant = this.getPlantByNumber(sender, numberStr);
if (!plant) {
@ -484,7 +513,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleUpcomingWaterings(roomId: string, sender: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.plantaService.getUpcomingWaterings(token);
if (result.error) {
@ -495,7 +524,10 @@ export class MatrixService extends BaseMatrixService {
const upcoming = result.data || [];
if (upcoming.length === 0) {
await this.sendMessage(roomId, '<p>Keine Pflanzen muessen in den naechsten Tagen gegossen werden.</p>');
await this.sendMessage(
roomId,
'<p>Keine Pflanzen muessen in den naechsten Tagen gegossen werden.</p>'
);
return;
}
@ -511,13 +543,16 @@ export class MatrixService extends BaseMatrixService {
html += '</ul>';
// Store plants for reference
this.plantsMapper.setList(sender, upcoming.map(u => u.plant));
this.plantsMapper.setList(
sender,
upcoming.map((u) => u.plant)
);
await this.sendMessage(roomId, html);
}
private async handleWateringHistory(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const plant = this.getPlantByNumber(sender, numberStr);
if (!plant) {
@ -566,16 +601,18 @@ export class MatrixService extends BaseMatrixService {
await this.sendMessage(roomId, html);
}
private async handleSetInterval(roomId: string, sender: string, numberStr: string, daysStr: string) {
private async handleSetInterval(
roomId: string,
sender: string,
numberStr: string,
daysStr: string
) {
if (!numberStr || !daysStr) {
await this.sendMessage(
roomId,
'<p>Verwendung: <code>!intervall [nr] [tage]</code></p>'
);
await this.sendMessage(roomId, '<p>Verwendung: <code>!intervall [nr] [tage]</code></p>');
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const plant = this.getPlantByNumber(sender, numberStr);
if (!plant) {
@ -614,10 +651,14 @@ export class MatrixService extends BaseMatrixService {
private getHealthEmoji(status?: string): string {
switch (status) {
case 'healthy': return '&#127793;'; // Seedling
case 'needs_attention': return '&#9888;&#65039;'; // Warning
case 'sick': return '&#129314;'; // Wilted
default: return '&#127793;';
case 'healthy':
return '&#127793;'; // Seedling
case 'needs_attention':
return '&#9888;&#65039;'; // Warning
case 'sick':
return '&#129314;'; // Wilted
default:
return '&#127793;';
}
}

View file

@ -104,7 +104,7 @@ export class MatrixService extends BaseMatrixService {
break;
case 'logout':
this.sessionService.logout(sender);
await this.sessionService.logout(sender);
await this.sendMessage(roomId, '<p>Erfolgreich abgemeldet.</p>');
break;
@ -186,8 +186,8 @@ export class MatrixService extends BaseMatrixService {
}
}
private requireAuth(sender: string): string {
const token = this.sessionService.getToken(sender);
private async requireAuth(sender: string): Promise<string> {
const token = await this.sessionService.getToken(sender);
if (!token) {
throw new Error('Nicht angemeldet. Nutze <code>!login email passwort</code>');
}
@ -205,12 +205,18 @@ export class MatrixService extends BaseMatrixService {
const result = await this.sessionService.login(sender, email, password);
if (result.success) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (token) {
const balance = await this.creditService.getBalance(token);
await this.sendMessage(roomId, `<p>✅ Erfolgreich angemeldet als <strong>${email}</strong><br/>⚡ Credits: ${balance.balance.toFixed(2)}</p>`);
await this.sendMessage(
roomId,
`<p>✅ Erfolgreich angemeldet als <strong>${email}</strong><br/>⚡ Credits: ${balance.balance.toFixed(2)}</p>`
);
} else {
await this.sendMessage(roomId, `<p>✅ Erfolgreich angemeldet als <strong>${email}</strong></p>`);
await this.sendMessage(
roomId,
`<p>✅ Erfolgreich angemeldet als <strong>${email}</strong></p>`
);
}
} else {
await this.sendMessage(roomId, `<p>Login fehlgeschlagen: ${result.error}</p>`);
@ -219,10 +225,10 @@ export class MatrixService extends BaseMatrixService {
private async handleStatus(roomId: string, sender: string) {
const backendOk = await this.presiService.checkHealth();
const loggedIn = this.sessionService.isLoggedIn(sender);
const sessions = this.sessionService.getSessionCount();
const session = this.sessionService.getSession(sender);
const token = this.sessionService.getToken(sender);
const loggedIn = await this.sessionService.isLoggedIn(sender);
const sessions = await this.sessionService.getSessionCount();
const session = await this.sessionService.getSession(sender);
const token = await this.sessionService.getToken(sender);
let statusHtml = '<h3>Presi Bot Status</h3><ul>';
statusHtml += `<li>Backend: ${backendOk ? 'Online' : 'Offline'}</li>`;
@ -242,7 +248,7 @@ export class MatrixService extends BaseMatrixService {
// Deck handlers
private async handleListDecks(roomId: string, sender: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.presiService.getDecks(token);
if (result.error) {
@ -274,7 +280,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleDeckDetails(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const number = parseInt(numberStr, 10);
const deck = this.decksMapper.getByNumber(sender, number);
@ -321,7 +327,7 @@ export class MatrixService extends BaseMatrixService {
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const parts = input.split('|').map((s) => s.trim());
const title = parts[0];
const description = parts[1];
@ -342,7 +348,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleDeleteDeck(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const number = parseInt(numberStr, 10);
const deck = this.decksMapper.getByNumber(sender, number);
@ -379,7 +385,7 @@ export class MatrixService extends BaseMatrixService {
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const number = parseInt(numberStr, 10);
const deck = this.decksMapper.getByNumber(sender, number);
@ -416,7 +422,7 @@ export class MatrixService extends BaseMatrixService {
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const number = parseInt(args[0], 10);
const deck = this.decksMapper.getByNumber(sender, number);
@ -506,7 +512,7 @@ export class MatrixService extends BaseMatrixService {
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const deckNumber = parseInt(deckNumStr, 10);
const deck = this.decksMapper.getByNumber(sender, deckNumber);
@ -584,7 +590,7 @@ export class MatrixService extends BaseMatrixService {
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const deckNumber = parseInt(deckNumStr, 10);
const themeNumber = parseInt(themeNumStr, 10);
const deck = this.decksMapper.getByNumber(sender, deckNumber);
@ -621,7 +627,7 @@ export class MatrixService extends BaseMatrixService {
const args = argString.split(/\s+/);
const numberStr = args[0];
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const number = parseInt(numberStr, 10);
const deck = this.decksMapper.getByNumber(sender, number);
@ -664,7 +670,7 @@ export class MatrixService extends BaseMatrixService {
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const number = parseInt(numberStr, 10);
const deck = this.decksMapper.getByNumber(sender, number);

View file

@ -45,9 +45,11 @@ export class MatrixService extends BaseMatrixService {
protected getConfig(): MatrixBotConfig {
return {
homeserverUrl: this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
homeserverUrl:
this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
accessToken: this.configService.get<string>('matrix.accessToken') || '',
storagePath: this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
storagePath:
this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
allowedRooms: [], // This bot uses allowedUsers instead
};
}
@ -208,11 +210,13 @@ ${styles}
const result = await this.sessionService.login(sender, email, password);
if (result.success) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (token) {
const balance = await this.creditService.getBalance(token);
await this.sendMessage(roomId,
`✅ Erfolgreich angemeldet als **${email}**\n⚡ Credits: ${balance.balance.toFixed(2)}`);
await this.sendMessage(
roomId,
`✅ Erfolgreich angemeldet als **${email}**\n⚡ Credits: ${balance.balance.toFixed(2)}`
);
} else {
await this.sendMessage(roomId, `✅ Erfolgreich angemeldet als **${email}**`);
}
@ -222,14 +226,14 @@ ${styles}
}
private async handleLogout(roomId: string, sender: string) {
this.sessionService.logout(sender);
await this.sessionService.logout(sender);
await this.sendMessage(roomId, '👋 Erfolgreich abgemeldet.');
}
private async handleAuthStatus(roomId: string, sender: string) {
const loggedIn = this.sessionService.isLoggedIn(sender);
const session = this.sessionService.getSession(sender);
const token = this.sessionService.getToken(sender);
const loggedIn = await this.sessionService.isLoggedIn(sender);
const session = await this.sessionService.getSession(sender);
const token = await this.sessionService.getToken(sender);
let response = '**📋 Account Status**\n\n';
@ -328,9 +332,9 @@ ${styles}
private async showStatus(roomId: string, sender: string) {
// Auth info
const loggedIn = this.sessionService.isLoggedIn(sender);
const session = this.sessionService.getSession(sender);
const token = this.sessionService.getToken(sender);
const loggedIn = await this.sessionService.isLoggedIn(sender);
const session = await this.sessionService.getSession(sender);
const token = await this.sessionService.getToken(sender);
let authInfo = '';
if (loggedIn && session && token) {
@ -340,14 +344,20 @@ ${styles}
const projectId = this.activeProjects.get(sender);
if (!projectId) {
await this.sendMessage(roomId, `${authInfo}Kein aktives Projekt.\n\nStarte mit: \`!new Projektname\``);
await this.sendMessage(
roomId,
`${authInfo}Kein aktives Projekt.\n\nStarte mit: \`!new Projektname\``
);
return;
}
const project = await this.projectService.findById(projectId);
if (!project) {
this.activeProjects.delete(sender);
await this.sendMessage(roomId, `${authInfo}Projekt nicht gefunden. Starte ein neues mit \`!new\``);
await this.sendMessage(
roomId,
`${authInfo}Projekt nicht gefunden. Starte ein neues mit \`!new\``
);
return;
}
@ -475,7 +485,11 @@ ${styles}
}
}
private async handleImage(roomId: string, sender: string, content: { url: string; info?: { mimetype?: string }; body?: string }) {
private async handleImage(
roomId: string,
sender: string,
content: { url: string; info?: { mimetype?: string }; body?: string }
) {
const projectId = this.activeProjects.get(sender);
if (!projectId) {
await this.sendMessage(roomId, 'Kein aktives Projekt.\n\nStarte mit: `!new Projektname`');
@ -499,7 +513,11 @@ ${styles}
}
}
private async handleAudio(roomId: string, sender: string, content: { url: string; info?: { mimetype?: string; duration?: number } }) {
private async handleAudio(
roomId: string,
sender: string,
content: { url: string; info?: { mimetype?: string; duration?: number } }
) {
const projectId = this.activeProjects.get(sender);
if (!projectId) {
await this.sendMessage(roomId, 'Kein aktives Projekt.\n\nStarte mit: `!new Projektname`');

View file

@ -103,7 +103,7 @@ export class MatrixService extends BaseMatrixService {
break;
case 'logout':
this.sessionService.logout(sender);
await this.sessionService.logout(sender);
await this.sendMessage(roomId, '<p>Erfolgreich abgemeldet.</p>');
break;
@ -189,8 +189,8 @@ export class MatrixService extends BaseMatrixService {
}
}
private requireAuth(sender: string): string {
const token = this.sessionService.getToken(sender);
private async requireAuth(sender: string): Promise<string> {
const token = await this.sessionService.getToken(sender);
if (!token) {
throw new Error('Nicht angemeldet. Nutze <code>!login email passwort</code>');
}
@ -208,12 +208,18 @@ export class MatrixService extends BaseMatrixService {
const result = await this.sessionService.login(sender, email, password);
if (result.success) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (token) {
const balance = await this.creditService.getBalance(token);
await this.sendMessage(roomId, `<p>✅ Erfolgreich angemeldet als <strong>${email}</strong><br/>⚡ Credits: ${balance.balance.toFixed(2)}</p>`);
await this.sendMessage(
roomId,
`<p>✅ Erfolgreich angemeldet als <strong>${email}</strong><br/>⚡ Credits: ${balance.balance.toFixed(2)}</p>`
);
} else {
await this.sendMessage(roomId, `<p>✅ Erfolgreich angemeldet als <strong>${email}</strong></p>`);
await this.sendMessage(
roomId,
`<p>✅ Erfolgreich angemeldet als <strong>${email}</strong></p>`
);
}
} else {
await this.sendMessage(roomId, `<p>Login fehlgeschlagen: ${result.error}</p>`);
@ -222,10 +228,10 @@ export class MatrixService extends BaseMatrixService {
private async handleStatus(roomId: string, sender: string) {
const backendOk = await this.skilltreeService.checkHealth();
const loggedIn = this.sessionService.isLoggedIn(sender);
const sessions = this.sessionService.getSessionCount();
const session = this.sessionService.getSession(sender);
const token = this.sessionService.getToken(sender);
const loggedIn = await this.sessionService.isLoggedIn(sender);
const sessions = await this.sessionService.getSessionCount();
const session = await this.sessionService.getSession(sender);
const token = await this.sessionService.getToken(sender);
let statusHtml = '<h3>Skilltree Bot Status</h3><ul>';
statusHtml += `<li>Backend: ${backendOk ? 'Online' : 'Offline'}</li>`;
@ -245,7 +251,7 @@ export class MatrixService extends BaseMatrixService {
// Skill handlers
private async handleListSkills(roomId: string, sender: string, branchFilter?: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
let branch: string | undefined;
if (branchFilter) {
@ -292,7 +298,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleSkillDetails(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const number = parseInt(numberStr, 10);
const skill = this.skillsMapper.getByNumber(sender, number);
@ -338,7 +344,7 @@ export class MatrixService extends BaseMatrixService {
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const parts = input.split('|').map((s) => s.trim());
const name = parts[0];
const branchInput = parts[1]?.toLowerCase() || 'custom';
@ -371,7 +377,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleDeleteSkill(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const number = parseInt(numberStr, 10);
const skill = this.skillsMapper.getByNumber(sender, number);
@ -403,7 +409,7 @@ export class MatrixService extends BaseMatrixService {
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const number = parseInt(args[0], 10);
const skill = this.skillsMapper.getByNumber(sender, number);
@ -454,7 +460,7 @@ export class MatrixService extends BaseMatrixService {
// Stats handler
private async handleStats(roomId: string, sender: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.skilltreeService.getStats(token);
if (result.error) {
@ -478,7 +484,7 @@ export class MatrixService extends BaseMatrixService {
// Activities handler
private async handleActivities(roomId: string, sender: string, numberStr?: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
let result;
let skillName = '';

View file

@ -8,7 +8,13 @@ import {
KeywordCommandDetector,
COMMON_KEYWORDS,
} from '@manacore/matrix-bot-common';
import { StorageService, StorageFile, Folder, ShareLink, TrashItem } from '../storage/storage.service';
import {
StorageService,
StorageFile,
Folder,
ShareLink,
TrashItem,
} from '../storage/storage.service';
import { SessionService, TranscriptionService, CreditService } from '@manacore/bot-services';
import { HELP_MESSAGE } from '../config/configuration';
@ -44,9 +50,11 @@ export class MatrixService extends BaseMatrixService {
protected getConfig(): MatrixBotConfig {
return {
homeserverUrl: this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
homeserverUrl:
this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
accessToken: this.configService.get<string>('matrix.accessToken') || '',
storagePath: this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
storagePath:
this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
allowedRooms: this.configService.get<string[]>('matrix.allowedRooms') || [],
};
}
@ -82,7 +90,7 @@ export class MatrixService extends BaseMatrixService {
break;
case 'logout':
this.sessionService.logout(sender);
await this.sessionService.logout(sender);
await this.sendMessage(roomId, '<p>Erfolgreich abgemeldet.</p>');
break;
@ -229,8 +237,8 @@ export class MatrixService extends BaseMatrixService {
}
}
private requireAuth(sender: string): string {
const token = this.sessionService.getToken(sender);
private async requireAuth(sender: string): Promise<string> {
const token = await this.sessionService.getToken(sender);
if (!token) {
throw new Error('Nicht angemeldet. Nutze <code>!login email passwort</code>');
}
@ -248,12 +256,18 @@ export class MatrixService extends BaseMatrixService {
const result = await this.sessionService.login(sender, email, password);
if (result.success) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (token) {
const balance = await this.creditService.getBalance(token);
await this.sendMessage(roomId, `<p>✅ Erfolgreich angemeldet als <strong>${email}</strong><br/>⚡ Credits: ${balance.balance.toFixed(2)}</p>`);
await this.sendMessage(
roomId,
`<p>✅ Erfolgreich angemeldet als <strong>${email}</strong><br/>⚡ Credits: ${balance.balance.toFixed(2)}</p>`
);
} else {
await this.sendMessage(roomId, `<p>✅ Erfolgreich angemeldet als <strong>${email}</strong></p>`);
await this.sendMessage(
roomId,
`<p>✅ Erfolgreich angemeldet als <strong>${email}</strong></p>`
);
}
} else {
await this.sendMessage(roomId, `<p>Login fehlgeschlagen: ${result.error}</p>`);
@ -262,10 +276,10 @@ export class MatrixService extends BaseMatrixService {
private async handleStatus(roomId: string, sender: string) {
const backendOk = await this.storageService.checkHealth();
const loggedIn = this.sessionService.isLoggedIn(sender);
const sessions = this.sessionService.getSessionCount();
const session = this.sessionService.getSession(sender);
const token = this.sessionService.getToken(sender);
const loggedIn = await this.sessionService.isLoggedIn(sender);
const sessions = await this.sessionService.getSessionCount();
const session = await this.sessionService.getSession(sender);
const token = await this.sessionService.getToken(sender);
let statusHtml = '<h3>Storage Bot Status</h3><ul>';
statusHtml += `<li>Backend: ${backendOk ? 'Online' : 'Offline'}</li>`;
@ -285,7 +299,7 @@ export class MatrixService extends BaseMatrixService {
// File handlers
private async handleListFiles(roomId: string, sender: string, folderNumStr?: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
let parentFolderId: string | undefined;
if (folderNumStr) {
@ -322,17 +336,21 @@ export class MatrixService extends BaseMatrixService {
html += `<li><strong>${file.name}</strong> (${size})${fav}</li>`;
}
html += '</ol>';
html += '<p><em>Nutze <code>!datei [nr]</code> fuer Details oder <code>!download [nr]</code></em></p>';
html +=
'<p><em>Nutze <code>!datei [nr]</code> fuer Details oder <code>!download [nr]</code></em></p>';
await this.sendMessage(roomId, html);
}
private async handleFileDetails(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const file = this.getFileByNumber(sender, numberStr);
if (!file) {
await this.sendMessage(roomId, '<p>Ungueltige Nummer. Nutze zuerst <code>!dateien</code></p>');
await this.sendMessage(
roomId,
'<p>Ungueltige Nummer. Nutze zuerst <code>!dateien</code></p>'
);
return;
}
@ -357,11 +375,14 @@ export class MatrixService extends BaseMatrixService {
}
private async handleDownload(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const file = this.getFileByNumber(sender, numberStr);
if (!file) {
await this.sendMessage(roomId, '<p>Ungueltige Nummer. Nutze zuerst <code>!dateien</code></p>');
await this.sendMessage(
roomId,
'<p>Ungueltige Nummer. Nutze zuerst <code>!dateien</code></p>'
);
return;
}
@ -379,11 +400,14 @@ export class MatrixService extends BaseMatrixService {
}
private async handleDeleteFile(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const file = this.getFileByNumber(sender, numberStr);
if (!file) {
await this.sendMessage(roomId, '<p>Ungueltige Nummer. Nutze zuerst <code>!dateien</code></p>');
await this.sendMessage(
roomId,
'<p>Ungueltige Nummer. Nutze zuerst <code>!dateien</code></p>'
);
return;
}
@ -395,20 +419,31 @@ export class MatrixService extends BaseMatrixService {
}
this.filesMapper.clearList(sender);
await this.sendMessage(roomId, `<p><strong>${file.name}</strong> in Papierkorb verschoben.</p>`);
await this.sendMessage(
roomId,
`<p><strong>${file.name}</strong> in Papierkorb verschoben.</p>`
);
}
private async handleRenameFile(roomId: string, sender: string, numberStr: string, newName: string) {
private async handleRenameFile(
roomId: string,
sender: string,
numberStr: string,
newName: string
) {
if (!newName) {
await this.sendMessage(roomId, '<p>Verwendung: <code>!umbenennen [nr] neuer name</code></p>');
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const file = this.getFileByNumber(sender, numberStr);
if (!file) {
await this.sendMessage(roomId, '<p>Ungueltige Nummer. Nutze zuerst <code>!dateien</code></p>');
await this.sendMessage(
roomId,
'<p>Ungueltige Nummer. Nutze zuerst <code>!dateien</code></p>'
);
return;
}
@ -419,11 +454,19 @@ export class MatrixService extends BaseMatrixService {
return;
}
await this.sendMessage(roomId, `<p><strong>${file.name}</strong> umbenannt zu <strong>${newName}</strong></p>`);
await this.sendMessage(
roomId,
`<p><strong>${file.name}</strong> umbenannt zu <strong>${newName}</strong></p>`
);
}
private async handleMoveFile(roomId: string, sender: string, fileNumStr: string, folderNumStr: string) {
const token = this.requireAuth(sender);
private async handleMoveFile(
roomId: string,
sender: string,
fileNumStr: string,
folderNumStr: string
) {
const token = await this.requireAuth(sender);
const file = this.getFileByNumber(sender, fileNumStr);
if (!file) {
@ -437,7 +480,10 @@ export class MatrixService extends BaseMatrixService {
if (folderNumStr && folderNumStr !== '0' && folderNumStr.toLowerCase() !== 'root') {
const folder = this.getFolderByNumber(sender, folderNumStr);
if (!folder) {
await this.sendMessage(roomId, '<p>Ungueltige Ordner-Nummer. Nutze 0 oder root fuer Root.</p>');
await this.sendMessage(
roomId,
'<p>Ungueltige Ordner-Nummer. Nutze 0 oder root fuer Root.</p>'
);
return;
}
parentFolderId = folder.id;
@ -451,12 +497,15 @@ export class MatrixService extends BaseMatrixService {
return;
}
await this.sendMessage(roomId, `<p><strong>${file.name}</strong> nach <strong>${folderName}</strong> verschoben.</p>`);
await this.sendMessage(
roomId,
`<p><strong>${file.name}</strong> nach <strong>${folderName}</strong> verschoben.</p>`
);
}
// Folder handlers
private async handleListFolders(roomId: string, sender: string, folderNumStr?: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
let parentFolderId: string | undefined;
if (folderNumStr) {
@ -497,11 +546,14 @@ export class MatrixService extends BaseMatrixService {
private async handleCreateFolder(roomId: string, sender: string, args: string[]) {
if (args.length === 0) {
await this.sendMessage(roomId, '<p>Verwendung: <code>!neuordner Name [in-ordner-nr]</code></p>');
await this.sendMessage(
roomId,
'<p>Verwendung: <code>!neuordner Name [in-ordner-nr]</code></p>'
);
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
// Check if last arg is a number (parent folder)
let parentFolderId: string | undefined;
@ -528,7 +580,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleDeleteFolder(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const folder = this.getFolderByNumber(sender, numberStr);
if (!folder) {
@ -544,12 +596,15 @@ export class MatrixService extends BaseMatrixService {
}
this.foldersMapper.clearList(sender);
await this.sendMessage(roomId, `<p>Ordner <strong>${folder.name}</strong> in Papierkorb verschoben.</p>`);
await this.sendMessage(
roomId,
`<p>Ordner <strong>${folder.name}</strong> in Papierkorb verschoben.</p>`
);
}
// Share handlers
private async handleShareFile(roomId: string, sender: string, argString: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
// Parse arguments
const args = argString.split(/\s+/);
@ -557,7 +612,10 @@ export class MatrixService extends BaseMatrixService {
const file = this.getFileByNumber(sender, numberStr);
if (!file) {
await this.sendMessage(roomId, '<p>Ungueltige Nummer. Nutze zuerst <code>!dateien</code></p>');
await this.sendMessage(
roomId,
'<p>Ungueltige Nummer. Nutze zuerst <code>!dateien</code></p>'
);
return;
}
@ -601,7 +659,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleListShares(roomId: string, sender: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.storageService.getShares(token);
if (result.error) {
@ -619,8 +677,12 @@ export class MatrixService extends BaseMatrixService {
let html = '<h3>Share-Links</h3><ol>';
for (const share of shares) {
const expires = share.expiresAt ? ` (bis ${new Date(share.expiresAt).toLocaleDateString('de-DE')})` : '';
const downloads = share.maxDownloads ? ` [${share.downloadCount}/${share.maxDownloads}]` : ` [${share.downloadCount} DL]`;
const expires = share.expiresAt
? ` (bis ${new Date(share.expiresAt).toLocaleDateString('de-DE')})`
: '';
const downloads = share.maxDownloads
? ` [${share.downloadCount}/${share.maxDownloads}]`
: ` [${share.downloadCount} DL]`;
html += `<li>${share.shareType}${expires}${downloads}</li>`;
}
html += '</ol>';
@ -630,7 +692,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleDeleteShare(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
if (!this.sharesMapper.hasList(sender)) {
await this.sendMessage(roomId, '<p>Nutze zuerst <code>!links</code></p>');
@ -661,7 +723,7 @@ export class MatrixService extends BaseMatrixService {
return;
}
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.storageService.search(token, query);
if (result.error) {
@ -700,7 +762,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleFavorites(roomId: string, sender: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.storageService.getFavorites(token);
if (result.error) {
@ -739,7 +801,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleToggleFavorite(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
// Try file first
const file = this.getFileByNumber(sender, numberStr);
@ -772,7 +834,7 @@ export class MatrixService extends BaseMatrixService {
// Trash handlers
private async handleTrash(roomId: string, sender: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.storageService.getTrash(token);
if (result.error) {
@ -801,7 +863,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleRestore(roomId: string, sender: string, numberStr: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
if (!this.trashMapper.hasList(sender)) {
await this.sendMessage(roomId, '<p>Nutze zuerst <code>!papierkorb</code></p>');
@ -826,7 +888,7 @@ export class MatrixService extends BaseMatrixService {
}
private async handleEmptyTrash(roomId: string, sender: string) {
const token = this.requireAuth(sender);
const token = await this.requireAuth(sender);
const result = await this.storageService.emptyTrash(token);
if (result.error) {

View file

@ -50,9 +50,11 @@ export class MatrixService extends BaseMatrixService {
protected getConfig(): MatrixBotConfig {
return {
homeserverUrl: this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
homeserverUrl:
this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
accessToken: this.configService.get<string>('matrix.accessToken') || '',
storagePath: this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
storagePath:
this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
allowedRooms: this.configService.get<string[]>('matrix.allowedRooms') || [],
};
}
@ -189,7 +191,12 @@ export class MatrixService extends BaseMatrixService {
}
}
private async handleVoiceCommand(roomId: string, event: MatrixRoomEvent, userId: string, args: string) {
private async handleVoiceCommand(
roomId: string,
event: MatrixRoomEvent,
userId: string,
args: string
) {
if (!args.trim()) {
await this.sendReply(
roomId,
@ -253,7 +260,12 @@ export class MatrixService extends BaseMatrixService {
}
}
private async handleSpeedCommand(roomId: string, event: MatrixRoomEvent, userId: string, args: string) {
private async handleSpeedCommand(
roomId: string,
event: MatrixRoomEvent,
userId: string,
args: string
) {
if (!args.trim()) {
await this.sendReply(
roomId,
@ -279,9 +291,9 @@ export class MatrixService extends BaseMatrixService {
private async handleStatusCommand(roomId: string, event: MatrixRoomEvent, userId: string) {
const settings = this.getUserSettings(userId);
const ttsHealthy = await this.ttsService.isHealthy();
const loggedIn = this.sessionService.isLoggedIn(userId);
const session = this.sessionService.getSession(userId);
const token = this.sessionService.getToken(userId);
const loggedIn = await this.sessionService.isLoggedIn(userId);
const session = await this.sessionService.getSession(userId);
const token = await this.sessionService.getToken(userId);
let response = '**Aktuelle Einstellungen:**\n\n';
response += `Stimme: \`${settings.voice}\`\n`;
@ -298,7 +310,12 @@ export class MatrixService extends BaseMatrixService {
await this.sendReply(roomId, event, response);
}
private async handleTextToSpeech(roomId: string, event: MatrixRoomEvent, userId: string, text: string) {
private async handleTextToSpeech(
roomId: string,
event: MatrixRoomEvent,
userId: string,
text: string
) {
// Check text length
if (text.length > this.maxTextLength) {
await this.sendReply(

View file

@ -41,9 +41,11 @@ export class MatrixService extends BaseMatrixService {
protected getConfig(): MatrixBotConfig {
return {
homeserverUrl: this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
homeserverUrl:
this.configService.get<string>('matrix.homeserverUrl') || 'http://localhost:8008',
accessToken: this.configService.get<string>('matrix.accessToken') || '',
storagePath: this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
storagePath:
this.configService.get<string>('matrix.storagePath') || './data/bot-storage.json',
allowedRooms: this.configService.get<string[]>('matrix.allowedRooms') || [],
};
}
@ -200,7 +202,7 @@ Sag "hilfe" fuer alle Befehle!`;
break;
case 'logout':
this.sessionService.logout(sender);
await this.sessionService.logout(sender);
await this.sendMessage(roomId, 'Du wurdest abgemeldet.');
break;
@ -273,7 +275,10 @@ Sag "hilfe" fuer alle Befehle!`;
private async handleSearch(roomId: string, sender: string, searchText: string) {
if (!searchText.trim()) {
await this.sendMessage(roomId, '**Verwendung:** `!suche [text]`\n\nBeispiel: `!suche Glueck`');
await this.sendMessage(
roomId,
'**Verwendung:** `!suche [text]`\n\nBeispiel: `!suche Glueck`'
);
return;
}
@ -362,7 +367,7 @@ Sag "hilfe" fuer alle Befehle!`;
const result = await this.sessionService.login(sender, email, password);
if (result.success) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (token) {
const balance = await this.creditService.getBalance(token);
await this.sendMessage(
@ -381,7 +386,7 @@ Sag "hilfe" fuer alle Befehle!`;
}
private async handleAddFavorite(roomId: string, sender: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -410,7 +415,7 @@ Sag "hilfe" fuer alle Befehle!`;
}
private async handleFavorites(roomId: string, sender: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -449,7 +454,7 @@ Sag "hilfe" fuer alle Befehle!`;
}
private async handleLists(roomId: string, sender: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -484,7 +489,7 @@ Sag "hilfe" fuer alle Befehle!`;
}
private async handleCreateList(roomId: string, sender: string, name: string) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -511,7 +516,7 @@ Sag "hilfe" fuer alle Befehle!`;
}
private async handleAddToList(roomId: string, sender: string, args: string[]) {
const token = this.sessionService.getToken(sender);
const token = await this.sessionService.getToken(sender);
if (!token) {
await this.sendMessage(roomId, `Du bist nicht angemeldet. Nutze \`!login\` zuerst.`);
return;
@ -563,11 +568,11 @@ Sag "hilfe" fuer alle Befehle!`;
private async handleStatus(roomId: string, sender: string) {
const backendHealthy = await this.zitareService.checkHealth();
const isLoggedIn = this.sessionService.isLoggedIn(sender);
const isLoggedIn = await this.sessionService.isLoggedIn(sender);
const sessionCount = this.sessionService.getSessionCount();
const totalQuotes = this.quotesService.getTotalCount();
const session = this.sessionService.getSession(sender);
const token = this.sessionService.getToken(sender);
const session = await this.sessionService.getSession(sender);
const token = await this.sessionService.getToken(sender);
let statusText = `**Zitare Bot Status**\n\n`;
statusText += `**Backend:** ${backendHealthy ? 'Online' : 'Offline'}\n`;