@@ -0,0 +1,137 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/textproto"
|
||||
txttpl "text/template"
|
||||
)
|
||||
|
||||
// Message is the message pushed to a Messenger.
|
||||
type Message struct {
|
||||
From string
|
||||
To []string
|
||||
Subject string
|
||||
ContentType string
|
||||
Body []byte
|
||||
AltBody []byte
|
||||
Headers textproto.MIMEHeader
|
||||
Attachments []Attachment
|
||||
|
||||
Subscriber Subscriber
|
||||
|
||||
// Campaign is generally the same instance for a large number of subscribers.
|
||||
Campaign *Campaign
|
||||
|
||||
// Messenger is the messenger backend to use: email|postback.
|
||||
Messenger string
|
||||
}
|
||||
|
||||
// Attachment represents a file or blob attachment that can be
|
||||
// sent along with a message by a Messenger.
|
||||
type Attachment struct {
|
||||
Name string
|
||||
Header textproto.MIMEHeader
|
||||
Content []byte
|
||||
|
||||
// IsInline marks the attachment as an inline (CID) part
|
||||
// to be wrapped in multipart/related.
|
||||
IsInline bool
|
||||
}
|
||||
|
||||
// TxMessage subscriber modes.
|
||||
const (
|
||||
TxSubModeDefault = "default"
|
||||
TxSubModeFallback = "fallback"
|
||||
TxSubModeExternal = "external"
|
||||
)
|
||||
|
||||
// TxMessage represents an e-mail campaign.
|
||||
type TxMessage struct {
|
||||
SubscriberMode string `json:"subscriber_mode"`
|
||||
SubscriberEmails []string `json:"subscriber_emails"`
|
||||
SubscriberIDs []int `json:"subscriber_ids"`
|
||||
|
||||
// Deprecated.
|
||||
SubscriberEmail string `json:"subscriber_email"`
|
||||
SubscriberID int `json:"subscriber_id"`
|
||||
|
||||
TemplateID int `json:"template_id"`
|
||||
Data map[string]any `json:"data"`
|
||||
FromEmail string `json:"from_email"`
|
||||
Headers Headers `json:"headers"`
|
||||
ContentType string `json:"content_type"`
|
||||
Messenger string `json:"messenger"`
|
||||
Subject string `json:"subject"`
|
||||
AltBody string `json:"altbody"`
|
||||
|
||||
// File attachments added from multi-part form data.
|
||||
Attachments []Attachment `json:"-"`
|
||||
|
||||
Body []byte `json:"-"`
|
||||
Tpl *template.Template `json:"-"`
|
||||
SubjectTpl *txttpl.Template `json:"-"`
|
||||
}
|
||||
|
||||
func (m *TxMessage) Render(sub Subscriber, tpl *Template, funcs txttpl.FuncMap) error {
|
||||
data := struct {
|
||||
Subscriber Subscriber
|
||||
Tx *TxMessage
|
||||
}{sub, m}
|
||||
|
||||
// Render the body.
|
||||
b := bytes.Buffer{}
|
||||
if err := tpl.Tpl.ExecuteTemplate(&b, BaseTpl, data); err != nil {
|
||||
return err
|
||||
}
|
||||
m.Body = make([]byte, b.Len())
|
||||
copy(m.Body, b.Bytes())
|
||||
b.Reset()
|
||||
|
||||
// Render alt body if it has any templating strings.
|
||||
if m.AltBody != "" && hasTplExpr(m.AltBody) {
|
||||
t, err := txttpl.New(BaseTpl).Funcs(funcs).Parse(m.AltBody)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error compiling alt body: %v", err)
|
||||
}
|
||||
if err := t.ExecuteTemplate(&b, BaseTpl, data); err != nil {
|
||||
return err
|
||||
}
|
||||
m.AltBody = b.String()
|
||||
b.Reset()
|
||||
}
|
||||
|
||||
// Was a subject provided in the message?
|
||||
var (
|
||||
subjTpl *txttpl.Template
|
||||
subject = m.Subject
|
||||
)
|
||||
if subject != "" {
|
||||
if hasTplExpr(m.Subject) {
|
||||
// If the subject has a template string, render that.
|
||||
s, err := txttpl.New(BaseTpl).Funcs(funcs).Parse(m.Subject)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error compiling subject: %v", err)
|
||||
}
|
||||
subjTpl = s
|
||||
}
|
||||
} else {
|
||||
// Use the subject from the template.
|
||||
subject = tpl.Subject
|
||||
subjTpl = tpl.SubjectTpl
|
||||
}
|
||||
|
||||
// If the subject is also a template, render that.
|
||||
if subjTpl != nil {
|
||||
if err := subjTpl.ExecuteTemplate(&b, BaseTpl, data); err != nil {
|
||||
return err
|
||||
}
|
||||
m.Subject = b.String()
|
||||
b.Reset()
|
||||
} else {
|
||||
m.Subject = subject
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user