Zum Hauptinhalt springen

Zurück zum Devlog

Samstag, 14. Februar 2026

Feature

56 Commits

18 min Lesezeit

Matrix STT Bot, Gift Code UI & Onboarding Bot

Speech-to-Text Bot für Matrix, Gift Code Web-Interface, Clock Bot Timer-Progress, Onboarding Bot für Profil-Setup und umfangreiche Bot-Fixes.

T

Till Schneider

Autor

Produktiver Valentinstag mit 56 Commits und vielen neuen Features:

  • Matrix STT Bot - Speech-to-Text direkt in Matrix
  • Gift Code UI - Web-Interface für Geschenkcode-Verwaltung
  • Onboarding Bot - Matrix Bot für Profil-Setup
  • Clock Bot Timer - Live Progress mit Message Editing
  • TTS German Voice - Kerstin als neue deutsche Stimme
  • Emoji Picker - Recently Used + WhatsApp-Style Input

Matrix STT Bot

Neuer Bot für Speech-to-Text-Transkription in Matrix.

Features

FeatureBeschreibung
Voice MessagesAutomatische Transkription
Multi-LanguageDeutsch, Englisch, weitere
Inline ResponseTranskription als Reply
High AccuracyWhisper Large V3

Architektur

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  Matrix Room    │────>│  STT Bot        │────>│  mana-stt       │
│  (Voice Msg)    │     │  (Port 3340)    │     │  (Whisper)      │
└─────────────────┘     └─────────────────┘     └─────────────────┘
         │                      │                       │
         │                      ▼                       │
         │              ┌─────────────────┐             │
         │              │  Transcription  │<────────────┘
         │              │  Result         │
         │              └────────┬────────┘
         │                       │
         ▼                       ▼
┌─────────────────────────────────────────┐
│  Matrix Room: Reply with Transcription  │
└─────────────────────────────────────────┘

Dockerfile Pattern

# Gleiche Struktur wie TTS Bot
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile

COPY . .
RUN pnpm build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/main.js"]

Gift Code Web UI

Web-Interface für Geschenkcode-Einlösung und Verwaltung.

Benutzer-Interface

┌─────────────────────────────────────────────────────┐
│              🎁 Geschenkcode einlösen               │
├─────────────────────────────────────────────────────┤
│                                                      │
│  ┌──────────────────────────────────────────────┐   │
│  │  CODE-XXXX-XXXX-XXXX                        │   │
│  └──────────────────────────────────────────────┘   │
│                                                      │
│               [ Einlösen ]                          │
│                                                      │
├─────────────────────────────────────────────────────┤
│  Meine eingelösten Codes:                           │
│  ✅ 500 Credits - 14.02.2026                        │
│  ✅ Pro Subscription 1 Month - 01.02.2026           │
└─────────────────────────────────────────────────────┘

API Endpoints

EndpointMethodBeschreibung
/api/gifts/redeemPOSTCode einlösen
/api/gifts/meGETEigene eingelöste Codes
/api/gifts/me/historyGETEinlöse-Historie

Gift Types

type GiftType =
	| 'credits' // Direkte Credits
	| 'subscription' // Abo-Zeit
	| 'first_come' // Begrenzte Anzahl
	| 'unlimited'; // Unbegrenzt einlösbar

Bugfixes

  • userId undefined - Guard verwendet userId, Controller erwartete sub
  • Duplicate Claim Check für first_come Type
  • Nullable Fields explizit auf null gesetzt für Drizzle

Onboarding Bot

Matrix Bot für geführtes Profil-Setup neuer Nutzer.

Onboarding Flow

┌─────────────────────────────────────────────────────┐
│              Onboarding Bot Flow                     │
├─────────────────────────────────────────────────────┤
│                                                      │
│  1. 👋 Willkommen! Wie heißt du?                    │
│     └─ User: "Max"                                  │
│                                                      │
│  2. 📸 Möchtest du ein Profilbild hochladen?        │
│     └─ User: [Bild] oder "Überspringen"             │
│                                                      │
│  3. 🎂 Wann hast du Geburtstag?                     │
│     └─ User: "15.03.1990"                           │
│                                                      │
│  4. 🌍 Welche Sprache bevorzugst du?                │
│     └─ User: "Deutsch"                              │
│                                                      │
│  5. ✅ Profil komplett! Viel Spaß!                  │
│                                                      │
└─────────────────────────────────────────────────────┘

State Machine

enum OnboardingState {
	WELCOME = 'welcome',
	NAME = 'name',
	AVATAR = 'avatar',
	BIRTHDAY = 'birthday',
	LANGUAGE = 'language',
	COMPLETE = 'complete',
}

// Transitions
const transitions = {
	[OnboardingState.WELCOME]: OnboardingState.NAME,
	[OnboardingState.NAME]: OnboardingState.AVATAR,
	[OnboardingState.AVATAR]: OnboardingState.BIRTHDAY,
	[OnboardingState.BIRTHDAY]: OnboardingState.LANGUAGE,
	[OnboardingState.LANGUAGE]: OnboardingState.COMPLETE,
};

Clock Bot Timer Progress

Live-Timer mit Message-Editing für Echtzeit-Updates.

Feature

Timer gestartet: 5 Minuten

┌────────────────────────────────┐
│  ⏱️ Timer                       │
│  ████████░░░░░░░░░░ 3:42       │
│                                │
│  Verbleibend: 3 Minuten 42 Sek │
└────────────────────────────────┘

Room Topic Updates

