imapclient

package
v2.0.0-beta.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 28, 2024 License: MIT Imports: 22 Imported by: 40

Documentation

Overview

Package imapclient implements an IMAP client.

Charset decoding

By default, only basic charset decoding is performed. For non-UTF-8 decoding of message subjects and e-mail address names, users can set Options.WordDecoder. For instance, to use go-message's collection of charsets:

import (
	"mime"

	"github.com/emersion/go-message/charset"
)

options := &imapclient.Options{
	WordDecoder: &mime.WordDecoder{CharsetReader: charset.Reader},
}
client, err := imapclient.DialTLS("imap.example.org:993", options)

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AppendCommand

type AppendCommand struct {
	// contains filtered or unexported fields
}

AppendCommand is an APPEND command.

Callers must write the message contents, then call Close.

func (*AppendCommand) Close

func (cmd *AppendCommand) Close() error

func (*AppendCommand) Wait

func (cmd *AppendCommand) Wait() (*imap.AppendData, error)

func (*AppendCommand) Write

func (cmd *AppendCommand) Write(b []byte) (int, error)

type CapabilityCommand

type CapabilityCommand struct {
	// contains filtered or unexported fields
}

CapabilityCommand is a CAPABILITY command.

func (*CapabilityCommand) Wait

func (cmd *CapabilityCommand) Wait() (imap.CapSet, error)

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is an IMAP client.

IMAP commands are exposed as methods. These methods will block until the command has been sent to the server, but won't block until the server sends a response. They return a command struct which can be used to wait for the server response. This can be used to execute multiple commands concurrently, however care must be taken to avoid ambiguities. See RFC 9051 section 5.5.

A client can be safely used from multiple goroutines, however this doesn't guarantee any command ordering and is subject to the same caveats as command pipelining (see above). Additionally, some commands (e.g. StartTLS, Authenticate, Idle) block the client during their execution.

Example
c, err := imapclient.DialTLS("mail.example.org:993", nil)
if err != nil {
	log.Fatalf("failed to dial IMAP server: %v", err)
}
defer c.Close()

if err := c.Login("root", "asdf").Wait(); err != nil {
	log.Fatalf("failed to login: %v", err)
}

mailboxes, err := c.List("", "%", nil).Collect()
if err != nil {
	log.Fatalf("failed to list mailboxes: %v", err)
}
log.Printf("Found %v mailboxes", len(mailboxes))
for _, mbox := range mailboxes {
	log.Printf(" - %v", mbox.Mailbox)
}

selectedMbox, err := c.Select("INBOX", nil).Wait()
if err != nil {
	log.Fatalf("failed to select INBOX: %v", err)
}
log.Printf("INBOX contains %v messages", selectedMbox.NumMessages)

if selectedMbox.NumMessages > 0 {
	seqSet := imap.SeqSetNum(1)
	fetchOptions := &imap.FetchOptions{Envelope: true}
	messages, err := c.Fetch(seqSet, fetchOptions).Collect()
	if err != nil {
		log.Fatalf("failed to fetch first message in INBOX: %v", err)
	}
	log.Printf("subject of first message in INBOX: %v", messages[0].Envelope.Subject)
}

if err := c.Logout().Wait(); err != nil {
	log.Fatalf("failed to logout: %v", err)
}
Output:

Example (Pipelining)
var c *imapclient.Client

uid := imap.UID(42)
fetchOptions := &imap.FetchOptions{Envelope: true}

// Login, select and fetch a message in a single roundtrip
loginCmd := c.Login("root", "root")
selectCmd := c.Select("INBOX", nil)
fetchCmd := c.Fetch(imap.UIDSetNum(uid), fetchOptions)

if err := loginCmd.Wait(); err != nil {
	log.Fatalf("failed to login: %v", err)
}
if _, err := selectCmd.Wait(); err != nil {
	log.Fatalf("failed to select INBOX: %v", err)
}
if messages, err := fetchCmd.Collect(); err != nil {
	log.Fatalf("failed to fetch message: %v", err)
} else {
	log.Printf("Subject: %v", messages[0].Envelope.Subject)
}
Output:

func DialInsecure

func DialInsecure(address string, options *Options) (*Client, error)

DialInsecure connects to an IMAP server without any encryption at all.

func DialStartTLS

func DialStartTLS(address string, options *Options) (*Client, error)

DialStartTLS connects to an IMAP server with STARTTLS.

func DialTLS

func DialTLS(address string, options *Options) (*Client, error)

DialTLS connects to an IMAP server with implicit TLS.

func New

func New(conn net.Conn, options *Options) *Client

New creates a new IMAP client.

This function doesn't perform I/O.

A nil options pointer is equivalent to a zero options value.

