Files
2026-06-06 22:28:36 +08:00

70 lines
1.4 KiB
Go

package pop3
import (
"context"
"fmt"
gopop3 "github.com/knadh/go-pop3"
"internal-mail-skill/internal/config"
"internal-mail-skill/internal/model"
)
type Fetcher struct {
cfg config.POP3Config
}
func NewFetcher(cfg config.POP3Config) *Fetcher {
return &Fetcher{cfg: cfg}
}
func (f *Fetcher) Fetch(ctx context.Context) ([]model.FetchedMessage, error) {
if f.cfg.Host == "" {
return nil, fmt.Errorf("POP3_HOST is required")
}
select {
case <-ctx.Done():
return nil, ctx.Err()
default:
}
client := gopop3.New(gopop3.Opt{
Host: f.cfg.Host,
Port: f.cfg.Port,
TLSEnabled: f.cfg.UseTLS,
DialTimeout: f.cfg.Timeout(),
})
conn, err := client.NewConn()
if err != nil {
return nil, fmt.Errorf("connect POP3: %w", err)
}
defer conn.Quit()
if err := conn.Auth(f.cfg.Username, f.cfg.Password); err != nil {
return nil, fmt.Errorf("POP3 auth: %w", err)
}
ids, err := conn.Uidl(0)
if err != nil {
return nil, fmt.Errorf("POP3 UIDL: %w", err)
}
out := make([]model.FetchedMessage, 0, len(ids))
for _, item := range ids {
select {
case <-ctx.Done():
return out, ctx.Err()
default:
}
raw, err := conn.RetrRaw(item.ID)
if err != nil {
out = append(out, model.FetchedMessage{ServerID: item.ID, UID: item.UID, Error: fmt.Sprintf("POP3 RETR %d: %v", item.ID, err)})
continue
}
out = append(out, model.FetchedMessage{
ServerID: item.ID,
UID: item.UID,
Raw: raw.Bytes(),
})
}
return out, nil
}