From 64d44707c2828b8f6442d42d2fe8b7b966607310 Mon Sep 17 00:00:00 2001 From: Kailash Nadh Date: Sun, 5 Jul 2020 18:39:24 +0530 Subject: [PATCH] Add {{ templating }} support to e-mail subjects --- campaigns.go | 5 ++++- internal/manager/manager.go | 19 ++++++++++++++++++- models/models.go | 14 ++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/campaigns.go b/campaigns.go index 31ae615..ceb4bd3 100644 --- a/campaigns.go +++ b/campaigns.go @@ -558,7 +558,10 @@ func sendTestMessage(sub models.Subscriber, camp *models.Campaign, app *App) err fmt.Sprintf("Error rendering message: %v", err)) } - if err := app.messenger.Push(camp.FromEmail, []string{sub.Email}, camp.Subject, m.Body(), nil); err != nil { + if err := app.messenger.Push(camp.FromEmail, + []string{sub.Email}, + m.Subject(), + m.Body(), nil); err != nil { return err } diff --git a/internal/manager/manager.go b/internal/manager/manager.go index 9af267c..e9804f3 100644 --- a/internal/manager/manager.go +++ b/internal/manager/manager.go @@ -68,6 +68,7 @@ type CampaignMessage struct { from string to string + subject string body []byte unsubURL string } @@ -126,6 +127,7 @@ func (m *Manager) NewCampaignMessage(c *models.Campaign, s models.Subscriber) Ca Campaign: c, Subscriber: s, + subject: c.Subject, from: c.FromEmail, to: s.Email, unsubURL: fmt.Sprintf(m.cfg.UnsubURL, c.UUID, s.UUID), @@ -271,7 +273,7 @@ func (m *Manager) SpawnWorkers() { numMsg++ err := m.messengers[msg.Campaign.MessengerID].Push( - msg.from, []string{msg.to}, msg.Campaign.Subject, msg.body, nil) + msg.from, []string{msg.to}, msg.subject, msg.body, nil) if err != nil { m.logger.Printf("error sending message in campaign %s: %v", msg.Campaign.Name, err) @@ -480,6 +482,16 @@ func (m *Manager) sendNotif(c *models.Campaign, status, reason string) error { // and applies the resultant bytes to Message.body to be used in messages. func (m *CampaignMessage) Render() error { out := bytes.Buffer{} + + // Render the subject if it's a template. + if m.Campaign.SubjectTpl != nil { + if err := m.Campaign.SubjectTpl.ExecuteTemplate(&out, models.ContentTpl, m); err != nil { + return err + } + m.subject = out.String() + out.Reset() + } + if err := m.Campaign.Tpl.ExecuteTemplate(&out, models.BaseTpl, m); err != nil { return err } @@ -487,6 +499,11 @@ func (m *CampaignMessage) Render() error { return nil } +// Subject returns a copy of the message subject +func (m *CampaignMessage) Subject() string { + return m.subject +} + // Body returns a copy of the message body. func (m *CampaignMessage) Body() []byte { out := make([]byte, len(m.body)) diff --git a/models/models.go b/models/models.go index 1423068..22477c7 100644 --- a/models/models.go +++ b/models/models.go @@ -169,6 +169,7 @@ type Campaign struct { // TemplateBody is joined in from templates by the next-campaigns query. TemplateBody string `db:"template_body" json:"-"` Tpl *template.Template `json:"-"` + SubjectTpl *template.Template `json:"-"` // Pseudofield for getting the total number of subscribers // in searches and queries. @@ -310,6 +311,19 @@ func (c *Campaign) CompileTemplate(f template.FuncMap) error { return fmt.Errorf("error inserting child template: %v", err) } + // If the subject line has a template string, compile it. + if strings.Contains(c.Subject, "{{") { + subj := c.Subject + for _, r := range regTplFuncs { + subj = r.regExp.ReplaceAllString(subj, r.replace) + } + subjTpl, err := template.New(ContentTpl).Funcs(f).Parse(subj) + if err != nil { + return fmt.Errorf("error compiling subject: %v", err) + } + c.SubjectTpl = subjTpl + } + c.Tpl = out return nil }