diff --git a/app/plugin_api.go b/app/plugin_api.go index 2a3779bca6..76e82004b3 100644 --- a/app/plugin_api.go +++ b/app/plugin_api.go @@ -16,6 +16,7 @@ import ( "github.com/mattermost/mattermost-server/v5/mlog" "github.com/mattermost/mattermost-server/v5/model" + "github.com/mattermost/mattermost-server/v5/utils" ) type PluginAPI struct { @@ -70,6 +71,20 @@ func (api *PluginAPI) UnregisterCommand(teamId, trigger string) error { return nil } +func (api *PluginAPI) ExecuteSlashCommand(commandArgs *model.CommandArgs) (*model.CommandResponse, error) { + user, appErr := api.app.GetUser(commandArgs.UserId) + if appErr != nil { + return nil, appErr + } + commandArgs.T = utils.GetUserTranslations(user.Locale) + commandArgs.SiteURL = api.app.GetSiteURL() + response, appErr := api.app.ExecuteCommand(commandArgs) + if appErr != nil { + return response, appErr + } + return response, nil +} + func (api *PluginAPI) GetSession(sessionId string) (*model.Session, *model.AppError) { session, err := api.app.GetSessionById(sessionId) diff --git a/app/plugin_api_test.go b/app/plugin_api_test.go index 4df144db46..edd4e47b68 100644 --- a/app/plugin_api_test.go +++ b/app/plugin_api_test.go @@ -1663,6 +1663,27 @@ func TestPluginHTTPUpgradeWebSocket(t *testing.T) { } } +func TestPluginExecuteSlashCommand(t *testing.T) { + th := Setup(t).InitBasic() + defer th.TearDown() + api := th.SetupPluginAPI() + + newUser := th.CreateUser() + th.LinkUserToTeam(newUser, th.BasicTeam) + + t.Run("run invite command", func(t *testing.T) { + _, err := api.ExecuteSlashCommand(&model.CommandArgs{ + Command: "/invite @" + newUser.Username, + TeamId: th.BasicTeam.Id, + UserId: th.BasicUser.Id, + ChannelId: th.BasicChannel.Id, + }) + require.NoError(t, err) + _, err2 := th.App.GetChannelMember(th.BasicChannel.Id, newUser.Id) + require.Nil(t, err2) + }) +} + func TestPluginAPISearchPostsInTeamByUser(t *testing.T) { th := Setup(t).InitBasic() defer th.TearDown() diff --git a/plugin/api.go b/plugin/api.go index 049f62ce0e..a6e498cff5 100644 --- a/plugin/api.go +++ b/plugin/api.go @@ -37,6 +37,12 @@ type API interface { // Minimum server version: 5.2 UnregisterCommand(teamId, trigger string) error + // ExecuteSlashCommand executes a slash command with the given parameters. + // + // @tag Command + // Minimum server version: 5.26 + ExecuteSlashCommand(commandArgs *model.CommandArgs) (*model.CommandResponse, error) + // GetSession returns the session object for the Session ID // // Minimum server version: 5.2 diff --git a/plugin/api_timer_layer_generated.go b/plugin/api_timer_layer_generated.go index 0fee0f0814..73204ef053 100644 --- a/plugin/api_timer_layer_generated.go +++ b/plugin/api_timer_layer_generated.go @@ -49,6 +49,13 @@ func (api *apiTimerLayer) UnregisterCommand(teamId, trigger string) error { return _returnsA } +func (api *apiTimerLayer) ExecuteSlashCommand(commandArgs *model.CommandArgs) (*model.CommandResponse, error) { + startTime := timePkg.Now() + _returnsA, _returnsB := api.apiImpl.ExecuteSlashCommand(commandArgs) + api.recordTime(startTime, "ExecuteSlashCommand", _returnsB == nil) + return _returnsA, _returnsB +} + func (api *apiTimerLayer) GetSession(sessionId string) (*model.Session, *model.AppError) { startTime := timePkg.Now() _returnsA, _returnsB := api.apiImpl.GetSession(sessionId) diff --git a/plugin/client_rpc_generated.go b/plugin/client_rpc_generated.go index d759595647..fdc1a09b9b 100644 --- a/plugin/client_rpc_generated.go +++ b/plugin/client_rpc_generated.go @@ -523,6 +523,36 @@ func (s *apiRPCServer) UnregisterCommand(args *Z_UnregisterCommandArgs, returns return nil } +type Z_ExecuteSlashCommandArgs struct { + A *model.CommandArgs +} + +type Z_ExecuteSlashCommandReturns struct { + A *model.CommandResponse + B error +} + +func (g *apiRPCClient) ExecuteSlashCommand(commandArgs *model.CommandArgs) (*model.CommandResponse, error) { + _args := &Z_ExecuteSlashCommandArgs{commandArgs} + _returns := &Z_ExecuteSlashCommandReturns{} + if err := g.client.Call("Plugin.ExecuteSlashCommand", _args, _returns); err != nil { + log.Printf("RPC call to ExecuteSlashCommand API failed: %s", err.Error()) + } + return _returns.A, _returns.B +} + +func (s *apiRPCServer) ExecuteSlashCommand(args *Z_ExecuteSlashCommandArgs, returns *Z_ExecuteSlashCommandReturns) error { + if hook, ok := s.impl.(interface { + ExecuteSlashCommand(commandArgs *model.CommandArgs) (*model.CommandResponse, error) + }); ok { + returns.A, returns.B = hook.ExecuteSlashCommand(args.A) + returns.B = encodableError(returns.B) + } else { + return encodableError(fmt.Errorf("API ExecuteSlashCommand called but not implemented.")) + } + return nil +} + type Z_GetSessionArgs struct { A string } diff --git a/plugin/plugintest/api.go b/plugin/plugintest/api.go index b7fff88f5d..191c0cc4e3 100644 --- a/plugin/plugintest/api.go +++ b/plugin/plugintest/api.go @@ -483,6 +483,29 @@ func (_m *API) EnablePlugin(id string) *model.AppError { return r0 } +// ExecuteSlashCommand provides a mock function with given fields: commandArgs +func (_m *API) ExecuteSlashCommand(commandArgs *model.CommandArgs) (*model.CommandResponse, error) { + ret := _m.Called(commandArgs) + + var r0 *model.CommandResponse + if rf, ok := ret.Get(0).(func(*model.CommandArgs) *model.CommandResponse); ok { + r0 = rf(commandArgs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.CommandResponse) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*model.CommandArgs) error); ok { + r1 = rf(commandArgs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetBot provides a mock function with given fields: botUserId, includeDeleted func (_m *API) GetBot(botUserId string, includeDeleted bool) (*model.Bot, *model.AppError) { ret := _m.Called(botUserId, includeDeleted)