package mail import ( "errors" "io/ioutil" "log" "strconv" "time" "git.0cd.xyz/michael/gtools/colour" "github.com/emersion/go-imap" "github.com/emersion/go-imap/client" ) type Mail struct { Client *client.Client } type Message struct { SeqNum uint32 Subject string To []*imap.Address From []*imap.Address Date time.Time Body imap.Literal } type Messages struct { Message []Message } func Login(addr, username, password string) (mail *Mail, err error) { colour.Green("Connecting to %s\n", addr) client, err := client.DialTLS(addr, nil) if err != nil { return nil, err } if err = client.Login(username, password); err != nil { return nil, err } log.Println("Logged in as", username) return &Mail{ Client: client, }, nil } func (mail *Mail) GetMessages(mailbox string, msgs int32) (*Messages, error) { var messages Messages mbox, err := mail.Client.Select(mailbox, true) if err != nil { return nil, err } if mbox.Messages == 0 { return nil, errors.New("no messages in mailbox") } seqSet := new(imap.SeqSet) seqSet.AddRange(1, mbox.Messages) var section imap.BodySectionName imapMessages := make(chan *imap.Message, msgs) done := make(chan error, 1) go func() { done <- mail.Client.Fetch(seqSet, []imap.FetchItem{imap.FetchEnvelope, section.FetchItem()}, imapMessages) }() for msg := range imapMessages { body := msg.GetBody(§ion) if body == nil { return nil, errors.New("server didn't returned message body") } message := Message{ SeqNum: msg.SeqNum, Subject: msg.Envelope.Subject, To: msg.Envelope.To, From: msg.Envelope.From, Date: msg.Envelope.Date, Body: body, } messages.Message = append(messages.Message, message) } if err := <-done; err != nil { return nil, err } return &messages, nil } func WriteMessages(path string, messages *Messages) error { for _, msg := range messages.Message { body, err := ioutil.ReadAll(msg.Body) if err != nil { return err } if err := ioutil.WriteFile(path+"/"+strconv.Itoa(int(msg.SeqNum))+"_"+msg.To[0].Address()+".eml", body, 0644); err != nil { return err } } return nil }