func NewStartTLS

func NewStartTLS(conn net.Conn, options *Options) (*Client, error)

NewStartTLS creates a new IMAP client with STARTTLS.

A nil options pointer is equivalent to a zero options value.

func (*Client) Append

func (c *Client) Append(mailbox string, size int64, options *imap.AppendOptions) *AppendCommand

Append sends an APPEND command.

The caller must call AppendCommand.Close.

The options are optional.

Example
package main

import (
	"log"

	"github.com/emersion/go-imap/v2/imapclient"
)

func main() {
	var c *imapclient.Client

	buf := []byte("From: <root@nsa.gov>\r\n\r\nHi <3")
	size := int64(len(buf))
	appendCmd := c.Append("INBOX", size, nil)
	if _, err := appendCmd.Write(buf); err != nil {
		log.Fatalf("failed to write message: %v", err)
	}
	if err := appendCmd.Close(); err != nil {
		log.Fatalf("failed to close message: %v", err)
	}
	if _, err := appendCmd.Wait(); err != nil {
		log.Fatalf("APPEND command failed: %v", err)
	}
}
Output:

func (*Client) Authenticate

func (c *Client) Authenticate(saslClient sasl.Client) error

Authenticate sends an AUTHENTICATE command.

Unlike other commands, this method blocks until the SASL exchange completes.

Example (Oauth)
var (
	c        *imapclient.Client
	username string
	token    string
)

if !c.Caps().Has(imap.AuthCap(sasl.OAuthBearer)) {
	log.Fatal("OAUTHBEARER not supported by the server")
}

saslClient := sasl.NewOAuthBearerClient(&sasl.OAuthBearerOptions{
	Username: username,
	Token:    token,
})
if err := c.Authenticate(saslClient); err != nil {
	log.Fatalf("authentication failed: %v", err)
}
Output:

func (*Client) Capability

func (c *Client) Capability() *CapabilityCommand

Capability sends a CAPABILITY command.

func (*Client) Caps

func (c *Client) Caps() imap.CapSet

Caps returns the capabilities advertised by the server.

When the server hasn't sent the capability list, this method will request it and block until it's received. If the capabilities cannot be fetched, nil is returned.

func (*Client) Close

func (c *Client) Close() error

Close immediately closes the connection.

func (*Client) Copy

func (c *Client) Copy(numSet imap.NumSet, mailbox string) *CopyCommand

Copy sends a COPY command.

func (*Client) Create

func (c *Client) Create(mailbox string, options *imap.CreateOptions) *Command

Create sends a CREATE command.

A nil options pointer is equivalent to a zero options value.

func (*Client) Delete

func (c *Client) Delete(mailbox string) *Command

Delete sends a DELETE command.

func (*Client) Enable

func (c *Client) Enable(caps ...imap.Cap) *EnableCommand

Enable sends an ENABLE command.

This command requires support for IMAP4rev2 or the ENABLE extension.

func (*Client) Expunge

func (c *Client) Expunge() *ExpungeCommand

Expunge sends an EXPUNGE command.

func (*Client) Fetch

func (c *Client) Fetch(numSet imap.NumSet, options *imap.FetchOptions) *FetchCommand

Fetch sends a FETCH command.

The caller must fully consume the FetchCommand. A simple way to do so is to defer a call to FetchCommand.Close.

A nil options pointer is equivalent to a zero options value.

Example
var c *imapclient.Client

seqSet := imap.SeqSetNum(1)
fetchOptions := &imap.FetchOptions{
	Flags:    true,
	Envelope: true,
	BodySection: []*imap.FetchItemBodySection{
		{Specifier: imap.PartSpecifierHeader},
	},
}
messages, err := c.Fetch(seqSet, fetchOptions).Collect()
if err != nil {
	log.Fatalf("FETCH command failed: %v", err)
}

msg := messages[0]
var header []byte
for _, buf := range msg.BodySection {
	header = buf
	break
}

log.Printf("Flags: %v", msg.Flags)
log.Printf("Subject: %v", msg.Envelope.Subject)
log.Printf("Header:\n%v", string(header))
Output:

Example (ParseBody)
var c *imapclient.Client

// Send a FETCH command to fetch the message body
seqSet := imap.SeqSetNum(1)
fetchOptions := &imap.FetchOptions{
	BodySection: []*imap.FetchItemBodySection{{}},
}
fetchCmd := c.Fetch(seqSet, fetchOptions)
defer fetchCmd.Close()

msg := fetchCmd.Next()
if msg == nil {
	log.Fatalf("FETCH command did not return any message")
}

