package telegram // 本文件锁定 **Telegram 入站语音**的字节内联(切片 IM-ASR):「渠道零改动」这条承诺要 // 在**真适配器**上被验证一次 —— 语音只有 `file_id` + `audio/ogg`(没有文件名、没有 // 扩展名),因此音频白名单必须能靠平台声明的 MIME 命中,否则 telegram 语音会被整条 // 挡掉。夹具复用 media_test.go 的假 Bot API。 import ( "context" "encoding/json" "fmt" "testing" ) // voiceUpdate 构造一条 Telegram 语音消息的原始 update(无 caption:纯语音)。 func voiceUpdate(fileID, mime string, size int64) []byte { body := map[string]any{ "update_id": 3, "message": map[string]any{ "message_id": 44, "date": 1700000002, "chat": map[string]any{"id": 7, "type": "private"}, "from": map[string]any{"id": 9, "first_name": "主人"}, "voice": map[string]any{"file_id": fileID, "file_size": size, "mime_type": mime, "duration": 3}, }, } raw, err := json.Marshal(body) if err != nil { panic(fmt.Sprintf("marshal update: %v", err)) } return raw } // TestInboundVoiceIsInlined 是正向用例:语音 ⇒ getFile ⇒ 下载 ⇒ Data 被填, // 且本切片**一行适配器代码都没改**(因此它同时是「渠道零改动」的回归保护)。 func TestInboundVoiceIsInlined(t *testing.T) { t.Parallel() s := newTGAssetServer(t) a, h, _ := newInlineAdapter(t, s) if _, err := a.ProcessUpdate(context.Background(), voiceUpdate("voice-id", "audio/ogg", 1024)); err != nil { t.Fatalf("ProcessUpdate: %v", err) } msg := h.message(t) if msg.Content != "" { t.Fatalf("Content = %q, want 空(纯语音没有 caption,转写由桥接器负责)", msg.Content) } if len(msg.Media) != 1 || string(msg.Media[0].Data) != "附件的正文\n" { t.Fatalf("Media.Data = %q, want 下载到的语音字节", msg.Media[0].Data) } if msg.Media[0].URL != "voice-id" || msg.Media[0].MIMEType != "audio/ogg" { t.Fatalf("内联改动了媒体元数据:%+v", msg.Media[0]) } if s.getFile.Load() != 1 || s.fileHits.Load() != 1 { t.Fatalf("getFile=%d fileHits=%d, want 1/1(MIME 兜底必须命中音频白名单)", s.getFile.Load(), s.fileHits.Load()) } } // TestInboundVoiceWithoutMIMEIsNotDownloaded 钉住 deny-by-default:平台既没给文件名也 // 没给类型时**不发起任何请求**(宁可诚实说读不到,也不猜一份类型不明的音频)。 func TestInboundVoiceWithoutMIMEIsNotDownloaded(t *testing.T) { t.Parallel() s := newTGAssetServer(t) a, h, _ := newInlineAdapter(t, s) if _, err := a.ProcessUpdate(context.Background(), voiceUpdate("voice-id", "", 1024)); err != nil { t.Fatalf("ProcessUpdate: %v", err) } msg := h.message(t) if len(msg.Media[0].Data) != 0 { t.Fatalf("类型不明的语音被内联了(%d 字节)", len(msg.Media[0].Data)) } if s.allHits.Load() != 0 { t.Fatalf("类型不明的语音仍发起了请求:all=%d", s.allHits.Load()) } }