stuve-it-backend/emailApi/main.go

116 lines
3.8 KiB
Go
Raw Normal View History

package emailApi
import (
"fmt"
"git.stuve.uni-ulm.de/stuve-it/stuve-it-backend/logger"
"github.com/microcosm-cc/bluemonday"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/models"
"github.com/pocketbase/pocketbase/tools/mailer"
"github.com/pocketbase/pocketbase/tools/template"
htemplate "html/template"
"net/mail"
)
// sendEmailToUser sends an email notification to the user
func sendEmailToUser(app *pocketbase.PocketBase, registry *template.Registry, recipient *models.Record, sender *models.Record, emailRecord *models.Record) {
// check if recipient and message are set and recipient is not the sender
if recipient == nil || emailRecord == nil || sender == nil {
return
}
// sanitize email content
policy := bluemonday.UGCPolicy()
content := emailRecord.GetString("content")
safeContent := policy.Sanitize(content)
// get recipient and sender email
recipientEmail := recipient.GetString("email")
senderEmail := sender.GetString("email")
// render email template
html, err := registry.LoadFiles(
2024-10-24 17:21:50 +00:00
"html/blankEmail.html",
).Render(map[string]any{
"APP_URL": app.Settings().Meta.AppUrl,
"SENDER_SN": sender.GetString("sn"),
"SENDER_GIVENNAME": sender.GetString("givenName"),
"SENDER_EMAIL": senderEmail,
"CONTENT": htemplate.HTML(safeContent),
})
if err != nil {
currentErrors := emailRecord.GetString("errors")
emailRecord.Set("errors", fmt.Sprintf("%s\nThe email was not sent to the user '%s' due to an error.", currentErrors, recipient.Username()))
logger.LogErrorF("Error rendering email notification to recipient with username '%s': %v", recipient.GetString("username"), err)
return
}
// get email subject
subject := emailRecord.GetString("subject")
// set reply-to header
headers := make(map[string]string)
headers["Reply-To"] = senderEmail
// send email
email := &mailer.Message{
From: mail.Address{
Address: app.Settings().Meta.SenderAddress,
Name: app.Settings().Meta.SenderName,
},
To: []mail.Address{{Address: recipientEmail}},
Subject: "[StuVe IT] " + subject,
HTML: html,
Headers: headers,
}
if err := app.NewMailClient().Send(email); err != nil {
currentErrors := emailRecord.GetString("errors")
emailRecord.Set("errors", fmt.Sprintf("%s\nThe email was not sent to the user '%s' due to an error.", currentErrors, recipient.Username()))
logger.LogErrorF("Error sending email notification to recipient with username '%s': %v", recipient.GetString("username"), err)
}
}
func sendEmails(app *pocketbase.PocketBase, emailRecord *models.Record) {
registry := template.NewRegistry()
// expand the createdMessageRecord to get recipient user and send email notification if recipient is set
2024-10-24 17:14:45 +00:00
if errs := app.Dao().ExpandRecord(emailRecord, []string{"recipients", "sender"}, nil); len(errs) > 0 {
// return new error with all errors
logger.LogErrorF("Error expanding created email record: %v", errs)
emailRecord.Set("errors", fmt.Sprintf("The email was not sent to anyone due to an error."))
return
}
sender := emailRecord.ExpandedOne("sender")
recipients := emailRecord.ExpandedAll("recipients")
for _, recipient := range recipients {
sendEmailToUser(app, registry, recipient, sender, emailRecord)
}
return
}
// InitEmailApi initializes the email notifier
//
// the function sends an email notification after it was created
func InitEmailApi(app *pocketbase.PocketBase, _ *core.ServeEvent) error {
logger.LogInfoF("Adding email notifier")
app.OnModelAfterCreate("emails").Add(func(e *core.ModelEvent) error {
// get created message record
createdMessageRecord, err := app.Dao().FindRecordById("emails", e.Model.GetId())
if err != nil {
return err
}
go sendEmails(app, createdMessageRecord)
return nil
})
return nil
}