Timer-Status wird auch im Room Topic angezeigt:

// Phase 3: Room Topic Integration
async function updateRoomTopic(roomId: string, timerStatus: string) {
	await client.sendStateEvent(roomId, 'm.room.topic', '', {
		topic: `⏱️ ${timerStatus}`,
	});
}

Widget Styling

Optimiert für Element Info Panel:

/* Kompaktes Layout für Widget */
.timer-widget {
	padding: 8px;
	font-size: 14px;
	background: var(--element-bg);
}

TTS German Voice

Neue deutsche Stimme “Kerstin” für natürlichere Sprachausgabe.

Verfügbare Stimmen

VoiceLanguageGenderEngine
de_kerstinDeutschFemalePiper
de_thorstenDeutschMalePiper
en_amyEnglishFemalePiper

Auto-Endpoint

// /synthesize/auto wählt automatisch passende Stimme
POST /synthesize/auto
{
  "text": "Hallo, wie geht es dir?",
  // Automatisch: de_kerstin (erkannt: Deutsch)
}

WAV Format

Für bessere Matrix-Kompatibilität auf WAV gewechselt:

// Vorher: MP3 (Probleme mit Element)
// Nachher: WAV (native Unterstützung)
const format = 'wav';

Emoji Picker Improvements

WhatsApp-Style Input und Recently Used Emojis.

Recently Used

┌─────────────────────────────────────────────────────┐
│  Kürzlich verwendet:                                 │
│  😀 😂 ❤️ 👍 🎉 🔥 💯 ✨                           │
├─────────────────────────────────────────────────────┤
│  Smileys & Menschen:                                 │
│  😀 😃 😄 😁 😆 😅 🤣 😂 ...                        │
└─────────────────────────────────────────────────────┘

Cross-App Sync

Recently Used Emojis werden über mana-core-auth synchronisiert:

// API Endpoint
GET / api / users / me / preferences / emojis;
POST / api / users / me / preferences / emojis;

WhatsApp-Style Input

<div class="chat-input">
	<button class="emoji-trigger" on:click={togglePicker}> 😀 </button>
	<textarea bind:value={message} />
	<button class="send" on:click={send}> ➤ </button>
</div>

NutriPhi Bot Improvements

Auto-Analyze Text

Mahlzeiten können jetzt auch als Text beschrieben werden:

User: Ich hatte heute Morgen 2 Scheiben Toast mit Butter und Marmelade

Bot: 🍽️ Mahlzeit erkannt:
     - 2x Toast: 140 kcal
     - Butter (20g): 144 kcal
     - Marmelade (30g): 78 kcal
     ─────────────────
     Gesamt: 362 kcal

Fixes

  • Gemini Model Update: gemini-2.0-flash-expgemini-2.5-flash
  • Korrektes API-Feldname für Bildanalyse
  • Dockerfile: Shared Packages hinzugefügt

Stats Bot Infrastructure Monitoring

Neue Commands für Server-Überwachung.

Commands

!infra status     - Service-Status aller Container
!infra memory     - Memory-Verbrauch
!infra cpu        - CPU-Auslastung
!infra disk       - Festplatten-Status
!infra network    - Netzwerk-Traffic

Prometheus Integration

// Metriken direkt aus Prometheus abrufen
const metrics = await prometheus.query('up{job=~".*backend.*"}');

Bot-to-Bot Loop Prevention

Fix für endlose Bot-Antwort-Schleifen.

Problem

User → Bot A → Bot B → Bot A → Bot B → ...

Lösung

// Ignoriere Messages von anderen Bots
if (isBot(event.sender)) {
	return; // Keine Antwort
}

// Ignoriere Edit-Events
if (event.content['m.relates_to']?.rel_type === 'm.replace') {
	return;
}

Session Auto-Refresh

Automatische JWT-Token-Erneuerung bei Ablauf.

// Interceptor für automatisches Refresh
async function fetchWithRefresh(url: string, options: RequestInit) {
	const response = await fetch(url, options);

	if (response.status === 401) {
		await refreshToken();
		return fetch(url, {
			...options,
			headers: {
				...options.headers,
				Authorization: `Bearer ${getNewToken()}`,
			},
		});
	}

	return response;
}

Umami Analytics Update

Tracking IDs für alle Web-Apps aktualisiert.

Betroffene Apps

AppNeue Tracking ID
manacore-webmanacore-prod
chat-webchat-prod
calendar-webcalendar-prod
clock-webclock-prod
contacts-webcontacts-prod
todo-webtodo-prod
picture-webpicture-prod
zitare-webzitare-prod

Zusammenfassung

BereichCommitsHighlights
Matrix STT3Speech-to-Text Bot
Gift Codes6Web UI + Fixes
Onboarding2Profile Setup Bot
Clock Bot4Timer Progress + Topic
TTS4German Voice + WAV
Emoji Picker3Recently Used + Sync
NutriPhi5Text-Analyse + Fixes
Stats Bot3Infra Monitoring
Bot Fixes8Loop Prevention + Auth
Session2Auto-Refresh
Analytics2Umami Update
Sonstige14Diverse Fixes

Nächste Schritte

  1. Onboarding UI in Web-Apps integrieren
  2. Gift Code Admin Dashboard
  3. Voice-to-Voice Matrix Bots
  4. Multi-Room Timer Sync

Tags

#matrix #stt #speech-to-text #gift-codes #onboarding #clock-bot #timer #tts #german-voice #emoji-picker #nutriphi #stats-bot