diff --git a/.env.example b/.env.example
index 29fda33..4b3e9e8 100644
--- a/.env.example
+++ b/.env.example
@@ -6,5 +6,5 @@ DATA_DIR=./data
# Telegram Bot Integration
TELEGRAM_BOT_TOKEN=
TELEGRAM_ALLOWED_CHAT_IDS=
-OPENAI_API_KEY=
+GEMINI_API_KEY=
diff --git a/telegram.js b/telegram.js
index be0d10b..14776fb 100644
--- a/telegram.js
+++ b/telegram.js
@@ -77,34 +77,48 @@ async function downloadTelegramFile(filePath) {
return await res.arrayBuffer();
}
-// Transcribe OGG/Opus voice data using OpenAI Whisper API
+// Transcribe OGG/Opus voice data using Google Gemini 1.5 Flash API (100% Free)
async function transcribeVoice(audioBuffer) {
- if (!process.env.OPENAI_API_KEY) {
- throw new Error("OPENAI_API_KEY is not configured in .env.");
+ const geminiKey = process.env.GEMINI_API_KEY;
+ if (!geminiKey) {
+ throw new Error("GEMINI_API_KEY is not configured in .env.");
}
- const formData = new FormData();
- // Whisper requires the ogg/opus file to have a proper filename extension
- const blob = new Blob([audioBuffer], { type: "audio/ogg" });
- formData.append("file", blob, "voice.ogg");
- formData.append("model", "whisper-1");
- formData.append("language", "de");
+ const base64Audio = Buffer.from(audioBuffer).toString("base64");
+ const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${geminiKey}`;
- const res = await fetch("https://api.openai.com/v1/audio/transcriptions", {
+ const res = await fetch(url, {
method: "POST",
headers: {
- Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
+ "Content-Type": "application/json",
},
- body: formData,
+ body: JSON.stringify({
+ contents: [
+ {
+ parts: [
+ {
+ inlineData: {
+ mimeType: "audio/ogg",
+ data: base64Audio,
+ },
+ },
+ {
+ text: "Transkribiere diese Sprachnachricht wortgetreu in deutschen Text. Gib NUR die Transkription zurück, ohne Einleitung, Kommentare oder sonstige Zusätze. Falls nichts verständlich gesprochen wurde, antworte mit einem leeren Text.",
+ },
+ ],
+ },
+ ],
+ }),
});
if (!res.ok) {
const errorText = await res.text();
- throw new Error(`OpenAI Whisper API failed (${res.status}): ${errorText}`);
+ throw new Error(`Gemini API failed (${res.status}): ${errorText}`);
}
const data = await res.json();
- return data.text || "";
+ const text = data.candidates?.[0]?.content?.parts?.[0]?.text || "";
+ return text.trim();
}
// Fetch available contacts from Monica to perform NLP name matching
@@ -180,10 +194,10 @@ async function handleUpdate(update) {
// 2. Extract text (either message text or transcribe voice note)
if (voice) {
isVoice = true;
- if (!process.env.OPENAI_API_KEY) {
+ if (!process.env.GEMINI_API_KEY) {
await sendTelegramMessage(
chatId,
- "⚠️ Sprachnachrichten deaktiviert:\nEs ist kein OPENAI_API_KEY in der .env-Konfiguration hinterlegt. Bitte sende stattdessen Textnachrichten oder füge den API-Key hinzu.",
+ "⚠️ Sprachnachrichten deaktiviert:\nEs ist kein GEMINI_API_KEY in der .env-Konfiguration hinterlegt. Bitte erstelle einen kostenlosen Key im Google AI Studio und füge ihn hinzu.",
message.message_id
);
return;
@@ -204,7 +218,7 @@ async function handleUpdate(update) {
// Download file binary
const audioBuffer = await downloadTelegramFile(fileInfo.result.file_path);
- // Transcribe via Whisper
+ // Transcribe via Gemini
processedText = await transcribeVoice(audioBuffer);
if (!processedText.trim()) {
await sendTelegramMessage(
@@ -262,7 +276,7 @@ async function handleUpdate(update) {
let responseText = `Eintrag erfasst! ✅\n\n`;
if (isVoice) {
- responseText += `🎤 Transkription:\n"${escapeHtml(processedText)}"\n\n`;
+ responseText += `🎤 Transkription (Gemini):\n"${escapeHtml(processedText)}"\n\n`;
}
if (analysis.contact) {