[CLD-6894] Add 60, 30, and 7 day reminder emails for Cloud Renewals (#25883)
* Add email notifications for Cloud Renewals * Updates * Updates * Update app-layers * make build-templates * Add ability to set an env variable as a unix timestamp in s as the current date when getting DaysToExpiration * Add a mechanism to ensure at least one admin receives every email --------- Co-authored-by: Mattermost Build <build@mattermost.com> Co-authored-by: Gabe Jackson <3694686+gabrieljackson@users.noreply.github.com>
Этот коммит содержится в:
@@ -1251,6 +1251,99 @@ func (es *Service) SendDelinquencyEmail90(email, locale, siteURL string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es *Service) SendCloudRenewalEmail60(email, locale, siteURL string) error {
|
||||
T := i18n.GetUserTranslations(locale)
|
||||
|
||||
subject := T("api.templates.cloud_renewal_60.subject")
|
||||
|
||||
data := es.NewEmailTemplateData(locale)
|
||||
data.Props["SiteURL"] = siteURL
|
||||
data.Props["Title"] = T("api.templates.cloud_renewal_60.title")
|
||||
data.Props["SubTitle"] = T("api.templates.cloud_renewal.subtitle")
|
||||
// TODO: use the open delinquency modal action
|
||||
data.Props["ButtonURL"] = siteURL + "/admin_console/billing/subscription"
|
||||
data.Props["Button"] = T("api.templates.cloud_renewal.button")
|
||||
|
||||
data.Props["QuestionTitle"] = T("api.templates.questions_footer.title")
|
||||
data.Props["QuestionInfo"] = T("api.templates.questions_footer.info")
|
||||
data.Props["SupportEmail"] = *es.config().SupportSettings.SupportEmail
|
||||
data.Props["EmailUs"] = T("api.templates.email_us_anytime_at")
|
||||
data.Props["Image"] = "payment_processing.png"
|
||||
|
||||
body, err := es.templatesContainer.RenderToString("cloud_renewal_notification", data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := es.sendMail(email, subject, body, "CloudRenewal60"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es *Service) SendCloudRenewalEmail30(email, locale, siteURL string) error {
|
||||
T := i18n.GetUserTranslations(locale)
|
||||
|
||||
subject := T("api.templates.cloud_renewal_30.subject")
|
||||
|
||||
data := es.NewEmailTemplateData(locale)
|
||||
data.Props["SiteURL"] = siteURL
|
||||
data.Props["Title"] = T("api.templates.cloud_renewal_30.title")
|
||||
data.Props["SubTitle"] = T("api.templates.cloud_renewal.subtitle")
|
||||
// TODO: use the open delinquency modal action
|
||||
data.Props["ButtonURL"] = siteURL + "/admin_console/billing/subscription"
|
||||
data.Props["Button"] = T("api.templates.cloud_renewal.button")
|
||||
|
||||
data.Props["QuestionTitle"] = T("api.templates.questions_footer.title")
|
||||
data.Props["QuestionInfo"] = T("api.templates.questions_footer.info")
|
||||
data.Props["SupportEmail"] = *es.config().SupportSettings.SupportEmail
|
||||
data.Props["EmailUs"] = T("api.templates.email_us_anytime_at")
|
||||
data.Props["Image"] = "payment_processing.png"
|
||||
|
||||
body, err := es.templatesContainer.RenderToString("cloud_renewal_notification", data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := es.sendMail(email, subject, body, "CloudRenewal30"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es *Service) SendCloudRenewalEmail7(email, locale, siteURL string) error {
|
||||
T := i18n.GetUserTranslations(locale)
|
||||
|
||||
subject := T("api.templates.cloud_renewal_7.subject")
|
||||
|
||||
data := es.NewEmailTemplateData(locale)
|
||||
data.Props["SiteURL"] = siteURL
|
||||
data.Props["Title"] = T("api.templates.cloud_renewal_7.title")
|
||||
data.Props["SubTitle"] = T("api.templates.cloud_renewal.subtitle")
|
||||
// TODO: use the open delinquency modal action
|
||||
data.Props["ButtonURL"] = siteURL + "/admin_console/billing/subscription"
|
||||
data.Props["Button"] = T("api.templates.cloud_renewal.button")
|
||||
|
||||
data.Props["QuestionTitle"] = T("api.templates.questions_footer.title")
|
||||
data.Props["QuestionInfo"] = T("api.templates.questions_footer.info")
|
||||
data.Props["SupportEmail"] = *es.config().SupportSettings.SupportEmail
|
||||
data.Props["EmailUs"] = T("api.templates.email_us_anytime_at")
|
||||
data.Props["Image"] = "purchase_alert.png"
|
||||
|
||||
body, err := es.templatesContainer.RenderToString("cloud_renewal_notification", data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := es.sendMail(email, subject, body, "CloudRenewal7"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SendRemoveExpiredLicenseEmail formats an email and uses the email service to send the email to user with link pointing to CWS
|
||||
// to renew the user license
|
||||
func (es *Service) SendRemoveExpiredLicenseEmail(ctaText, ctaLink, email, locale, siteURL string) error {
|
||||
|
||||
@@ -128,6 +128,48 @@ func (_m *ServiceInterface) SendChangeUsernameEmail(newUsername string, _a1 stri
|
||||
return r0
|
||||
}
|
||||
|
||||
// SendCloudRenewalEmail30 provides a mock function with given fields: _a0, locale, siteURL
|
||||
func (_m *ServiceInterface) SendCloudRenewalEmail30(_a0 string, locale string, siteURL string) error {
|
||||
ret := _m.Called(_a0, locale, siteURL)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, string) error); ok {
|
||||
r0 = rf(_a0, locale, siteURL)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SendCloudRenewalEmail60 provides a mock function with given fields: _a0, locale, siteURL
|
||||
func (_m *ServiceInterface) SendCloudRenewalEmail60(_a0 string, locale string, siteURL string) error {
|
||||
ret := _m.Called(_a0, locale, siteURL)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, string) error); ok {
|
||||
r0 = rf(_a0, locale, siteURL)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SendCloudRenewalEmail7 provides a mock function with given fields: _a0, locale, siteURL
|
||||
func (_m *ServiceInterface) SendCloudRenewalEmail7(_a0 string, locale string, siteURL string) error {
|
||||
ret := _m.Called(_a0, locale, siteURL)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, string) error); ok {
|
||||
r0 = rf(_a0, locale, siteURL)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SendCloudUpgradeConfirmationEmail provides a mock function with given fields: userEmail, name, trialEndDate, locale, siteURL, workspaceName, isYearly, embeddedFiles
|
||||
func (_m *ServiceInterface) SendCloudUpgradeConfirmationEmail(userEmail string, name string, trialEndDate string, locale string, siteURL string, workspaceName string, isYearly bool, embeddedFiles map[string]io.Reader) error {
|
||||
ret := _m.Called(userEmail, name, trialEndDate, locale, siteURL, workspaceName, isYearly, embeddedFiles)
|
||||
|
||||
@@ -156,6 +156,9 @@ type ServiceInterface interface {
|
||||
SendDelinquencyEmail60(email, locale, siteURL string) error
|
||||
SendDelinquencyEmail75(email, locale, siteURL, planName, delinquencyDate string) error
|
||||
SendDelinquencyEmail90(email, locale, siteURL string) error
|
||||
SendCloudRenewalEmail60(email, locale, siteURL string) error
|
||||
SendCloudRenewalEmail30(email, locale, siteURL string) error
|
||||
SendCloudRenewalEmail7(email, locale, siteURL string) error
|
||||
SendNoCardPaymentFailedEmail(email string, locale string, siteURL string) error
|
||||
SendRemoveExpiredLicenseEmail(ctaText, ctaLink, email, locale, siteURL string) error
|
||||
AddNotificationEmailToBatch(user *model.User, post *model.Post, team *model.Team) *model.AppError
|
||||
|
||||
Ссылка в новой задаче
Block a user