// Find the body section in the response
var bodySection imapclient.FetchItemDataBodySection
ok := false
for {
	item := msg.Next()
	if item == nil {
		break
	}
	bodySection, ok = item.(imapclient.FetchItemDataBodySection)
	if ok {
		break
	}
}
if !ok {
	log.Fatalf("FETCH command did not return body section")
}

// Read the message via the go-message library
mr, err := mail.CreateReader(bodySection.Literal)
if err != nil {
	log.Fatalf("failed to create mail reader: %v", err)
}

// Print a few header fields
h := mr.Header
if date, err := h.Date(); err != nil {
	log.Printf("failed to parse Date header field: %v", err)
} else {
	log.Printf("Date: %v", date)
}
if to, err := h.AddressList("To"); err != nil {
	log.Printf("failed to parse To header field: %v", err)
} else {
	log.Printf("To: %v", to)
}
if subject, err := h.Text("Subject"); err != nil {
	log.Printf("failed to parse Subject header field: %v", err)
} else {
	log.Printf("Subject: %v", subject)
}

// Process the message's parts
for {
	p, err := mr.NextPart()
	if err == io.EOF {
		break
	} else if err != nil {
		log.Fatalf("failed to read message part: %v", err)
	}

	switch h := p.Header.(type) {
	case *mail.InlineHeader:
		// This is the message's text (can be plain-text or HTML)
		b, _ := io.ReadAll(p.Body)
		log.Printf("Inline text: %v", string(b))
	case *mail.AttachmentHeader:
		// This is an attachment
		filename, _ := h.Filename()
		log.Printf("Attachment: %v", filename)
	}
}

if err := fetchCmd.Close(); err != nil {
	log.Fatalf("FETCH command failed: %v", err)
}
Output:

Example (StreamBody)
var c *imapclient.Client

seqSet := imap.SeqSetNum(1)
fetchOptions := &imap.FetchOptions{
	UID:         true,
	BodySection: []*imap.FetchItemBodySection{{}},
}
fetchCmd := c.Fetch(seqSet, fetchOptions)
defer fetchCmd.Close()

for {
	msg := fetchCmd.Next()
	if msg == nil {
		break
	}

	for {
		item := msg.Next()
		if item == nil {
			break
		}

		switch item := item.(type) {
		case imapclient.FetchItemDataUID:
			log.Printf("UID: %v", item.UID)
		case imapclient.FetchItemDataBodySection:
			b, err := io.ReadAll(item.Literal)
			if err != nil {
				log.Fatalf("failed to read body section: %v", err)
			}
			log.Printf("Body:\n%v", string(b))
		}
	}
}

if err := fetchCmd.Close(); err != nil {
	log.Fatalf("FETCH command failed: %v", err)
}
Output:

func (*Client) GetACL

func (c *Client) GetACL(mailbox string) *GetACLCommand

GetACL sends a GETACL command.

This command requires support for the ACL extension.

func (*Client) GetMetadata

func (c *Client) GetMetadata(mailbox string, entries []string, options *GetMetadataOptions) *GetMetadataCommand

GetMetadata sends a GETMETADATA command.

This command requires support for the METADATA or METADATA-SERVER extension.

func (*Client) GetQuota

func (c *Client) GetQuota(root string) *GetQuotaCommand

GetQuota sends a GETQUOTA command.

This command requires support for the QUOTA extension.

func (*Client) GetQuotaRoot

func (c *Client) GetQuotaRoot(mailbox string) *GetQuotaRootCommand

GetQuotaRoot sends a GETQUOTAROOT command.

This command requires support for the QUOTA extension.

func (*Client) ID

func (c *Client) ID(idData *imap.IDData) *IDCommand

ID sends an ID command.

The ID command is introduced in RFC 2971. It requires support for the ID extension.

An example ID command:

ID ("name" "go-imap" "version" "1.0" "os" "Linux" "os-version" "7.9.4" "vendor" "Yahoo")

func (*Client) Idle

func (c *Client) Idle() (*IdleCommand, error)

Idle sends an IDLE command.

Unlike other commands, this method blocks until the server acknowledges it. On success, the IDLE command is running and other commands cannot be sent. The caller must invoke IdleCommand.Close to stop IDLE and unblock the client.

This command requires support for IMAP4rev2 or the IDLE extension. The IDLE command is restarted automatically to avoid getting disconnected due to inactivity timeouts.

Example
package main

import (
	"log"
	"time"

	"github.com/emersion/go-imap/v2/imapclient"
)

