feat(imap): add fallback for servers without ESEARCH support

Check ESEARCH capability before using extended search options. For
servers that don't support ESEARCH, fall back to using sequence
numbers from AllSeqNums() instead of Min/Max range.

Ref #181
This commit is contained in:
Abhinav Raut
2025-12-01 01:33:50 +05:30
parent b649d189b7
commit d4420cff7d
+22 -7
View File
@@ -112,23 +112,38 @@ func (e *Email) processMailbox(ctx context.Context, scanInboxSince time.Duration
// searchMessages searches for messages in the specified time range.
func (e *Email) searchMessages(client *imapclient.Client, since time.Time) (*imap.SearchData, error) {
searchCMD := client.Search(&imap.SearchCriteria{
criteria := &imap.SearchCriteria{
Since: since,
},
&imap.SearchOptions{
}
// Only use ESEARCH options if server supports it
var opts *imap.SearchOptions
if client.Caps().Has(imap.CapESearch) {
opts = &imap.SearchOptions{
ReturnMin: true,
ReturnMax: true,
ReturnAll: true,
ReturnCount: true,
},
)
return searchCMD.Wait()
}
}
return client.Search(criteria, opts).Wait()
}
// fetchAndProcessMessages fetches and processes messages based on the search results.
func (e *Email) fetchAndProcessMessages(ctx context.Context, client *imapclient.Client, searchResults *imap.SearchData, inboxID int) error {
seqSet := imap.SeqSet{}
seqSet.AddRange(searchResults.Min, searchResults.Max)
if searchResults.Min > 0 && searchResults.Max > 0 {
e.lo.Debug("using ESEARCH range", "min", searchResults.Min, "max", searchResults.Max, "inbox_id", inboxID)
seqSet.AddRange(searchResults.Min, searchResults.Max)
} else if seqNums := searchResults.AllSeqNums(); len(seqNums) > 0 {
e.lo.Debug("using SEARCH fallback (no ESEARCH support)", "count", len(seqNums), "inbox_id", inboxID)
seqSet.AddNum(seqNums...)
} else {
// No results found
e.lo.Debug("no messages found in search results", "inbox_id", inboxID)
return nil
}
// Fetch envelope and headers needed for auto-reply detection.
fetchOptions := &imap.FetchOptions{