package main import ( "bytes" "io" "log" "mime" "github.com/emersion/go-imap/v2" "github.com/emersion/go-imap/v2/imapclient" "github.com/emersion/go-message/charset" "github.com/emersion/go-message/mail" ) type MailBox struct { Server string User string Password string InBox string Client *imapclient.Client } func (mb *MailBox) ListMessages() (string, error) { return "", nil } func (mb *MailBox) Connect() error { options := &imapclient.Options{ WordDecoder: &mime.WordDecoder{CharsetReader: charset.Reader}, } var err error mb.Client, err = imapclient.DialTLS(mb.Server, options) if err != nil { log.Println("Error connnecting to", mb.Server, ":", err) return err } log.Println("Connected") err = mb.Client.Login(mb.User, mb.Password).Wait() if err != nil { log.Fatal("failed to login:", err) } log.Println("Logged in") mailBoxes, err := mb.Client.List("", "%", nil).Collect() if err != nil { log.Fatal("Error listing mailboxes", err) } for _, mbox := range mailBoxes { log.Println("mailbox:", mbox.Mailbox) } inbox, err := mb.Client.Select(mb.InBox, nil).Wait() if err != nil { log.Fatal("Error selecting mailbox:", mb.InBox, err) } log.Println("Inbox has", inbox.NumMessages, "messages") for i := uint32(0); i <= inbox.NumMessages; i++ { seqSet := imap.SeqSetNum(i) bodySection := &imap.FetchItemBodySection{} fetchOptions := &imap.FetchOptions{ Envelope: true, BodySection: []*imap.FetchItemBodySection{bodySection}, } messages, err := mb.Client.Fetch(seqSet, fetchOptions).Collect() if err != nil { log.Fatal("Error fetching mails:", err) } for _, msg := range messages { log.Println(msg.Envelope.From) log.Println(msg.Envelope.To) log.Println(msg.Envelope.Date) log.Println(msg.Envelope.Subject) section := msg.FindBodySection(bodySection) ioReader := bytes.NewReader(section) mailReader, err := mail.CreateReader(ioReader) if err != nil { log.Fatalf("failed to create mail reader: %v", err) } for { part, err := mailReader.NextPart() if err == io.EOF { log.Println("------------") break } else if err != nil { log.Fatal("Error reading part", err) } switch header := part.Header.(type) { case *mail.AttachmentHeader: filename, _ := header.Filename() log.Println("Attachment:", filename) case *mail.InlineHeader: body, _ := io.ReadAll(part.Body) log.Println(string(body)) } } } } return nil } func (mb *MailBox) Close() { mb.Client.Close() }