email

package
v0.12.2 Latest Latest
Warning

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

Go to latest
Published: Jun 29, 2022 License: BSD-3-Clause, MIT, MIT-0, + 1 more Imports: 15 Imported by: 0

README

email - format multipart MIME email

go get -u "tawesoft.co.uk/go"
import "tawesoft.co.uk/go/email"
Links License Stable?
homedocssrc MIT candidate

About

Package email implements the formatting of multipart MIME e-mail messages, including Unicode headers, attachments, HTML email, and plain text.

File attachments are lazy, and read from disk only at the time the e-mail is sent.

(Optionally) supports encoding very long headers using folding whitespace.

Examples

Format an email message and print it, as well as its JSON serialisation, to a Writer (here, stdout).

package main

import (
    "encoding/json"
    "fmt"
    "net/mail"
    "os"
    "strings"

    "tawesoft.co.uk/go/email"
)

func main() {
    eml := email.Message{
        ID:    email.NewMessageID("localhost"),
        From:  mail.Address{"Alan Turing", "turing.alan@example.org"},
        To:  []mail.Address{{"Grace Hopper", "amazing.grace@example.net"},},
        Bcc: []mail.Address{{"BCC1", "bcc1@example.net"}, {"BCC2", "bbc2@example.net"}},
        Subject: "Computer Science is Cool! ❤",
        Text: `This is a test email!`,
        Html: `<!DOCTYPE html><html lang="en"><body><p>This is a test email!</p></body></html>`,
        Attachments: []*email.Attachment{
            email.FileAttachment("attachment1.txt"),
        },
        Headers: mail.Header{
            "X-Category": []string{"newsletter", "marketing"},
        },
    }

    fmt.Printf("Formatted email:\n")
    err := eml.Write(os.Stdout)
    if err != nil { panic(err) }

    fmt.Printf("\n\nJSON serialisation:\n")
    encoder := json.NewEncoder(os.Stdout)
    encoder.SetIndent("", "    ")
    encoder.SetEscapeHTML(false)
    err = encoder.Encode(eml)
    if err != nil { panic(err) }

    fmt.Printf("\n\nJSON deserialisation:\n")
    var out email.Message
    decoder := json.NewDecoder(strings.NewReader(`{
    "ID": "20210312143531.183a5bf8f218c9c3e2dc4976a70676d2@localhost",
    "From": {
        "Name": "Alan Turing",
        "Address": "turing.alan@example.org"
    },
    "To": [
        {
            "Name": "Grace Hopper",
            "Address": "amazing.grace@example.net"
        }
    ],
    "Cc": null,
    "Bcc": [
        {
            "Name": "BCC1",
            "Address": "bcc1@example.net"
        },
        {
            "Name": "BCC2",
            "Address": "bbc2@example.net"
        }
    ],
    "Subject": "Computer Science is Cool! ❤",
    "Headers": {
        "X-Category": [
            "newsletter",
            "marketing"
        ]
    },
    "Html": "<!DOCTYPE html><html lang=\"en\"><body><p>This is a test email!</p></body></html>",
    "Text": "This is a test email!",
    "Attachments": [
        {
            "Filename": "attachment1.txt",
            "Mimetype": "text/plain; charset=utf-8",
            "Content": "U0dWc2JHOGdkMjl5YkdRaA=="
        }
    ]
}
`))
    decoder.DisallowUnknownFields()
    err = decoder.Decode(&out)
    if err != nil { panic(err) }
    out.Write(os.Stdout)
}

Changes

2021-03-13
  • The envelope From field has been renamed ReturnPath. It was intended for this change to make part of the 2021-03-07 changes - apologies for its late inclusion. This should be the last breaking API change.
2021-03-12
  • Add JSON (de)serialisation

  • Add missing error case

2021-03-07
  • Breaking changes to this email package, as previously warned, bump the monorepo tagged version to v0.2.0 and upgrade the email package stability rating from "unstable" to "candidate". For previous behavior, point your imports to tawesoft.co.uk/go/legacy/email.

  • Attachments are now read/written more efficiently.

  • Attachments are now closed properly!

  • Attachment Reader method is now required to return something satisfying the io.ReadCloser interface. If no Close is required, wrap the return value in an io.NopCloser.

  • The Envelope struct no longer has a message field - instead, use an (Envelope, Message) 2-tuple where you need both of these items.

  • An email's Message-ID header is no longer implicitly generated for an email. This is left to the mail submission agent.

  • If you ARE implementing a mail submission agent, an email's Message-ID header can be specified by the new ID field on the Message struct type.

  • A cryptographically unique Message ID can be generated from the newly exposed function, NewMessageID.

  • The Print method on Message is renamed Write.

  • Email message lines longer than 998 characters are now supported in headers using folding white space. Note that some parsers, such as Go's net.mail, do not understand this syntax (even though it is allowed).

  • The new method WriteCompat on Message won't use folding white space to support long headers and will instead generate an error. Use this method in preference to Write if you are expecting the consumer of your email message (e.g. a Go implementation) will be unable to handle folding white space.

Getting Help

This package is part of tawesoft.co.uk/go, a monorepo for small Go modules maintained by Tawesoft®. Check out that URL for more information about other Go modules from Tawesoft plus community and commercial support options.

Documentation

Overview

Package email implements the formatting of multipart MIME e-mail messages, including Unicode headers, attachments, HTML email, and plain text.

File attachments are lazy, and read from disk only at the time the e-mail is sent.

(Optionally) supports encoding very long headers using folding whitespace.

Examples

