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