blackmail – zgo.at/blackmail Index | Files | Directories

package blackmail

import "zgo.at/blackmail"

Package blackmail sends emails.

Index

Constants

const (
	ConnectWriter = "writer" // Write to an io.Writer.
	ConnectDirect = "direct" // Connect directly to MX records.
)
const (
	AuthLogin   = "login"
	AuthPlain   = "plain"
	AuthCramMD5 = "cram-md5"
)

Authentication methods for MailerAuth().

Variables

var DefaultMailer = NewMailer(ConnectDirect)

DefaultMailer is used with blackmail.Send().

Functions

func Attachment

func Attachment(contentType, filename string, body []byte) bodyPart

Attachment returns a new attachment part with the given Content-Type.

It will try to guess the Content-Type if empty.

func Bcc

func Bcc(addr ...string) []recipient

func BccAddress

func BccAddress(addr ...mail.Address) []recipient

func BccNames

func BccNames(nameAddr ...string) []recipient

func Body

func Body(contentType string, body []byte) bodyPart

Body returns a new part with the given Content-Type.

func BodyHTML

func BodyHTML(body []byte, images ...bodyPart) bodyPart

BodyHTML returns a new text/html part.

func BodyMust

func BodyMust(contentType string, fn func() ([]byte, error)) bodyPart

BodyMust sets the body using a callback, propagating any errors back up.

This is useful when using Go templates for the mail body;

buf := new(bytes.Buffer)
err := tpl.ExecuteTemplate(buf, "email", struct{
    Name string
}{"Martin"})
if err != nil {
    log.Fatal(err)
}

err := Send("Basic test", From("", "me@example.com"),
    To("to@to.to"),
    Body("text/plain", buf.Bytes()))

With BodyMust(), it's simpler; you just need to define a little helper re-usable helper function and call that:

func template(tplname string, args interface{}) func() ([]byte, error) {
    return func() ([]byte, error) {
        buf := new(bytes.Buffer)
        err := tpl.ExecuteTemplate(buf, tplname, args)
        return buf.Bytes(), err
    }
}

err := Send("Basic test", From("", "me@example.com"),
    To("to@to.to"),
    BodyMust("text/html", template("email", struct {
        Name string
    }{"Martin"})))

Other use cases include things like loading data from a file, reading from a stream, etc.

func BodyMustHTML

func BodyMustHTML(fn func() ([]byte, error)) bodyPart

BodyMustHTML is like BodyMust() with contentType text/html.

func BodyMustText

func BodyMustText(fn func() ([]byte, error)) bodyPart

BodyMustText is like BodyMust() with contentType text/plain.

func BodyText

func BodyText(body []byte) bodyPart

BodyText returns a new text/plain part.

func Bodyf

func Bodyf(s string, args ...interface{}) bodyPart

Bodyf returns a new text/plain part.

func Cc

func Cc(addr ...string) []recipient

func CcAddress

func CcAddress(addr ...mail.Address) []recipient

func CcNames

func CcNames(nameAddr ...string) []recipient

func From

func From(name, address string) mail.Address

From makes creating a mail.Address a bit more convenient.

mail.Address{Name: "foo, Address: "foo@example.com}
blackmail.From{"foo, "foo@example.com)

func Headers

func Headers(keyValue ...string) bodyPart

Headers adds the headers to the message.

This will override any headers set automatically by the system, such as Date: or Message-Id:

Headers("My-Header", "value",
    "Message-Id", "<my-message-id@example.com>")

func HeadersAutoreply

func HeadersAutoreply() bodyPart

HeadersAutoreply sets headers to indicate this message is a an autoreply.

See e.g: https://www.arp242.net/autoreply.html#what-you-need-to-set-on-your-auto-response

func InlineImage

func InlineImage(contentType, filename string, body []byte) bodyPart

InlineImage returns a new inline image part.

It will try to guess the Content-Type if empty.

Then use "cid:blackmail:<n>" to reference it:

<img src="cid:blackmail:1">     First InlineImage()
<img src="cid:blackmail:2">     Second InlineImage()

func MailerAuth

func MailerAuth(v string) senderOpt

MailerAuth sets the AUTH method for the relay mailer. Currently LOGIN, PLAIN, and CRAM-MD5 are supported.

In general, PLAIN is preferred and it's the default. Note that CRAM-MD5 only provides weak security over untrusted connections.

func MailerOut

func MailerOut(v io.Writer) senderOpt

MailerOut sets the output for the writer mailer.

func MailerRequireTLS

func MailerRequireTLS(v bool) senderOpt

MailerRequireTLS sets whether TLS is required.

func MailerTLS

func MailerTLS(v *tls.Config) senderOpt

MailerTLS sets the tls config for the relay and direct mailer.

func Message

func Message(subject string, from mail.Address, rcpt []recipient, firstPart bodyPart, parts ...bodyPart) ([]byte, []string, error)

Message formats a message.

func NopCloser

func NopCloser(r io.Writer) io.WriteCloser

func Send

func Send(subject string, from mail.Address, rcpt []recipient, firstPart bodyPart, parts ...bodyPart) error

Send an email using the DefaultMailer.

The arguments are identical to Message().

func To

func To(addr ...string) []recipient

To sets the To: from a list of email addresses.

func ToAddress

func ToAddress(addr ...mail.Address) []recipient

ToAddress sets the To: from a list of mail.Addresses.

func ToNames

func ToNames(nameAddr ...string) []recipient

ToNames sets the To: from a list of "name", "addr" arguments.

func With

func With(ctx context.Context, m *Mailer) context.Context

With returns a copy of the context with the Mailer as a value.

Types

type Mailer

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

Mailer to send messages; use NewMailer() to construct a new instance.

func Get

func Get(ctx context.Context) *Mailer

Get retrieves the Mailer stored on the context with With, returning nil if there is no context stored.

func MustGet

func MustGet(ctx context.Context) *Mailer

MustGet works like Get, but will panic on errors.

func NewMailer

func NewMailer(smtp string, opts ...senderOpt) Mailer

NewMailer returns a new re-usable mailer.

Setting the connection string to blackmail.Writer will print all messages to stdout without sending them:

NewMailer(blackmail.Writer)

You can pass Mailer.Writer() as an option to send them somewhere else:

NewMailer(blackmail.Writer, blackmail.MailerOut(os.Stderr))

buf := new(bytes.Buffer)
NewMailer(blackmail.Writer, blackmail.MailerOut(buf))

If the connection string is set to blackmail.Direct, blackmail will look up the MX records and attempt to deliver to them.

NewMailer(blackmail.Direct)

Any URL will be used as a SMTP relay:

NewMailer("smtps://foo:foo@mail.foo.com")

The default authentication is PLAIN; add MailerAuth() to set something different.

func (Mailer) Send

func (m Mailer) Send(subject string, from mail.Address, rcpt []recipient, firstPart bodyPart, parts ...bodyPart) error

Send an email.

The arguments are identical to Message().

type SoftError

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

func (SoftError) Error

func (f SoftError) Error() string

func (SoftError) Unwrap

func (f SoftError) Unwrap() error

Source Files

blackmail.go blackmail_aux.go ctx.go mailer.go mailer_aux.go mailer_direct.go mailer_relay.go

Directories

PathSynopsis
cmd
cmd/blackmail
internal
smtpPackage smtp implements a SMTP client as defined in RFC 5321.
Version
v0.0.0-20241118175226-9a8f9442bb0d (latest)
Published
Nov 18, 2024
Platform
linux/amd64
Imports
24 packages
Last checked
13 hours ago

Tools for package owners.