github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/app/command_groupmsg.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package app
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	goi18n "github.com/mattermost/go-i18n/i18n"
    11  	"github.com/mattermost/mattermost-server/v5/mlog"
    12  	"github.com/mattermost/mattermost-server/v5/model"
    13  )
    14  
    15  type groupmsgProvider struct {
    16  }
    17  
    18  const (
    19  	CMD_GROUPMSG = "groupmsg"
    20  )
    21  
    22  func init() {
    23  	RegisterCommandProvider(&groupmsgProvider{})
    24  }
    25  
    26  func (me *groupmsgProvider) GetTrigger() string {
    27  	return CMD_GROUPMSG
    28  }
    29  
    30  func (me *groupmsgProvider) GetCommand(a *App, T goi18n.TranslateFunc) *model.Command {
    31  	return &model.Command{
    32  		Trigger:          CMD_GROUPMSG,
    33  		AutoComplete:     true,
    34  		AutoCompleteDesc: T("api.command_groupmsg.desc"),
    35  		AutoCompleteHint: T("api.command_groupmsg.hint"),
    36  		DisplayName:      T("api.command_groupmsg.name"),
    37  	}
    38  }
    39  
    40  func (me *groupmsgProvider) DoCommand(a *App, args *model.CommandArgs, message string) *model.CommandResponse {
    41  	targetUsers := map[string]*model.User{}
    42  	targetUsersSlice := []string{args.UserId}
    43  	invalidUsernames := []string{}
    44  
    45  	users, parsedMessage := groupMsgUsernames(message)
    46  
    47  	for _, username := range users {
    48  		username = strings.TrimSpace(username)
    49  		username = strings.TrimPrefix(username, "@")
    50  		targetUser, err := a.Srv().Store.User().GetByUsername(username)
    51  		if err != nil {
    52  			invalidUsernames = append(invalidUsernames, username)
    53  			continue
    54  		}
    55  
    56  		canSee, err := a.UserCanSeeOtherUser(args.UserId, targetUser.Id)
    57  		if err != nil {
    58  			return &model.CommandResponse{Text: args.T("api.command_groupmsg.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
    59  		}
    60  
    61  		if !canSee {
    62  			invalidUsernames = append(invalidUsernames, username)
    63  			continue
    64  		}
    65  
    66  		_, exists := targetUsers[targetUser.Id]
    67  		if !exists && targetUser.Id != args.UserId {
    68  			targetUsers[targetUser.Id] = targetUser
    69  			targetUsersSlice = append(targetUsersSlice, targetUser.Id)
    70  		}
    71  	}
    72  
    73  	if len(invalidUsernames) > 0 {
    74  		invalidUsersString := map[string]interface{}{
    75  			"Users": "@" + strings.Join(invalidUsernames, ", @"),
    76  		}
    77  		return &model.CommandResponse{
    78  			Text:         args.T("api.command_groupmsg.invalid_user.app_error", len(invalidUsernames), invalidUsersString),
    79  			ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL,
    80  		}
    81  	}
    82  
    83  	if len(targetUsersSlice) == 2 {
    84  		return GetCommandProvider("msg").DoCommand(a, args, fmt.Sprintf("%s %s", targetUsers[targetUsersSlice[1]].Username, parsedMessage))
    85  	}
    86  
    87  	if len(targetUsersSlice) < model.CHANNEL_GROUP_MIN_USERS {
    88  		minUsers := map[string]interface{}{
    89  			"MinUsers": model.CHANNEL_GROUP_MIN_USERS - 1,
    90  		}
    91  		return &model.CommandResponse{
    92  			Text:         args.T("api.command_groupmsg.min_users.app_error", minUsers),
    93  			ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL,
    94  		}
    95  	}
    96  
    97  	if len(targetUsersSlice) > model.CHANNEL_GROUP_MAX_USERS {
    98  		maxUsers := map[string]interface{}{
    99  			"MaxUsers": model.CHANNEL_GROUP_MAX_USERS - 1,
   100  		}
   101  		return &model.CommandResponse{
   102  			Text:         args.T("api.command_groupmsg.max_users.app_error", maxUsers),
   103  			ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL,
   104  		}
   105  	}
   106  
   107  	var groupChannel *model.Channel
   108  	var channelErr *model.AppError
   109  
   110  	if a.HasPermissionTo(args.UserId, model.PERMISSION_CREATE_GROUP_CHANNEL) {
   111  		groupChannel, channelErr = a.CreateGroupChannel(targetUsersSlice, args.UserId)
   112  		if channelErr != nil {
   113  			mlog.Error(channelErr.Error())
   114  			return &model.CommandResponse{Text: args.T("api.command_groupmsg.group_fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
   115  		}
   116  	} else {
   117  		groupChannel, channelErr = a.GetGroupChannel(targetUsersSlice)
   118  		if channelErr != nil {
   119  			return &model.CommandResponse{Text: args.T("api.command_groupmsg.permission.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
   120  		}
   121  	}
   122  
   123  	if len(parsedMessage) > 0 {
   124  		post := &model.Post{}
   125  		post.Message = parsedMessage
   126  		post.ChannelId = groupChannel.Id
   127  		post.UserId = args.UserId
   128  		if _, err := a.CreatePostMissingChannel(post, true); err != nil {
   129  			return &model.CommandResponse{Text: args.T("api.command_groupmsg.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
   130  		}
   131  	}
   132  
   133  	team, err := a.GetTeam(args.TeamId)
   134  	if err != nil {
   135  		return &model.CommandResponse{Text: args.T("api.command_groupmsg.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
   136  	}
   137  
   138  	return &model.CommandResponse{GotoLocation: args.SiteURL + "/" + team.Name + "/channels/" + groupChannel.Name, Text: "", ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
   139  }
   140  
   141  func groupMsgUsernames(message string) ([]string, string) {
   142  	result := []string{}
   143  	resultMessage := ""
   144  	for idx, part := range strings.Split(message, ",") {
   145  		clean := strings.TrimPrefix(strings.TrimSpace(part), "@")
   146  		split := strings.Fields(clean)
   147  		if len(split) > 0 {
   148  			result = append(result, split[0])
   149  		}
   150  		if len(split) > 1 {
   151  			splitted := strings.SplitN(message, ",", idx+1)
   152  			resultMessage = strings.TrimPrefix(strings.TrimSpace(splitted[len(splitted)-1]), "@")
   153  			resultMessage = strings.TrimSpace(strings.TrimPrefix(resultMessage, split[0]))
   154  			break
   155  		}
   156  	}
   157  	return result, resultMessage
   158  }