func main() {
	options := imapclient.Options{
		UnilateralDataHandler: &imapclient.UnilateralDataHandler{
			Expunge: func(seqNum uint32) {
				log.Printf("message %v has been expunged", seqNum)
			},
			Mailbox: func(data *imapclient.UnilateralDataMailbox) {
				if data.NumMessages != nil {
					log.Printf("a new message has been received")
				}
			},
		},
	}

	c, err := imapclient.DialTLS("mail.example.org:993", &options)
	if err != nil {
		log.Fatalf("failed to dial IMAP server: %v", err)
	}
	defer c.Close()

	if err := c.Login("root", "asdf").Wait(); err != nil {
		log.Fatalf("failed to login: %v", err)
	}
	if _, err := c.Select("INBOX", nil).Wait(); err != nil {
		log.Fatalf("failed to select INBOX: %v", err)
	}

	// Start idling
	idleCmd, err := c.Idle()
	if err != nil {
		log.Fatalf("IDLE command failed: %v", err)
	}

	// Wait for 30s to receive updates from the server
	time.Sleep(30 * time.Second)

	// Stop idling
	if err := idleCmd.Close(); err != nil {
		log.Fatalf("failed to stop idling: %v", err)
	}
}
Output:

func (*Client) List

func (c *Client) List(ref, pattern string, options *imap.ListOptions) *ListCommand

List sends a LIST command.

The caller must fully consume the ListCommand. A simple way to do so is to defer a call to ListCommand.Close.

A nil options pointer is equivalent to a zero options value.

A non-zero options value requires support for IMAP4rev2 or the LIST-EXTENDED extension.

Example (Stream)
var c *imapclient.Client

// ReturnStatus requires server support for IMAP4rev2 or LIST-STATUS
listCmd := c.List("", "%", &imap.ListOptions{
	ReturnStatus: &imap.StatusOptions{
		NumMessages: true,
		NumUnseen:   true,
	},
})
for {
	mbox := listCmd.Next()
	if mbox == nil {
		break
	}
	log.Printf("Mailbox %q contains %v messages (%v unseen)", mbox.Mailbox, mbox.Status.NumMessages, mbox.Status.NumUnseen)
}
if err := listCmd.Close(); err != nil {
	log.Fatalf("LIST command failed: %v", err)
}
Output:

func (*Client) Login

func (c *Client) Login(username, password string) *Command

Login sends a LOGIN command.

func (*Client) Logout

func (c *Client) Logout() *Command

Logout sends a LOGOUT command.

This command informs the server that the client is done with the connection.

func (*Client) Mailbox

func (c *Client) Mailbox() *SelectedMailbox

Mailbox returns the state of the currently selected mailbox.

If there is no currently selected mailbox, nil is returned.

The returned struct must not be mutated.

func (*Client) Move

func (c *Client) Move(numSet imap.NumSet, mailbox string) *MoveCommand

Move sends a MOVE command.

If the server doesn't support IMAP4rev2 nor the MOVE extension, a fallback with COPY + STORE + EXPUNGE commands is used.

func (*Client) MyRights

func (c *Client) MyRights(mailbox string) *MyRightsCommand

MyRights sends a MYRIGHTS command.

This command requires support for the ACL extension.

func (*Client) Namespace

func (c *Client) Namespace() *NamespaceCommand

Namespace sends a NAMESPACE command.

This command requires support for IMAP4rev2 or the NAMESPACE extension.

func (*Client) Noop

func (c *Client) Noop() *Command

Noop sends a NOOP command.

func (*Client) Rename

func (c *Client) Rename(mailbox, newName string) *Command

Rename sends a RENAME command.

func (*Client) Search

func (c *Client) Search(criteria *imap.SearchCriteria, options *imap.SearchOptions) *SearchCommand

Search sends a SEARCH command.

Example
var c *imapclient.Client

data, err := c.UIDSearch(&imap.SearchCriteria{
	Body: []string{"Hello world"},
}, nil).Wait()
if err != nil {
	log.Fatalf("UID SEARCH command failed: %v", err)
}
log.Fatalf("UIDs matching the search criteria: %v", data.AllUIDs())
Output:

func (*Client) Select

func (c *Client) Select(mailbox string, options *imap.SelectOptions) *SelectCommand

Select sends a SELECT or EXAMINE command.

A nil options pointer is equivalent to a zero options value.

func (*Client) SetACL

func (c *Client) SetACL(mailbox string, ri imap.RightsIdentifier, rm imap.RightModification, rs imap.RightSet) *SetACLCommand

SetACL sends a SETACL command.

This command requires support for the ACL extension.

func (*Client) SetMetadata

func (c *Client) SetMetadata(mailbox string, entries map[string]*[]byte) *Command

SetMetadata sends a SETMETADATA command.

To remove an entry, set it to nil.

This command requires support for the METADATA or METADATA-SERVER extension.

func (*Client) SetQuota

func (c *Client) SetQuota(root string, limits map[imap.QuotaResourceType]int64) *Command

SetQuota sends a SETQUOTA command.

This command requires support for the SETQUOTA extension.

