[MM-48472]: Update the Upgrade Confirmation Email for yearly subscriptions (#21766)
Этот коммит содержится в:
@@ -136,9 +136,16 @@ func changeSubscription(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
product, err := c.App.Cloud().GetCloudProduct(c.AppContext.Session().UserId, subscriptionChange.ProductID)
|
||||
if err != nil || product == nil {
|
||||
c.Logger.Error("Error finding the new cloud product", mlog.Err(err))
|
||||
}
|
||||
|
||||
isYearly := product.IsYearly()
|
||||
|
||||
// Log failures for purchase confirmation email, but don't show an error to the user so as not to confuse them
|
||||
// At this point, the upgrade is complete.
|
||||
if appErr := c.App.SendUpgradeConfirmationEmail(); appErr != nil {
|
||||
if appErr := c.App.SendUpgradeConfirmationEmail(isYearly); appErr != nil {
|
||||
c.Logger.Error("Error sending purchase confirmation email", mlog.Err(appErr))
|
||||
}
|
||||
|
||||
@@ -636,7 +643,26 @@ func handleCWSWebhook(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
case model.EventTypeSendUpgradeConfirmationEmail:
|
||||
if nErr := c.App.SendUpgradeConfirmationEmail(); nErr != nil {
|
||||
|
||||
// isYearly determines whether to send the yearly or monthly Upgrade email
|
||||
isYearly := false
|
||||
if event.Subscription != nil && event.CloudWorkspaceOwner != nil {
|
||||
user, appErr := c.App.GetUserByUsername(event.CloudWorkspaceOwner.UserName)
|
||||
if appErr != nil {
|
||||
c.Err = model.NewAppError("Api4.handleCWSWebhook", appErr.Id, nil, appErr.Error(), appErr.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
// Get the current cloud product to determine whether it's a monthly or yearly product
|
||||
product, err := c.App.Cloud().GetCloudProduct(user.Id, event.Subscription.ProductID)
|
||||
if err != nil {
|
||||
c.Err = model.NewAppError("Api4.handleCWSWebhook", "api.cloud.request_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
isYearly = product.IsYearly()
|
||||
}
|
||||
|
||||
if nErr := c.App.SendUpgradeConfirmationEmail(isYearly); nErr != nil {
|
||||
c.Err = nErr
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1038,7 +1038,7 @@ type AppIface interface {
|
||||
SendPasswordReset(email string, siteURL string) (bool, *model.AppError)
|
||||
SendPaymentFailedEmail(failedPayment *model.FailedPayment) *model.AppError
|
||||
SendTestPushNotification(deviceID string) string
|
||||
SendUpgradeConfirmationEmail() *model.AppError
|
||||
SendUpgradeConfirmationEmail(isYearly bool) *model.AppError
|
||||
ServeInterPluginRequest(w http.ResponseWriter, r *http.Request, sourcePluginId, destinationPluginId string)
|
||||
SessionHasPermissionTo(session model.Session, permission *model.Permission) bool
|
||||
SessionHasPermissionToAny(session model.Session, permissions []*model.Permission) bool
|
||||
|
||||
@@ -174,7 +174,7 @@ func getNextBillingDateString() string {
|
||||
return fmt.Sprintf("%s %d, %d", t.Month(), t.Day(), t.Year())
|
||||
}
|
||||
|
||||
func (a *App) SendUpgradeConfirmationEmail() *model.AppError {
|
||||
func (a *App) SendUpgradeConfirmationEmail(isYearly bool) *model.AppError {
|
||||
sysAdmins, e := a.getSysAdminsEmailRecipients()
|
||||
if e != nil {
|
||||
return e
|
||||
@@ -200,7 +200,7 @@ func (a *App) SendUpgradeConfirmationEmail() *model.AppError {
|
||||
name = admin.Username
|
||||
}
|
||||
|
||||
err := a.Srv().EmailService.SendCloudUpgradeConfirmationEmail(admin.Email, name, billingDate, admin.Locale, *a.Config().ServiceSettings.SiteURL, subscription.GetWorkSpaceNameFromDNS())
|
||||
err := a.Srv().EmailService.SendCloudUpgradeConfirmationEmail(admin.Email, name, billingDate, admin.Locale, *a.Config().ServiceSettings.SiteURL, subscription.GetWorkSpaceNameFromDNS(), isYearly)
|
||||
if err != nil {
|
||||
a.Log().Error("Error sending trial ended email to", mlog.String("email", admin.Email), mlog.Err(err))
|
||||
countNotOks++
|
||||
|
||||
@@ -233,13 +233,13 @@ func (es *Service) SendWelcomeEmail(userID string, email string, verified bool,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es *Service) SendCloudUpgradeConfirmationEmail(userEmail, name, date, locale, siteURL, workspaceName string) error {
|
||||
func (es *Service) SendCloudUpgradeConfirmationEmail(userEmail, name, date, locale, siteURL, workspaceName string, isYearly bool) error {
|
||||
T := i18n.GetUserTranslations(locale)
|
||||
subject := T("api.templates.cloud_upgrade_confirmation.subject")
|
||||
|
||||
data := es.NewEmailTemplateData(locale)
|
||||
data.Props["Title"] = T("api.templates.cloud_upgrade_confirmation.title")
|
||||
data.Props["SubTitle"] = T("api.templates.cloud_upgrade_confirmation.subtitle", map[string]any{"WorkspaceName": workspaceName, "Date": date})
|
||||
data.Props["SubTitle"] = T("api.templates.cloud_upgrade_confirmation_monthly.subtitle", map[string]any{"WorkspaceName": workspaceName, "Date": date})
|
||||
data.Props["SiteURL"] = siteURL
|
||||
data.Props["ButtonURL"] = siteURL
|
||||
data.Props["Button"] = T("api.templates.cloud_welcome_email.button")
|
||||
@@ -247,6 +247,12 @@ func (es *Service) SendCloudUpgradeConfirmationEmail(userEmail, name, date, loca
|
||||
data.Props["QuestionInfo"] = T("api.templates.questions_footer.info")
|
||||
data.Props["SupportEmail"] = *es.config().SupportSettings.SupportEmail
|
||||
|
||||
if isYearly {
|
||||
data.Props["SubTitle"] = T("api.templates.cloud_upgrade_confirmation_yearly.subtitle", map[string]any{"WorkspaceName": workspaceName})
|
||||
data.Props["ButtonURL"] = siteURL + "/admin_console/billing/billing_history"
|
||||
data.Props["Button"] = T("api.templates.cloud_welcome_email.yearly_plan_button")
|
||||
}
|
||||
|
||||
body, err := es.templatesContainer.RenderToString("cloud_upgrade_confirmation", data)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -258,7 +258,7 @@ func TestSendCloudUpgradedEmail(t *testing.T) {
|
||||
emailTo := "testclouduser@example.com"
|
||||
emailToUsername := strings.Split(emailTo, "@")[0]
|
||||
|
||||
t.Run("SendCloudUpgradedEmail", func(t *testing.T) {
|
||||
t.Run("SendCloudMonthlyUpgradedEmail", func(t *testing.T) {
|
||||
verifyMailbox := func(t *testing.T) {
|
||||
t.Helper()
|
||||
|
||||
@@ -278,10 +278,44 @@ func TestSendCloudUpgradedEmail(t *testing.T) {
|
||||
require.NoError(t, err, "Could not get message from mailbox")
|
||||
require.Contains(t, resultsEmail.Body.Text, "You are now upgraded!", "Wrong received message %s", resultsEmail.Body.Text)
|
||||
require.Contains(t, resultsEmail.Body.Text, "SomeName workspace has now been upgraded", "Wrong received message %s", resultsEmail.Body.Text)
|
||||
require.Contains(t, resultsEmail.Body.Text, "You'll be billed from", "Wrong received message %s", resultsEmail.Body.Text)
|
||||
require.Contains(t, resultsEmail.Body.Text, "Open Mattermost", "Wrong received message %s", resultsEmail.Body.Text)
|
||||
}
|
||||
mail.DeleteMailBox(emailTo)
|
||||
|
||||
err := th.service.SendCloudUpgradeConfirmationEmail(emailTo, emailToUsername, "June 23, 2200", th.BasicUser.Locale, "https://example.com", "SomeName")
|
||||
// Send Update to Monthly Plan email
|
||||
err := th.service.SendCloudUpgradeConfirmationEmail(emailTo, emailToUsername, "June 23, 2200", th.BasicUser.Locale, "https://example.com", "SomeName", false)
|
||||
require.NoError(t, err)
|
||||
|
||||
verifyMailbox(t)
|
||||
})
|
||||
|
||||
t.Run("SendCloudYearlyUpgradedEmail", func(t *testing.T) {
|
||||
verifyMailbox := func(t *testing.T) {
|
||||
t.Helper()
|
||||
|
||||
var resultsMailbox mail.JSONMessageHeaderInbucket
|
||||
err2 := mail.RetryInbucket(5, func() error {
|
||||
var err error
|
||||
resultsMailbox, err = mail.GetMailBox(emailTo)
|
||||
return err
|
||||
})
|
||||
if err2 != nil {
|
||||
t.Skipf("No email was received, maybe due load on the server: %v", err2)
|
||||
}
|
||||
|
||||
require.Len(t, resultsMailbox, 1)
|
||||
require.Contains(t, resultsMailbox[0].To[0], emailTo, "Wrong To: recipient")
|
||||
resultsEmail, err := mail.GetMessageFromMailbox(emailTo, resultsMailbox[0].ID)
|
||||
require.NoError(t, err, "Could not get message from mailbox")
|
||||
require.Contains(t, resultsEmail.Body.Text, "You are now upgraded!", "Wrong received message %s", resultsEmail.Body.Text)
|
||||
require.Contains(t, resultsEmail.Body.Text, "SomeName workspace has now been upgraded", "Wrong received message %s", resultsEmail.Body.Text)
|
||||
require.Contains(t, resultsEmail.Body.Text, "View your invoice", "Wrong received message %s", resultsEmail.Body.Text)
|
||||
}
|
||||
mail.DeleteMailBox(emailTo)
|
||||
|
||||
// Send Update to Monthly Plan email
|
||||
err := th.service.SendCloudUpgradeConfirmationEmail(emailTo, emailToUsername, "June 23, 2200", th.BasicUser.Locale, "https://example.com", "SomeName", true)
|
||||
require.NoError(t, err)
|
||||
|
||||
verifyMailbox(t)
|
||||
|
||||
@@ -125,13 +125,13 @@ func (_m *ServiceInterface) SendChangeUsernameEmail(newUsername string, _a1 stri
|
||||
return r0
|
||||
}
|
||||
|
||||
// SendCloudUpgradeConfirmationEmail provides a mock function with given fields: userEmail, name, trialEndDate, locale, siteURL, workspaceName
|
||||
func (_m *ServiceInterface) SendCloudUpgradeConfirmationEmail(userEmail string, name string, trialEndDate string, locale string, siteURL string, workspaceName string) error {
|
||||
ret := _m.Called(userEmail, name, trialEndDate, locale, siteURL, workspaceName)
|
||||
// SendCloudUpgradeConfirmationEmail provides a mock function with given fields: userEmail, name, trialEndDate, locale, siteURL, workspaceName, isYearly
|
||||
func (_m *ServiceInterface) SendCloudUpgradeConfirmationEmail(userEmail string, name string, trialEndDate string, locale string, siteURL string, workspaceName string, isYearly bool) error {
|
||||
ret := _m.Called(userEmail, name, trialEndDate, locale, siteURL, workspaceName, isYearly)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, string, string, string, string) error); ok {
|
||||
r0 = rf(userEmail, name, trialEndDate, locale, siteURL, workspaceName)
|
||||
if rf, ok := ret.Get(0).(func(string, string, string, string, string, string, bool) error); ok {
|
||||
r0 = rf(userEmail, name, trialEndDate, locale, siteURL, workspaceName, isYearly)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ type ServiceInterface interface {
|
||||
SendVerifyEmail(userEmail, locale, siteURL, token, redirect string) error
|
||||
SendSignInChangeEmail(email, method, locale, siteURL string) error
|
||||
SendWelcomeEmail(userID string, email string, verified bool, disableWelcomeEmail bool, locale, siteURL, redirect string) error
|
||||
SendCloudUpgradeConfirmationEmail(userEmail, name, trialEndDate, locale, siteURL, workspaceName string) error
|
||||
SendCloudUpgradeConfirmationEmail(userEmail, name, trialEndDate, locale, siteURL, workspaceName string, isYearly bool) error
|
||||
SendCloudWelcomeEmail(userEmail, locale, teamInviteID, workSpaceName, dns, siteURL string) error
|
||||
SendPasswordChangeEmail(email, method, locale, siteURL string) error
|
||||
SendUserAccessTokenAddedEmail(email, locale, siteURL string) error
|
||||
|
||||
@@ -15546,7 +15546,7 @@ func (a *OpenTracingAppLayer) SendTestPushNotification(deviceID string) string {
|
||||
return resultVar0
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) SendUpgradeConfirmationEmail() *model.AppError {
|
||||
func (a *OpenTracingAppLayer) SendUpgradeConfirmationEmail(isYearly bool) *model.AppError {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.SendUpgradeConfirmationEmail")
|
||||
|
||||
@@ -15558,7 +15558,7 @@ func (a *OpenTracingAppLayer) SendUpgradeConfirmationEmail() *model.AppError {
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
resultVar0 := a.app.SendUpgradeConfirmationEmail()
|
||||
resultVar0 := a.app.SendUpgradeConfirmationEmail(isYearly)
|
||||
|
||||
if resultVar0 != nil {
|
||||
span.LogFields(spanlog.Error(resultVar0))
|
||||
|
||||
14
i18n/en.json
14
i18n/en.json
@@ -3164,12 +3164,16 @@
|
||||
"translation": "Mattermost Upgrade Confirmation"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.cloud_upgrade_confirmation.subtitle",
|
||||
"id": "api.templates.cloud_upgrade_confirmation.title",
|
||||
"translation": "You are now upgraded!"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.cloud_upgrade_confirmation_monthly.subtitle",
|
||||
"translation": "Your {{.WorkspaceName}} workspace has now been upgraded. You'll be billed from {{.Date}}"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.cloud_upgrade_confirmation.title",
|
||||
"translation": "You are now upgraded!"
|
||||
"id": "api.templates.cloud_upgrade_confirmation_yearly.subtitle",
|
||||
"translation": "Your {{.WorkspaceName}} workspace has now been upgraded."
|
||||
},
|
||||
{
|
||||
"id": "api.templates.cloud_welcome_email.add_apps_info",
|
||||
@@ -3239,6 +3243,10 @@
|
||||
"id": "api.templates.cloud_welcome_email.title",
|
||||
"translation": "Your workspace is ready to go!"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.cloud_welcome_email.yearly_plan_button",
|
||||
"translation": "View your invoice"
|
||||
},
|
||||
{
|
||||
"id": "api.templates.copyright",
|
||||
"translation": "© 2021 Mattermost, Inc. 530 Lytton Avenue, Second floor, Palo Alto, CA, 94301"
|
||||
|
||||
Ссылка в новой задаче
Block a user