mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-25 07:00:48 +09:00
fix(channel): resolve attachment filename and prevent duplicate sends
- Derive attachment name from path basename when not explicitly set in parseAttachmentDelta, fixing the "file.bin" fallback on Telegram. - Infer correct AttachmentType (image/audio/video) from MIME in applyAssetToAttachment instead of keeping the generic "file" type. - Remove outboundAttachments re-attachment to final messages since attachments are already delivered during streaming via StreamEventAttachment, preventing duplicate file sends on platforms.
This commit is contained in:
@@ -394,9 +394,8 @@ func (p *ChannelInboundProcessor) HandleInbound(ctx context.Context, cfg channel
|
||||
})
|
||||
|
||||
var (
|
||||
finalMessages []conversation.ModelMessage
|
||||
outboundAttachments []channel.Attachment
|
||||
streamErr error
|
||||
finalMessages []conversation.ModelMessage
|
||||
streamErr error
|
||||
)
|
||||
for chunkCh != nil || streamErrCh != nil {
|
||||
select {
|
||||
@@ -422,7 +421,6 @@ func (p *ChannelInboundProcessor) HandleInbound(ctx context.Context, cfg channel
|
||||
if event.Type == channel.StreamEventAttachment && len(event.Attachments) > 0 {
|
||||
ingested := p.ingestOutboundAttachments(ctx, strings.TrimSpace(identity.BotID), event.Attachments)
|
||||
events[i].Attachments = ingested
|
||||
outboundAttachments = append(outboundAttachments, ingested...)
|
||||
assetMu.Lock()
|
||||
for _, att := range ingested {
|
||||
contentHash := strings.TrimSpace(att.ContentHash)
|
||||
@@ -506,10 +504,9 @@ func (p *ChannelInboundProcessor) HandleInbound(ctx context.Context, cfg channel
|
||||
}
|
||||
|
||||
outputs := flow.ExtractAssistantOutputs(finalMessages)
|
||||
attachmentsApplied := false
|
||||
for _, output := range outputs {
|
||||
outMessage := buildChannelMessage(output, desc.Capabilities)
|
||||
if outMessage.IsEmpty() && (len(outboundAttachments) == 0 || attachmentsApplied) {
|
||||
if outMessage.IsEmpty() {
|
||||
continue
|
||||
}
|
||||
plainText := strings.TrimSpace(outMessage.PlainText())
|
||||
@@ -519,10 +516,6 @@ func (p *ChannelInboundProcessor) HandleInbound(ctx context.Context, cfg channel
|
||||
if isMessagingToolDuplicate(plainText, sentTexts) {
|
||||
continue
|
||||
}
|
||||
if !attachmentsApplied && len(outboundAttachments) > 0 {
|
||||
outMessage.Attachments = append(outMessage.Attachments, outboundAttachments...)
|
||||
attachmentsApplied = true
|
||||
}
|
||||
if outMessage.Reply == nil && sourceMessageID != "" {
|
||||
outMessage.Reply = &channel.ReplyRef{
|
||||
Target: target,
|
||||
@@ -538,18 +531,6 @@ func (p *ChannelInboundProcessor) HandleInbound(ctx context.Context, cfg channel
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !attachmentsApplied && len(outboundAttachments) > 0 {
|
||||
attachMsg := channel.Message{Attachments: outboundAttachments}
|
||||
if sourceMessageID != "" {
|
||||
attachMsg.Reply = &channel.ReplyRef{Target: target, MessageID: sourceMessageID}
|
||||
}
|
||||
if err := stream.Push(ctx, channel.StreamEvent{
|
||||
Type: channel.StreamEventFinal,
|
||||
Final: &channel.StreamFinalizePayload{Message: attachMsg},
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := stream.Push(ctx, channel.StreamEvent{
|
||||
Type: channel.StreamEventStatus,
|
||||
Status: channel.StreamStatusCompleted,
|
||||
@@ -1750,6 +1731,24 @@ func applyAssetToAttachment(asset media.Asset, botID string, item *channel.Attac
|
||||
if item.Size == 0 && asset.SizeBytes > 0 {
|
||||
item.Size = asset.SizeBytes
|
||||
}
|
||||
// Infer a better attachment type from MIME when the TS side sent a generic "file".
|
||||
if item.Type == channel.AttachmentFile || item.Type == "" {
|
||||
item.Type = inferAttachmentTypeFromMime(strings.TrimSpace(item.Mime))
|
||||
}
|
||||
}
|
||||
|
||||
func inferAttachmentTypeFromMime(mime string) channel.AttachmentType {
|
||||
mime = strings.ToLower(strings.TrimSpace(mime))
|
||||
switch {
|
||||
case strings.HasPrefix(mime, "image/"):
|
||||
return channel.AttachmentImage
|
||||
case strings.HasPrefix(mime, "audio/"):
|
||||
return channel.AttachmentAudio
|
||||
case strings.HasPrefix(mime, "video/"):
|
||||
return channel.AttachmentVideo
|
||||
default:
|
||||
return channel.AttachmentFile
|
||||
}
|
||||
}
|
||||
|
||||
// extractStorageKey derives the media storage key from a container-internal
|
||||
@@ -1919,12 +1918,16 @@ func parseAttachmentDelta(raw json.RawMessage) []channel.Attachment {
|
||||
if url == "" {
|
||||
url = strings.TrimSpace(item.Path)
|
||||
}
|
||||
name := strings.TrimSpace(item.Name)
|
||||
if name == "" && url != "" && !isDataURL(url) {
|
||||
name = filepath.Base(url)
|
||||
}
|
||||
attachments = append(attachments, channel.Attachment{
|
||||
Type: channel.AttachmentType(strings.TrimSpace(item.Type)),
|
||||
URL: url,
|
||||
PlatformKey: strings.TrimSpace(item.PlatformKey),
|
||||
ContentHash: strings.TrimSpace(item.ContentHash),
|
||||
Name: strings.TrimSpace(item.Name),
|
||||
Name: name,
|
||||
Mime: strings.TrimSpace(item.Mime),
|
||||
Size: item.Size,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user