func (*Client) Sort

func (c *Client) Sort(options *SortOptions) *SortCommand

Sort sends a SORT command.

This command requires support for the SORT extension.

func (*Client) State

func (c *Client) State() imap.ConnState

State returns the current connection state of the client.

func (*Client) Status

func (c *Client) Status(mailbox string, options *imap.StatusOptions) *StatusCommand

Status sends a STATUS command.

A nil options pointer is equivalent to a zero options value.

Example
var c *imapclient.Client

options := imap.StatusOptions{NumMessages: true}
if data, err := c.Status("INBOX", &options).Wait(); err != nil {
	log.Fatalf("STATUS command failed: %v", err)
} else {
	log.Printf("INBOX contains %v messages", *data.NumMessages)
}
Output:

func (*Client) Store

func (c *Client) Store(numSet imap.NumSet, store *imap.StoreFlags, options *imap.StoreOptions) *FetchCommand

Store sends a STORE command.

Unless StoreFlags.Silent is set, the server will return the updated values.

A nil options pointer is equivalent to a zero options value.

Example
var c *imapclient.Client

seqSet := imap.SeqSetNum(1)
storeFlags := imap.StoreFlags{
	Op:     imap.StoreFlagsAdd,
	Flags:  []imap.Flag{imap.FlagFlagged},
	Silent: true,
}
if err := c.Store(seqSet, &storeFlags, nil).Close(); err != nil {
	log.Fatalf("STORE command failed: %v", err)
}
Output:

func (*Client) Subscribe

func (c *Client) Subscribe(mailbox string) *Command

Subscribe sends a SUBSCRIBE command.

func (*Client) Thread

func (c *Client) Thread(options *ThreadOptions) *ThreadCommand

Thread sends a THREAD command.

This command requires support for the THREAD extension.

func (*Client) UIDExpunge

func (c *Client) UIDExpunge(uids imap.UIDSet) *ExpungeCommand

UIDExpunge sends a UID EXPUNGE command.

This command requires support for IMAP4rev2 or the UIDPLUS extension.

func (*Client) UIDSearch

func (c *Client) UIDSearch(criteria *imap.SearchCriteria, options *imap.SearchOptions) *SearchCommand

UIDSearch sends a UID SEARCH command.

func (*Client) UIDSort

func (c *Client) UIDSort(options *SortOptions) *SortCommand

UIDSort sends a UID SORT command.

See Sort.

func (*Client) UIDThread

func (c *Client) UIDThread(options *ThreadOptions) *ThreadCommand

UIDThread sends a UID THREAD command.

See Thread.

func (*Client) Unauthenticate

func (c *Client) Unauthenticate() *Command

Unauthenticate sends an UNAUTHENTICATE command.

This command requires support for the UNAUTHENTICATE extension.

func (*Client) Unselect

func (c *Client) Unselect() *Command

Unselect sends an UNSELECT command.

This command requires support for IMAP4rev2 or the UNSELECT extension.

func (*Client) UnselectAndExpunge

func (c *Client) UnselectAndExpunge() *Command

UnselectAndExpunge sends a CLOSE command.

CLOSE implicitly performs a silent EXPUNGE command.

func (*Client) Unsubscribe

func (c *Client) Unsubscribe(mailbox string) *Command

Subscribe sends an UNSUBSCRIBE command.

func (*Client) WaitGreeting

func (c *Client) WaitGreeting() error

WaitGreeting waits for the server's initial greeting.

type Command

type Command struct {
	// contains filtered or unexported fields
}

Command is a basic IMAP command.

func (*Command) Wait

func (cmd *Command) Wait() error

Wait blocks until the command has completed.

type CopyCommand

type CopyCommand struct {
	// contains filtered or unexported fields
}

CopyCommand is a COPY command.

func (*CopyCommand) Wait

func (cmd *CopyCommand) Wait() (*imap.CopyData, error)

type EnableCommand

type EnableCommand struct {
	// contains filtered or unexported fields
}

EnableCommand is an ENABLE command.

func (*EnableCommand) Wait

func (cmd *EnableCommand) Wait() (*EnableData, error)

type EnableData

type EnableData struct {
	// Capabilities that were successfully enabled
	Caps imap.CapSet
}

EnableData is the data returned by the ENABLE command.

type ExpungeCommand

type ExpungeCommand struct {
	// contains filtered or unexported fields
}

ExpungeCommand is an EXPUNGE command.

The caller must fully consume the ExpungeCommand. A simple way to do so is to defer a call to FetchCommand.Close.

func (*ExpungeCommand) Close

func (cmd *ExpungeCommand) Close() error

Close releases the command.

Calling Close unblocks the IMAP client decoder and lets it read the next responses. Next will always return nil after Close.

