diff --git a/emailApi/main.go b/emailApi/main.go new file mode 100644 index 0000000..12274ee --- /dev/null +++ b/emailApi/main.go @@ -0,0 +1,102 @@ +package emailApi + +import ( + "fmt" + "git.stuve.uni-ulm.de/stuve-it/stuve-it-backend/logger" + "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 + } + + recipientEmail := recipient.GetString("email") + senderEmail := sender.GetString("email") + + // render email template + html, err := registry.LoadFiles( + "html/emailNotification.html", + ).Render(map[string]any{ + "APP_URL": app.Settings().Meta.AppUrl, + "SENDER": sender.Username(), + "SENDER_EMAIL": senderEmail, + "CONTENT": emailRecord.GetString("content"), + }) + 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 + } + + subject := emailRecord.GetString("subject") + 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, + } + 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, e *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 +} diff --git a/html/blankEmail.html b/html/blankEmail.html new file mode 100644 index 0000000..b2195af --- /dev/null +++ b/html/blankEmail.html @@ -0,0 +1,97 @@ + +
Du hast eine neue Nachricht von {{.SENDER_NAME}} ({{.SENDER_EMAIL}})
+{{.CONTENT}}
+