[MM-45564] - Notify Admin v2 (#20777)
* [MM-45564] - Notify Admin v2 * add dummy data * update dummy data * add store methods * experiment with recurring task * complete saving of the notification * make improvements * make improvements * add store layer tests * fix lint * update store layer tests * add app layer unit tests * add store layers * add app layer tests * fix lint * fix lint * fix tests * fix tests lint * fix lint * fix lint * fix retry layer test * add notifications manual trigger * filter notifications based on current plan * add test case * temp change * feedback impl * fix translations * change job scheduler * refactor job * fix store layer tests * extract i18n * fix lint * fix translations * fix translations * add license statement for new file * feedback impl-2 * fix lint * update make file * add intl ids * improve * fix lint * feedback impl * move code and rename files * fix lint * feedback impl * add config for trigger notifications api * fix tests * tmp change * undo temp changes Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
c11ad8995f
Коммит
bd42f0cd8c
@@ -8020,20 +8020,36 @@ func (c *Client4) ValidateWorkspaceBusinessEmail() (*Response, error) {
|
||||
return BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) NotifyAdmin(nr *NotifyAdminToUpgradeRequest) int {
|
||||
func (c *Client4) NotifyAdmin(nr *NotifyAdminToUpgradeRequest) (int, error) {
|
||||
nrJSON, err := json.Marshal(nr)
|
||||
if err != nil {
|
||||
return 0
|
||||
return 0, err
|
||||
}
|
||||
|
||||
r, err := c.DoAPIPost(c.cloudRoute()+"/notify-admin-to-upgrade", string(nrJSON))
|
||||
r, err := c.DoAPIPost("/users/notify-admin", string(nrJSON))
|
||||
if err != nil {
|
||||
return r.StatusCode
|
||||
return r.StatusCode, err
|
||||
}
|
||||
|
||||
closeBody(r)
|
||||
|
||||
return r.StatusCode
|
||||
return r.StatusCode, nil
|
||||
}
|
||||
|
||||
func (c *Client4) TriggerNotifyAdmin(nr *NotifyAdminToUpgradeRequest) (int, error) {
|
||||
nrJSON, err := json.Marshal(nr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
r, err := c.DoAPIPost("/users/trigger-notify-admin-posts", string(nrJSON))
|
||||
if err != nil {
|
||||
return r.StatusCode, err
|
||||
}
|
||||
|
||||
closeBody(r)
|
||||
|
||||
return r.StatusCode, nil
|
||||
}
|
||||
|
||||
func (c *Client4) ValidateBusinessEmail(email *ValidateBusinessEmailRequest) (*Response, error) {
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -42,9 +40,6 @@ const (
|
||||
SubscriptionFamilyOnPrem = SubscriptionFamily("on-prem")
|
||||
)
|
||||
|
||||
const defaultCloudNotifyAdminCoolOffDays = 30
|
||||
const CloudNotifyAdminInfo = "cloud_notify_admin_info"
|
||||
|
||||
// Product model represents a product on the cloud system.
|
||||
type Product struct {
|
||||
ID string `json:"id"`
|
||||
@@ -258,23 +253,3 @@ type ProductLimits struct {
|
||||
Messages *MessagesLimits `json:"messages,omitempty"`
|
||||
Teams *TeamsLimits `json:"teams,omitempty"`
|
||||
}
|
||||
|
||||
type NotifyAdminToUpgradeRequest struct {
|
||||
CurrentTeamId string `json:"current_team_id"`
|
||||
}
|
||||
|
||||
type AdminNotificationUserInfo struct {
|
||||
LastUserIDToNotify string
|
||||
LastNotificationTimestamp int64
|
||||
}
|
||||
|
||||
func CanNotify(lastNotificationTimestamp int64) bool {
|
||||
coolOffPeriodDaysEnv := os.Getenv("MM_CLOUD_NOTIFY_ADMIN_COOL_OFF_DAYS")
|
||||
coolOffPeriodDays, parseError := strconv.ParseFloat(coolOffPeriodDaysEnv, 64)
|
||||
if parseError != nil {
|
||||
coolOffPeriodDays = defaultCloudNotifyAdminCoolOffDays
|
||||
}
|
||||
daysToMillis := coolOffPeriodDays * 24 * 60 * 60 * 1000
|
||||
timeDiff := GetMillis() - lastNotificationTimestamp
|
||||
return timeDiff >= int64(daysToMillis)
|
||||
}
|
||||
|
||||
@@ -361,6 +361,7 @@ type ServiceSettings struct {
|
||||
ExperimentalEnableDefaultChannelLeaveJoinMessages *bool `access:"experimental_features"`
|
||||
ExperimentalGroupUnreadChannels *string `access:"experimental_features"`
|
||||
EnableAPITeamDeletion *bool
|
||||
EnableAPITriggerAdminNotifications *bool
|
||||
EnableAPIUserDeletion *bool
|
||||
ExperimentalEnableHardenedMode *bool `access:"experimental_features"`
|
||||
ExperimentalStrictCSRFEnforcement *bool `access:"experimental_features,write_restrictable,cloud_restrictable"`
|
||||
@@ -754,6 +755,10 @@ func (s *ServiceSettings) SetDefaults(isUpdate bool) {
|
||||
s.EnableAPITeamDeletion = NewBool(false)
|
||||
}
|
||||
|
||||
if s.EnableAPITriggerAdminNotifications == nil {
|
||||
s.EnableAPITriggerAdminNotifications = NewBool(false)
|
||||
}
|
||||
|
||||
if s.EnableAPIUserDeletion == nil {
|
||||
s.EnableAPIUserDeletion = NewBool(false)
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ const (
|
||||
JobTypeResendInvitationEmail = "resend_invitation_email"
|
||||
JobTypeExtractContent = "extract_content"
|
||||
JobTypeLastAccessiblePost = "last_accessible_post"
|
||||
JobTypeUpgradeNotifyAdmin = "upgrade_notify_admin"
|
||||
JobTypeTrialNotifyAdmin = "trial_notify_admin"
|
||||
|
||||
JobStatusPending = "pending"
|
||||
JobStatusInProgress = "in_progress"
|
||||
|
||||
75
model/notify_admin.go
Обычный файл
75
model/notify_admin.go
Обычный файл
@@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type MattermostPaidFeature string
|
||||
|
||||
const (
|
||||
PaidFeatureGuestAccounts = MattermostPaidFeature("mattermost.feature.guest_accounts")
|
||||
PaidFeatureCustomUsergroups = MattermostPaidFeature("mattermost.feature.custom_user_groups")
|
||||
PaidFeatureCreateMultipleTeams = MattermostPaidFeature("mattermost.feature.create_multiple_teams")
|
||||
PaidFeatureStartcall = MattermostPaidFeature("mattermost.feature.start_call")
|
||||
PaidFeaturePlaybooksRetrospective = MattermostPaidFeature("mattermost.feature.playbooks_retro")
|
||||
PaidFeatureUnlimitedMessages = MattermostPaidFeature("mattermost.feature.unlimited_messages")
|
||||
PaidFeatureUnlimitedFileStorage = MattermostPaidFeature("mattermost.feature.unlimited_file_storage")
|
||||
PaidFeatureUnlimitedIntegrations = MattermostPaidFeature("mattermost.feature.unlimited_integrations")
|
||||
PaidFeatureUnlimitedBoardcards = MattermostPaidFeature("mattermost.feature.unlimited_board_cards")
|
||||
PaidFeatureAllProfessionalfeatures = MattermostPaidFeature("mattermost.feature.all_professional")
|
||||
PaidFeatureAllEnterprisefeatures = MattermostPaidFeature("mattermost.feature.all_enterprise")
|
||||
)
|
||||
|
||||
var validSKUs map[string]struct{} = map[string]struct{}{
|
||||
LicenseShortSkuProfessional: {},
|
||||
LicenseShortSkuEnterprise: {},
|
||||
}
|
||||
|
||||
// These are the features a non admin would typically ping an admin about
|
||||
var paidFeatures map[MattermostPaidFeature]struct{} = map[MattermostPaidFeature]struct{}{
|
||||
PaidFeatureGuestAccounts: {},
|
||||
PaidFeatureCustomUsergroups: {},
|
||||
PaidFeatureCreateMultipleTeams: {},
|
||||
PaidFeatureStartcall: {},
|
||||
PaidFeaturePlaybooksRetrospective: {},
|
||||
PaidFeatureUnlimitedMessages: {},
|
||||
PaidFeatureUnlimitedFileStorage: {},
|
||||
PaidFeatureUnlimitedIntegrations: {},
|
||||
PaidFeatureUnlimitedBoardcards: {},
|
||||
PaidFeatureAllProfessionalfeatures: {},
|
||||
PaidFeatureAllEnterprisefeatures: {},
|
||||
}
|
||||
|
||||
type NotifyAdminToUpgradeRequest struct {
|
||||
TrialNotification bool `json:"trial_notification"`
|
||||
RequiredPlan string `json:"required_plan"`
|
||||
RequiredFeature MattermostPaidFeature `json:"required_feature"`
|
||||
}
|
||||
|
||||
type NotifyAdminData struct {
|
||||
CreateAt int64 `json:"create_at,omitempty"`
|
||||
UserId string `json:"user_id"`
|
||||
RequiredPlan string `json:"required_plan"`
|
||||
RequiredFeature MattermostPaidFeature `json:"required_feature"`
|
||||
Trial bool `json:"trial"`
|
||||
}
|
||||
|
||||
func (nad *NotifyAdminData) IsValid() *AppError {
|
||||
if _, planOk := validSKUs[nad.RequiredPlan]; !planOk {
|
||||
return NewAppError("NotifyAdmin.IsValid", fmt.Sprintf("Invalid plan, %s provided", nad.RequiredPlan), nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if _, featureOk := paidFeatures[nad.RequiredFeature]; !featureOk {
|
||||
return NewAppError("NotifyAdmin.IsValid", fmt.Sprintf("Invalid feature, %s provided", nad.RequiredFeature), nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (nad *NotifyAdminData) PreSave() {
|
||||
nad.CreateAt = GetMillis()
|
||||
}
|
||||
Ссылка в новой задаче
Block a user