func (*ExpungeCommand) Collect

func (cmd *ExpungeCommand) Collect() ([]uint32, error)

Collect accumulates expunged sequence numbers into a list.

This is equivalent to calling Next repeatedly and then Close.

func (*ExpungeCommand) Next

func (cmd *ExpungeCommand) Next() uint32

Next advances to the next expunged message sequence number.

On success, the message sequence number is returned. On error or if there are no more messages, 0 is returned. To check the error value, use Close.

type FetchCommand

type FetchCommand struct {
	// contains filtered or unexported fields
}

FetchCommand is a FETCH command.

func (*FetchCommand) Close

func (cmd *FetchCommand) Close() error

Close releases the command.

Calling Close unblocks the IMAP client decoder and lets it read the next responses. Next will always return nil after Close.

func (*FetchCommand) Collect

func (cmd *FetchCommand) Collect() ([]*FetchMessageBuffer, error)

Collect accumulates message data into a list.

This method will read and store message contents in memory. This is acceptable when the message contents have a reasonable size, but may not be suitable when fetching e.g. attachments.

This is equivalent to calling Next repeatedly and then Close.

func (*FetchCommand) Next

func (cmd *FetchCommand) Next() *FetchMessageData

Next advances to the next message.

On success, the message is returned. On error or if there are no more messages, nil is returned. To check the error value, use Close.

type FetchItemData

type FetchItemData interface {
	// contains filtered or unexported methods
}

FetchItemData contains a message's FETCH item data.

type FetchItemDataBinarySection

type FetchItemDataBinarySection struct {
	Section *imap.FetchItemBinarySection
	Literal imap.LiteralReader
}

FetchItemDataBinarySection holds data returned by FETCH BINARY[].

Literal might be nil.

type FetchItemDataBinarySectionSize

type FetchItemDataBinarySectionSize struct {
	Part []int
	Size uint32
}

FetchItemDataBinarySectionSize holds data returned by FETCH BINARY.SIZE[].

type FetchItemDataBodySection

type FetchItemDataBodySection struct {
	Section *imap.FetchItemBodySection
	Literal imap.LiteralReader
}

FetchItemDataBodySection holds data returned by FETCH BODY[].

Literal might be nil.

type FetchItemDataBodyStructure

type FetchItemDataBodyStructure struct {
	BodyStructure imap.BodyStructure
	IsExtended    bool // True if BODYSTRUCTURE, false if BODY
}

FetchItemDataBodyStructure holds data returned by FETCH BODYSTRUCTURE or FETCH BODY.

type FetchItemDataEnvelope

type FetchItemDataEnvelope struct {
	Envelope *imap.Envelope
}

FetchItemDataEnvelope holds data returned by FETCH ENVELOPE.

type FetchItemDataFlags

type FetchItemDataFlags struct {
	Flags []imap.Flag
}

FetchItemDataFlags holds data returned by FETCH FLAGS.

type FetchItemDataInternalDate

type FetchItemDataInternalDate struct {
	Time time.Time
}

FetchItemDataInternalDate holds data returned by FETCH INTERNALDATE.

type FetchItemDataModSeq

type FetchItemDataModSeq struct {
	ModSeq uint64
}

FetchItemDataModSeq holds data returned by FETCH MODSEQ.

This requires the CONDSTORE extension.

type FetchItemDataRFC822Size

type FetchItemDataRFC822Size struct {
	Size int64
}

FetchItemDataRFC822Size holds data returned by FETCH RFC822.SIZE.

type FetchItemDataUID

type FetchItemDataUID struct {
	UID imap.UID
}

FetchItemDataUID holds data returned by FETCH UID.

type FetchMessageBuffer

type FetchMessageBuffer struct {
	SeqNum            uint32
	Flags             []imap.Flag
	Envelope          *imap.Envelope
	InternalDate      time.Time
	RFC822Size        int64
	UID               imap.UID
	BodyStructure     imap.BodyStructure
	BodySection       map[*imap.FetchItemBodySection][]byte
	BinarySection     map[*imap.FetchItemBinarySection][]byte
	BinarySectionSize []FetchItemDataBinarySectionSize
	ModSeq            uint64 // requires CONDSTORE
}

FetchMessageBuffer is a buffer for the data returned by FetchMessageData.

The SeqNum field is always populated. All remaining fields are optional.

type FetchMessageData

type FetchMessageData struct {
	SeqNum uint32
	// contains filtered or unexported fields
}

FetchMessageData contains a message's FETCH data.

func (*FetchMessageData) Collect

func (data *FetchMessageData) Collect() (*FetchMessageBuffer, error)

Collect accumulates message data into a struct.

