mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
chore: send notification on successful import
This commit is contained in:
@ -11,29 +11,37 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
tplPath = "/views/mail"
|
||||
tplNamePasswordReset = "reset_password"
|
||||
subjectPasswordReset = "Wakapi – Password Reset"
|
||||
tplPath = "/views/mail"
|
||||
tplNamePasswordReset = "reset_password"
|
||||
tplNameImportNotification = "import_finished"
|
||||
subjectPasswordReset = "Wakapi – Password Reset"
|
||||
subjectImportNotification = "Wakapi – Data Import Finished"
|
||||
)
|
||||
|
||||
type passwordResetLinkTplData struct {
|
||||
type PasswordResetTplData struct {
|
||||
ResetLink string
|
||||
}
|
||||
|
||||
type ImportNotificationTplData struct {
|
||||
PublicUrl string
|
||||
Duration string
|
||||
NumHeartbeats int
|
||||
}
|
||||
|
||||
// Factory
|
||||
func NewMailService() services.IMailService {
|
||||
config := conf.Get()
|
||||
if config.Mail.Enabled {
|
||||
if config.Mail.Provider == conf.MailProviderMailWhale {
|
||||
return NewMailWhaleService(config.Mail.MailWhale)
|
||||
return NewMailWhaleService(config.Mail.MailWhale, config.Server.PublicUrl)
|
||||
} else if config.Mail.Provider == conf.MailProviderSmtp {
|
||||
return NewSMTPMailService(config.Mail.Smtp)
|
||||
return NewSMTPMailService(config.Mail.Smtp, config.Server.PublicUrl)
|
||||
}
|
||||
}
|
||||
return &NoopMailService{}
|
||||
}
|
||||
|
||||
func getPasswordResetTemplate(data passwordResetLinkTplData) (*bytes.Buffer, error) {
|
||||
func getPasswordResetTemplate(data PasswordResetTplData) (*bytes.Buffer, error) {
|
||||
tpl, err := loadTemplate(tplNamePasswordReset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -45,6 +53,18 @@ func getPasswordResetTemplate(data passwordResetLinkTplData) (*bytes.Buffer, err
|
||||
return &rendered, nil
|
||||
}
|
||||
|
||||
func getImportNotificationTemplate(data ImportNotificationTplData) (*bytes.Buffer, error) {
|
||||
tpl, err := loadTemplate(tplNameImportNotification)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var rendered bytes.Buffer
|
||||
if err := tpl.Execute(&rendered, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rendered, nil
|
||||
}
|
||||
|
||||
func loadTemplate(tplName string) (*template.Template, error) {
|
||||
tplFile, err := pkger.Open(fmt.Sprintf("%s/%s.tpl.html", tplPath, tplName))
|
||||
if err != nil {
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
)
|
||||
|
||||
type MailWhaleMailService struct {
|
||||
publicUrl string
|
||||
config *conf.MailwhaleMailConfig
|
||||
httpClient *http.Client
|
||||
}
|
||||
@ -25,26 +26,39 @@ type MailWhaleSendRequest struct {
|
||||
TemplateVars map[string]string `json:"template_vars"`
|
||||
}
|
||||
|
||||
func NewMailWhaleService(config *conf.MailwhaleMailConfig) *MailWhaleMailService {
|
||||
func NewMailWhaleService(config *conf.MailwhaleMailConfig, publicUrl string) *MailWhaleMailService {
|
||||
return &MailWhaleMailService{
|
||||
config: config,
|
||||
publicUrl: publicUrl,
|
||||
config: config,
|
||||
httpClient: &http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *MailWhaleMailService) SendPasswordResetMail(recipient *models.User, resetLink string) error {
|
||||
template, err := getPasswordResetTemplate(passwordResetLinkTplData{ResetLink: resetLink})
|
||||
func (s *MailWhaleMailService) SendPasswordReset(recipient *models.User, resetLink string) error {
|
||||
template, err := getPasswordResetTemplate(PasswordResetTplData{ResetLink: resetLink})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.send(recipient.Email, subjectPasswordReset, template.String(), true)
|
||||
}
|
||||
|
||||
func (s *MailWhaleMailService) SendImportNotification(recipient *models.User, duration time.Duration, numHeartbeats int) error {
|
||||
template, err := getImportNotificationTemplate(ImportNotificationTplData{
|
||||
PublicUrl: s.publicUrl,
|
||||
Duration: fmt.Sprintf("%.0f seconds", duration.Seconds()),
|
||||
NumHeartbeats: numHeartbeats,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.send(recipient.Email, subjectImportNotification, template.String(), true)
|
||||
}
|
||||
|
||||
func (s *MailWhaleMailService) send(to, subject, body string, isHtml bool) error {
|
||||
if to == "" {
|
||||
return errors.New("no recipient mail address set, cannot send password reset link")
|
||||
return errors.New("not sending mail as recipient mail address seems to be invalid")
|
||||
}
|
||||
|
||||
sendRequest := &MailWhaleSendRequest{
|
||||
|
@ -3,11 +3,17 @@ package mail
|
||||
import (
|
||||
"github.com/emvi/logbuch"
|
||||
"github.com/muety/wakapi/models"
|
||||
"time"
|
||||
)
|
||||
|
||||
type NoopMailService struct{}
|
||||
|
||||
func (n *NoopMailService) SendPasswordResetMail(recipient *models.User, resetLink string) error {
|
||||
func (n *NoopMailService) SendPasswordReset(recipient *models.User, resetLink string) error {
|
||||
logbuch.Info("noop mail service doing nothing instead of sending password reset mail to %s", recipient.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NoopMailService) SendImportNotification(recipient *models.User, duration time.Duration, numHeartbeats int) error {
|
||||
logbuch.Info("noop mail service doing nothing instead of sending import notification mail to %s", recipient.ID)
|
||||
return nil
|
||||
}
|
||||
|
@ -2,21 +2,25 @@ package mail
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/emersion/go-sasl"
|
||||
"github.com/emersion/go-smtp"
|
||||
conf "github.com/muety/wakapi/config"
|
||||
"github.com/muety/wakapi/models"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SMTPMailService struct {
|
||||
config *conf.SMTPMailConfig
|
||||
auth sasl.Client
|
||||
publicUrl string
|
||||
config *conf.SMTPMailConfig
|
||||
auth sasl.Client
|
||||
}
|
||||
|
||||
func NewSMTPMailService(config *conf.SMTPMailConfig) *SMTPMailService {
|
||||
func NewSMTPMailService(config *conf.SMTPMailConfig, publicUrl string) *SMTPMailService {
|
||||
return &SMTPMailService{
|
||||
config: config,
|
||||
publicUrl: publicUrl,
|
||||
config: config,
|
||||
auth: sasl.NewPlainClient(
|
||||
"",
|
||||
config.Username,
|
||||
@ -25,8 +29,8 @@ func NewSMTPMailService(config *conf.SMTPMailConfig) *SMTPMailService {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SMTPMailService) SendPasswordResetMail(recipient *models.User, resetLink string) error {
|
||||
template, err := getPasswordResetTemplate(passwordResetLinkTplData{ResetLink: resetLink})
|
||||
func (s *SMTPMailService) SendPasswordReset(recipient *models.User, resetLink string) error {
|
||||
template, err := getPasswordResetTemplate(PasswordResetTplData{ResetLink: resetLink})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -38,14 +42,27 @@ func (s *SMTPMailService) SendPasswordResetMail(recipient *models.User, resetLin
|
||||
}
|
||||
mail.WithHTML(template.String())
|
||||
|
||||
return s.send(
|
||||
s.config.ConnStr(),
|
||||
s.config.TLS,
|
||||
s.auth,
|
||||
mail.From.Raw(),
|
||||
mail.To.RawStrings(),
|
||||
mail.Reader(),
|
||||
)
|
||||
return s.send(s.config.ConnStr(), s.config.TLS, s.auth, mail.From.Raw(), mail.To.RawStrings(), mail.Reader())
|
||||
}
|
||||
|
||||
func (s *SMTPMailService) SendImportNotification(recipient *models.User, duration time.Duration, numHeartbeats int) error {
|
||||
template, err := getImportNotificationTemplate(ImportNotificationTplData{
|
||||
PublicUrl: s.publicUrl,
|
||||
Duration: fmt.Sprintf("%.0f seconds", duration.Seconds()),
|
||||
NumHeartbeats: numHeartbeats,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mail := &models.Mail{
|
||||
From: models.MailAddress(s.config.Sender),
|
||||
To: models.MailAddresses([]models.MailAddress{models.MailAddress(recipient.Email)}),
|
||||
Subject: subjectImportNotification,
|
||||
}
|
||||
mail.WithHTML(template.String())
|
||||
|
||||
return s.send(s.config.ConnStr(), s.config.TLS, s.auth, mail.From.Raw(), mail.To.RawStrings(), mail.Reader())
|
||||
}
|
||||
|
||||
func (s *SMTPMailService) send(addr string, tls bool, a sasl.Client, from string, to []string, r io.Reader) error {
|
||||
|
@ -80,5 +80,6 @@ type IUserService interface {
|
||||
}
|
||||
|
||||
type IMailService interface {
|
||||
SendPasswordResetMail(recipient *models.User, resetLink string) error
|
||||
SendPasswordReset(*models.User, string) error
|
||||
SendImportNotification(*models.User, time.Duration, int) error
|
||||
}
|
||||
|
Reference in New Issue
Block a user