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 }