This method will read and store message contents in memory. This is acceptable when the message contents have a reasonable size, but may not be suitable when fetching e.g. attachments.

func (*FetchMessageData) Next

func (data *FetchMessageData) Next() FetchItemData

Next advances to the next data item for this message.

If there is one or more data items left, the next item is returned. Otherwise nil is returned.

type GetACLCommand

type GetACLCommand struct {
	// contains filtered or unexported fields
}

GetACLCommand is a GETACL command.

func (*GetACLCommand) Wait

func (cmd *GetACLCommand) Wait() (*GetACLData, error)

type GetACLData

type GetACLData struct {
	Mailbox string
	Rights  map[imap.RightsIdentifier]imap.RightSet
}

GetACLData is the data returned by the GETACL command.

type GetMetadataCommand

type GetMetadataCommand struct {
	// contains filtered or unexported fields
}

GetMetadataCommand is a GETMETADATA command.

func (*GetMetadataCommand) Wait

func (cmd *GetMetadataCommand) Wait() (*GetMetadataData, error)

type GetMetadataData

type GetMetadataData struct {
	Mailbox string
	Entries map[string]*[]byte
}

GetMetadataData is the data returned by the GETMETADATA command.

type GetMetadataDepth

type GetMetadataDepth int
const (
	GetMetadataDepthZero     GetMetadataDepth = 0
	GetMetadataDepthOne      GetMetadataDepth = 1
	GetMetadataDepthInfinity GetMetadataDepth = -1
)

func (GetMetadataDepth) String

func (depth GetMetadataDepth) String() string

type GetMetadataOptions

type GetMetadataOptions struct {
	MaxSize *uint32
	Depth   GetMetadataDepth
}

GetMetadataOptions contains options for the GETMETADATA command.

type GetQuotaCommand

type GetQuotaCommand struct {
	// contains filtered or unexported fields
}

GetQuotaCommand is a GETQUOTA command.

func (*GetQuotaCommand) Wait

func (cmd *GetQuotaCommand) Wait() (*QuotaData, error)

type GetQuotaRootCommand

type GetQuotaRootCommand struct {
	// contains filtered or unexported fields
}

GetQuotaRootCommand is a GETQUOTAROOT command.

func (*GetQuotaRootCommand) Wait

func (cmd *GetQuotaRootCommand) Wait() ([]QuotaData, error)

type IDCommand

type IDCommand struct {
	// contains filtered or unexported fields
}

func (*IDCommand) Wait

func (r *IDCommand) Wait() (*imap.IDData, error)

type IdleCommand

type IdleCommand struct {
	// contains filtered or unexported fields
}

IdleCommand is an IDLE command.

Initially, the IDLE command is running. The server may send unilateral data. The client cannot send any command while IDLE is running.

Close must be called to stop the IDLE command.

func (*IdleCommand) Close

func (cmd *IdleCommand) Close() error

Close stops the IDLE command.

This method blocks until the command to stop IDLE is written, but doesn't wait for the server to respond. Callers can use Wait for this purpose.

func (*IdleCommand) Wait

func (cmd *IdleCommand) Wait() error

Wait blocks until the IDLE command has completed.

type ListCommand

type ListCommand struct {
	// contains filtered or unexported fields
}

ListCommand is a LIST command.

func (*ListCommand) Close

func (cmd *ListCommand) Close() error

Close releases the command.

Calling Close unblocks the IMAP client decoder and lets it read the next responses. Next will always return nil after Close.

func (*ListCommand) Collect

func (cmd *ListCommand) Collect() ([]*imap.ListData, error)

Collect accumulates mailboxes into a list.

This is equivalent to calling Next repeatedly and then Close.

func (*ListCommand) Next

func (cmd *ListCommand) Next() *imap.ListData

Next advances to the next mailbox.

On success, the mailbox LIST data is returned. On error or if there are no more mailboxes, nil is returned.

type MoveCommand

type MoveCommand struct {
	// contains filtered or unexported fields
}

MoveCommand is a MOVE command.

func (*MoveCommand) Wait

func (cmd *MoveCommand) Wait() (*MoveData, error)

type MoveData

type MoveData struct {
	// requires UIDPLUS or IMAP4rev2
	UIDValidity uint32
	SourceUIDs  imap.NumSet
	DestUIDs    imap.NumSet
}

MoveData contains the data returned by a MOVE command.

type MyRightsCommand

type MyRightsCommand struct {
	// contains filtered or unexported fields
}

MyRightsCommand is a MYRIGHTS command.

func (*MyRightsCommand) Wait

func (cmd *MyRightsCommand) Wait() (*MyRightsData, error)

type MyRightsData

type MyRightsData struct {
	Mailbox string
	Rights  imap.RightSet
}

