package stt import ( "encoding/json" "strings" "time" ) func ParseElevenLabsEvent(data []byte) (Event, error) { var m map[string]any if err := json.Unmarshal(data, &m); err != nil { return Event{}, err } typ := strings.ToLower(toString(m["type"])) text := firstString(m, "text", "transcript", "partial", "final") lang := firstString(m, "language", "language_code") ev := Event{Text: text, Language: lang, At: time.Now().UTC(), Metadata: map[string]any{}} switch typ { case "partial_transcript", "partial", "transcript.partial": ev.Type = EventPartialTranscript case "final_transcript", "final", "transcript.final": ev.Type = EventFinalTranscript case "committed_transcript", "committed", "transcript.committed": ev.Type = EventCommittedTranscript case "speech_started", "speech.start", "vad.speech_started": ev.Type = EventSpeechStarted case "speech_ended", "speech.end", "vad.speech_ended": ev.Type = EventSpeechEnded case "error": ev.Type = EventError ev.Error = firstString(m, "error", "message") case "closed": ev.Type = EventClosed default: if final, _ := m["is_final"].(bool); final && text != "" { ev.Type = EventCommittedTranscript } else if text != "" { ev.Type = EventPartialTranscript } } return ev, nil } func firstString(m map[string]any, keys ...string) string { for _, k := range keys { if s := toString(m[k]); s != "" { return s } } return "" } func toString(v any) string { if s, ok := v.(string); ok { return s } return "" }