mail

package module
v0.0.0-...-52bc9c5 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2015 License: BSD-2-Clause Imports: 19 Imported by: 0

README

Package mail

Build Status GoDoc

Package mail implements composing and parsing of mail messages.

Creating a message with multiple parts and attachments ends up being a surprisingly painful task in Go. The net/mail package in the standard library only offers tools to parse mail messages and addresses.

This package can replace the net/mail in your code without breaking it.

Feedback and contributions are more than welcome.

Features

  • multipart support
  • attachments (base64)
  • quoted-printable encoding of body text
  • quoted-printable decoding of headers
  • getters and setters common headers

Known issues

Installation

Alex Cesaro's quotedprintable package is the only external dependency. It's likely to be included in Go 1.5 in a new mime/quotedprintable package.

go get godoc.org/gopkg.in/alexcesaro/quotedprintable.v1
go get github.com/mohamedattahri/mail

Examples

Plain text message
msg := NewMessage()
msg.SetFrom(sender)
msg.To().Add(recipient)
msg.SetSubject("Plain text message")
msg.SetContentType("text/plain")
fmt.Fprintf(msg.Body, "Hello, World!")
fmt.Println(msg)
HTML and alternative text
msg := NewMessage()
msg.SetFrom(sender)
msg.To().Add(recipient)
msg.SetSubject("HTML and alternative text")
alternative := NewMultipart("multipart/alternative", msg)
alternative.AddText("text/plain", text)
alternative.AddText("text/html", html)
alternative.Close()
fmt.Println(msg)
Simple message with an attachment
msg := NewMessage()
msg.SetFrom(sender)
msg.To().Add(recipient)
msg.SetSubject("Simple message with an attachment")
mixed := NewMultipart("multipart/mixed", msg)
mixed.AddText("text/plain", text)
mixed.AddAttachment(Attachment, "Gopher.png", "", attachment)
mixed.Close()
fmt.Println(msg)
HTML message, alternative text and an attachment
msg := NewMessage()
msg.SetFrom(sender)
msg.To().Add(recipient)
msg.SetSubject("HTML message, alternative text and an attachment")

mixed := NewMultipart("multipart/mixed", msg)
alternative, _ := mixed.AddPart("multipart/alternative", nil)
alternative.AddText("text/plain", text)
alternative.AddText("text/html", html)
alternative.Close()
mixed.AddAttachment(Inline, "Photo", "image/jpeg", attachment)
mixed.Close()

fmt.Println(msg)
Attached image and cid URI Scheme

This example shows how to use the cid URI Scheme to use an attachment as a data source for an HTML img tag.

msg := NewMessage()
msg.SetFrom(&Address{"Al Bumin", "a.bumin@example.name"})
msg.To().Add(&Address{"Polly Ester", "p.ester@example.com"})
msg.SetSubject("Message with HTML, alternative text, and an attachment")
mixed := NewMultipart("multipart/mixed", msg)
// filename is the name that will be suggested to a user who would like to
// download the attachment, but also the ID with which you can refer to the
// attachment in a cid URI scheme.
filename := "gopher.jpg"
// The src of the image in this HTML is set to use the attachment with the
// Content-ID filename.
html := fmt.Sprintf("<html><body><img src=\"cid:%s\"/></body></html>", filename)
mixed.AddText("text/html", bytes.NewReader([]byte(html)))
// Load the photo and add the attachment with filename.
attachment, _ := ioutil.ReadFile("path/of/image.jpg")
mixed.AddAttachment(Attachment, filename, "image/jpeg", bytes.NewReader(attachment))
// Closing mixed, the parent part.
mixed.Close()

fmt.Println(msg)

Documentation

Overview

Package mail implements composing and parsing of mail messages.

Creating a message with multiple parts and attachments ends up being a surprisingly painful task in Go. That's because the mail package in the standard library only offers tools to parse mail messages and addresses.

This package can replace the net/mail package of the standard library without breaking your existing code.

Features

- multipart support

- attachments

- quoted-printable encoding of body text

