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