Format an email message and print it, as well as its JSON serialisation, to a Writer (here, stdout).

https://www.tawesoft.co.uk/go/doc/email/examples/stdout/

Package Information

License: MIT (see LICENSE.txt)

Stable: candidate

For more information, documentation, source code, examples, support, links, etc. please see https://www.tawesoft.co.uk/go and https://www.tawesoft.co.uk/go/email

2021-03-13

    * The envelope From field has been renamed ReturnPath. It was intended for
      this change to make part of the 2021-03-07 changes - apologies for its
      late inclusion. This should be the last breaking API change.

2021-03-12

    * Add JSON (de)serialisation

    * Add missing error case

2021-03-07

    * Breaking changes to this email package, as previously warned, bump the
      monorepo tagged version to v0.2.0 and upgrade the email package stability
      rating from "unstable" to "candidate". For previous behavior, point your
      imports to `tawesoft.co.uk/go/legacy/email`.

    * Attachments are now read/written more efficiently.

    * Attachments are now closed properly!

    * Attachment Reader method is now required to return something satisfying
      the io.ReadCloser interface. If no Close is required, wrap the return
      value in an `io.NopCloser`.

    * The Envelope struct no longer has a message field - instead, use
      an (Envelope, Message) 2-tuple where you need both of these items.

    * An email's Message-ID header is no longer implicitly generated for an
      email. This is left to the mail submission agent.

    * If you ARE implementing a mail submission agent, an email's Message-ID
      header can be specified by the new ID field on the Message struct type.

    * A cryptographically unique Message ID can be generated from the newly
      exposed function, NewMessageID.

    * The Print method on Message is renamed Write.

    * Email message lines longer than 998 characters are now supported in
      headers using folding white space. Note that some parsers, such as Go's
      `net.mail`, do not understand this syntax (even though it is allowed).

    * The new method WriteCompat on Message won't use folding white space to
      support long headers and will instead generate an error. Use this method
      in preference to Write if you are expecting the consumer of your email
      message (e.g. a Go implementation) will be unable to handle folding white
      space.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewMessageID added in v0.2.0

func NewMessageID(host string) string

NewMessageID generates a cryptographically unique RFC 2822 3.6.4 Message ID (not including angle brackets).

Types

type Attachment

type Attachment struct {
	// Filename is the name to give the attachment in the email
	Filename string

	// Mimetype e.g. "application/pdf".
	// If an empty string, then attempts to automatically detect based on filename extension.
	Mimetype string

	// Reader is a lazy reader. e.g. a function that returns the result of os.Open.
	Reader func() (io.ReadCloser, error)
}

Attachment defines an e-mail attachment. They are read lazily.

func FileAttachment

func FileAttachment(src string) *Attachment

FileAttachment returns an Attachment from a file path. The file at that path is lazily opened at the time the attachment is sent.

func (*Attachment) MarshalJSON added in v0.4.0

func (a *Attachment) MarshalJSON() ([]byte, error)

Implements the json.Marshal interface. Note that the JSON content is ALWAYS Base64 encoded (with whitespace).

func (*Attachment) UnmarshalJSON added in v0.4.0

func (a *Attachment) UnmarshalJSON(data []byte) error

Implements the json.Unarshal interface. Note that the JSON content is ALWAYS Base64 encoded (with whitespace).

type Envelope

type Envelope struct {
	// ReturnPath is the sender in the FROM SMTP command.
	//
	// Often, this should match the Email From address.
	//
	// In the cause of autoreplies (like "Out of Office" or bounces or delivery
	// status notifications) this should be an empty string to stop an infinite
	// loop of bounces.
	ReturnPath string

	// ReceiptTo is a list of recipients. This is normally automatically
	// generated from the Email To/CC/BCC addresses.
	ReceiptTo []string
}

Envelope wraps an Email with some SMTP protocol information for extra control.

type Message

type Message struct {
	ID      string // Message-ID header, excluding angle brackets
	From    mail.Address
	To      []mail.Address
	Cc      []mail.Address
	Bcc     []mail.Address
	Subject string

	// Headers are additional headers for the message. The combination of a
	// header and a value as strings must not exceed a length of 996
	// characters. Longer values CANNOT be supported with folding white space
	// syntax without advance knowledge (special cases are possible but not
	// currently implemented).
	Headers mail.Header

	// Html is a HTML-encoded version of the message. Lines must not exceed
	// 998 characters.
	Html string

	// Text is a plain-text version of the message. It is your responsibility
	// to ensure word-wrapping. Lines must not exceed 998 characters.
	Text string

	// Attachments is a lazily-loaded sequence of attachments. May be nil.
	Attachments []*Attachment
}

Message defines a multipart e-mail (including headers, HTML body, plain text body, and attachments).

Use the `headers` parameter to specify additional headers. Note that `mail.Header` maps keys to a *list* of strings, because some headers may appear multiple times.

func (*Message) Write added in v0.2.0

func (e *Message) Write(dest io.Writer) error

Write writes a multipart Email to dest.

func (*Message) WriteCompat added in v0.2.0

func (e *Message) WriteCompat(dest io.Writer) error

WriteCompat is like Write, however very long headers (caused, for example, by sending a message with many To addresses, or a subject that is too long) are not encoded using folding white space and instead cause an error.

Directories

Path Synopsis
examples
stdout
Format an email message and print it, as well as its JSON serialisation, to a Writer (here, stdout).
Format an email message and print it, as well as its JSON serialisation, to a Writer (here, stdout).

Jump to

Keyboard shortcuts

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