Fearure:
- 增加收件箱功能(有BUG) - 增加已发送|草稿箱|发送历史 本地记录
This commit is contained in:
181
imap.go
Normal file
181
imap.go
Normal file
@@ -0,0 +1,181 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
imap "github.com/BrianLeishman/go-imap"
|
||||
)
|
||||
|
||||
type ReceivedEmail struct {
|
||||
UID uint32
|
||||
From string
|
||||
FromName string
|
||||
Subject string
|
||||
Date time.Time
|
||||
Preview string
|
||||
Account string
|
||||
AccountID string
|
||||
}
|
||||
|
||||
func getEmailProviderName(email string) string {
|
||||
if len(email) == 0 {
|
||||
return "Email"
|
||||
}
|
||||
atIdx := -1
|
||||
for i := len(email) - 1; i >= 0; i-- {
|
||||
if email[i] == '@' {
|
||||
atIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if atIdx == -1 {
|
||||
return "Email"
|
||||
}
|
||||
domain := email[atIdx+1:]
|
||||
for i := len(domain) - 1; i >= 0; i-- {
|
||||
if domain[i] == '.' {
|
||||
return domain[:i]
|
||||
}
|
||||
}
|
||||
return domain
|
||||
}
|
||||
|
||||
func FetchUnreadEmails(account Account, days int) ([]ReceivedEmail, error) {
|
||||
if account.IMAP.Host == "" {
|
||||
return nil, fmt.Errorf("IMAP host not configured for account: %s", account.Email)
|
||||
}
|
||||
|
||||
port := account.IMAP.Port
|
||||
if port == 0 {
|
||||
port = 993
|
||||
}
|
||||
|
||||
username := account.IMAP.Username
|
||||
if username == "" {
|
||||
username = account.Email
|
||||
}
|
||||
|
||||
m, err := imap.New(username, account.IMAP.Password, account.IMAP.Host, port)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to connect to IMAP server: %w", err)
|
||||
}
|
||||
defer m.Close()
|
||||
|
||||
err = m.SelectFolder("INBOX")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to select inbox: %w", err)
|
||||
}
|
||||
|
||||
sinceDate := time.Now().AddDate(0, 0, -days)
|
||||
|
||||
uids, err := m.GetUIDs(imap.Search().Since(sinceDate).Unseen().Build())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to search emails: %w", err)
|
||||
}
|
||||
|
||||
if len(uids) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
overviews, err := m.GetOverviews(uids...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch emails: %w", err)
|
||||
}
|
||||
|
||||
var emails []ReceivedEmail
|
||||
accountName := getEmailProviderName(account.Email)
|
||||
accountID := account.Email
|
||||
if account.Name != "" {
|
||||
accountName = account.Name
|
||||
accountID = account.Name
|
||||
}
|
||||
|
||||
for uid, email := range overviews {
|
||||
from := ""
|
||||
if len(email.From) > 0 {
|
||||
for _, addr := range email.From {
|
||||
from = addr
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
emails = append(emails, ReceivedEmail{
|
||||
UID: uint32(uid),
|
||||
From: from,
|
||||
FromName: "",
|
||||
Subject: email.Subject,
|
||||
Date: email.Sent,
|
||||
Preview: fmt.Sprintf("(%.1f KB)", float64(email.Size)/1024),
|
||||
Account: accountName,
|
||||
AccountID: accountID,
|
||||
})
|
||||
}
|
||||
|
||||
return emails, nil
|
||||
}
|
||||
|
||||
func GetAccountByEmail(email string) (Account, error) {
|
||||
accounts, err := getAccounts()
|
||||
if err != nil {
|
||||
return Account{}, err
|
||||
}
|
||||
|
||||
for _, acc := range accounts {
|
||||
if acc.Email == email || acc.Name == email {
|
||||
return acc, nil
|
||||
}
|
||||
}
|
||||
|
||||
return Account{}, fmt.Errorf("account not found: %s", email)
|
||||
}
|
||||
|
||||
func GetAccountByID(id string) (Account, error) {
|
||||
accounts, err := getAccounts()
|
||||
if err != nil {
|
||||
return Account{}, err
|
||||
}
|
||||
|
||||
for _, acc := range accounts {
|
||||
if acc.Email == id || acc.Name == id {
|
||||
return acc, nil
|
||||
}
|
||||
}
|
||||
|
||||
return Account{}, fmt.Errorf("account not found: %s", id)
|
||||
}
|
||||
|
||||
func FetchAllUnreadEmails(days int) ([]ReceivedEmail, error) {
|
||||
accounts, err := getAccounts()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(accounts) == 0 {
|
||||
return nil, fmt.Errorf("no accounts configured")
|
||||
}
|
||||
|
||||
var allEmails []ReceivedEmail
|
||||
|
||||
for _, account := range accounts {
|
||||
emails, err := FetchUnreadEmails(account, days)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
allEmails = append(allEmails, emails...)
|
||||
}
|
||||
|
||||
sortEmailsByDate(allEmails)
|
||||
|
||||
return allEmails, nil
|
||||
}
|
||||
|
||||
func sortEmailsByDate(emails []ReceivedEmail) {
|
||||
for i := 0; i < len(emails)-1; i++ {
|
||||
for j := i + 1; j < len(emails); j++ {
|
||||
if emails[j].Date.After(emails[i].Date) {
|
||||
emails[i], emails[j] = emails[j], emails[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user