mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Adding 'MessageHasBeenDeleted' hook to plugins (#22476)
* Adding 'MessageHasBeenDeleted' hook to plugins * Remove debug logs * Add unit test * Bumping the required version * Fix CI problems * Increasing the minimum version * go fmt --------- Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com> Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
parent
c731630e88
commit
17ff2049ec
@ -429,6 +429,50 @@ func TestHookMessageHasBeenUpdated(t *testing.T) {
|
|||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHookMessageHasBeenDeleted(t *testing.T) {
|
||||||
|
th := Setup(t).InitBasic()
|
||||||
|
defer th.TearDown()
|
||||||
|
|
||||||
|
var mockAPI plugintest.API
|
||||||
|
mockAPI.On("LoadPluginConfiguration", mock.Anything).Return(nil)
|
||||||
|
mockAPI.On("LogDebug", "message").Return(nil).Times(1)
|
||||||
|
|
||||||
|
tearDown, _, _ := SetAppEnvironmentWithPlugins(t,
|
||||||
|
[]string{
|
||||||
|
`
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mattermost/mattermost/server/public/plugin"
|
||||||
|
"github.com/mattermost/mattermost/server/public/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MyPlugin struct {
|
||||||
|
plugin.MattermostPlugin
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *MyPlugin) MessageHasBeenDeleted(c *plugin.Context, post *model.Post) {
|
||||||
|
p.API.LogDebug(post.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
plugin.ClientMain(&MyPlugin{})
|
||||||
|
}
|
||||||
|
`}, th.App, func(*model.Manifest) plugin.API { return &mockAPI })
|
||||||
|
defer tearDown()
|
||||||
|
|
||||||
|
post := &model.Post{
|
||||||
|
UserId: th.BasicUser.Id,
|
||||||
|
ChannelId: th.BasicChannel.Id,
|
||||||
|
Message: "message",
|
||||||
|
CreateAt: model.GetMillis() - 10000,
|
||||||
|
}
|
||||||
|
_, err := th.App.CreatePost(th.Context, post, th.BasicChannel, false, true)
|
||||||
|
require.Nil(t, err)
|
||||||
|
_, err = th.App.DeletePost(th.Context, post.Id, th.BasicUser.Id)
|
||||||
|
require.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestHookFileWillBeUploaded(t *testing.T) {
|
func TestHookFileWillBeUploaded(t *testing.T) {
|
||||||
t.Run("rejected", func(t *testing.T) {
|
t.Run("rejected", func(t *testing.T) {
|
||||||
th := Setup(t).InitBasic()
|
th := Setup(t).InitBasic()
|
||||||
|
@ -1339,6 +1339,15 @@ func (a *App) DeletePost(c request.CTX, postID, deleteByID string) (*model.Post,
|
|||||||
a.deleteFlaggedPosts(post.Id)
|
a.deleteFlaggedPosts(post.Id)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
pluginPost := post.ForPlugin()
|
||||||
|
pluginContext := pluginContext(c)
|
||||||
|
a.Srv().Go(func() {
|
||||||
|
a.ch.RunMultiHook(func(hooks plugin.Hooks) bool {
|
||||||
|
hooks.MessageHasBeenDeleted(pluginContext, pluginPost)
|
||||||
|
return true
|
||||||
|
}, plugin.MessageHasBeenDeletedID)
|
||||||
|
})
|
||||||
|
|
||||||
a.Srv().Go(func() {
|
a.Srv().Go(func() {
|
||||||
if err = a.RemoveNotifications(c, post, channel); err != nil {
|
if err = a.RemoveNotifications(c, post, channel); err != nil {
|
||||||
a.Log().Error("DeletePost failed to delete notification", mlog.Err(err))
|
a.Log().Error("DeletePost failed to delete notification", mlog.Err(err))
|
||||||
|
@ -290,6 +290,40 @@ func (s *hooksRPCServer) MessageHasBeenUpdated(args *Z_MessageHasBeenUpdatedArgs
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
hookNameToId["MessageHasBeenDeleted"] = MessageHasBeenDeletedID
|
||||||
|
}
|
||||||
|
|
||||||
|
type Z_MessageHasBeenDeletedArgs struct {
|
||||||
|
A *Context
|
||||||
|
B *model.Post
|
||||||
|
}
|
||||||
|
|
||||||
|
type Z_MessageHasBeenDeletedReturns struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *hooksRPCClient) MessageHasBeenDeleted(c *Context, post *model.Post) {
|
||||||
|
_args := &Z_MessageHasBeenDeletedArgs{c, post}
|
||||||
|
_returns := &Z_MessageHasBeenDeletedReturns{}
|
||||||
|
if g.implemented[MessageHasBeenDeletedID] {
|
||||||
|
if err := g.client.Call("Plugin.MessageHasBeenDeleted", _args, _returns); err != nil {
|
||||||
|
g.log.Error("RPC call MessageHasBeenDeleted to plugin failed.", mlog.Err(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *hooksRPCServer) MessageHasBeenDeleted(args *Z_MessageHasBeenDeletedArgs, returns *Z_MessageHasBeenDeletedReturns) error {
|
||||||
|
if hook, ok := s.impl.(interface {
|
||||||
|
MessageHasBeenDeleted(c *Context, post *model.Post)
|
||||||
|
}); ok {
|
||||||
|
hook.MessageHasBeenDeleted(args.A, args.B)
|
||||||
|
} else {
|
||||||
|
return encodableError(fmt.Errorf("Hook MessageHasBeenDeleted called but not implemented."))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
hookNameToId["ChannelHasBeenCreated"] = ChannelHasBeenCreatedID
|
hookNameToId["ChannelHasBeenCreated"] = ChannelHasBeenCreatedID
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@ const (
|
|||||||
ConfigurationWillBeSavedID = 34
|
ConfigurationWillBeSavedID = 34
|
||||||
NotificationWillBePushedID = 35
|
NotificationWillBePushedID = 35
|
||||||
UserHasBeenDeactivatedID = 36
|
UserHasBeenDeactivatedID = 36
|
||||||
|
MessageHasBeenDeletedID = 37
|
||||||
TotalHooksID = iota
|
TotalHooksID = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -169,6 +170,13 @@ type Hooks interface {
|
|||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
MessageHasBeenUpdated(c *Context, newPost, oldPost *model.Post)
|
MessageHasBeenUpdated(c *Context, newPost, oldPost *model.Post)
|
||||||
|
|
||||||
|
// MessageHasBeenDeleted is invoked after the message has been deleted from the database.
|
||||||
|
// Note that this method will be called for posts deleted by plugins, including the plugin that
|
||||||
|
// deleted the post.
|
||||||
|
//
|
||||||
|
// Minimum server version: 9.1
|
||||||
|
MessageHasBeenDeleted(c *Context, post *model.Post)
|
||||||
|
|
||||||
// ChannelHasBeenCreated is invoked after the channel has been committed to the database.
|
// ChannelHasBeenCreated is invoked after the channel has been committed to the database.
|
||||||
//
|
//
|
||||||
// Minimum server version: 5.2
|
// Minimum server version: 5.2
|
||||||
|
@ -113,6 +113,12 @@ func (hooks *hooksTimerLayer) MessageHasBeenUpdated(c *Context, newPost, oldPost
|
|||||||
hooks.recordTime(startTime, "MessageHasBeenUpdated", true)
|
hooks.recordTime(startTime, "MessageHasBeenUpdated", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (hooks *hooksTimerLayer) MessageHasBeenDeleted(c *Context, post *model.Post) {
|
||||||
|
startTime := timePkg.Now()
|
||||||
|
hooks.hooksImpl.MessageHasBeenDeleted(c, post)
|
||||||
|
hooks.recordTime(startTime, "MessageHasBeenDeleted", true)
|
||||||
|
}
|
||||||
|
|
||||||
func (hooks *hooksTimerLayer) ChannelHasBeenCreated(c *Context, channel *model.Channel) {
|
func (hooks *hooksTimerLayer) ChannelHasBeenCreated(c *Context, channel *model.Channel) {
|
||||||
startTime := timePkg.Now()
|
startTime := timePkg.Now()
|
||||||
hooks.hooksImpl.ChannelHasBeenCreated(c, channel)
|
hooks.hooksImpl.ChannelHasBeenCreated(c, channel)
|
||||||
|
@ -131,6 +131,11 @@ func (_m *Hooks) Implemented() ([]string, error) {
|
|||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MessageHasBeenDeleted provides a mock function with given fields: c, post
|
||||||
|
func (_m *Hooks) MessageHasBeenDeleted(c *plugin.Context, post *model.Post) {
|
||||||
|
_m.Called(c, post)
|
||||||
|
}
|
||||||
|
|
||||||
// MessageHasBeenPosted provides a mock function with given fields: c, post
|
// MessageHasBeenPosted provides a mock function with given fields: c, post
|
||||||
func (_m *Hooks) MessageHasBeenPosted(c *plugin.Context, post *model.Post) {
|
func (_m *Hooks) MessageHasBeenPosted(c *plugin.Context, post *model.Post) {
|
||||||
_m.Called(c, post)
|
_m.Called(c, post)
|
||||||
|
@ -50,6 +50,10 @@ type MessageHasBeenUpdatedIFace interface {
|
|||||||
MessageHasBeenUpdated(c *Context, newPost, oldPost *model.Post)
|
MessageHasBeenUpdated(c *Context, newPost, oldPost *model.Post)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MessageHasBeenDeletedIFace interface {
|
||||||
|
MessageHasBeenDeleted(c *Context, post *model.Post)
|
||||||
|
}
|
||||||
|
|
||||||
type ChannelHasBeenCreatedIFace interface {
|
type ChannelHasBeenCreatedIFace interface {
|
||||||
ChannelHasBeenCreated(c *Context, channel *model.Channel)
|
ChannelHasBeenCreated(c *Context, channel *model.Channel)
|
||||||
}
|
}
|
||||||
@ -220,6 +224,15 @@ func NewAdapter(productHooks any) (*HooksAdapter, error) {
|
|||||||
return nil, errors.New("hook has MessageHasBeenUpdated method but does not implement plugin.MessageHasBeenUpdated interface")
|
return nil, errors.New("hook has MessageHasBeenUpdated method but does not implement plugin.MessageHasBeenUpdated interface")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assessing the type of the productHooks if it individually implements MessageHasBeenDeleted interface.
|
||||||
|
tt = reflect.TypeOf((*MessageHasBeenDeletedIFace)(nil)).Elem()
|
||||||
|
|
||||||
|
if ft.Implements(tt) {
|
||||||
|
a.implemented[MessageHasBeenDeletedID] = struct{}{}
|
||||||
|
} else if _, ok := ft.MethodByName("MessageHasBeenDeleted"); ok {
|
||||||
|
return nil, errors.New("hook has MessageHasBeenDeleted method but does not implement plugin.MessageHasBeenDeleted interface")
|
||||||
|
}
|
||||||
|
|
||||||
// Assessing the type of the productHooks if it individually implements ChannelHasBeenCreated interface.
|
// Assessing the type of the productHooks if it individually implements ChannelHasBeenCreated interface.
|
||||||
tt = reflect.TypeOf((*ChannelHasBeenCreatedIFace)(nil)).Elem()
|
tt = reflect.TypeOf((*ChannelHasBeenCreatedIFace)(nil)).Elem()
|
||||||
|
|
||||||
@ -475,6 +488,15 @@ func (a *HooksAdapter) MessageHasBeenUpdated(c *Context, newPost, oldPost *model
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *HooksAdapter) MessageHasBeenDeleted(c *Context, post *model.Post) {
|
||||||
|
if _, ok := a.implemented[MessageHasBeenDeletedID]; !ok {
|
||||||
|
panic("product hooks must implement MessageHasBeenDeleted")
|
||||||
|
}
|
||||||
|
|
||||||
|
a.productHooks.(MessageHasBeenDeletedIFace).MessageHasBeenDeleted(c, post)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (a *HooksAdapter) ChannelHasBeenCreated(c *Context, channel *model.Channel) {
|
func (a *HooksAdapter) ChannelHasBeenCreated(c *Context, channel *model.Channel) {
|
||||||
if _, ok := a.implemented[ChannelHasBeenCreatedID]; !ok {
|
if _, ok := a.implemented[ChannelHasBeenCreatedID]; !ok {
|
||||||
panic("product hooks must implement ChannelHasBeenCreated")
|
panic("product hooks must implement ChannelHasBeenCreated")
|
||||||
|
Loading…
Reference in New Issue
Block a user