Blame view

email.go 3.11 KB
bca3975fd   Marko Tikvić   email
1
2
3
4
5
6
7
8
9
10
11
  package webutility
  
  // TODO(markO): test test test test test (and open source?)
  
  import (
  	"crypto/tls"
  	"errors"
  	"fmt"
  	"net/smtp"
  	"strings"
  )
707782344   Marko Tikvić   lint; vet
12
  // Email ...
bca3975fd   Marko Tikvić   email
13
  type Email struct {
707782344   Marko Tikvić   lint; vet
14
15
16
17
  	recipients []string
  	sender     string
  	subject    string
  	body       string
edd7c4f4d   Marko Tikvić   new email interface
18
19
  
  	config *EmailConfig
bca3975fd   Marko Tikvić   email
20
  }
707782344   Marko Tikvić   lint; vet
21
  // NewEmail ...
edd7c4f4d   Marko Tikvić   new email interface
22
  func NewEmail() *Email {
707782344   Marko Tikvić   lint; vet
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  	return new(Email)
  }
  
  // EmailConfig ...
  type EmailConfig struct {
  	ServerName string `json:"-"`
  	Identity   string `json:"-"`
  	Username   string `json:"username"`
  	Password   string `json:"password"`
  	Host       string `json:"host"`
  	Port       int    `json:"port"`
  }
  
  // NewEmailConfig ...
  func NewEmailConfig(ident, uname, pword, host string, port int) *EmailConfig {
  	return &EmailConfig{
  		ServerName: host + fmt.Sprintf(":%d", port),
  		Identity:   ident,
  		Username:   uname,
  		Password:   pword,
  		Host:       host,
  		Port:       port,
bca3975fd   Marko Tikvić   email
45
46
  	}
  }
707782344   Marko Tikvić   lint; vet
47
  // Config ...
edd7c4f4d   Marko Tikvić   new email interface
48
49
50
  func (e *Email) Config(cfg *EmailConfig) {
  	e.config = cfg
  }
707782344   Marko Tikvić   lint; vet
51
52
53
  // Sender ...
  func (e *Email) Sender(from string) {
  	e.sender = from
edd7c4f4d   Marko Tikvić   new email interface
54
  }
707782344   Marko Tikvić   lint; vet
55
56
57
  // AddRecipient ...
  func (e *Email) AddRecipient(r string) {
  	e.recipients = append(e.recipients, r)
edd7c4f4d   Marko Tikvić   new email interface
58
  }
707782344   Marko Tikvić   lint; vet
59
60
61
  // Subject ...
  func (e *Email) Subject(sub string) {
  	e.subject = sub
edd7c4f4d   Marko Tikvić   new email interface
62
  }
707782344   Marko Tikvić   lint; vet
63
64
  func (e *Email) Write(body string) {
  	e.body = body
edd7c4f4d   Marko Tikvić   new email interface
65
  }
2cff4b70c   Marko Tikvić   refactored email:...
66
67
  func (e *Email) String() string {
  	var str strings.Builder
707782344   Marko Tikvić   lint; vet
68
69
  	str.WriteString("From:" + e.sender + "\r
  ")
2cff4b70c   Marko Tikvić   refactored email:...
70
71
  
  	str.WriteString("To:")
707782344   Marko Tikvić   lint; vet
72
  	for i := range e.recipients {
2cff4b70c   Marko Tikvić   refactored email:...
73
74
75
  		if i > 0 {
  			str.WriteString(",")
  		}
707782344   Marko Tikvić   lint; vet
76
  		str.WriteString(e.recipients[i])
2cff4b70c   Marko Tikvić   refactored email:...
77
78
79
  	}
  	str.WriteString("\r
  ")
707782344   Marko Tikvić   lint; vet
80
81
  	str.WriteString("Subject:" + e.subject + "\r
  ")
2cff4b70c   Marko Tikvić   refactored email:...
82
83
  
  	// body
707782344   Marko Tikvić   lint; vet
84
85
86
  	str.WriteString("\r
  " + e.body + "\r
  ")
2cff4b70c   Marko Tikvić   refactored email:...
87
88
89
  
  	return str.String()
  }
707782344   Marko Tikvić   lint; vet
90
  // Bytes ...
2cff4b70c   Marko Tikvić   refactored email:...
91
92
93
  func (e *Email) Bytes() []byte {
  	return []byte(e.String())
  }
707782344   Marko Tikvić   lint; vet
94
95
96
  // Send ...
  func (e *Email) Send() error {
  	if e.config == nil {
2cff4b70c   Marko Tikvić   refactored email:...
97
  		return errors.New("email configuration not provided")
bca3975fd   Marko Tikvić   email
98
  	}
707782344   Marko Tikvić   lint; vet
99
  	conf := e.config
bca3975fd   Marko Tikvić   email
100
101
102
103
104
  
  	c, err := smtp.Dial(conf.ServerName)
  	if err != nil {
  		return err
  	}
bca3975fd   Marko Tikvić   email
105
  	defer c.Close()
707782344   Marko Tikvić   lint; vet
106
107
108
109
110
111
  	/*
  		// not sure if this is needed
  		if err = c.Hello(conf.ServerName); err != nil {
  			return err
  		}
  	*/
bca3975fd   Marko Tikvić   email
112
113
114
115
116
117
118
  
  	if ok, _ := c.Extension("STARTTLS"); ok {
  		// disable stupid tls check for self-signed certificates
  		config := &tls.Config{
  			ServerName:         conf.ServerName,
  			InsecureSkipVerify: true,
  		}
707782344   Marko Tikvić   lint; vet
119
120
121
122
123
124
  		/*
  			// for golang testing
  			if testHookStartTLS != nil {
  				testHookStartTLS(config)
  			}
  		*/
bca3975fd   Marko Tikvić   email
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
  		if err = c.StartTLS(config); err != nil {
  			return err
  		}
  	}
  
  	/*
  		// don't know what to do with this
  		if a != nil && c.ext != nil {
  			if _, ok := c.ext["AUTH"]; !ok {
  				return errors.New("smtp: server doesn't support AUTH")
  			}
  			if err = c.Auth(a); err != nil {
  				return err
  			}
  		}
  	*/
  
  	// Set up authentication information.
  	auth := smtp.PlainAuth(conf.Identity, conf.Username, conf.Password, conf.Host)
  	if err = c.Auth(auth); err != nil {
  		return err
  	}
707782344   Marko Tikvić   lint; vet
147
  	if err = c.Mail(e.sender); err != nil {
bca3975fd   Marko Tikvić   email
148
149
  		return err
  	}
707782344   Marko Tikvić   lint; vet
150
  	for _, addr := range e.recipients {
bca3975fd   Marko Tikvić   email
151
152
153
154
155
156
157
158
159
  		if err = c.Rcpt(addr); err != nil {
  			return err
  		}
  	}
  
  	w, err := c.Data()
  	if err != nil {
  		return err
  	}
707782344   Marko Tikvić   lint; vet
160
  	_, err = w.Write(e.Bytes())
bca3975fd   Marko Tikvić   email
161
162
163
164
165
166
167
168
169
170
171
  	if err != nil {
  		return err
  	}
  
  	err = w.Close()
  	if err != nil {
  		return err
  	}
  
  	return c.Quit()
  }