This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/admin-v2/ai-compliance-sdk/internal/academy/elevenlabs_client.go
BreakPilot Dev ac1bb1d97b
Some checks failed
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
ci/woodpecker/push/integration Pipeline failed
ci/woodpecker/push/main Pipeline failed
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
feat: Implement Compliance Academy E-Learning module (Phases 1-7)
Add complete Academy backend (Go) and frontend (Next.js) for DSGVO/IT-Security/AI-Literacy compliance training:
- Go backend: Course CRUD, enrollments, quiz evaluation, PDF certificates (gofpdf), video generation pipeline (ElevenLabs + HeyGen)
- In-memory data store with PostgreSQL migration for future DB support
- Frontend: Course creation (AI + manual), lesson viewer, interactive quiz, certificate viewer with PDF download
- Fix existing compile errors in generate.go (SearchResult type mismatch), llm/service.go (unused var), rag/service.go (Unicode chars)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 21:18:51 +01:00

106 lines
2.5 KiB
Go

package academy
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
// ElevenLabsClient handles text-to-speech via the ElevenLabs API
type ElevenLabsClient struct {
apiKey string
voiceID string
client *http.Client
}
// NewElevenLabsClient creates a new ElevenLabs client
func NewElevenLabsClient() *ElevenLabsClient {
apiKey := os.Getenv("ELEVENLABS_API_KEY")
voiceID := os.Getenv("ELEVENLABS_VOICE_ID")
if voiceID == "" {
voiceID = "EXAVITQu4vr4xnSDxMaL" // Default: "Sarah" voice
}
return &ElevenLabsClient{
apiKey: apiKey,
voiceID: voiceID,
client: &http.Client{
Timeout: 120 * time.Second,
},
}
}
// IsConfigured returns true if API key is set
func (c *ElevenLabsClient) IsConfigured() bool {
return c.apiKey != ""
}
// TextToSpeechRequest represents the API request
type TextToSpeechRequest struct {
Text string `json:"text"`
ModelID string `json:"model_id"`
VoiceSettings VoiceSettings `json:"voice_settings"`
}
// VoiceSettings controls voice parameters
type VoiceSettings struct {
Stability float64 `json:"stability"`
SimilarityBoost float64 `json:"similarity_boost"`
Style float64 `json:"style"`
}
// TextToSpeech converts text to speech audio (MP3)
func (c *ElevenLabsClient) TextToSpeech(text string) ([]byte, error) {
if !c.IsConfigured() {
return nil, fmt.Errorf("ElevenLabs API key not configured")
}
url := fmt.Sprintf("https://api.elevenlabs.io/v1/text-to-speech/%s", c.voiceID)
reqBody := TextToSpeechRequest{
Text: text,
ModelID: "eleven_multilingual_v2",
VoiceSettings: VoiceSettings{
Stability: 0.5,
SimilarityBoost: 0.75,
Style: 0.5,
},
}
jsonBody, err := json.Marshal(reqBody)
if err != nil {
return nil, fmt.Errorf("failed to marshal request: %w", err)
}
req, err := http.NewRequest("POST", url, bytes.NewReader(jsonBody))
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("xi-api-key", c.apiKey)
req.Header.Set("Accept", "audio/mpeg")
resp, err := c.client.Do(req)
if err != nil {
return nil, fmt.Errorf("ElevenLabs API request failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("ElevenLabs API error %d: %s", resp.StatusCode, string(body))
}
audioData, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read audio response: %w", err)
}
return audioData, nil
}