[MM-48472]: Update the Upgrade Confirmation Email for yearly subscriptions (#21766)

Этот коммит содержится в:
emmyni
2022-12-05 12:10:00 -05:00
коммит произвёл GitHub
родитель 3059abdd88
Коммит 9e79ca7160
9 изменённых файлов: 94 добавлений и 20 удалений

Просмотреть файл

@@ -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))

Просмотреть файл

@@ -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"