fix(im): parse Drafty entities for message type classification (#31)

Favorites from Drafty messages (link/file/image/video/voice) always fell back to text because imMessageType only recognized flat file_id/url content. Derive the type from Drafty ent[] entities: LN->link, IM->image, VD->video, AU->voice, EX refined by mime. Attachments win over inline links.
This commit is contained in:
Austin
2026-09-20 16:38:51 +08:00
parent 48b3369799
commit 532ff49737
2 changed files with 167 additions and 0 deletions
+60
View File
@@ -8885,10 +8885,70 @@ func imMessageType(msg *types.Message) string {
if stringFromAny(content["url"]) != "" {
return "link"
}
if mtype := draftyIMMessageType(content); mtype != "" {
return mtype
}
}
return "text"
}
// draftyIMMessageType derives the semantic message type from Drafty content
// ({"txt","fmt","ent"}), where "ent" holds entity definitions {"tp","data"}.
// Attachment entities win over inline links; EX is refined by its mime type.
// Returns "" when no recognized entity is present.
func draftyIMMessageType(content map[string]any) string {
ents, ok := content["ent"].([]any)
if !ok || len(ents) == 0 {
return ""
}
link := ""
file := ""
for _, e := range ents {
ent, ok := e.(map[string]any)
if !ok {
continue
}
data, _ := ent["data"].(map[string]any)
switch stringFromAny(ent["tp"]) {
case "IM":
return "image"
case "VD":
return "video"
case "AU":
return "voice"
case "EX":
if file == "" {
file = draftyAttachmentType(data)
}
case "LN":
if link == "" {
link = "link"
}
}
}
if file != "" {
return file
}
return link
}
func draftyAttachmentType(data map[string]any) string {
mime := ""
if data != nil {
mime = stringFromAny(data["mime"])
}
switch {
case strings.HasPrefix(mime, "image/"):
return "image"
case strings.HasPrefix(mime, "video/"):
return "video"
case strings.HasPrefix(mime, "audio/"):
return "voice"
default:
return "file"
}
}
func favoriteSnapshot(msg *types.Message) map[string]any {
if msg == nil {
return map[string]any{}