fix: move voice-bubble detection into Telegram channel to avoid regression in other channels

Address review feedback: keep inferMediaType returning "audio" for all
OGG files. Voice-bubble detection (SendVoice vs SendAudio) is now done
inside the Telegram channel based on filename, so other channels that
map "audio" explicitly are unaffected.
This commit is contained in:
Orkun Manap 2026-03-23 00:11:05 +01:00
parent b47a32e89a
commit 4ba86894a6
4 changed files with 22 additions and 23 deletions

View file

@ -1152,12 +1152,6 @@ func inferMediaType(filename, contentType string) string {
ct := strings.ToLower(contentType) ct := strings.ToLower(contentType)
fn := strings.ToLower(filename) fn := strings.ToLower(filename)
// Detect voice messages: OGG files with "voice" in the filename.
// These are sent as Telegram voice bubbles rather than audio attachments.
if strings.Contains(fn, "voice") && (strings.HasSuffix(fn, ".ogg") || strings.HasSuffix(fn, ".oga")) {
return "voice"
}
if strings.HasPrefix(ct, "image/") { if strings.HasPrefix(ct, "image/") {
return "image" return "image"
} }

View file

@ -480,15 +480,19 @@ func (c *TelegramChannel) SendMedia(ctx context.Context, msg bus.OutboundMediaMe
} }
_, err = c.bot.SendDocument(ctx, docParams) _, err = c.bot.SendDocument(ctx, docParams)
} }
case "voice": case "audio":
params := &telego.SendVoiceParams{ // Send OGG files with "voice" in the filename as Telegram voice
// bubbles (SendVoice) instead of audio attachments (SendAudio).
fn := strings.ToLower(part.Filename)
if strings.Contains(fn, "voice") && (strings.HasSuffix(fn, ".ogg") || strings.HasSuffix(fn, ".oga")) {
vparams := &telego.SendVoiceParams{
ChatID: tu.ID(chatID), ChatID: tu.ID(chatID),
MessageThreadID: threadID, MessageThreadID: threadID,
Voice: telego.InputFile{File: file}, Voice: telego.InputFile{File: file},
Caption: part.Caption, Caption: part.Caption,
} }
_, err = c.bot.SendVoice(ctx, params) _, err = c.bot.SendVoice(ctx, vparams)
case "audio": } else {
params := &telego.SendAudioParams{ params := &telego.SendAudioParams{
ChatID: tu.ID(chatID), ChatID: tu.ID(chatID),
MessageThreadID: threadID, MessageThreadID: threadID,
@ -496,6 +500,7 @@ func (c *TelegramChannel) SendMedia(ctx context.Context, msg bus.OutboundMediaMe
Caption: part.Caption, Caption: part.Caption,
} }
_, err = c.bot.SendAudio(ctx, params) _, err = c.bot.SendAudio(ctx, params)
}
case "video": case "video":
params := &telego.SendVideoParams{ params := &telego.SendVideoParams{
ChatID: tu.ID(chatID), ChatID: tu.ID(chatID),

View file

@ -87,7 +87,7 @@ func (t *ElevenLabsTranscriber) Transcribe(ctx context.Context, audioFilePath st
} }
req.Header.Set("Content-Type", writer.FormDataContentType()) req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("xi-api-key", t.apiKey) req.Header.Set("Xi-Api-Key", t.apiKey)
logger.DebugCF("voice", "Sending transcription request to ElevenLabs API", map[string]any{ logger.DebugCF("voice", "Sending transcription request to ElevenLabs API", map[string]any{
"url": url, "url": url,

View file

@ -32,8 +32,8 @@ func TestElevenLabsTranscribe(t *testing.T) {
if r.URL.Path != "/v1/speech-to-text" { if r.URL.Path != "/v1/speech-to-text" {
t.Errorf("unexpected path: %s", r.URL.Path) t.Errorf("unexpected path: %s", r.URL.Path)
} }
if r.Header.Get("xi-api-key") != "sk_test" { if r.Header.Get("Xi-Api-Key") != "sk_test" {
t.Errorf("unexpected xi-api-key header: %s", r.Header.Get("xi-api-key")) t.Errorf("unexpected xi-api-key header: %s", r.Header.Get("Xi-Api-Key"))
} }
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(TranscriptionResponse{ _ = json.NewEncoder(w).Encode(TranscriptionResponse{