使用Telego发送音频时自定义标题与表演者不生效的问题求助
问题:发送音频时指定的Title和Performer不生效
发送音频时,代码中设置的title和performer参数未生效,音频显示的是文件自身的元数据,或是该文件首次上传到Telegram服务器时的信息。但发送Telegram从未存储过、且自身无标题/表演者元数据的文件时,指定的参数能正常生效。使用的是Golang的telego库。
代码示例
func main() { botToken := "token" bot, err := telego.NewBot(botToken, telego.WithDefaultDebugLogger()) if err != nil { fmt.Println(err) os.Exit(1) } updates, _ := bot.UpdatesViaLongPolling(nil) defer bot.StopLongPolling() // 自定义获取音频参数的包 var m music.Music m.Authorization() for update := range updates { if update.Message != nil { chatID := tu.ID(update.Message.Chat.ID) // 获取音频参数 params, err := m.GetAudioParams(update.Message.Text) if err != nil { _, _ = bot.SendMessage(&telego.SendMessageParams{ ChatID: chatID, Text: err.Error(), }) continue } // 通过URL创建音频参数 audio := tu.Audio(chatID, tu.FileByURL(params.URL)) // 设置表演者 audio.WithPerformer(params.Performer) // 设置标题 audio.WithTitle(params.Title) _, _ = bot.SendAudio(audio) } } }
调试响应
[Mon Apr 24 17:40:17 MSK 2023] DEBUG API call to: "https://api.telegram.org/botBOT_TOKEN/sendAudio", with data: {"chat_id":848447660,"audio":"https://s147iva.storage.yandex.net/get-mp3/bda9fda28fe66f5e3d4032b4a10bd888/0005fa16d2d871bc/rmusic/U2FsdGVkX19wkWz_DC4Mg4N6EoV332DXOynFrntt3AvzEYKgmcZd93n6fMrhy5u9Mcb7YcBr14nlkBrKxiEvJ2HXUM3AQ7RRFvxNXFkyYGU/575f1549004e4aa8ecc991e6696224e6af4248ddad339812300119ffbff2b6a8/27023","performer":"Performer","title":"Title"} [Mon Apr 24 17:40:18 MSK 2023] DEBUG API response sendAudio: Ok: true, Err: [<nil>], Result: {"message_id":90,"from":{"id":6210745530,"is_bot":true,"first_name":"ya_music","username":"cleonia_music_bot"},"chat":{"id":848447660,"first_name":"Даниил","username":"Cleonia_21","type":"private"},"date":1682347218,"audio":{"duration":171,"file_name":"27023.mp3","mime_type":"audio/mpeg","file_id":"CQACAgQAAxkDAANaZEaU0qB2MyMvdaurhgOqYkDQdaoAAtsDAAIXTDVSLA0Gj1gWr_gvBA","file_unique_id":"AgAD2wMAAhdMNVI","file_size":4116480}}
解决方案
这是Telegram API的机制导致的:当音频文件已经在Telegram服务器的缓存中存在时,API会复用已存储的文件信息,忽略你传入的title和performer参数。要强制使用自定义参数,需要让Telegram将文件视为新文件重新处理,最可靠的方法是本地上传文件,而不是直接使用URL。
修改后的代码示例
func main() { botToken := "token" bot, err := telego.NewBot(botToken, telego.WithDefaultDebugLogger()) if err != nil { fmt.Println(err) os.Exit(1) } updates, _ := bot.UpdatesViaLongPolling(nil) defer bot.StopLongPolling() var m music.Music m.Authorization() for update := range updates { if update.Message != nil { chatID := tu.ID(update.Message.Chat.ID) params, err := m.GetAudioParams(update.Message.Text) if err != nil { _, _ = bot.SendMessage(&telego.SendMessageParams{ ChatID: chatID, Text: err.Error(), }) continue } // 1. 下载音频文件到本地临时文件 resp, err := http.Get(params.URL) if err != nil { _, _ = bot.SendMessage(&telego.SendMessageParams{ ChatID: chatID, Text: "下载音频失败: " + err.Error(), }) continue } defer resp.Body.Close() tempFile, err := os.CreateTemp("", "audio-*.mp3") if err != nil { _, _ = bot.SendMessage(&telego.SendMessageParams{ ChatID: chatID, Text: "创建临时文件失败: " + err.Error(), }) continue } defer os.Remove(tempFile.Name()) // 上传完成后删除临时文件 _, err = io.Copy(tempFile, resp.Body) if err != nil { _, _ = bot.SendMessage(&telego.SendMessageParams{ ChatID: chatID, Text: "保存音频失败: " + err.Error(), }) continue } // 重置文件指针到开头,确保能正常读取 _, err = tempFile.Seek(0, io.SeekStart) if err != nil { _, _ = bot.SendMessage(&telego.SendMessageParams{ ChatID: chatID, Text: "读取临时文件失败: " + err.Error(), }) continue } // 2. 使用本地文件创建音频参数,而非直接用URL audio := tu.Audio(chatID, tu.FileByReader(tempFile.Name(), tempFile)) audio.WithPerformer(params.Performer) audio.WithTitle(params.Title) _, _ = bot.SendAudio(audio) } } }
原理说明
通过本地上传文件,Telegram会将其视为全新的文件,不再复用缓存中的旧信息,此时你设置的title和performer会被正确应用,覆盖文件自身的元数据。
另外也可以尝试在原URL后添加随机查询参数(比如params.URL + "?rand=" + strconv.Itoa(rand.Intn(1000000))),让Telegram认为是新URL并重新下载,但这种方法稳定性较差——如果文件内容哈希一致,Telegram仍可能复用缓存,因此本地上传是更可靠的方案。
内容的提问来源于stack exchange,提问作者Cleonia
相关产品推荐
相关产品推荐

