Skip to content
📥 An IMAP library for clients and servers
Go
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
backend Fix search larger and smaller edge case Oct 19, 2019
client Make SEARCH charset a RawString Sep 15, 2019
commands commands: Properly handle EOF in Authenticate.Handle Oct 9, 2019
internal go fmt Oct 27, 2016
responses Explicit separation for quoted strings and atoms (#261) Jun 6, 2019
server Don't send CAPABILITY statement unsolicited after Jul 15, 2019
utf7 utf7: explicitly set Encoding type to improve docs Nov 13, 2017
.build.yml ci: migrate to sr.ht Apr 14, 2019
.gitignore Generate coverage for all packages in the repo Jun 8, 2016
LICENSE Update LICENSE Jul 21, 2016
README.md readme: remove stability badge Jun 29, 2019
command.go Explicit separation for quoted strings and atoms (#261) Jun 6, 2019
command_test.go Explicit separation for quoted strings and atoms (#261) Jun 6, 2019
conn.go Pass basic connection information to backend May 4, 2019
conn_test.go Fix data races in Upgrade and SetDebug. Mar 8, 2019
date.go Add basic comment stripping for date-time Aug 15, 2019
date_test.go Addressed #60 (review) Oct 4, 2016
go.mod backendutil: Decode headers in Match before comparsion Jun 9, 2019
go.sum Add go.sum Jun 18, 2019
imap.go all: fix some lint issues Apr 7, 2019
literal.go Makes imap.Literal an interface Oct 16, 2016
logger.go Make ErrorLog a small interface Dec 1, 2016
mailbox.go Explicit separation for quoted strings and atoms (#261) Jun 6, 2019
mailbox_test.go Explicit separation for quoted strings and atoms (#261) Jun 6, 2019
message.go Make MIMEType and MIMESubType string comparisons case insensitive (#237) Jun 6, 2019
message_test.go Explicit separation for quoted strings and atoms (#261) Jun 6, 2019
read.go Explicit separation for quoted strings and atoms (#261) Jun 6, 2019
read_test.go Server-side (reader) support for non-synchronizing literals (#258) Jun 1, 2019
response.go Explicit separation for quoted strings and atoms (#261) Jun 6, 2019
response_test.go Explicit separation for quoted strings and atoms (#261) Jun 6, 2019
search.go Explicit separation for quoted strings and atoms (#261) Jun 6, 2019
search_test.go Explicit separation for quoted strings and atoms (#261) Jun 6, 2019
seqset.go all: some simplification Dec 1, 2017
seqset_test.go imap: rename NewSeqSet to ParseSeqSet Jun 7, 2017
status.go Explicit separation for quoted strings and atoms (#261) Jun 6, 2019
status_test.go Explicit separation for quoted strings and atoms (#261) Jun 6, 2019
write.go client: Use non-synchronizing literals when length is small (<4096) (#… Jun 10, 2019
write_test.go client: Use non-synchronizing literals when length is small (<4096) (#… Jun 10, 2019

README.md

go-imap

GoDoc builds.sr.ht status Codecov

An IMAP4rev1 library written in Go. It can be used to build a client and/or a server.

go get github.com/emersion/go-imap/...

Usage

Client GoDoc

package main

import (
	"log"

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

func main() {
	log.Println("Connecting to server...")

	// Connect to server
	c, err := client.DialTLS("mail.example.org:993", nil)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("Connected")

	// Don't forget to logout
	defer c.Logout()

	// Login
	if err := c.Login("username", "password"); err != nil {
		log.Fatal(err)
	}
	log.Println("Logged in")

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

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

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

	// Select INBOX
	mbox, err := c.Select("INBOX", false)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("Flags for INBOX:", mbox.Flags)

	// Get the last 4 messages
	from := uint32(1)
	to := mbox.Messages
	if mbox.Messages > 3 {
		// We're using unsigned integers here, only substract if the result is > 0
		from = mbox.Messages - 3
	}
	seqset := new(imap.SeqSet)
	seqset.AddRange(from, to)

	messages := make(chan *imap.Message, 10)
	done = make(chan error, 1)
	go func() {
		done <- c.Fetch(seqset, []imap.FetchItem{imap.FetchEnvelope}, messages)
	}()

	log.Println("Last 4 messages:")
	for msg := range messages {
		log.Println("* " + msg.Envelope.Subject)
	}

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

	log.Println("Done!")
}

Server GoDoc

package main

import (
	"log"

	"github.com/emersion/go-imap/server"
	"github.com/emersion/go-imap/backend/memory"
)

func main() {
	// Create a memory backend
	be := memory.New()

	// Create a new server
	s := server.New(be)
	s.Addr = ":1143"
	// Since we will use this server for testing only, we can allow plain text
	// authentication over unencrypted connections
	s.AllowInsecureAuth = true

	log.Println("Starting IMAP server at localhost:1143")
	if err := s.ListenAndServe(); err != nil {
		log.Fatal(err)
	}
}

You can now use telnet localhost 1143 to manually connect to the server.

Extending go-imap

Extensions

Commands defined in IMAP extensions are available in other packages. See the wiki to learn how to use them.

Server backends

Related projects

  • go-message - parsing and formatting MIME and mail messages
  • go-msgauth - handle DKIM, DMARC and Authentication-Results
  • go-pgpmail - decrypting and encrypting mails with OpenPGP
  • go-sasl - sending and receiving SASL authentications
  • go-smtp - building SMTP clients and servers

License

MIT

You can’t perform that action at this time.