github.com/jlevesy/mattermost-server@v5.3.2-0.20181003190404-7468f35cb0c8+incompatible/app/command_echo.go (about)

     1  // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package app
     5  
     6  import (
     7  	"fmt"
     8  	"strconv"
     9  	"strings"
    10  	"time"
    11  
    12  	"github.com/mattermost/mattermost-server/mlog"
    13  	"github.com/mattermost/mattermost-server/model"
    14  	goi18n "github.com/nicksnyder/go-i18n/i18n"
    15  )
    16  
    17  var echoSem chan bool
    18  
    19  type EchoProvider struct {
    20  }
    21  
    22  const (
    23  	CMD_ECHO = "echo"
    24  )
    25  
    26  func init() {
    27  	RegisterCommandProvider(&EchoProvider{})
    28  }
    29  
    30  func (me *EchoProvider) GetTrigger() string {
    31  	return CMD_ECHO
    32  }
    33  
    34  func (me *EchoProvider) GetCommand(a *App, T goi18n.TranslateFunc) *model.Command {
    35  	return &model.Command{
    36  		Trigger:          CMD_ECHO,
    37  		AutoComplete:     true,
    38  		AutoCompleteDesc: T("api.command_echo.desc"),
    39  		AutoCompleteHint: T("api.command_echo.hint"),
    40  		DisplayName:      T("api.command_echo.name"),
    41  	}
    42  }
    43  
    44  func (me *EchoProvider) DoCommand(a *App, args *model.CommandArgs, message string) *model.CommandResponse {
    45  	if len(message) == 0 {
    46  		return &model.CommandResponse{Text: args.T("api.command_echo.message.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
    47  	}
    48  
    49  	maxThreads := 100
    50  
    51  	delay := 0
    52  	if endMsg := strings.LastIndex(message, "\""); string(message[0]) == "\"" && endMsg > 1 {
    53  		if checkDelay, err := strconv.Atoi(strings.Trim(message[endMsg:], " \"")); err == nil {
    54  			delay = checkDelay
    55  		}
    56  		message = message[1:endMsg]
    57  	} else if strings.Contains(message, " ") {
    58  		delayIdx := strings.LastIndex(message, " ")
    59  		delayStr := strings.Trim(message[delayIdx:], " ")
    60  
    61  		if checkDelay, err := strconv.Atoi(delayStr); err == nil {
    62  			delay = checkDelay
    63  			message = message[:delayIdx]
    64  		}
    65  	}
    66  
    67  	if delay > 10000 {
    68  		return &model.CommandResponse{Text: args.T("api.command_echo.delay.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
    69  	}
    70  
    71  	if echoSem == nil {
    72  		// We want one additional thread allowed so we never reach channel lockup
    73  		echoSem = make(chan bool, maxThreads+1)
    74  	}
    75  
    76  	if len(echoSem) >= maxThreads {
    77  		return &model.CommandResponse{Text: args.T("api.command_echo.high_volume.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
    78  	}
    79  
    80  	echoSem <- true
    81  	a.Go(func() {
    82  		defer func() { <-echoSem }()
    83  		post := &model.Post{}
    84  		post.ChannelId = args.ChannelId
    85  		post.RootId = args.RootId
    86  		post.ParentId = args.ParentId
    87  		post.Message = message
    88  		post.UserId = args.UserId
    89  
    90  		time.Sleep(time.Duration(delay) * time.Second)
    91  
    92  		if _, err := a.CreatePostMissingChannel(post, true); err != nil {
    93  			mlog.Error(fmt.Sprintf("Unable to create /echo post, err=%v", err))
    94  		}
    95  	})
    96  
    97  	return &model.CommandResponse{}
    98  }