70 lines
1.4 KiB
Go
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
|
|
}
|