[MM-43920] - Set Workspace Inactivity Email to only fire once and change subject (#20134)

* [MM-43920] - Set Workspace Inactivity Email to only fire once and change subject

* feedback impl

* temp change

* revert

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Allan Guwatudde
2022-05-06 11:54:38 +03:00
коммит произвёл GitHub
родитель d9e3125e87
Коммит 37fd699175
5 изменённых файлов: 43 добавлений и 49 удалений

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

@@ -11,6 +11,8 @@ import (
"io"
"net/http"
"net/url"
"os"
"strconv"
"strings"
"time"
@@ -24,6 +26,8 @@ import (
"github.com/microcosm-cc/bluemonday"
)
const serverInactivityHours = 100
func (es *Service) SendChangeUsernameEmail(newUsername, email, locale, siteURL string) error {
T := i18n.GetUserTranslations(locale)
@@ -944,6 +948,15 @@ func (es *Service) SendLicenseInactivityEmail(email, name, locale, siteURL strin
data.Props["Playbooks"] = T("Playbooks")
data.Props["Boards"] = T("Boards")
inactivityDurationHoursEnv := os.Getenv("MM_INACTIVITY_DURATION")
inactivityDurationHours, parseError := strconv.ParseFloat(inactivityDurationHoursEnv, 64)
if parseError != nil {
// default to 100 hours
inactivityDurationHours = serverInactivityHours
}
data.Props["FooterDisclaimer"] = T("api.templates.server_inactivity_footer_disclaimer", map[string]interface{}{"Hours": inactivityDurationHours})
body, err := es.templatesContainer.RenderToString("inactivity_body", data)
if err != nil {
return err

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

@@ -4,19 +4,24 @@
package app
import (
"fmt"
"os"
"strconv"
"time"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
"github.com/mattermost/mattermost-server/v6/store"
)
const serverInactivityHours = 100
const inactivityEmailSent = "INACTIVITY"
func (s *Server) doInactivityCheck() {
if *s.Config().ServiceSettings.EnableDeveloper {
mlog.Info("No activity check because developer mode is enabled")
return
}
if !*s.Config().EmailSettings.EnableInactivityEmail {
mlog.Info("No activity check because EnableInactivityEmail is false")
return
@@ -27,6 +32,12 @@ func (s *Server) doInactivityCheck() {
return
}
_, sysValErr := s.Store.System().GetByName(inactivityEmailSent)
// if there is no error which may include *store.ErrNotFound, it means this check was already flagged as done
if sysValErr == nil {
return
}
inactivityDurationHoursEnv := os.Getenv("MM_INACTIVITY_DURATION")
inactivityDurationHours, parseError := strconv.ParseFloat(inactivityDurationHoursEnv, 64)
if parseError != nil {
@@ -34,51 +45,9 @@ func (s *Server) doInactivityCheck() {
inactivityDurationHours = serverInactivityHours
}
systemValue, sysValErr := s.Store.System().GetByName("INACTIVITY")
if sysValErr != nil {
// any other error apart from ErrNotFound we stop execution
if _, ok := sysValErr.(*store.ErrNotFound); !ok {
mlog.Warn("An error occurred while getting INACTIVITY from system store", mlog.Err(sysValErr))
return
}
}
// If we have a system value, it means this job already ran atleast once.
// we then check the last time the job ran plus the last time a post was made to determine if we
// can remind the user to use workspace again. If no post was made, we check the last time they logged in (session)
// and determine whether to send them a reminder.
if systemValue != nil {
sysT, _ := strconv.ParseInt(systemValue.Value, 10, 64)
tt := time.Unix(sysT/1000, 0)
timeLastSentInactivityEmail := time.Since(tt).Hours()
lastPostAt, _ := s.Store.Post().GetLastPostRowCreateAt()
if lastPostAt != 0 {
posT := time.Unix(lastPostAt/1000, 0)
timeForLastPost := time.Since(posT).Hours()
if timeLastSentInactivityEmail > inactivityDurationHours && timeForLastPost > inactivityDurationHours {
s.takeInactivityAction()
}
return
}
lastSessionAt, _ := s.Store.Session().GetLastSessionRowCreateAt()
if lastSessionAt != 0 {
sesT := time.Unix(lastSessionAt/1000, 0)
timeForLastSession := time.Since(sesT).Hours()
if timeLastSentInactivityEmail > inactivityDurationHours && timeForLastSession > inactivityDurationHours {
s.takeInactivityAction()
}
return
}
}
// The first time this job runs. We check if the user has not made any posts
// The first time this job runs. We check if the user has not made any posts in last inactivityDurationHours
// and remind them to use the workspace. If no posts have been made. We check the last time
// they logged in (session) and send a reminder.
// they logged in (session) for the last inactivityDurationHours and send a reminder.
lastPostAt, _ := s.Store.Post().GetLastPostRowCreateAt()
if lastPostAt != 0 {
posT := time.Unix(lastPostAt/1000, 0)
@@ -139,8 +108,8 @@ func (s *Server) takeInactivityAction() {
})
}
// Mark time that we sent emails. The next time we calculate
sysVar := &model.System{Name: "INACTIVITY", Value: fmt.Sprint(model.GetMillis())}
// Mark that we sent emails.
sysVar := &model.System{Name: inactivityEmailSent, Value: "true"}
if err := s.Store.System().SaveOrUpdate(sysVar); err != nil {
mlog.Error("Unable to save INACTIVITY", mlog.Err(err))
}

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

@@ -3499,6 +3499,10 @@
"id": "api.templates.server_inactivity_button",
"translation": "Open Mattermost"
},
{
"id": "api.templates.server_inactivity_footer_disclaimer",
"translation": "You received this one-time email because your Mattermost server was inactive for more than {{.Hours}} hours. This email was automatically generated by your Mattermost server."
},
{
"id": "api.templates.server_inactivity_info",
"translation": "Come and check it out!"
@@ -3517,7 +3521,7 @@
},
{
"id": "api.templates.server_inactivity_subject",
"translation": "HEY! Open Mattermost to increase your teams productivity!"
"translation": "Come open Mattermost to increase your teams productivity!"
},
{
"id": "api.templates.server_inactivity_subtitle",

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

@@ -506,6 +506,11 @@
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-top:1px solid #E5E5E5;vertical-align:top;" width="100%">
<tbody>
<tr>
<td align="center" class="emailFooter" style="font-size:0px;padding:10px 25px;word-break:break-word;">
<div style="font-family: Arial; text-align: center; font-size: 12px; line-height: 16px; color: rgba(63, 67, 80, 0.56); padding: 8px 24px 8px 24px;">{{.Props.FooterDisclaimer}}</div>
</td>
</tr>
<tr>
<td align="center" class="emailFooter" style="font-size:0px;padding:10px 25px;word-break:break-word;">
<div style="font-family: Arial; text-align: center; font-size: 12px; line-height: 16px; color: rgba(63, 67, 80, 0.56); padding: 8px 24px 8px 24px;">{{.Props.Organization}}

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

@@ -50,6 +50,9 @@
<mj-section padding="0px 24px 40px 24px">
<mj-column border-top="1px solid #E5E5E5">
<mj-text css-class="emailFooter" font-family="Arial" font-size="12px" line-height="16px" color="#3F4350">
{{.Props.FooterDisclaimer}}
</mj-text>
<mj-text css-class="emailFooter" font-family="Arial" font-size="12px" line-height="16px" color="#3F4350">
{{.Props.Organization}}
{{.Props.FooterV2}}