summaryrefslogtreecommitdiff
path: root/srv/mailinglist/mailer.go
blob: 81d0b91685f13a6e98138e0617665d00cd1a24e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package mailinglist

import (
	"github.com/emersion/go-sasl"
	"github.com/emersion/go-smtp"
)

// Mailer is used to deliver emails to arbitrary recipients.
type Mailer interface {
	Send(to, subject, body string) error
}

// MailerParams are used to initialize a new Mailer instance
type MailerParams struct {
	SMTPAddr string

	// Optional, if not given then no auth is attempted.
	SMTPAuth sasl.Client

	// The sending email address to use for all emails being sent.
	SendAs string
}

type mailer struct {
	params MailerParams
}

// NewMailer initializes and returns a Mailer which will use an external SMTP
// server to deliver email.
func NewMailer(params MailerParams) Mailer {
	return &mailer{
		params: params,
	}
}

func (m *mailer) Send(to, subject, body string) error {

	msg := []byte("From: " + m.params.SendAs + "\r\n" +
		"To: " + to + "\r\n" +
		"Subject: " + subject + "\r\n\r\n" +
		body + "\r\n")

	c, err := smtp.Dial(m.params.SMTPAddr)
	if err != nil {
		return err
	}
	defer c.Close()

	if err = c.Auth(m.params.SMTPAuth); err != nil {
		return err
	}

	if err = c.Mail(m.params.SendAs, nil); err != nil {
		return err
	}

	if err = c.Rcpt(to); err != nil {
		return err
	}

	w, err := c.Data()
	if err != nil {
		return err
	}

	if _, err = w.Write(msg); err != nil {
		return err
	}

	if err = w.Close(); err != nil {
		return err
	}

	return c.Quit()
}