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