Add basic email abstraction layer
(Untested.) This will allow us to send via any supported provider within WriteFreely. Ref T731 T905
This commit is contained in:
parent
5b6d17c9b9
commit
d06077c432
3 changed files with 105 additions and 0 deletions
3
go.mod
3
go.mod
|
@ -53,6 +53,8 @@ require (
|
||||||
golang.org/x/net v0.30.0
|
golang.org/x/net v0.30.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require github.com/xhit/go-simple-mail/v2 v2.16.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
code.as/core/socks v1.0.0 // indirect
|
code.as/core/socks v1.0.0 // indirect
|
||||||
filippo.io/edwards25519 v1.1.0 // indirect
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
|
@ -82,6 +84,7 @@ require (
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/sasha-s/go-deadlock v0.3.1 // indirect
|
github.com/sasha-s/go-deadlock v0.3.1 // indirect
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||||
|
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 // indirect
|
||||||
github.com/writeas/go-writeas/v2 v2.0.2 // indirect
|
github.com/writeas/go-writeas/v2 v2.0.2 // indirect
|
||||||
github.com/writeas/openssl-go v1.0.0 // indirect
|
github.com/writeas/openssl-go v1.0.0 // indirect
|
||||||
github.com/writeas/slug v1.2.0 // indirect
|
github.com/writeas/slug v1.2.0 // indirect
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -177,6 +177,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 h1:PM5hJF7HVfNWmCjMdEfbuOBNXSVF2cMFGgQTPdKCbwM=
|
||||||
|
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208/go.mod h1:BzWtXXrXzZUvMacR0oF/fbDDgUPO8L36tDMmRAf14ns=
|
||||||
github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8=
|
github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8=
|
||||||
github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ=
|
github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ=
|
||||||
github.com/writeas/activity v0.1.2 h1:Y12B5lIrabfqKE7e7HFCWiXrlfXljr9tlkFm2mp7DgY=
|
github.com/writeas/activity v0.1.2 h1:Y12B5lIrabfqKE7e7HFCWiXrlfXljr9tlkFm2mp7DgY=
|
||||||
|
@ -212,6 +214,8 @@ github.com/writefreely/go-gopher v0.0.0-20220429181814-40127126f83b h1:h3NzB8OZ5
|
||||||
github.com/writefreely/go-gopher v0.0.0-20220429181814-40127126f83b/go.mod h1:T2UVVzt+R5KSSZe2xRSytnwc2M9AoDegi7foeIsik+M=
|
github.com/writefreely/go-gopher v0.0.0-20220429181814-40127126f83b/go.mod h1:T2UVVzt+R5KSSZe2xRSytnwc2M9AoDegi7foeIsik+M=
|
||||||
github.com/writefreely/go-nodeinfo v1.2.0 h1:La+YbTCvmpTwFhBSlebWDDL81N88Qf/SCAvRLR7F8ss=
|
github.com/writefreely/go-nodeinfo v1.2.0 h1:La+YbTCvmpTwFhBSlebWDDL81N88Qf/SCAvRLR7F8ss=
|
||||||
github.com/writefreely/go-nodeinfo v1.2.0/go.mod h1:UTvE78KpcjYOlRHupZIiSEFcXHioTXuacCbHU+CAcPg=
|
github.com/writefreely/go-nodeinfo v1.2.0/go.mod h1:UTvE78KpcjYOlRHupZIiSEFcXHioTXuacCbHU+CAcPg=
|
||||||
|
github.com/xhit/go-simple-mail/v2 v2.16.0 h1:ouGy/Ww4kuaqu2E2UrDw7SvLaziWTB60ICLkIkNVccA=
|
||||||
|
github.com/xhit/go-simple-mail/v2 v2.16.0/go.mod h1:b7P5ygho6SYE+VIqpxA6QkYfv4teeyG4MKqB3utRu98=
|
||||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
||||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
|
98
mailer/mailer.go
Normal file
98
mailer/mailer.go
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2024 Musing Studio LLC.
|
||||||
|
*
|
||||||
|
* This file is part of WriteFreely.
|
||||||
|
*
|
||||||
|
* WriteFreely is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, included
|
||||||
|
* in the LICENSE file in this source code package.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package mailer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/mailgun/mailgun-go"
|
||||||
|
"github.com/writefreely/writefreely/config"
|
||||||
|
mail "github.com/xhit/go-simple-mail/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// Mailer holds configurations for the preferred mailing provider.
|
||||||
|
Mailer struct {
|
||||||
|
smtp *mail.SMTPServer
|
||||||
|
mailGun *mailgun.MailgunImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message holds the email contents and metadata for the preferred mailing provider.
|
||||||
|
Message struct {
|
||||||
|
mgMsg *mailgun.Message
|
||||||
|
smtpMsg *mail.Email
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// New creates a new Mailer from the instance's config.EmailCfg, returning an error if not properly configured.
|
||||||
|
func New(eCfg *config.EmailCfg) (*Mailer, error) {
|
||||||
|
m := &Mailer{}
|
||||||
|
if eCfg.Domain != "" && eCfg.MailgunPrivate != "" {
|
||||||
|
m.mailGun = mailgun.NewMailgun(eCfg.Domain, eCfg.MailgunPrivate)
|
||||||
|
} else if eCfg.Username != "" && eCfg.Password != "" && eCfg.Host != "" && eCfg.Port > 0 {
|
||||||
|
m.smtp = mail.NewSMTPClient()
|
||||||
|
m.smtp.Host = eCfg.Host
|
||||||
|
m.smtp.Port = eCfg.Port
|
||||||
|
m.smtp.Username = eCfg.Username
|
||||||
|
m.smtp.Password = eCfg.Password
|
||||||
|
if eCfg.EnableStartTLS {
|
||||||
|
m.smtp.Encryption = mail.EncryptionSTARTTLS
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("no email provider is configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMessage creates a new Message from the given parameters.
|
||||||
|
func (m *Mailer) NewMessage(from, subject, text string, to ...string) (*Message, error) {
|
||||||
|
msg := &Message{}
|
||||||
|
if m.mailGun != nil {
|
||||||
|
msg.mgMsg = m.mailGun.NewMessage(from, subject, text, to...)
|
||||||
|
} else if m.smtp != nil {
|
||||||
|
msg.smtpMsg = mail.NewMSG()
|
||||||
|
msg.smtpMsg.SetFrom(from)
|
||||||
|
msg.smtpMsg.AddTo(to...)
|
||||||
|
msg.smtpMsg.SetSubject(subject)
|
||||||
|
msg.smtpMsg.AddAlternative(mail.TextPlain, text)
|
||||||
|
|
||||||
|
if msg.smtpMsg.Error != nil {
|
||||||
|
return nil, msg.smtpMsg.Error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetHTML sets the body of the message.
|
||||||
|
func (m *Message) SetHTML(html string) {
|
||||||
|
if m.smtpMsg != nil {
|
||||||
|
m.smtpMsg.SetBody(mail.TextHTML, html)
|
||||||
|
} else if m.mgMsg != nil {
|
||||||
|
m.mgMsg.SetHtml(html)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send sends the given message via the preferred provider.
|
||||||
|
func (m *Mailer) Send(msg *Message) error {
|
||||||
|
if m.smtp != nil {
|
||||||
|
client, err := m.smtp.Connect()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return msg.smtpMsg.Send(client)
|
||||||
|
} else if m.mailGun != nil {
|
||||||
|
_, _, err := m.mailGun.Send(msg.mgMsg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue