-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtemplates.go
230 lines (188 loc) · 7.44 KB
/
templates.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
package emailtemplates
import (
"fmt"
"github.com/theopenlane/newman"
)
// Email subject lines
const (
welcomeSubject = "Welcome to %s!"
verifyEmailSubject = "Please verify your email address to login to %s"
inviteSubject = "Join Your Teammate %s on %s!"
passwordResetRequestSubject = "%s Password Reset - Action Required"
passwordResetSuccessSubject = "%s Password Reset Confirmation"
inviteAcceptedSubject = "You've been added to an Organization on %s"
subscribedSubject = "You've been subscribed to %s"
)
// Config includes fields that are common to all the email builders that are configurable
type Config struct {
// CompanyName is the name of the company that is sending the email
CompanyName string `koanf:"companyName" json:"companyName" default:""`
// CompanyAddress is the address of the company that is sending the email, included in the footer
CompanyAddress string `koanf:"companyAddress" json:"companyAddress" default:""`
// Corporation is the official corporation name that is sending the email, included in the footer
Corporation string `koanf:"corporation" json:"corporation" default:""`
// FromEmail is the email address that the email is sent from
FromEmail string `koanf:"fromEmail" json:"fromEmail" default:""`
// SupportEmail is the email address that the recipient can contact for support
SupportEmail string `koanf:"supportEmail" json:"supportEmail" default:""`
// LogoURL is the URL to the company logo that is included in the email if provided
LogoURL string `koanf:"logoURL" json:"logoURL" default:""`
// URLS includes URLs that are used in the email templates
URLS URLConfig `koanf:"urls" json:"urls"`
}
// URLConfig includes urls that are used in the email templates
type URLConfig struct {
// Root is the root domain for the email
Root string `koanf:"root" json:"root" default:""`
// Product is the product domain for the email, usually the main UI where a user logs in
Product string `koanf:"product" json:"product" default:""`
// Docs is the docs domain for the email, where a user can find documentation
Docs string `koanf:"docs" json:"docs" default:""`
// Verify is the URL to verify an email address
Verify string `koanf:"verify" json:"verify" default:""`
// Invite is the URL to accept an invite to an organization
Invite string `koanf:"invite" json:"invite" default:""`
// PasswordReset is the URL to reset a password
PasswordReset string `koanf:"reset" json:"reset" default:""`
// VerifySubscriber is the URL to verify a subscriber for an organization
VerifySubscriber string `koanf:"verifySubscriber" json:"verifySubscriber" default:""`
}
// EmailData includes data fields that are common to all the email builders
type EmailData struct {
Config
// Subject is the subject line of the email
Subject string `json:"subject"`
// Recipient is the person who will receive the email
Recipient Recipient `json:"recipient"`
}
// Recipient includes fields for the recipient of the email
type Recipient struct {
// Email is the email address of the recipient
Email string `json:"email"`
// FirstName is the first name of the recipient
FirstName string `json:"first_name"`
// LastName is the last name of the recipient
LastName string `json:"last_name"`
}
// WelcomeData includes fields for the welcome email
type WelcomeData struct {
EmailData
// Organization is the name of the organization that the user is joining
Organization string `json:"organization"`
}
// VerifyEmailData includes fields for the verify email
type VerifyEmailData struct {
EmailData
}
// SubscriberEmailData includes fields for the subscriber email
type SubscriberEmailData struct {
EmailData
// Organization is the name of the organization that the user is subscribing to
OrganizationName string `json:"organization_name"`
}
// InviteData includes fields for the invite email
type InviteData struct {
EmailData
// InviterName is the name of the person who is inviting the recipient
InviterName string `json:"inviter_name"`
// OrganizationName is the name of the organization that the user is being invited to
OrganizationName string `json:"organization_name"`
// Role is the role that the user is being invited to join the organization as
Role string `json:"role"`
}
// ResetRequestData includes fields for the password reset request email
type ResetRequestData struct {
EmailData
}
// ResetSuccessData includes fields for the password reset success email
type ResetSuccessData struct {
EmailData
}
// Build valids and creates a new email from pre-rendered templates
func (e EmailData) Build(text, html string) (*newman.EmailMessage, error) {
if err := e.Validate(); err != nil {
return nil, err
}
opts :=
[]newman.MessageOption{
newman.WithTo([]string{e.Recipient.Email}),
newman.WithFrom(e.FromEmail),
newman.WithSubject(e.Subject),
newman.WithHTML(html),
newman.WithText(text),
}
return newman.NewEmailMessageWithOptions(opts...), nil
}
// Validate that all required data is present to assemble a sendable email
func (e EmailData) Validate() error {
switch {
case e.Subject == "":
return newMissingRequiredFieldError("subject")
case e.Recipient.Email == "":
return newMissingRequiredFieldError("email")
}
return nil
}
// verify creates a new email to verify an email address
func verify(data VerifyEmailData) (*newman.EmailMessage, error) {
text, html, err := Render("verify_email", data)
if err != nil {
return nil, err
}
data.Subject = fmt.Sprintf(verifyEmailSubject, data.CompanyName)
return data.Build(text, html)
}
// welcome creates a new email to welcome a new user
func welcome(data WelcomeData) (*newman.EmailMessage, error) {
text, html, err := Render("welcome", data)
if err != nil {
return nil, err
}
data.Subject = fmt.Sprintf(welcomeSubject, data.CompanyName)
return data.Build(text, html)
}
// invite creates a new email to invite a user to an organization
func invite(data InviteData) (*newman.EmailMessage, error) {
text, html, err := Render("invite", data)
if err != nil {
return nil, err
}
data.Subject = fmt.Sprintf(inviteSubject, data.InviterName, data.CompanyName)
return data.Build(text, html)
}
// inviteAccepted creates a new email to notify a user that their invite has been accepted
func inviteAccepted(data InviteData) (*newman.EmailMessage, error) {
text, html, err := Render("invite_joined", data)
if err != nil {
return nil, err
}
data.Subject = fmt.Sprintf(inviteAcceptedSubject, data.CompanyName)
return data.Build(text, html)
}
// passwordResetRequest creates a new email to request a password reset
func passwordResetRequest(data ResetRequestData) (*newman.EmailMessage, error) {
text, html, err := Render("password_reset_request", data)
if err != nil {
return nil, err
}
data.Subject = fmt.Sprintf(passwordResetRequestSubject, data.CompanyName)
return data.Build(text, html)
}
// passwordResetSuccess creates a new email to confirm a password reset
func passwordResetSuccess(data ResetSuccessData) (*newman.EmailMessage, error) {
text, html, err := Render("password_reset_success", data)
if err != nil {
return nil, err
}
data.Subject = fmt.Sprintf(passwordResetSuccessSubject, data.CompanyName)
return data.Build(text, html)
}
// subscribe creates a new email to confirm a subscription
func subscribe(data SubscriberEmailData) (*newman.EmailMessage, error) {
text, html, err := Render("subscribe", data)
if err != nil {
return nil, err
}
data.Subject = fmt.Sprintf(subscribedSubject, data.CompanyName)
return data.Build(text, html)
}