📑

Goでドコモメールimap受信

2020/10/28に公開

Goでドコモのキャリアメールを受信するサンプル実装

package main

import (
	"io"
	"io/ioutil"
	"log"
	"os"

	"github.com/emersion/go-imap"
	"github.com/emersion/go-imap/client"
	"github.com/emersion/go-message/mail"
)

func main() {
	c := login()

	defer c.Logout()

	viewMailBox(c)
	viewInBox(c)
}

func login() *client.Client {
	c, err := client.DialTLS("imap.spmode.ne.jp:993", nil)
	if err != nil {
		log.Fatal(err)
	}
	if err := c.Login("account_id", "password"); err != nil {
		log.Fatal(err)
	}
	return c
}

func viewMailBox(c *client.Client) {
	mailboxes := make(chan *imap.MailboxInfo, 10)
	done := make(chan error, 1)
	go func() {
		done <- c.List("", "*", mailboxes)
	}()

	for m := range mailboxes {
		log.Println("* " + m.Name)
	}

	if err := <-done; err != nil {
		log.Fatal(err)
	}
}

func viewInBox(c *client.Client) {
	mbox, err := c.Select("INBOX", false)
	if err != nil {
		log.Fatal(err)
	}

	if mbox.Messages == 0 {
		log.Fatal("No message in mailbox")
	}
	seqSet := new(imap.SeqSet)
	seqSet.AddNum(mbox.Messages)

	var section imap.BodySectionName
	items := []imap.FetchItem{section.FetchItem(), imap.FetchEnvelope}

	messages := make(chan *imap.Message, 1)
	go func() {
		if err := c.Fetch(seqSet, items, messages); err != nil {
			log.Fatal(err)
		}
	}()

	msg := <-messages
	if msg == nil {
		log.Fatal("Server didn't returned message")
	}

	r := msg.GetBody(&section)
	if r == nil {
		log.Fatal("Server didn't returned message body")
	}

	mr, err := mail.CreateReader(r)
	if err != nil {
		log.Fatal(err)
	}

	log.Println("Subject:", msg.Envelope.Subject)

	header := mr.Header
	if date, err := header.Date(); err == nil {
		log.Println("Date:", date)
	}
	if from, err := header.AddressList("From"); err == nil {
		log.Println("From:", from)
	}
	if to, err := header.AddressList("To"); err == nil {
		log.Println("To:", to)
	}

	// Process each message's part
	for {
		p, err := mr.NextPart()
		if err == io.EOF {
			break
		} else if err != nil {
			log.Fatal(err)
		}

		switch h := p.Header.(type) {
		case *mail.InlineHeader:
			b, _ := ioutil.ReadAll(p.Body)
			log.Println("Got text: ", string(b))
		case *mail.AttachmentHeader:
			filename, err := h.Filename()
			if err != nil {
				log.Fatal(err)
			}

			log.Println("Got attachment: ", filename)

			b, _ := ioutil.ReadAll(p.Body)
			if err != nil {
				log.Fatal(err)
			}

			file, err := os.Create(`./imap/attachment.txt`)
			if err != nil {
				log.Fatal(err)
			}
			defer file.Close()

			if _, err = file.Write(b); err != nil {
				log.Fatal(err)
			}
		}
	}
}

Discussion