Skip to content

Commit

Permalink
Merge pull request #4564 from dragonchaser/email-template
Browse files Browse the repository at this point in the history
Add email templating
  • Loading branch information
David Christofas authored Sep 22, 2022
2 parents 13b2b16 + e96ab9f commit d7b6ecf
Show file tree
Hide file tree
Showing 9 changed files with 377 additions and 29 deletions.
7 changes: 7 additions & 0 deletions changelog/unreleased/add-email-templating.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: Add Email templating

We have added email templating to ocis. Which are send on the SpaceShared and ShareCreated event.

https://github.com/owncloud/ocis/pull/4564
https://github.com/owncloud/ocis/issues/4303
https://github.com/cs3org/reva/pull/3252
1 change: 1 addition & 0 deletions services/audit/pkg/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func RegisteredEvents() []events.Unmarshaller {
events.SpaceEnabled{},
events.SpaceDisabled{},
events.SpaceDeleted{},
events.SpaceShared{},
events.UserCreated{},
events.UserDeleted{},
events.UserFeatureChanged{},
Expand Down
18 changes: 12 additions & 6 deletions services/notifications/pkg/channels/channels.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package channels
import (
"context"
"crypto/tls"
"fmt"
"strings"

gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
Expand All @@ -19,9 +20,9 @@ import (
// Channel defines the methods of a communication channel.
type Channel interface {
// SendMessage sends a message to users.
SendMessage(userIDs []string, msg string) error
SendMessage(userIDs []string, msg, subject, senderDisplayName string) error
// SendMessageToGroup sends a message to a group.
SendMessageToGroup(groupdID *groups.GroupId, msg string) error
SendMessageToGroup(groupdID *groups.GroupId, msg, subject, senderDisplayName string) error
}

// NewMailChannel instantiates a new mail communication channel.
Expand Down Expand Up @@ -100,7 +101,7 @@ func (m Mail) getMailClient() (*mail.SMTPClient, error) {
}

// SendMessage sends a message to all given users.
func (m Mail) SendMessage(userIDs []string, msg string) error {
func (m Mail) SendMessage(userIDs []string, msg, subject, senderDisplayName string) error {
if m.conf.Notifications.SMTP.Host == "" {
return nil
}
Expand All @@ -116,14 +117,19 @@ func (m Mail) SendMessage(userIDs []string, msg string) error {
}

email := mail.NewMSG()
email.SetFrom(m.conf.Notifications.SMTP.Sender).AddTo(to...)
if senderDisplayName != "" {
email.SetFrom(fmt.Sprintf("%s via owncloud <%s>", senderDisplayName, m.conf.Notifications.SMTP.Sender)).AddTo(to...)
} else {
email.SetFrom(m.conf.Notifications.SMTP.Sender).AddTo(to...)
}
email.SetBody(mail.TextPlain, msg)
email.SetSubject(subject)

return email.Send(smtpClient)
}

// SendMessageToGroup sends a message to all members of the given group.
func (m Mail) SendMessageToGroup(groupID *groups.GroupId, msg string) error {
func (m Mail) SendMessageToGroup(groupID *groups.GroupId, msg, subject, senderDisplayName string) error {
// TODO We need an authenticated context here...
res, err := m.gatewayClient.GetGroup(context.Background(), &groups.GetGroupRequest{GroupId: groupID})
if err != nil {
Expand All @@ -138,7 +144,7 @@ func (m Mail) SendMessageToGroup(groupID *groups.GroupId, msg string) error {
members = append(members, id.OpaqueId)
}

return m.SendMessage(members, msg)
return m.SendMessage(members, msg, subject, senderDisplayName)
}

func (m Mail) getReceiverAddresses(receivers []string) ([]string, error) {
Expand Down
10 changes: 9 additions & 1 deletion services/notifications/pkg/command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/cs3org/reva/v2/pkg/events"
"github.com/cs3org/reva/v2/pkg/events/server"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/go-micro/plugins/v4/events/natsjs"
"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
"github.com/owncloud/ocis/v2/services/notifications/pkg/channels"
Expand All @@ -27,8 +28,10 @@ func Server(cfg *config.Config) *cli.Command {
Action: func(c *cli.Context) error {
logger := logging.Configure(cfg.Service.Name, cfg.Log)

// evs defines a list of events to subscribe to
evs := []events.Unmarshaller{
events.ShareCreated{},
events.SpaceShared{},
}

evtsCfg := cfg.Notifications.Events
Expand All @@ -47,7 +50,12 @@ func Server(cfg *config.Config) *cli.Command {
if err != nil {
return err
}
svc := service.NewEventsNotifier(evts, channel, logger)
gwclient, err := pool.GetGatewayServiceClient(cfg.Notifications.RevaGateway)
if err != nil {
logger.Fatal().Err(err).Str("addr", cfg.Notifications.RevaGateway).Msg("could not get reva client")
}

svc := service.NewEventsNotifier(evts, channel, logger, gwclient, cfg.Commons.MachineAuthAPIKey, cfg.Notifications.EmailTemplatePath)
return svc.Run()
},
}
Expand Down
1 change: 1 addition & 0 deletions services/notifications/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type Notifications struct {
Events Events `yaml:"events"`
RevaGateway string `yaml:"reva_gateway" env:"REVA_GATEWAY;NOTIFICATIONS_REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata"`
MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OCIS_MACHINE_AUTH_API_KEY;NOTIFICATIONS_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary to access resources from other services."`
EmailTemplatePath string `yaml:"email_template_path" env:"OCIS_EMAIL_TEMPLATE_PATH;NOTIFICATIONS_EMAIL_TEMPLATE_PATH" desc:"Path to the E-Mail templates for the notifications to override the embedded ones."`
}

// SMTP combines the smtp configuration options.
Expand Down
34 changes: 34 additions & 0 deletions services/notifications/pkg/email/email.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package email

import (
"bytes"
"embed"
"html/template"
"path/filepath"
)

var (
//go:embed templates
templatesFS embed.FS
)

// RenderEmailTemplate renders the email template for a new share
func RenderEmailTemplate(templateName string, templateVariables map[string]string, emailTemplatePath string) (string, error) {
var err error
var tpl *template.Template
// try to lookup the files in the filesystem
tpl, err = template.ParseFiles(filepath.Join(emailTemplatePath, templateName))
if err != nil {
// template has not been found in the fs, or path has not been specified => use embed templates
tpl, err = template.ParseFS(templatesFS, filepath.Join("templates/", templateName))
if err != nil {
return "", err
}
}
var writer bytes.Buffer
err = tpl.Execute(&writer, templateVariables)
if err != nil {
return "", err
}
return writer.String(), nil
}
18 changes: 18 additions & 0 deletions services/notifications/pkg/email/templates/shareCreated.email.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Hello {{ .ShareGrantee }},

{{ .ShareSharer }} has shared {{ .ShareFolder }} with you.

Click here to view it: {{ .ShareLink }}

----------------------------------------------------------

Hallo {{ .Grantee }},

{{ .ShareSharer }} hat dich zu {{ .ShareFolder }} eingeladen.

Klicke hier zum Anzeigen: {{ .ShareLink }}


---
ownCloud - Store. Share. Work.
https://owncloud.com
18 changes: 18 additions & 0 deletions services/notifications/pkg/email/templates/sharedSpace.email.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Hello {{ .SpaceGrantee }},

{{ .SpaceSharer }} has invited you to join {{ .SpaceName }}.

Click here to view it: {{ .ShareLink }}

----------------------------------------------------------

Hallo {{ .SpaceGrantee }},

{{ .SpaceSharer }} hat dich in den Space {{ .SpaceName }} eingeladen.

Klicke hier zum Anzeigen: {{ .ShareLink }}


---
ownCloud - Store. Share. Work.
https://owncloud.com
Loading

0 comments on commit d7b6ecf

Please sign in to comment.