diff --git a/pkg/channels/discord.go b/pkg/channels/discord.go index 342ddb478..deacbc7d5 100644 --- a/pkg/channels/discord.go +++ b/pkg/channels/discord.go @@ -3,7 +3,6 @@ package channels import ( "context" "fmt" - "os" "strings" "sync" "time" @@ -210,19 +209,10 @@ func (c *DiscordChannel) handleMessage(s *discordgo.Session, m *discordgo.Messag content := m.Content content = c.stripBotMention(content) mediaPaths := make([]string, 0, len(m.Attachments)) - localFiles := make([]string, 0, len(m.Attachments)) - - // Ensure temp files are cleaned up when function returns - defer func() { - for _, file := range localFiles { - if err := os.Remove(file); err != nil { - logger.DebugCF("discord", "Failed to cleanup temp file", map[string]any{ - "file": file, - "error": err.Error(), - }) - } - } - }() + // Note: media files in os.TempDir()/picoclaw_media/ are not cleaned up here + // because HandleMessage publishes to an async message bus. The consumer + // goroutine may still need these files after this function returns. + // Temp files are managed by OS temp directory lifecycle. for _, attachment := range m.Attachments { isAudio := utils.IsAudioFile(attachment.Filename, attachment.ContentType) @@ -230,8 +220,6 @@ func (c *DiscordChannel) handleMessage(s *discordgo.Session, m *discordgo.Messag if isAudio { localPath := c.downloadAttachment(attachment.URL, attachment.Filename) if localPath != "" { - localFiles = append(localFiles, localPath) - transcribedText := "" if c.transcriber != nil && c.transcriber.IsAvailable() { ctx, cancel := context.WithTimeout(c.getContext(), transcriptionTimeout) diff --git a/pkg/channels/line.go b/pkg/channels/line.go index 9f7d2bde0..ec7ac9e72 100644 --- a/pkg/channels/line.go +++ b/pkg/channels/line.go @@ -10,7 +10,6 @@ import ( "fmt" "io" "net/http" - "os" "strings" "sync" "time" @@ -307,18 +306,10 @@ func (c *LINEChannel) processEvent(event lineEvent) { var content string var mediaPaths []string - localFiles := []string{} - - defer func() { - for _, file := range localFiles { - if err := os.Remove(file); err != nil { - logger.DebugCF("line", "Failed to cleanup temp file", map[string]interface{}{ - "file": file, - "error": err.Error(), - }) - } - } - }() + // Note: media files in os.TempDir()/picoclaw_media/ are not cleaned up here + // because HandleMessage publishes to an async message bus. The consumer + // goroutine may still need these files after this function returns. + // Temp files are managed by OS temp directory lifecycle. switch msg.Type { case "text": @@ -330,21 +321,18 @@ func (c *LINEChannel) processEvent(event lineEvent) { case "image": localPath := c.downloadContent(msg.ID, "image.jpg") if localPath != "" { - localFiles = append(localFiles, localPath) mediaPaths = append(mediaPaths, localPath) content = "[image]" } case "audio": localPath := c.downloadContent(msg.ID, "audio.m4a") if localPath != "" { - localFiles = append(localFiles, localPath) mediaPaths = append(mediaPaths, localPath) content = "[audio]" } case "video": localPath := c.downloadContent(msg.ID, "video.mp4") if localPath != "" { - localFiles = append(localFiles, localPath) mediaPaths = append(mediaPaths, localPath) content = "[video]" } diff --git a/pkg/channels/slack.go b/pkg/channels/slack.go index 0060972ed..f7a337195 100644 --- a/pkg/channels/slack.go +++ b/pkg/channels/slack.go @@ -3,7 +3,6 @@ package channels import ( "context" "fmt" - "os" "strings" "sync" "time" @@ -232,19 +231,10 @@ func (c *SlackChannel) handleMessageEvent(ev *slackevents.MessageEvent) { content = c.stripBotMention(content) var mediaPaths []string - localFiles := []string{} // 跟踪需要清理的本地文件 - - // 确保临时文件在函数返回时被清理 - defer func() { - for _, file := range localFiles { - if err := os.Remove(file); err != nil { - logger.DebugCF("slack", "Failed to cleanup temp file", map[string]interface{}{ - "file": file, - "error": err.Error(), - }) - } - } - }() + // Note: media files in os.TempDir()/picoclaw_media/ are not cleaned up here + // because HandleMessage publishes to an async message bus. The consumer + // goroutine may still need these files after this function returns. + // Temp files are managed by OS temp directory lifecycle. if ev.Message != nil && len(ev.Message.Files) > 0 { for _, file := range ev.Message.Files { @@ -252,7 +242,6 @@ func (c *SlackChannel) handleMessageEvent(ev *slackevents.MessageEvent) { if localPath == "" { continue } - localFiles = append(localFiles, localPath) mediaPaths = append(mediaPaths, localPath) if utils.IsAudioFile(file.Name, file.Mimetype) && c.transcriber != nil && c.transcriber.IsAvailable() { diff --git a/pkg/channels/telegram.go b/pkg/channels/telegram.go index 20bbf6830..c64fb7126 100644 --- a/pkg/channels/telegram.go +++ b/pkg/channels/telegram.go @@ -221,19 +221,10 @@ func (c *TelegramChannel) handleMessage(ctx context.Context, message *telego.Mes content := "" mediaPaths := []string{} - localFiles := []string{} // 跟踪需要清理的本地文件 - - // 确保临时文件在函数返回时被清理 - defer func() { - for _, file := range localFiles { - if err := os.Remove(file); err != nil { - logger.DebugCF("telegram", "Failed to cleanup temp file", map[string]interface{}{ - "file": file, - "error": err.Error(), - }) - } - } - }() + // Note: media files in os.TempDir()/picoclaw_media/ are not cleaned up here + // because HandleMessage publishes to an async message bus. The consumer + // goroutine may still need these files after this function returns. + // Temp files are managed by OS temp directory lifecycle. if message.Text != "" { content += message.Text @@ -250,7 +241,6 @@ func (c *TelegramChannel) handleMessage(ctx context.Context, message *telego.Mes photo := message.Photo[len(message.Photo)-1] photoPath := c.downloadPhoto(ctx, photo.FileID) if photoPath != "" { - localFiles = append(localFiles, photoPath) mediaPaths = append(mediaPaths, photoPath) if content != "" { content += "\n" @@ -262,7 +252,6 @@ func (c *TelegramChannel) handleMessage(ctx context.Context, message *telego.Mes if message.Voice != nil { voicePath := c.downloadFile(ctx, message.Voice.FileID, ".ogg") if voicePath != "" { - localFiles = append(localFiles, voicePath) mediaPaths = append(mediaPaths, voicePath) transcribedText := "" @@ -297,7 +286,6 @@ func (c *TelegramChannel) handleMessage(ctx context.Context, message *telego.Mes if message.Audio != nil { audioPath := c.downloadFile(ctx, message.Audio.FileID, ".mp3") if audioPath != "" { - localFiles = append(localFiles, audioPath) mediaPaths = append(mediaPaths, audioPath) if content != "" { content += "\n" @@ -309,7 +297,6 @@ func (c *TelegramChannel) handleMessage(ctx context.Context, message *telego.Mes if message.Document != nil { docPath := c.downloadFile(ctx, message.Document.FileID, "") if docPath != "" { - localFiles = append(localFiles, docPath) mediaPaths = append(mediaPaths, docPath) if content != "" { content += "\n"