package imap import ( "strings" "github.com/emersion/go-imap/v2" ) var folderDisplayNames = map[string]string{ "inbox": "Inbox", "sent": "Sent", "drafts": "Drafts", "trash": "Trash", "archive": "Archive", "spam": "Spam", } var folderNameHeuristics = map[string]string{ "inbox": "inbox", "sent": "sent", "sent items": "sent", "sent messages": "sent", "[gmail]/sent mail": "sent", "inbox.sent": "sent", "drafts": "drafts", "[gmail]/drafts": "drafts", "trash": "trash", "deleted": "trash", "[gmail]/trash": "trash", "archive": "archive", "all mail": "archive", "[gmail]/all mail": "archive", "junk": "spam", "spam": "spam", "[gmail]/spam": "spam", } // DetectFolderType classifies an IMAP mailbox for sync using SPECIAL-USE // attributes when present, otherwise name heuristics. NoSelect mailboxes // return "" so callers can skip sync. func DetectFolderType(mailbox string, attrs []imap.MailboxAttr) string { for _, attr := range attrs { if attr == imap.MailboxAttrNoSelect { return "" } } if folderType := folderTypeFromAttrs(attrs); folderType != "" { return folderType } return folderTypeFromName(mailbox) } // DisplayName returns a user-facing folder label from the detected type, // or the last path segment of mailbox when type is custom or unknown. func DisplayName(mailbox, folderType string) string { folderType = strings.ToLower(strings.TrimSpace(folderType)) if name, ok := folderDisplayNames[folderType]; ok { return name } return mailboxLeaf(mailbox) } func folderTypeFromAttrs(attrs []imap.MailboxAttr) string { for _, attr := range attrs { switch attr { case imap.MailboxAttrSent: return "sent" case imap.MailboxAttrDrafts: return "drafts" case imap.MailboxAttrTrash: return "trash" case imap.MailboxAttrArchive: return "archive" case imap.MailboxAttrJunk: return "spam" } } return "" } func folderTypeFromName(mailbox string) string { full := strings.ToLower(strings.TrimSpace(mailbox)) if folderType, ok := folderNameHeuristics[full]; ok { return folderType } leaf := strings.ToLower(mailboxLeaf(mailbox)) if folderType, ok := folderNameHeuristics[leaf]; ok { return folderType } return "custom" } func mailboxLeaf(mailbox string) string { mailbox = strings.TrimSpace(mailbox) if mailbox == "" { return "" } leaf := mailbox for _, sep := range []string{"/", "."} { if idx := strings.LastIndex(leaf, sep); idx >= 0 && idx < len(leaf)-len(sep) { leaf = leaf[idx+len(sep):] } } return leaf }