- quoted-printable decoding of headers

- getters and setters common headers

Known issues

- Quoted-printable encoding does not respect the 76 characters per line limitation imposed by RFC 2045 (https://github.com/golang/go/issues/4943).

Installation

Alex Cesaro's quotedprintable package (https://godoc.org/gopkg.in/alexcesaro/quotedprintable.v1) is the only external dependency. It's likely to be included in Go 1.5 in a new mime/quotedprintable package (https://codereview.appspot.com/132680044).

go get godoc.org/gopkg.in/alexcesaro/quotedprintable.v1
go get github.com/mohamedattahri/mail

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrHeaderNotPresent = errors.New("mail: header not in message")
View Source
var ErrPartClosed = errors.New("mail: part has been closed")

Functions

This section is empty.

Types

type Address

type Address struct {
	Name    string // Proper name; may be empty.
	Address string // user@domain
}

Address represents a single mail address. An address such as "Barry Gibbs <bg@example.com>" is represented as Address{Name: "Barry Gibbs", Address: "bg@example.com"}.

func ParseAddress

func ParseAddress(address string) (*Address, error)

ParseAddress parses a single RFC 5322 address, e.g. "Barry Gibbs <bg@example.com>"

func ParseAddressList

func ParseAddressList(list string) ([]*Address, error)

ParseAddressList parses the given string as a list of addresses.

func (*Address) String

func (a *Address) String() string

String formats the address as a valid RFC 5322 address. If the address's name contains non-ASCII characters the name will be rendered according to RFC 2047.

type AddressList

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

AddressList implements methods to manipulate a comma-separated list of mail addresses.

func (*AddressList) Add

func (a *AddressList) Add(address *Address)

Add address to the list.

func (*AddressList) Addresses

func (a *AddressList) Addresses() ([]*Address, error)

Addresses contained in the list as an array or an error if the underlying string is malformed.

func (*AddressList) Contain

func (a *AddressList) Contain(address *Address) bool

Contain returns a value indicating whether address is in the list.

func (*AddressList) Remove

func (a *AddressList) Remove(address *Address)

Remove address from the list.

func (*AddressList) String

func (a *AddressList) String() string

String returns the addresses in the list in a comma-separated string.

type AttachmentType

type AttachmentType string

AttachmentType indicates to the mail user agent how an attachment should be treated.

const (
	// Attachment indicates that the attachment should be offered as an optional
	// download.
	Attachment AttachmentType = "attachment"
	// Inline indicates that the attachment should be rendered in the body of
	// the message.
	Inline AttachmentType = "inline"
)
type Header map[string][]string

A Header represents the key-value pairs in a mail message header.

func (Header) AddressList

func (h Header) AddressList(key string) ([]*Address, error)

AddressList parses the named header field as a list of addresses.

func (Header) Date

func (h Header) Date() (time.Time, error)

Date parses the Date header field.

func (Header) Get

func (h Header) Get(key string) string

Get gets the first value associated with the given key. If there are no values associated with the key, Get returns "".

type Message

type Message struct {
	Header Header
	Body   io.ReadWriter
	// contains filtered or unexported fields
}

A Message represents a mail message.

Example

Example of a simple message with plain text.

msg := NewMessage()
msg.SetFrom(&Address{"Al Bumin", "a.bumin@example.name"})
msg.To().Add(&Address{"Polly Ester", "p.ester@example.com"})
msg.SetSubject("Simple message with plain text")
msg.SetContentType("text/plain")
fmt.Fprintf(msg.Body, "Hello, World!")

fmt.Println(msg)
Output:

Example (Alternative)

Example of a message with HTML and alternative plain text.

text := bytes.NewReader([]byte("Hello, World!"))
html := bytes.NewReader([]byte("<html><body>Hello, World!</body></html>"))

msg := NewMessage()
msg.SetFrom(&Address{"Al Bumin", "a.bumin@example.name"})
msg.To().Add(&Address{"Polly Ester", "p.ester@example.com"})
msg.SetSubject("Message with HTML and alternative text")

alternative := NewMultipart("multipart/alternative", msg)
alternative.AddText("text/plain", text)
alternative.AddText("text/html", html)
alternative.Close()

fmt.Println(msg)
Output:

Example (Cid)

This example shows how to use the cid URI Scheme to use an attachment as a data source for an HTML img tag.

msg := NewMessage()
msg.SetFrom(&Address{"Al Bumin", "a.bumin@example.name"})
msg.To().Add(&Address{"Polly Ester", "p.ester@example.com"})
msg.SetSubject("Message with HTML, alternative text, and an attachment")
mixed := NewMultipart("multipart/mixed", msg)

// filename is the name that will be suggested to a user who would like to
// download the attachment, but also the ID with which you can refer to the
// attachment in a cid URI scheme.
filename := "gopher.jpg"

// The src of the image in this HTML is set to use the attachment with the
// Content-ID filename.
html := fmt.Sprintf("<html><body><img src=\"cid:%s\"/></body></html>", filename)
mixed.AddText("text/html", bytes.NewReader([]byte(html)))

// Load the photo and add the attachment with filename.
attachment, _ := ioutil.ReadFile("path/of/image.jpg")
mixed.AddAttachment(Attachment, filename, "image/jpeg", bytes.NewReader(attachment))

// Closing mixed, the parent part.
mixed.Close()

fmt.Println(msg)
Output:

Example (Mixed)

Example of a message with HTML content, alternative text, and an attachment.

text := bytes.NewReader([]byte("Hello, World!"))
html := bytes.NewReader([]byte("<html><body>Hello, World!</body></html>"))
data, _ := ioutil.ReadFile("path/of/photo.jpg")
attachment := bytes.NewReader(data)

msg := NewMessage()
msg.SetFrom(&Address{"Al Bumin", "a.bumin@example.name"})
msg.To().Add(&Address{"Polly Ester", "p.ester@example.com"})
msg.SetSubject("Message with HTML, alternative text, and an attachment")

mixed := NewMultipart("multipart/mixed", msg)
alternative, _ := mixed.AddMultipart("multipart/alternative")
alternative.AddText("text/plain", text)
alternative.AddText("text/html", html)
alternative.Close()
mixed.AddAttachment(Attachment, "Photo", "image/jpeg", attachment)
mixed.Close()

fmt.Println(msg)
Output:

func NewMessage

func NewMessage() *Message

NewMessage returns a new empty message.

func ReadMessage

func ReadMessage(r io.Reader) (msg *Message, err error)

ReadMessage reads a message from r. The headers are parsed, and the body of the message will be available for reading from r.

func (*Message) Bcc

func (m *Message) Bcc() *AddressList

Bcc gives access to the list of recipients Bcced in the message.

func (*Message) Bytes

func (m *Message) Bytes() []byte

Bytes assembles the message in an array of bytes.

func (*Message) Cc

func (m *Message) Cc() *AddressList

Cc gives access to the list of recipients Cced in the message.

func (*Message) ContentType

func (m *Message) ContentType() string

ContentType returns the MIME type of the message.

func (*Message) Date

func (m *Message) Date() time.Time

Date returns the time and date when the message was written.

func (*Message) From

func (m *Message) From() *Address

From returns the address of the author.

func (*Message) GetHeader

func (m *Message) GetHeader(header string) string

GetHeader returns the undecoded value of header if found. To access the raw (potentially encoded) value of header, use the Message.Header.

func (*Message) InReplyTo

func (m *Message) InReplyTo() string

InReplyTo returns the Message-Id of the message that this message is a reply to.

func (*Message) MessageID

func (m *Message) MessageID() string

MessageID returns the unique identifier of this message.

func (*Message) ReplyTo

func (m *Message) ReplyTo() string

ReplyTo returns the address that should be used to reply to the message.

func (*Message) Sender

func (m *Message) Sender() string

Sender returns the address of the actual sender acting on behalf of the author listed in From.

func (*Message) SetContentType

func (m *Message) SetContentType(mediaType string)

SetContentType returns the MIME type of the message.

func (*Message) SetFrom

func (m *Message) SetFrom(address *Address)

SetFrom sets the address of the message's author.

func (*Message) SetHeader

func (m *Message) SetHeader(header, value string)

SetHeader adds header to the list of headers and sets it to quoted-printable encoded value.

func (*Message) SetInReplyTo

func (m *Message) SetInReplyTo(id string)

SetInReplyTo sets the Message-Id of the message that this message is a reply to.

func (*Message) SetMessageID

func (m *Message) SetMessageID(id string)

SetMessageID sets the unique identifier of this message.

func (*Message) SetReplyTo

func (m *Message) SetReplyTo(address string)

SetReplyTo sets the address that should be used to reply to the message.

func (*Message) SetSender

func (m *Message) SetSender(address string)

SetSender sets the address of the actual sender acting on behalf of the author listed in From.

func (*Message) SetSubject

func (m *Message) SetSubject(subject string)

SetSubject sets the subject line of the message.

func (*Message) String

func (m *Message) String() string

String returns a text representation of the message.

func (*Message) Subject

func (m *Message) Subject() string

Subject line of the message.

func (*Message) To

func (m *Message) To() *AddressList

To gives access to the list of recipients of the message.

type Multipart

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

Multipart repreents a multipart message body. It can other nest multiparts, texts, and attachments.

func NewMultipart

func NewMultipart(mediaType string, msg *Message) (root *Multipart)

NewMultipart modifies msg to become a multipart message and returns the root part inside which other parts, texts and attachments can be nested.

Example:

multipart := NewMultipart("multipart/alternative", msg)
multipart.AddPart("text/plain", text)
multipart.AddPart("text/html", html)
multipart.Close()

func (*Multipart) AddAttachment

func (p *Multipart) AddAttachment(attachType AttachmentType, filename, mediaType string, r io.Reader) (err error)

AddAttachment encodes the content of r in base64 and writes it as an attachment of type attachType in this part.

filename is the file name that will be suggested by the mail user agent to a user who would like to download the attachment. It's also the value to which the Content-ID header will be set. A name with an extension such as "report.docx" or "photo.jpg" is recommended. RFC 5987 is not supported, so the charset is restricted to ASCII characters.

mediaType indicates the content type of the attachment. If an empty string is passed, mime.TypeByExtension will first be called to deduce a value from the extension of filemame before defaulting to "application/octet-stream".

In the following example, the media MIME type will be set to "image/png" based on the ".png" extension of the filename "gopher.png":

part.AddAttachment(Inline, "gopher.png", "", image)

func (*Multipart) AddMultipart

func (p *Multipart) AddMultipart(mediaType string) (nested *Multipart, err error)

AddMultipart creates a nested part with mediaType and a randomly generated boundary. The returned nested part can then be used to add a text or an attachment.

Example:

alt, _ := part.AddMultipart("multipart/mixed")
alt.AddText("text/plain", text)
alt.AddAttachment("gopher.png", "", image)
alt.Close()

func (*Multipart) AddText

func (p *Multipart) AddText(mediaType string, r io.Reader) error

AddText applies quoted-printable encoding to the content of r before writing the encoded result in a new sub-part with media MIME type set to mediaType.

Specifying the charset in the mediaType string is recommended ("plain/text; charset=utf-8").

func (*Multipart) Boundary

func (p *Multipart) Boundary() string

Boundary separating the children of this part.

func (*Multipart) Close

func (p *Multipart) Close() error

Close adds a closing boundary to the part.

Calling AddText, AddAttachment or AddMultipart on a closed part will return ErrPartClosed.

func (*Multipart) Closed

func (p *Multipart) Closed() bool

Closed returns true if the part has been closed.

func (*Multipart) Header

func (p *Multipart) Header() textproto.MIMEHeader

Header map of the part.

func (*Multipart) MediaType

func (p *Multipart) MediaType() string

MediaType returns the media MIME type of this part.

Jump to

Keyboard shortcuts

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