Generalized webhook post code and added it to outgoing webhooks
Этот коммит содержится в:
42
api/post.go
42
api/post.go
@@ -13,6 +13,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -144,6 +145,40 @@ func CreatePost(c *Context, post *model.Post, triggerWebhooks bool) (*model.Post
|
|||||||
return rpost, nil
|
return rpost, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateWebhookPost(c *Context, channelId, text, overrideUsername, overrideIconUrl string) (*model.Post, *model.AppError) {
|
||||||
|
// parse links into Markdown format
|
||||||
|
linkWithTextRegex := regexp.MustCompile(`<([^<\|]+)\|([^>]+)>`)
|
||||||
|
text = linkWithTextRegex.ReplaceAllString(text, "[${2}](${1})")
|
||||||
|
|
||||||
|
linkRegex := regexp.MustCompile(`<\s*(\S*)\s*>`)
|
||||||
|
text = linkRegex.ReplaceAllString(text, "${1}")
|
||||||
|
|
||||||
|
post := &model.Post{UserId: c.Session.UserId, ChannelId: channelId, Message: text}
|
||||||
|
post.AddProp("from_webhook", "true")
|
||||||
|
|
||||||
|
if utils.Cfg.ServiceSettings.EnablePostUsernameOverride {
|
||||||
|
if len(overrideUsername) != 0 {
|
||||||
|
post.AddProp("override_username", overrideUsername)
|
||||||
|
} else {
|
||||||
|
post.AddProp("override_username", model.DEFAULT_WEBHOOK_USERNAME)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if utils.Cfg.ServiceSettings.EnablePostIconOverride {
|
||||||
|
if len(overrideIconUrl) != 0 {
|
||||||
|
post.AddProp("override_icon_url", overrideIconUrl)
|
||||||
|
} else {
|
||||||
|
post.AddProp("override_icon_url", model.DEFAULT_WEBHOOK_ICON)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := CreatePost(c, post, false); err != nil {
|
||||||
|
return nil, model.NewAppError("CreateWebhookPost", "Error creating post", "err="+err.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
return post, nil
|
||||||
|
}
|
||||||
|
|
||||||
func handlePostEventsAndForget(c *Context, post *model.Post, triggerWebhooks bool) {
|
func handlePostEventsAndForget(c *Context, post *model.Post, triggerWebhooks bool) {
|
||||||
go func() {
|
go func() {
|
||||||
tchan := Srv.Store.Team().Get(c.Session.TeamId)
|
tchan := Srv.Store.Team().Get(c.Session.TeamId)
|
||||||
@@ -244,9 +279,12 @@ func handleWebhookEventsAndForget(c *Context, post *model.Post, team *model.Team
|
|||||||
} else {
|
} else {
|
||||||
respProps := model.MapFromJson(resp.Body)
|
respProps := model.MapFromJson(resp.Body)
|
||||||
|
|
||||||
|
// copy the context and create a mock session for posting the message
|
||||||
|
mockSession := model.Session{UserId: hook.CreatorId, TeamId: hook.TeamId, IsOAuth: false}
|
||||||
|
newContext := &Context{mockSession, model.NewId(), "", c.Path, nil, c.teamURLValid, c.teamURL, c.siteURL}
|
||||||
|
|
||||||
if text, ok := respProps["text"]; ok {
|
if text, ok := respProps["text"]; ok {
|
||||||
respPost := &model.Post{Message: text, ChannelId: post.ChannelId}
|
if _, err := CreateWebhookPost(newContext, post.ChannelId, text, respProps["username"], respProps["icon_url"]); err != nil {
|
||||||
if _, err := CreatePost(c, respPost, false); err != nil {
|
|
||||||
l4g.Error("Failed to create response post, err=%v", err)
|
l4g.Error("Failed to create response post, err=%v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
39
web/web.go
39
web/web.go
@@ -15,7 +15,6 @@ import (
|
|||||||
"gopkg.in/fsnotify.v1"
|
"gopkg.in/fsnotify.v1"
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -921,9 +920,6 @@ func incomingWebhook(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
channelName := props["channel"]
|
channelName := props["channel"]
|
||||||
|
|
||||||
overrideUsername := props["username"]
|
|
||||||
overrideIconUrl := props["icon_url"]
|
|
||||||
|
|
||||||
var hook *model.IncomingWebhook
|
var hook *model.IncomingWebhook
|
||||||
if result := <-hchan; result.Err != nil {
|
if result := <-hchan; result.Err != nil {
|
||||||
c.Err = model.NewAppError("incomingWebhook", "Invalid webhook", "err="+result.Err.Message)
|
c.Err = model.NewAppError("incomingWebhook", "Invalid webhook", "err="+result.Err.Message)
|
||||||
@@ -952,12 +948,8 @@ func incomingWebhook(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
cchan = api.Srv.Store.Channel().Get(hook.ChannelId)
|
cchan = api.Srv.Store.Channel().Get(hook.ChannelId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse links into Markdown format
|
overrideUsername := props["username"]
|
||||||
linkWithTextRegex := regexp.MustCompile(`<([^<\|]+)\|([^>]+)>`)
|
overrideIconUrl := props["icon_url"]
|
||||||
text = linkWithTextRegex.ReplaceAllString(text, "[${2}](${1})")
|
|
||||||
|
|
||||||
linkRegex := regexp.MustCompile(`<\s*(\S*)\s*>`)
|
|
||||||
text = linkRegex.ReplaceAllString(text, "${1}")
|
|
||||||
|
|
||||||
if result := <-cchan; result.Err != nil {
|
if result := <-cchan; result.Err != nil {
|
||||||
c.Err = model.NewAppError("incomingWebhook", "Couldn't find the channel", "err="+result.Err.Message)
|
c.Err = model.NewAppError("incomingWebhook", "Couldn't find the channel", "err="+result.Err.Message)
|
||||||
@@ -968,35 +960,16 @@ func incomingWebhook(c *api.Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
pchan := api.Srv.Store.Channel().CheckPermissionsTo(hook.TeamId, channel.Id, hook.UserId)
|
pchan := api.Srv.Store.Channel().CheckPermissionsTo(hook.TeamId, channel.Id, hook.UserId)
|
||||||
|
|
||||||
post := &model.Post{UserId: hook.UserId, ChannelId: channel.Id, Message: text}
|
// create a mock session
|
||||||
post.AddProp("from_webhook", "true")
|
c.Session = model.Session{UserId: hook.UserId, TeamId: hook.TeamId, IsOAuth: false}
|
||||||
|
|
||||||
if utils.Cfg.ServiceSettings.EnablePostUsernameOverride {
|
|
||||||
if len(overrideUsername) != 0 {
|
|
||||||
post.AddProp("override_username", overrideUsername)
|
|
||||||
} else {
|
|
||||||
post.AddProp("override_username", model.DEFAULT_WEBHOOK_USERNAME)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if utils.Cfg.ServiceSettings.EnablePostIconOverride {
|
|
||||||
if len(overrideIconUrl) != 0 {
|
|
||||||
post.AddProp("override_icon_url", overrideIconUrl)
|
|
||||||
} else {
|
|
||||||
post.AddProp("override_icon_url", model.DEFAULT_WEBHOOK_ICON)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !c.HasPermissionsToChannel(pchan, "createIncomingHook") && channel.Type != model.CHANNEL_OPEN {
|
if !c.HasPermissionsToChannel(pchan, "createIncomingHook") && channel.Type != model.CHANNEL_OPEN {
|
||||||
c.Err = model.NewAppError("incomingWebhook", "Inappropriate channel permissions", "")
|
c.Err = model.NewAppError("incomingWebhook", "Inappropriate channel permissions", "")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a mock session
|
if _, err := api.CreateWebhookPost(c, channel.Id, text, overrideUsername, overrideIconUrl); err != nil {
|
||||||
c.Session = model.Session{UserId: hook.UserId, TeamId: hook.TeamId, IsOAuth: false}
|
c.Err = err
|
||||||
|
|
||||||
if _, err := api.CreatePost(c, post, false); err != nil {
|
|
||||||
c.Err = model.NewAppError("incomingWebhook", "Error creating post", "err="+err.Message)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user