Merge pull request 'feat(talk): ElevenLabs TTS voice notification package' (#17) from feat/talk-package into master

Reviewed-on: #17
This commit was merged in pull request #17.
This commit is contained in:
2026-07-02 18:53:06 +02:00
2 changed files with 114 additions and 0 deletions
+1
View File
@@ -33,6 +33,7 @@ in {
openwork = pkgs.callPackage ./openwork {};
zellij-ps = pkgs.callPackage ./zellij-ps {};
vibetyper = pkgs.callPackage ./vibetyper {};
talk = pkgs.callPackage ./talk {};
# ── Pass-through packages ──────────────────────────────────────────
# Imported directly from flake inputs. No local modifications.
+113
View File
@@ -0,0 +1,113 @@
{
lib,
stdenv,
writeShellScriptBin,
curl,
python3,
mpv,
libnotify,
busybox,
}: let
script = writeShellScriptBin "talk" ''
#!/usr/bin/env bash
set -euo pipefail
# Toggle: VOICE_NOTIFY=0 deaktiviert alles
if [ "''${VOICE_NOTIFY:-1}" = "0" ]; then
exit 0
fi
# Config
API_KEY="''${ELEVENLABS_API_KEY:?Set ELEVENLABS_API_KEY in your environment}"
VOICE_ID="''${ELEVENLABS_VOICE_ID:-KXxZd16DiBqt82nbarJx}"
TEXT="''${1:?Usage: talk \"Text zum Sprechen\"}"
AUDIO_FILE="/tmp/voice-notify-$$.mp3"
ACTION_FILE="/tmp/voice-action-$$"
CURL="${lib.getExe curl}"
PYTHON="${lib.getExe python3}"
MPV="${lib.getExe mpv}"
NOTIFY="${lib.getExe libnotify}"
RM="${busybox}/bin/rm"
CAT="${busybox}/bin/cat"
GREP="${busybox}/bin/grep"
SLEEP="${busybox}/bin/sleep"
KILL="${busybox}/bin/kill"
STAT="${busybox}/bin/stat"
trap '$RM -f "$AUDIO_FILE" "$ACTION_FILE"' EXIT
# TTS generieren
PAYLOAD=$("$PYTHON" -c '
import json, sys
print(json.dumps({
"text": sys.argv[1],
"model_id": "eleven_multilingual_v2",
"voice_settings": {"stability": 0.5, "similarity_boost": 0.75}
}))
' "$TEXT")
HTTP_CODE=$("$CURL" -s -o "$AUDIO_FILE" -w "%{http_code}" \
-X POST "https://api.elevenlabs.io/v1/text-to-speech/''${VOICE_ID}" \
-H "xi-api-key: ''${API_KEY}" \
-H "Content-Type: application/json" \
-d "$PAYLOAD") || HTTP_CODE="000"
if [ "$HTTP_CODE" != "200" ]; then
ERR=$($CAT "$AUDIO_FILE" 2>/dev/null | head -c 300)
$RM -f "$AUDIO_FILE"
"$NOTIFY" -u critical " Voice Fehler" "HTTP ''${HTTP_CODE}\n''${ERR}"
exit 1
fi
# Gleichzeitig: Audio + Notification
"$MPV" --no-video --no-terminal --really-quiet "$AUDIO_FILE" &
MPV_PID=$!
(
exec "$NOTIFY" \
--action=cancel=" Abbrechen" \
--urgency=normal \
--icon=audio-x-generic \
"🔊 KI Antwort" \
"$TEXT" > "$ACTION_FILE" 2>/dev/null
) &
NOTIFY_PID=$!
# Poll-Loop
while true; do
if ! $KILL -0 "$MPV_PID" 2>/dev/null; then
$KILL "$NOTIFY_PID" 2>/dev/null || true
break
fi
if [ -f "$ACTION_FILE" ]; then
if $GREP -q "cancel" "$ACTION_FILE" 2>/dev/null; then
$KILL "$MPV_PID" 2>/dev/null || true
fi
break
fi
$SLEEP 0.2
done
wait "$MPV_PID" 2>/dev/null || true
'';
in
stdenv.mkDerivation {
pname = "talk";
version = "0.1.0";
dontUnpack = true;
installPhase = ''
mkdir -p "$out/bin"
ln -s ${script}/bin/talk "$out/bin/talk"
'';
meta = with lib; {
description = "ElevenLabs TTS voice notifications with dismissable popup";
homepage = "https://code.m3ta.dev/m3tam3re/nixpkgs";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "talk";
};
}