MyRightsData is the data returned by the MYRIGHTS command.

type NamespaceCommand

type NamespaceCommand struct {
	// contains filtered or unexported fields
}

NamespaceCommand is a NAMESPACE command.

func (*NamespaceCommand) Wait

func (cmd *NamespaceCommand) Wait() (*imap.NamespaceData, error)

type Options

type Options struct {
	// TLS configuration for use by DialTLS and DialStartTLS. If nil, the
	// default configuration is used.
	TLSConfig *tls.Config
	// Raw ingress and egress data will be written to this writer, if any.
	// Note, this may include sensitive information such as credentials used
	// during authentication.
	DebugWriter io.Writer
	// Unilateral data handler.
	UnilateralDataHandler *UnilateralDataHandler
	// Decoder for RFC 2047 words.
	WordDecoder *mime.WordDecoder
}

Options contains options for Client.

type QuotaData

type QuotaData struct {
	Root      string
	Resources map[imap.QuotaResourceType]QuotaResourceData
}

QuotaData is the data returned by a QUOTA response.

type QuotaResourceData

type QuotaResourceData struct {
	Usage int64
	Limit int64
}

QuotaResourceData contains the usage and limit for a quota resource.

type SearchCommand

type SearchCommand struct {
	// contains filtered or unexported fields
}

SearchCommand is a SEARCH command.

func (*SearchCommand) Wait

func (cmd *SearchCommand) Wait() (*imap.SearchData, error)

type SelectCommand

type SelectCommand struct {
	// contains filtered or unexported fields
}

SelectCommand is a SELECT command.

func (*SelectCommand) Wait

func (cmd *SelectCommand) Wait() (*imap.SelectData, error)

type SelectedMailbox

type SelectedMailbox struct {
	Name           string
	NumMessages    uint32
	Flags          []imap.Flag
	PermanentFlags []imap.Flag
}

SelectedMailbox contains metadata for the currently selected mailbox.

type SetACLCommand

type SetACLCommand struct {
	// contains filtered or unexported fields
}

SetACLCommand is a SETACL command.

func (*SetACLCommand) Wait

func (cmd *SetACLCommand) Wait() error

type SortCommand

type SortCommand struct {
	// contains filtered or unexported fields
}

SortCommand is a SORT command.

func (*SortCommand) Wait

func (cmd *SortCommand) Wait() ([]uint32, error)

type SortCriterion

type SortCriterion struct {
	Key     SortKey
	Reverse bool
}

type SortKey

type SortKey string
const (
	SortKeyArrival SortKey = "ARRIVAL"
	SortKeyCc      SortKey = "CC"
	SortKeyDate    SortKey = "DATE"
	SortKeyFrom    SortKey = "FROM"
	SortKeySize    SortKey = "SIZE"
	SortKeySubject SortKey = "SUBJECT"
	SortKeyTo      SortKey = "TO"
)

type SortOptions

type SortOptions struct {
	SearchCriteria *imap.SearchCriteria
	SortCriteria   []SortCriterion
}

SortOptions contains options for the SORT command.

type StatusCommand

type StatusCommand struct {
	// contains filtered or unexported fields
}

StatusCommand is a STATUS command.

func (*StatusCommand) Wait

func (cmd *StatusCommand) Wait() (*imap.StatusData, error)

type ThreadCommand

type ThreadCommand struct {
	// contains filtered or unexported fields
}

ThreadCommand is a THREAD command.

func (*ThreadCommand) Wait

func (cmd *ThreadCommand) Wait() ([]ThreadData, error)

type ThreadData

type ThreadData struct {
	Chain      []uint32
	SubThreads []ThreadData
}

type ThreadOptions

type ThreadOptions struct {
	Algorithm      imap.ThreadAlgorithm
	SearchCriteria *imap.SearchCriteria
}

ThreadOptions contains options for the THREAD command.

type UnilateralDataHandler

type UnilateralDataHandler struct {
	Expunge func(seqNum uint32)
	Mailbox func(data *UnilateralDataMailbox)
	Fetch   func(msg *FetchMessageData)

	// requires ENABLE METADATA or ENABLE SERVER-METADATA
	Metadata func(mailbox string, entries []string)
}

UnilateralDataHandler handles unilateral data.

The handler will block the client while running. If the caller intends to perform slow operations, a buffered channel and a separate goroutine should be used.

The handler will be invoked in an arbitrary goroutine.

See Options.UnilateralDataHandler.

type UnilateralDataMailbox

type UnilateralDataMailbox struct {
	NumMessages    *uint32
	Flags          []imap.Flag
	PermanentFlags []imap.Flag
}

UnilateralDataMailbox describes a mailbox status update.

If a field is nil, it hasn't changed.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL