github.com/jfrerich/mattermost-server@v5.8.0-rc2+incompatible/cmd/mattermost/commands/webhook.go (about)

     1  // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package commands
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/mattermost/mattermost-server/model"
    11  	"github.com/pkg/errors"
    12  	"github.com/spf13/cobra"
    13  )
    14  
    15  var WebhookCmd = &cobra.Command{
    16  	Use:   "webhook",
    17  	Short: "Management of webhooks",
    18  }
    19  
    20  var WebhookListCmd = &cobra.Command{
    21  	Use:     "list",
    22  	Short:   "List webhooks",
    23  	Long:    "list all webhooks",
    24  	Example: "  webhook list myteam",
    25  	RunE:    listWebhookCmdF,
    26  }
    27  
    28  var WebhookCreateIncomingCmd = &cobra.Command{
    29  	Use:     "create-incoming",
    30  	Short:   "Create incoming webhook",
    31  	Long:    "create incoming webhook which allows external posting of messages to specific channel",
    32  	Example: "  webhook create-incoming --channel [channelID] --user [userID] --display-name [displayName] --description [webhookDescription] --lock-to-channel --icon [iconURL]",
    33  	RunE:    createIncomingWebhookCmdF,
    34  }
    35  
    36  var WebhookModifyIncomingCmd = &cobra.Command{
    37  	Use:     "modify-incoming",
    38  	Short:   "Modify incoming webhook",
    39  	Long:    "Modify existing incoming webhook by changing its title, description, channel or icon url",
    40  	Example: "  webhook modify-incoming [webhookID] --channel [channelID] --display-name [displayName] --description [webhookDescription] --lock-to-channel --icon [iconURL]",
    41  	RunE:    modifyIncomingWebhookCmdF,
    42  }
    43  
    44  var WebhookCreateOutgoingCmd = &cobra.Command{
    45  	Use:   "create-outgoing",
    46  	Short: "Create outgoing webhook",
    47  	Long:  "create outgoing webhook which allows external posting of messages from a specific channel",
    48  	Example: `  webhook create-outgoing --team myteam --user myusername --display-name mywebhook --trigger-word "build" --trigger-word "test" --url http://localhost:8000/my-webhook-handler
    49  	webhook create-outgoing --team myteam --channel mychannel --user myusername --display-name mywebhook --description "My cool webhook" --trigger-when start --trigger-word build --trigger-word test --icon http://localhost:8000/my-slash-handler-bot-icon.png --url http://localhost:8000/my-webhook-handler --content-type "application/json"`,
    50  	RunE: createOutgoingWebhookCmdF,
    51  }
    52  
    53  var WebhookModifyOutgoingCmd = &cobra.Command{
    54  	Use:     "modify-outgoing",
    55  	Short:   "Modify outgoing webhook",
    56  	Long:    "Modify existing outgoing webhook by changing its title, description, channel, icon, url, content-type, and triggers",
    57  	Example: `  webhook modify-outgoing [webhookId] --channel [channelId] --display-name [displayName] --description "New webhook description" --icon http://localhost:8000/my-slash-handler-bot-icon.png --url http://localhost:8000/my-webhook-handler --content-type "application/json" --trigger-word test --trigger-when start`,
    58  	RunE:    modifyOutgoingWebhookCmdF,
    59  }
    60  
    61  var WebhookDeleteCmd = &cobra.Command{
    62  	Use:     "delete",
    63  	Short:   "Delete webhooks",
    64  	Long:    "Delete webhook with given id",
    65  	Example: "  webhook delete [webhookID]",
    66  	RunE:    deleteWebhookCmdF,
    67  }
    68  
    69  func listWebhookCmdF(command *cobra.Command, args []string) error {
    70  	app, err := InitDBCommandContextCobra(command)
    71  	if err != nil {
    72  		return err
    73  	}
    74  	defer app.Shutdown()
    75  
    76  	var teams []*model.Team
    77  	if len(args) < 1 {
    78  		var getErr *model.AppError
    79  		// If no team is specified, list all teams
    80  		teams, getErr = app.GetAllTeams()
    81  		if getErr != nil {
    82  			return getErr
    83  		}
    84  	} else {
    85  		teams = getTeamsFromTeamArgs(app, args)
    86  	}
    87  
    88  	for i, team := range teams {
    89  		if team == nil {
    90  			CommandPrintErrorln("Unable to find team '" + args[i] + "'")
    91  			continue
    92  		}
    93  
    94  		// Fetch all hooks with a very large limit so we get them all.
    95  		incomingResult := app.Srv.Store.Webhook().GetIncomingByTeam(team.Id, 0, 100000000)
    96  		outgoingResult := app.Srv.Store.Webhook().GetOutgoingByTeam(team.Id, 0, 100000000)
    97  
    98  		if result := <-incomingResult; result.Err == nil {
    99  			CommandPrettyPrintln(fmt.Sprintf("Incoming webhooks for %s (%s):", team.DisplayName, team.Name))
   100  			hooks := result.Data.([]*model.IncomingWebhook)
   101  			for _, hook := range hooks {
   102  				CommandPrettyPrintln("\t" + hook.DisplayName + " (" + hook.Id + ")")
   103  			}
   104  		} else {
   105  			CommandPrintErrorln("Unable to list incoming webhooks for '" + args[i] + "'")
   106  		}
   107  
   108  		if result := <-outgoingResult; result.Err == nil {
   109  			hooks := result.Data.([]*model.OutgoingWebhook)
   110  			CommandPrettyPrintln(fmt.Sprintf("Outgoing webhooks for %s (%s):", team.DisplayName, team.Name))
   111  			for _, hook := range hooks {
   112  				CommandPrettyPrintln("\t" + hook.DisplayName + " (" + hook.Id + ")")
   113  			}
   114  		} else {
   115  			CommandPrintErrorln("Unable to list outgoing webhooks for '" + args[i] + "'")
   116  		}
   117  	}
   118  	return nil
   119  }
   120  
   121  func createIncomingWebhookCmdF(command *cobra.Command, args []string) error {
   122  	app, err := InitDBCommandContextCobra(command)
   123  	if err != nil {
   124  		return err
   125  	}
   126  	defer app.Shutdown()
   127  
   128  	channelArg, errChannel := command.Flags().GetString("channel")
   129  	if errChannel != nil || channelArg == "" {
   130  		return errors.New("Channel is required")
   131  	}
   132  	channel := getChannelFromChannelArg(app, channelArg)
   133  	if channel == nil {
   134  		return errors.New("Unable to find channel '" + channelArg + "'")
   135  	}
   136  
   137  	userArg, errUser := command.Flags().GetString("user")
   138  	if errUser != nil || userArg == "" {
   139  		return errors.New("User is required")
   140  	}
   141  	user := getUserFromUserArg(app, userArg)
   142  	if user == nil {
   143  		return errors.New("Unable to find user '" + userArg + "'")
   144  	}
   145  
   146  	displayName, _ := command.Flags().GetString("display-name")
   147  	description, _ := command.Flags().GetString("description")
   148  	iconURL, _ := command.Flags().GetString("icon")
   149  	channelLocked, _ := command.Flags().GetBool("lock-to-channel")
   150  
   151  	incomingWebhook := &model.IncomingWebhook{
   152  		ChannelId:     channel.Id,
   153  		DisplayName:   displayName,
   154  		Description:   description,
   155  		IconURL:       iconURL,
   156  		ChannelLocked: channelLocked,
   157  	}
   158  
   159  	createdIncoming, errIncomingWebhook := app.CreateIncomingWebhookForChannel(user.Id, channel, incomingWebhook)
   160  	if errIncomingWebhook != nil {
   161  		return errIncomingWebhook
   162  	}
   163  
   164  	CommandPrettyPrintln("Id: " + createdIncoming.Id)
   165  	CommandPrettyPrintln("Display Name: " + createdIncoming.DisplayName)
   166  
   167  	return nil
   168  }
   169  
   170  func modifyIncomingWebhookCmdF(command *cobra.Command, args []string) error {
   171  	app, err := InitDBCommandContextCobra(command)
   172  	if err != nil {
   173  		return err
   174  	}
   175  	defer app.Shutdown()
   176  
   177  	if len(args) < 1 {
   178  		return errors.New("WebhookID is not specified")
   179  	}
   180  
   181  	webhookArg := args[0]
   182  	oldHook, getErr := app.GetIncomingWebhook(webhookArg)
   183  	if getErr != nil {
   184  		return errors.New("Unable to find webhook '" + webhookArg + "'")
   185  	}
   186  
   187  	updatedHook := oldHook
   188  
   189  	channelArg, _ := command.Flags().GetString("channel")
   190  	if channelArg != "" {
   191  		channel := getChannelFromChannelArg(app, channelArg)
   192  		if channel == nil {
   193  			return errors.New("Unable to find channel '" + channelArg + "'")
   194  		}
   195  		updatedHook.ChannelId = channel.Id
   196  	}
   197  
   198  	displayName, _ := command.Flags().GetString("display-name")
   199  	if displayName != "" {
   200  		updatedHook.DisplayName = displayName
   201  	}
   202  	description, _ := command.Flags().GetString("description")
   203  	if description != "" {
   204  		updatedHook.Description = description
   205  	}
   206  	iconUrl, _ := command.Flags().GetString("icon")
   207  	if iconUrl != "" {
   208  		updatedHook.IconURL = iconUrl
   209  	}
   210  	channelLocked, _ := command.Flags().GetBool("lock-to-channel")
   211  	updatedHook.ChannelLocked = channelLocked
   212  
   213  	if _, err := app.UpdateIncomingWebhook(oldHook, updatedHook); err != nil {
   214  		return err
   215  	}
   216  
   217  	return nil
   218  }
   219  
   220  func createOutgoingWebhookCmdF(command *cobra.Command, args []string) error {
   221  	app, err := InitDBCommandContextCobra(command)
   222  	if err != nil {
   223  		return err
   224  	}
   225  	defer app.Shutdown()
   226  
   227  	teamArg, errTeam := command.Flags().GetString("team")
   228  	if errTeam != nil || teamArg == "" {
   229  		return errors.New("Team is required")
   230  	}
   231  	team := getTeamFromTeamArg(app, teamArg)
   232  	if team == nil {
   233  		return errors.New("Unable to find team: " + teamArg)
   234  	}
   235  
   236  	userArg, errUser := command.Flags().GetString("user")
   237  	if errUser != nil || userArg == "" {
   238  		return errors.New("User is required")
   239  	}
   240  	user := getUserFromUserArg(app, userArg)
   241  	if user == nil {
   242  		return errors.New("Unable to find user: " + userArg)
   243  	}
   244  
   245  	displayName, errName := command.Flags().GetString("display-name")
   246  	if errName != nil || displayName == "" {
   247  		return errors.New("Display name is required")
   248  	}
   249  
   250  	triggerWords, errWords := command.Flags().GetStringArray("trigger-word")
   251  	if errWords != nil || len(triggerWords) == 0 {
   252  		return errors.New("Trigger word or words required")
   253  	}
   254  
   255  	callbackURLs, errURL := command.Flags().GetStringArray("url")
   256  	if errURL != nil || len(callbackURLs) == 0 {
   257  		return errors.New("Callback URL or URLs required")
   258  	}
   259  
   260  	triggerWhenString, _ := command.Flags().GetString("trigger-when")
   261  	var triggerWhen int
   262  	if triggerWhenString == "exact" {
   263  		triggerWhen = 0
   264  	} else if triggerWhenString == "start" {
   265  		triggerWhen = 1
   266  	} else {
   267  		return errors.New("Invalid trigger when parameter")
   268  	}
   269  	description, _ := command.Flags().GetString("description")
   270  	contentType, _ := command.Flags().GetString("content-type")
   271  	iconURL, _ := command.Flags().GetString("icon")
   272  
   273  	outgoingWebhook := &model.OutgoingWebhook{
   274  		CreatorId:    user.Id,
   275  		Username:     user.Username,
   276  		TeamId:       team.Id,
   277  		TriggerWords: triggerWords,
   278  		TriggerWhen:  triggerWhen,
   279  		CallbackURLs: callbackURLs,
   280  		DisplayName:  displayName,
   281  		Description:  description,
   282  		ContentType:  contentType,
   283  		IconURL:      iconURL,
   284  	}
   285  
   286  	channelArg, _ := command.Flags().GetString("channel")
   287  	if channelArg != "" {
   288  		channel := getChannelFromChannelArg(app, channelArg)
   289  		if channel != nil {
   290  			outgoingWebhook.ChannelId = channel.Id
   291  		}
   292  	}
   293  
   294  	createdOutgoing, errOutgoing := app.CreateOutgoingWebhook(outgoingWebhook)
   295  	if errOutgoing != nil {
   296  		return errOutgoing
   297  	}
   298  
   299  	CommandPrettyPrintln("Id: " + createdOutgoing.Id)
   300  	CommandPrettyPrintln("Display Name: " + createdOutgoing.DisplayName)
   301  
   302  	return nil
   303  }
   304  
   305  func modifyOutgoingWebhookCmdF(command *cobra.Command, args []string) error {
   306  	app, err := InitDBCommandContextCobra(command)
   307  	if err != nil {
   308  		return err
   309  	}
   310  	defer app.Shutdown()
   311  
   312  	if len(args) < 1 {
   313  		return errors.New("WebhookID is not specified")
   314  	}
   315  
   316  	webhookArg := args[0]
   317  	oldHook, appErr := app.GetOutgoingWebhook(webhookArg)
   318  	if appErr != nil {
   319  		return fmt.Errorf("unable to find webhook '%s'", webhookArg)
   320  	}
   321  
   322  	updatedHook := model.OutgoingWebhookFromJson(strings.NewReader(oldHook.ToJson()))
   323  
   324  	channelArg, _ := command.Flags().GetString("channel")
   325  	if channelArg != "" {
   326  		channel := getChannelFromChannelArg(app, channelArg)
   327  		if channel == nil {
   328  			return fmt.Errorf("unable to find channel '%s'", channelArg)
   329  		}
   330  		updatedHook.ChannelId = channel.Id
   331  	}
   332  
   333  	displayName, _ := command.Flags().GetString("display-name")
   334  	if displayName != "" {
   335  		updatedHook.DisplayName = displayName
   336  	}
   337  
   338  	description, _ := command.Flags().GetString("description")
   339  	if description != "" {
   340  		updatedHook.Description = description
   341  	}
   342  
   343  	triggerWords, err := command.Flags().GetStringArray("trigger-word")
   344  	if err != nil {
   345  		return errors.Wrap(err, "invalid trigger-word parameter")
   346  	}
   347  	if len(triggerWords) > 0 {
   348  		updatedHook.TriggerWords = triggerWords
   349  	}
   350  
   351  	triggerWhenString, _ := command.Flags().GetString("trigger-when")
   352  	if triggerWhenString != "" {
   353  		var triggerWhen int
   354  		if triggerWhenString == "exact" {
   355  			triggerWhen = 0
   356  		} else if triggerWhenString == "start" {
   357  			triggerWhen = 1
   358  		} else {
   359  			return errors.New("invalid trigger-when parameter")
   360  		}
   361  		updatedHook.TriggerWhen = triggerWhen
   362  	}
   363  
   364  	iconURL, _ := command.Flags().GetString("icon")
   365  	if iconURL != "" {
   366  		updatedHook.IconURL = iconURL
   367  	}
   368  
   369  	contentType, _ := command.Flags().GetString("content-type")
   370  	if contentType != "" {
   371  		updatedHook.ContentType = contentType
   372  	}
   373  
   374  	callbackURLs, err := command.Flags().GetStringArray("url")
   375  	if err != nil {
   376  		return errors.Wrap(err, "invalid URL parameter")
   377  	}
   378  	if len(callbackURLs) > 0 {
   379  		updatedHook.CallbackURLs = callbackURLs
   380  	}
   381  
   382  	if _, appErr := app.UpdateOutgoingWebhook(oldHook, updatedHook); appErr != nil {
   383  		return appErr
   384  	}
   385  
   386  	return nil
   387  }
   388  
   389  func deleteWebhookCmdF(command *cobra.Command, args []string) error {
   390  	app, err := InitDBCommandContextCobra(command)
   391  	if err != nil {
   392  		return err
   393  	}
   394  	defer app.Shutdown()
   395  
   396  	if len(args) < 1 {
   397  		return errors.New("WebhookID is not specified")
   398  	}
   399  
   400  	webhookId := args[0]
   401  	errIncomingWebhook := app.DeleteIncomingWebhook(webhookId)
   402  	errOutgoingWebhook := app.DeleteOutgoingWebhook(webhookId)
   403  
   404  	if errIncomingWebhook != nil && errOutgoingWebhook != nil {
   405  		return errors.New("Unable to delete webhook '" + webhookId + "'")
   406  	}
   407  
   408  	return nil
   409  }
   410  
   411  func init() {
   412  	WebhookCreateIncomingCmd.Flags().String("channel", "", "Channel ID (required)")
   413  	WebhookCreateIncomingCmd.Flags().String("user", "", "User ID (required)")
   414  	WebhookCreateIncomingCmd.Flags().String("display-name", "", "Incoming webhook display name")
   415  	WebhookCreateIncomingCmd.Flags().String("description", "", "Incoming webhook description")
   416  	WebhookCreateIncomingCmd.Flags().String("icon", "", "Icon URL")
   417  	WebhookCreateIncomingCmd.Flags().Bool("lock-to-channel", false, "Lock to channel")
   418  
   419  	WebhookModifyIncomingCmd.Flags().String("channel", "", "Channel ID")
   420  	WebhookModifyIncomingCmd.Flags().String("display-name", "", "Incoming webhook display name")
   421  	WebhookModifyIncomingCmd.Flags().String("description", "", "Incoming webhook description")
   422  	WebhookModifyIncomingCmd.Flags().String("icon", "", "Icon URL")
   423  	WebhookModifyIncomingCmd.Flags().Bool("lock-to-channel", false, "Lock to channel")
   424  
   425  	WebhookCreateOutgoingCmd.Flags().String("team", "", "Team name or ID (required)")
   426  	WebhookCreateOutgoingCmd.Flags().String("channel", "", "Channel name or ID")
   427  	WebhookCreateOutgoingCmd.Flags().String("user", "", "User username, email, or ID (required)")
   428  	WebhookCreateOutgoingCmd.Flags().String("display-name", "", "Outgoing webhook display name (required)")
   429  	WebhookCreateOutgoingCmd.Flags().String("description", "", "Outgoing webhook description")
   430  	WebhookCreateOutgoingCmd.Flags().StringArray("trigger-word", []string{}, "Word to trigger webhook (required)")
   431  	WebhookCreateOutgoingCmd.Flags().String("trigger-when", "exact", "When to trigger webhook (exact: for first word matches a trigger word exactly, start: for first word starts with a trigger word)")
   432  	WebhookCreateOutgoingCmd.Flags().String("icon", "", "Icon URL")
   433  	WebhookCreateOutgoingCmd.Flags().StringArray("url", []string{}, "Callback URL (required)")
   434  	WebhookCreateOutgoingCmd.Flags().String("content-type", "", "Content-type")
   435  
   436  	WebhookModifyOutgoingCmd.Flags().String("channel", "", "Channel name or ID")
   437  	WebhookModifyOutgoingCmd.Flags().String("display-name", "", "Outgoing webhook display name")
   438  	WebhookModifyOutgoingCmd.Flags().String("description", "", "Outgoing webhook description")
   439  	WebhookModifyOutgoingCmd.Flags().StringArray("trigger-word", []string{}, "Word to trigger webhook")
   440  	WebhookModifyOutgoingCmd.Flags().String("trigger-when", "", "When to trigger webhook (exact: for first word matches a trigger word exactly, start: for first word starts with a trigger word)")
   441  	WebhookModifyOutgoingCmd.Flags().String("icon", "", "Icon URL")
   442  	WebhookModifyOutgoingCmd.Flags().StringArray("url", []string{}, "Callback URL")
   443  	WebhookModifyOutgoingCmd.Flags().String("content-type", "", "Content-type")
   444  
   445  	WebhookCmd.AddCommand(
   446  		WebhookListCmd,
   447  		WebhookCreateIncomingCmd,
   448  		WebhookModifyIncomingCmd,
   449  		WebhookCreateOutgoingCmd,
   450  		WebhookModifyOutgoingCmd,
   451  		WebhookDeleteCmd,
   452  	)
   453  
   454  	RootCmd.AddCommand(WebhookCmd)
   455  }