mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-22 17:10:10 +00:00
smtp: only construct email once
also switch layout in email file to group each driver and its methods together.
This commit is contained in:
parent
5ff3839239
commit
77799b2917
161
email.go
161
email.go
@ -13,7 +13,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
textTemplate "text/template"
|
textTemplate "text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -31,84 +30,6 @@ type EmailClient interface {
|
|||||||
Send(fromName, fromAddr string, message *Message, address ...string) error
|
Send(fromName, fromAddr string, message *Message, address ...string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type DummyClient struct{}
|
|
||||||
|
|
||||||
func (dc *DummyClient) Send(fromName, fromAddr string, email *Message, address ...string) error {
|
|
||||||
fmt.Printf("FROM: %s <%s>\nTO: %s\nTEXT: %s\n", fromName, fromAddr, strings.Join(address, ", "), email.Text)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mailgun client implements EmailClient.
|
|
||||||
type Mailgun struct {
|
|
||||||
client *mailgun.MailgunImpl
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mg *Mailgun) Send(fromName, fromAddr string, email *Message, address ...string) error {
|
|
||||||
message := mg.client.NewMessage(
|
|
||||||
fmt.Sprintf("%s <%s>", fromName, fromAddr),
|
|
||||||
email.Subject,
|
|
||||||
email.Text,
|
|
||||||
)
|
|
||||||
for _, a := range address {
|
|
||||||
// Adding variable tells mailgun to do a batch send, so users don't see other recipients.
|
|
||||||
message.AddRecipientAndVariables(a, map[string]interface{}{"unique_id": a})
|
|
||||||
}
|
|
||||||
message.SetHtml(email.HTML)
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
|
||||||
defer cancel()
|
|
||||||
_, _, err := mg.client.Send(ctx, message)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SMTP supports SSL/TLS and STARTTLS; implements EmailClient.
|
|
||||||
type SMTP struct {
|
|
||||||
Client *sMail.SMTPServer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sm *SMTP) Send(fromName, fromAddr string, email *Message, address ...string) error {
|
|
||||||
from := fmt.Sprintf("%s <%s>", fromName, fromAddr)
|
|
||||||
var cli *sMail.SMTPClient
|
|
||||||
var err error
|
|
||||||
cli, err = sm.Client.Connect()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer cli.Close()
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
for _, addr := range address {
|
|
||||||
wg.Add(1)
|
|
||||||
go func(addr string) {
|
|
||||||
defer wg.Done()
|
|
||||||
e := sMail.NewMSG()
|
|
||||||
e.SetFrom(from)
|
|
||||||
e.SetSubject(email.Subject)
|
|
||||||
e.AddTo(addr)
|
|
||||||
if email.HTML == "" {
|
|
||||||
e.SetBody(sMail.TextPlain, email.Text)
|
|
||||||
} else {
|
|
||||||
e.SetBody(sMail.TextHTML, email.HTML)
|
|
||||||
e.AddAlternative(sMail.TextPlain, email.Text)
|
|
||||||
}
|
|
||||||
err = e.Send(cli)
|
|
||||||
// e := jEmail.NewEmail()
|
|
||||||
// e.Subject = email.Subject
|
|
||||||
// e.From = from
|
|
||||||
// e.Text = []byte(email.Text)
|
|
||||||
// e.HTML = []byte(email.HTML)
|
|
||||||
// e.To = []string{addr}
|
|
||||||
// err = sm.Pool.Send(e, 15*time.Second)
|
|
||||||
// if sm.sslTLS {
|
|
||||||
// err = sm.Pool.S
|
|
||||||
// err = e.SendWithTLS(server, sm.auth, sm.tlsConfig)
|
|
||||||
// } else {
|
|
||||||
// err = e.SendWithStartTLS(server, sm.auth, sm.tlsConfig)
|
|
||||||
// }
|
|
||||||
}(addr)
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emailer contains the email sender, translations, and methods to construct messages.
|
// Emailer contains the email sender, translations, and methods to construct messages.
|
||||||
type Emailer struct {
|
type Emailer struct {
|
||||||
fromAddr, fromName string
|
fromAddr, fromName string
|
||||||
@ -175,18 +96,17 @@ func NewEmailer(app *appContext) *Emailer {
|
|||||||
return emailer
|
return emailer
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMailgun returns a Mailgun emailClient.
|
// DummyClient just logs the email to the console for debugging purposes. It can be used by settings [email]/method to "dummy".
|
||||||
func (emailer *Emailer) NewMailgun(url, key string) {
|
type DummyClient struct{}
|
||||||
sender := &Mailgun{
|
|
||||||
client: mailgun.NewMailgun(strings.Split(emailer.fromAddr, "@")[1], key),
|
func (dc *DummyClient) Send(fromName, fromAddr string, email *Message, address ...string) error {
|
||||||
}
|
fmt.Printf("FROM: %s <%s>\nTO: %s\nTEXT: %s\n", fromName, fromAddr, strings.Join(address, ", "), email.Text)
|
||||||
// Mailgun client takes the base url, so we need to trim off the end (e.g 'v3/messages')
|
return nil
|
||||||
if strings.Contains(url, "messages") {
|
}
|
||||||
url = url[0:strings.LastIndex(url, "/")]
|
|
||||||
url = url[0:strings.LastIndex(url, "/")]
|
// SMTP supports SSL/TLS and STARTTLS; implements EmailClient.
|
||||||
}
|
type SMTP struct {
|
||||||
sender.client.SetAPIBase(url)
|
Client *sMail.SMTPServer
|
||||||
emailer.sender = sender
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSMTP returns an SMTP emailClient.
|
// NewSMTP returns an SMTP emailClient.
|
||||||
@ -237,6 +157,65 @@ func (emailer *Emailer) NewSMTP(server string, port int, username, password stri
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sm *SMTP) Send(fromName, fromAddr string, email *Message, address ...string) error {
|
||||||
|
from := fmt.Sprintf("%s <%s>", fromName, fromAddr)
|
||||||
|
var cli *sMail.SMTPClient
|
||||||
|
var err error
|
||||||
|
cli, err = sm.Client.Connect()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer cli.Close()
|
||||||
|
e := sMail.NewMSG()
|
||||||
|
e.SetFrom(from)
|
||||||
|
e.SetSubject(email.Subject)
|
||||||
|
e.AddTo(address...)
|
||||||
|
if email.HTML == "" {
|
||||||
|
e.SetBody(sMail.TextPlain, email.Text)
|
||||||
|
} else {
|
||||||
|
e.SetBody(sMail.TextHTML, email.HTML)
|
||||||
|
e.AddAlternative(sMail.TextPlain, email.Text)
|
||||||
|
}
|
||||||
|
err = e.Send(cli)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mailgun client implements EmailClient.
|
||||||
|
type Mailgun struct {
|
||||||
|
client *mailgun.MailgunImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMailgun returns a Mailgun emailClient.
|
||||||
|
func (emailer *Emailer) NewMailgun(url, key string) {
|
||||||
|
sender := &Mailgun{
|
||||||
|
client: mailgun.NewMailgun(strings.Split(emailer.fromAddr, "@")[1], key),
|
||||||
|
}
|
||||||
|
// Mailgun client takes the base url, so we need to trim off the end (e.g 'v3/messages')
|
||||||
|
if strings.Contains(url, "messages") {
|
||||||
|
url = url[0:strings.LastIndex(url, "/")]
|
||||||
|
url = url[0:strings.LastIndex(url, "/")]
|
||||||
|
}
|
||||||
|
sender.client.SetAPIBase(url)
|
||||||
|
emailer.sender = sender
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mg *Mailgun) Send(fromName, fromAddr string, email *Message, address ...string) error {
|
||||||
|
message := mg.client.NewMessage(
|
||||||
|
fmt.Sprintf("%s <%s>", fromName, fromAddr),
|
||||||
|
email.Subject,
|
||||||
|
email.Text,
|
||||||
|
)
|
||||||
|
for _, a := range address {
|
||||||
|
// Adding variable tells mailgun to do a batch send, so users don't see other recipients.
|
||||||
|
message.AddRecipientAndVariables(a, map[string]interface{}{"unique_id": a})
|
||||||
|
}
|
||||||
|
message.SetHtml(email.HTML)
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||||
|
defer cancel()
|
||||||
|
_, _, err := mg.client.Send(ctx, message)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
type templ interface {
|
type templ interface {
|
||||||
Execute(wr io.Writer, data interface{}) error
|
Execute(wr io.Writer, data interface{}) error
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user