Skip to content

Commit f00caa8

Browse files
committed
added queue to the mailer
1 parent 46a2333 commit f00caa8

File tree

1 file changed

+64
-40
lines changed

1 file changed

+64
-40
lines changed

example-mail/mailer.go

+64-40
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import (
77
"fmt"
88
"github.com/domodwyer/mailyak/v3"
99
"github.com/joho/godotenv"
10+
log "github.com/sirupsen/logrus"
1011
"gopkg.in/square/go-jose.v2/jwt"
11-
"log"
1212
"net/http"
1313
"net/smtp"
1414
"os"
@@ -24,6 +24,17 @@ curl -k -X POST -H "Authorization: Bearer ${TOKEN}" -H "Content-Type: applicatio
2424
2525
*/
2626

27+
const (
28+
emailParallel = 1
29+
)
30+
31+
var (
32+
opts *Opts
33+
jwtKey []byte
34+
debug = false
35+
queue chan *EmailRequest
36+
)
37+
2738
type TokenClaims struct {
2839
MailFrom string `json:"mail_from,omitempty"`
2940
MailTo string `json:"mail_to,omitempty"`
@@ -39,74 +50,47 @@ type Opts struct {
3950
SmtpPort int
4051
}
4152

42-
var (
43-
opts *Opts
44-
jwtKey []byte
45-
debug = false
46-
)
47-
4853
type EmailRequest struct {
4954
MailTo string `json:"mail_to,omitempty"`
5055
Subject string `json:"subject"`
5156
TextMessage string `json:"text_message"`
5257
HtmlMessage string `json:"html_message"`
58+
claims *TokenClaims
5359
}
5460

5561
func mailer(w http.ResponseWriter, r *http.Request, claims *TokenClaims) {
5662
if r.Method != "POST" {
57-
writeErr(w, http.StatusBadRequest, "ERR-07, only POST supported: %v", r.Method)
63+
writeErr(w, http.StatusBadRequest, "mailer, only POST supported: %v", r.Method)
5864
return
5965
}
6066

6167
var email EmailRequest
6268
err := json.NewDecoder(r.Body).Decode(&email)
6369
if err != nil {
64-
writeErr(w, http.StatusBadRequest, "ERR-08, could not decode request: %v", err)
65-
return
66-
}
67-
68-
mail := mailyak.New(opts.SmtpHost+":"+strconv.Itoa(opts.SmtpPort), smtp.PlainAuth("", claims.MailFrom, opts.SmtpPassword, opts.SmtpHost))
69-
var to string
70-
if claims.MailTo != "" {
71-
to = claims.MailTo
72-
} else {
73-
to = email.MailTo
74-
}
75-
mail.To(to)
76-
mail.From(claims.MailFrom)
77-
mail.Subject(email.Subject)
78-
if email.TextMessage != "" {
79-
mail.Plain().Set(email.TextMessage)
80-
}
81-
if email.HtmlMessage != "" {
82-
mail.HTML().Set(email.HtmlMessage)
83-
}
84-
85-
err = mail.Send()
86-
if err != nil {
87-
writeErr(w, http.StatusBadRequest, "ERR-09, could not send email: %v", err)
70+
writeErr(w, http.StatusBadRequest, "mailer, could not decode request: %v", err)
8871
return
8972
}
90-
log.Printf("Email sent from [%s] to [%v], subject: [%v]\n", claims.MailFrom, to, email.Subject)
73+
email.claims = claims
74+
queue <- &email
9175
}
9276

9377
func jwtAuth(next func(w http.ResponseWriter, r *http.Request, claims *TokenClaims)) func(http.ResponseWriter, *http.Request) {
9478
return func(w http.ResponseWriter, r *http.Request) {
9579
authHeader := r.Header.Get("Authorization")
9680
if authHeader == "" {
97-
writeErr(w, http.StatusBadRequest, "ERR-01, authorization header not set")
81+
writeErr(w, http.StatusBadRequest, "jwtAuth, authorization header not set")
9882
return
9983
}
10084

10185
bearerToken := strings.Split(authHeader, " ")
10286
if len(bearerToken) != 2 {
103-
writeErr(w, http.StatusBadRequest, "ERR-02, could not split token: %v", bearerToken)
87+
writeErr(w, http.StatusBadRequest, "jwtAuth, could not split token: %v", bearerToken)
10488
return
10589
}
10690

10791
tok, err := jwt.ParseSigned(bearerToken[1])
10892
if err != nil {
109-
writeErr(w, http.StatusBadRequest, "ERR-03, could not parse token: %v", bearerToken[1])
93+
writeErr(w, http.StatusBadRequest, "jwtAuth, could not parse token: %v", bearerToken[1])
11094
return
11195
}
11296

@@ -115,17 +99,17 @@ func jwtAuth(next func(w http.ResponseWriter, r *http.Request, claims *TokenClai
11599
if tok.Headers[0].Algorithm == "HS256" {
116100
err = tok.Claims(jwtKey, claims)
117101
} else {
118-
writeErr(w, http.StatusUnauthorized, "ERR-04, unknown algorithm: %v", tok.Headers[0].Algorithm)
102+
writeErr(w, http.StatusUnauthorized, "jwtAuth, unknown algorithm: %v", tok.Headers[0].Algorithm)
119103
return
120104
}
121105

122106
if err != nil {
123-
writeErr(w, http.StatusUnauthorized, "ERR-05, could not parse claims: %v", bearerToken[1])
107+
writeErr(w, http.StatusUnauthorized, "jwtAuth, could not parse claims: %v", bearerToken[1])
124108
return
125109
}
126110

127111
if claims.Expiry != nil && !claims.Expiry.Time().After(time.Now()) {
128-
writeErr(w, http.StatusBadRequest, "ERR-06, expired: %v", claims.Expiry.Time())
112+
writeErr(w, http.StatusBadRequest, "jwtAuth, expired: %v", claims.Expiry.Time())
129113
return
130114
}
131115

@@ -135,7 +119,7 @@ func jwtAuth(next func(w http.ResponseWriter, r *http.Request, claims *TokenClai
135119

136120
func writeErr(w http.ResponseWriter, code int, format string, a ...interface{}) {
137121
msg := fmt.Sprintf(format, a...)
138-
log.Printf(msg)
122+
log.Warnf(msg)
139123
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
140124
w.Header().Set("Cache-Control", "no-store")
141125
w.Header().Set("Pragma", "no-cache")
@@ -213,5 +197,45 @@ func main() {
213197

214198
http.HandleFunc("/", jwtAuth(mailer))
215199
log.Printf("listening on port %v...", opts.Port)
200+
201+
//create a queue, and send one after the other
202+
queue = make(chan *EmailRequest)
203+
for i := 0; i < emailParallel; i++ {
204+
go func() {
205+
for {
206+
select {
207+
case e := <-queue:
208+
send(e)
209+
}
210+
}
211+
}()
212+
}
213+
216214
http.ListenAndServe(":"+strconv.Itoa(opts.Port), nil)
217215
}
216+
217+
func send(e *EmailRequest) {
218+
mail := mailyak.New(opts.SmtpHost+":"+strconv.Itoa(opts.SmtpPort), smtp.PlainAuth("", e.claims.MailFrom, opts.SmtpPassword, opts.SmtpHost))
219+
var to string
220+
if e.claims.MailTo != "" {
221+
to = e.claims.MailTo
222+
} else {
223+
to = e.MailTo
224+
}
225+
mail.To(to)
226+
mail.From(e.claims.MailFrom)
227+
mail.Subject(e.Subject)
228+
if e.TextMessage != "" {
229+
mail.Plain().Set(e.TextMessage)
230+
}
231+
if e.HtmlMessage != "" {
232+
mail.HTML().Set(e.HtmlMessage)
233+
}
234+
235+
err := mail.Send()
236+
if err != nil {
237+
log.Warnf("could not send email: %v", err)
238+
} else {
239+
log.Infof("Email sent from [%s] to [%v], subject: [%v]\n", e.claims.MailFrom, to, e.Subject)
240+
}
241+
}

0 commit comments

Comments
 (0)