115 lines
3.7 KiB
Go
115 lines
3.7 KiB
Go
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"
|
|
"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(
|
|
"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": 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
|
|
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
|
|
}
|