MM-12369 Add Create Outgoing Webhook Command (#9779)
* add create outgoing webhook command * add create outgoing webhook command
Этот коммит содержится в:
коммит произвёл
Joram Wilander
родитель
04a6a779e2
Коммит
c155359e58
@@ -5,6 +5,7 @@ package commands
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/model"
|
"github.com/mattermost/mattermost-server/model"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -40,6 +41,15 @@ var WebhookModifyIncomingCmd = &cobra.Command{
|
|||||||
RunE: modifyIncomingWebhookCmdF,
|
RunE: modifyIncomingWebhookCmdF,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var WebhookCreateOutgoingCmd = &cobra.Command{
|
||||||
|
Use: "create-outgoing",
|
||||||
|
Short: "Create outgoing webhook",
|
||||||
|
Long: "create outgoing webhook which allows external posting of messages from a specific channel",
|
||||||
|
Example: ` webhook create-outgoing --team myteam --user myusername --display-name mywebhook --trigger-words "build\ntest" --urls http://localhost:8000/my-webhook-handler
|
||||||
|
webhook create-outgoing --team myteam --channel mychannel --user myusername --display-name mywebhook --description "My cool webhook" --trigger-when 1 --trigger-words "build\ntest" --icon http://localhost:8000/my-slash-handler-bot-icon.png --urls http://localhost:8000/my-webhook-handler --content-type "application/json"`,
|
||||||
|
RunE: createOutgoingWebhookCmdF,
|
||||||
|
}
|
||||||
|
|
||||||
func listWebhookCmdF(command *cobra.Command, args []string) error {
|
func listWebhookCmdF(command *cobra.Command, args []string) error {
|
||||||
app, err := InitDBCommandContextCobra(command)
|
app, err := InitDBCommandContextCobra(command)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -177,6 +187,81 @@ func modifyIncomingWebhookCmdF(command *cobra.Command, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createOutgoingWebhookCmdF(command *cobra.Command, args []string) error {
|
||||||
|
app, err := InitDBCommandContextCobra(command)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer app.Shutdown()
|
||||||
|
|
||||||
|
teamArg, errTeam := command.Flags().GetString("team")
|
||||||
|
if errTeam != nil || teamArg == "" {
|
||||||
|
return errors.New("Team is required")
|
||||||
|
}
|
||||||
|
team := getTeamFromTeamArg(app, teamArg)
|
||||||
|
if team == nil {
|
||||||
|
return errors.New("Unable to find team: " + teamArg)
|
||||||
|
}
|
||||||
|
|
||||||
|
userArg, errUser := command.Flags().GetString("user")
|
||||||
|
if errUser != nil || userArg == "" {
|
||||||
|
return errors.New("User is required")
|
||||||
|
}
|
||||||
|
user := getUserFromUserArg(app, userArg)
|
||||||
|
if user == nil {
|
||||||
|
return errors.New("Unable to find user: " + userArg)
|
||||||
|
}
|
||||||
|
|
||||||
|
displayName, errName := command.Flags().GetString("display-name")
|
||||||
|
if errName != nil || displayName == "" {
|
||||||
|
return errors.New("Display name is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerWordsString, errWords := command.Flags().GetString("trigger-words")
|
||||||
|
if errWords != nil || triggerWordsString == "" {
|
||||||
|
return errors.New("Trigger word or words required")
|
||||||
|
}
|
||||||
|
triggerWords := strings.Split(triggerWordsString, "\n")
|
||||||
|
|
||||||
|
callbackURLsString, errURL := command.Flags().GetString("urls")
|
||||||
|
if errURL != nil || callbackURLsString == "" {
|
||||||
|
return errors.New("Callback URL or URLs required")
|
||||||
|
}
|
||||||
|
callbackURLs := strings.Split(callbackURLsString, "\n")
|
||||||
|
|
||||||
|
triggerWhen, _ := command.Flags().GetInt("trigger-when")
|
||||||
|
description, _ := command.Flags().GetString("description")
|
||||||
|
contentType, _ := command.Flags().GetString("content-type")
|
||||||
|
iconURL, _ := command.Flags().GetString("icon")
|
||||||
|
|
||||||
|
outgoingWebhook := &model.OutgoingWebhook{
|
||||||
|
CreatorId: user.Id,
|
||||||
|
Username: user.Username,
|
||||||
|
TeamId: team.Id,
|
||||||
|
TriggerWords: triggerWords,
|
||||||
|
TriggerWhen: triggerWhen,
|
||||||
|
CallbackURLs: callbackURLs,
|
||||||
|
DisplayName: displayName,
|
||||||
|
Description: description,
|
||||||
|
ContentType: contentType,
|
||||||
|
IconURL: iconURL,
|
||||||
|
}
|
||||||
|
|
||||||
|
channelArg, _ := command.Flags().GetString("channel")
|
||||||
|
if channelArg != "" {
|
||||||
|
channel := getChannelFromChannelArg(app, channelArg)
|
||||||
|
if channel != nil {
|
||||||
|
outgoingWebhook.ChannelId = channel.Id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := app.CreateOutgoingWebhook(outgoingWebhook); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
WebhookCreateIncomingCmd.Flags().String("channel", "", "Channel ID")
|
WebhookCreateIncomingCmd.Flags().String("channel", "", "Channel ID")
|
||||||
WebhookCreateIncomingCmd.Flags().String("user", "", "User ID")
|
WebhookCreateIncomingCmd.Flags().String("user", "", "User ID")
|
||||||
@@ -191,10 +276,22 @@ func init() {
|
|||||||
WebhookModifyIncomingCmd.Flags().String("icon", "", "Icon URL")
|
WebhookModifyIncomingCmd.Flags().String("icon", "", "Icon URL")
|
||||||
WebhookModifyIncomingCmd.Flags().Bool("lock-to-channel", false, "Lock to channel")
|
WebhookModifyIncomingCmd.Flags().Bool("lock-to-channel", false, "Lock to channel")
|
||||||
|
|
||||||
|
WebhookCreateOutgoingCmd.Flags().String("team", "", "Team name or ID (required)")
|
||||||
|
WebhookCreateOutgoingCmd.Flags().String("channel", "", "Channel name or ID")
|
||||||
|
WebhookCreateOutgoingCmd.Flags().String("user", "", "User username, email, or ID (required)")
|
||||||
|
WebhookCreateOutgoingCmd.Flags().String("display-name", "", "Outgoing webhook display name (required)")
|
||||||
|
WebhookCreateOutgoingCmd.Flags().String("description", "", "Outgoing webhook description")
|
||||||
|
WebhookCreateOutgoingCmd.Flags().String("trigger-words", "", "Words to trigger webhook (word1\nword2) (required)")
|
||||||
|
WebhookCreateOutgoingCmd.Flags().Int("trigger-when", 0, "When to trigger webhook (either when trigger word is first (enter 1) or when it's anywhere (enter 0))")
|
||||||
|
WebhookCreateOutgoingCmd.Flags().String("icon", "", "Icon URL")
|
||||||
|
WebhookCreateOutgoingCmd.Flags().String("urls", "", "Callback URLs (url1\nurl2) (required)")
|
||||||
|
WebhookCreateOutgoingCmd.Flags().String("content-type", "", "Content-type")
|
||||||
|
|
||||||
WebhookCmd.AddCommand(
|
WebhookCmd.AddCommand(
|
||||||
WebhookListCmd,
|
WebhookListCmd,
|
||||||
WebhookCreateIncomingCmd,
|
WebhookCreateIncomingCmd,
|
||||||
WebhookModifyIncomingCmd,
|
WebhookModifyIncomingCmd,
|
||||||
|
WebhookCreateOutgoingCmd,
|
||||||
)
|
)
|
||||||
|
|
||||||
RootCmd.AddCommand(WebhookCmd)
|
RootCmd.AddCommand(WebhookCmd)
|
||||||
|
|||||||
@@ -116,9 +116,9 @@ func TestModifyIncomingWebhook(t *testing.T) {
|
|||||||
displayName := "myhookincname"
|
displayName := "myhookincname"
|
||||||
|
|
||||||
incomingWebhook := &model.IncomingWebhook{
|
incomingWebhook := &model.IncomingWebhook{
|
||||||
ChannelId: th.BasicChannel.Id,
|
ChannelId: th.BasicChannel.Id,
|
||||||
DisplayName: displayName,
|
DisplayName: displayName,
|
||||||
Description: description,
|
Description: description,
|
||||||
}
|
}
|
||||||
|
|
||||||
oldHook, err := th.App.CreateIncomingWebhookForChannel(th.BasicUser.Id, th.BasicChannel, incomingWebhook)
|
oldHook, err := th.App.CreateIncomingWebhookForChannel(th.BasicUser.Id, th.BasicChannel, incomingWebhook)
|
||||||
@@ -150,3 +150,62 @@ func TestModifyIncomingWebhook(t *testing.T) {
|
|||||||
t.Fatal("Failed to update incoming webhook")
|
t.Fatal("Failed to update incoming webhook")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateOutgoingWebhook(t *testing.T) {
|
||||||
|
th := api4.Setup().InitBasic().InitSystemAdmin()
|
||||||
|
defer th.TearDown()
|
||||||
|
|
||||||
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
|
||||||
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
|
||||||
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostUsernameOverride = true })
|
||||||
|
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostIconOverride = true })
|
||||||
|
|
||||||
|
defaultRolePermissions := th.SaveDefaultRolePermissions()
|
||||||
|
defer func() {
|
||||||
|
th.RestoreDefaultRolePermissions(defaultRolePermissions)
|
||||||
|
}()
|
||||||
|
th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
|
||||||
|
th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
|
||||||
|
|
||||||
|
// team, user, display name, trigger words, callback urls are required
|
||||||
|
team := th.BasicTeam.Id
|
||||||
|
user := th.BasicUser.Id
|
||||||
|
displayName := "totally radical webhook"
|
||||||
|
triggerWords := "build\ndefenestrate"
|
||||||
|
callbackURLs := "http://localhost:8000/my-webhook-handler\nhttp://localhost:8000/my-webhook-handler2"
|
||||||
|
|
||||||
|
// should fail because team is not specified
|
||||||
|
require.Error(t, RunCommand(t, "webhook", "create-outgoing", "--display-name", displayName, "--trigger-words", triggerWords, "--urls", callbackURLs, "--user", user))
|
||||||
|
|
||||||
|
// should fail because user is not specified
|
||||||
|
require.Error(t, RunCommand(t, "webhook", "create-outgoing", "--team", team, "--display-name", displayName, "--trigger-words", triggerWords, "--urls", callbackURLs))
|
||||||
|
|
||||||
|
// should fail because display name is not specified
|
||||||
|
require.Error(t, RunCommand(t, "webhook", "create-outgoing", "--team", team, "--trigger-words", triggerWords, "--urls", callbackURLs, "--user", user))
|
||||||
|
|
||||||
|
// should fail because trigger words are not specified
|
||||||
|
require.Error(t, RunCommand(t, "webhook", "create-outgoing", "--team", team, "--display-name", displayName, "--urls", callbackURLs, "--user", user))
|
||||||
|
|
||||||
|
// should fail because callback URLs are not specified
|
||||||
|
require.Error(t, RunCommand(t, "webhook", "create-outgoing", "--team", team, "--display-name", displayName, "--trigger-words", triggerWords, "--user", user))
|
||||||
|
|
||||||
|
// should fail because outgoing webhooks cannot be made for private channels
|
||||||
|
require.Error(t, RunCommand(t, "webhook", "create-outgoing", "--team", team, "--channel", th.BasicPrivateChannel.Id, "--display-name", displayName, "--trigger-words", triggerWords, "--urls", callbackURLs, "--user", user))
|
||||||
|
|
||||||
|
CheckCommand(t, "webhook", "create-outgoing", "--team", team, "--channel", th.BasicChannel.Id, "--display-name", displayName, "--trigger-words", triggerWords, "--urls", callbackURLs, "--user", user)
|
||||||
|
|
||||||
|
webhooks, err := th.App.GetOutgoingWebhooksPage(0, 1000)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Unable to retreive outgoing webhooks")
|
||||||
|
}
|
||||||
|
|
||||||
|
found := false
|
||||||
|
for _, webhook := range webhooks {
|
||||||
|
if webhook.DisplayName == displayName && webhook.CreatorId == th.BasicUser.Id {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
t.Fatal("Failed to create incoming webhook")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user