Plugin API hook for Shared Channel file attachment sync (#25874)

* option for auto inviting plugin to all shared channels.

* auto-invite remotes to shared channels when flag set

* fix unit test

* immediately ping new remotes; fix unique siteurl bug

* make i18n-extract

* fix translations

* plugin hooks for file attachments

* hook for profile image sync

* fix profile image sync

* fix unit test

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Doug Lauder
2024-01-16 09:48:51 -05:00
коммит произвёл GitHub
родитель d90d3e4036
Коммит a07097ed57
21 изменённых файлов: 461 добавлений и 76 удалений

Просмотреть файл

@@ -1052,6 +1052,79 @@ func (s *hooksRPCServer) PreferencesHaveChanged(args *Z_PreferencesHaveChangedAr
return nil
}
func init() {
hookNameToId["OnSharedChannelsAttachmentSyncMsg"] = OnSharedChannelsAttachmentSyncMsgID
}
type Z_OnSharedChannelsAttachmentSyncMsgArgs struct {
A *model.FileInfo
B *model.Post
C *model.RemoteCluster
}
type Z_OnSharedChannelsAttachmentSyncMsgReturns struct {
A error
}
func (g *hooksRPCClient) OnSharedChannelsAttachmentSyncMsg(fi *model.FileInfo, post *model.Post, rc *model.RemoteCluster) error {
_args := &Z_OnSharedChannelsAttachmentSyncMsgArgs{fi, post, rc}
_returns := &Z_OnSharedChannelsAttachmentSyncMsgReturns{}
if g.implemented[OnSharedChannelsAttachmentSyncMsgID] {
if err := g.client.Call("Plugin.OnSharedChannelsAttachmentSyncMsg", _args, _returns); err != nil {
g.log.Error("RPC call OnSharedChannelsAttachmentSyncMsg to plugin failed.", mlog.Err(err))
}
}
return _returns.A
}
func (s *hooksRPCServer) OnSharedChannelsAttachmentSyncMsg(args *Z_OnSharedChannelsAttachmentSyncMsgArgs, returns *Z_OnSharedChannelsAttachmentSyncMsgReturns) error {
if hook, ok := s.impl.(interface {
OnSharedChannelsAttachmentSyncMsg(fi *model.FileInfo, post *model.Post, rc *model.RemoteCluster) error
}); ok {
returns.A = hook.OnSharedChannelsAttachmentSyncMsg(args.A, args.B, args.C)
returns.A = encodableError(returns.A)
} else {
return encodableError(fmt.Errorf("Hook OnSharedChannelsAttachmentSyncMsg called but not implemented."))
}
return nil
}
func init() {
hookNameToId["OnSharedChannelsProfileImageSyncMsg"] = OnSharedChannelsProfileImageSyncMsgID
}
type Z_OnSharedChannelsProfileImageSyncMsgArgs struct {
A *model.User
B *model.RemoteCluster
}
type Z_OnSharedChannelsProfileImageSyncMsgReturns struct {
A error
}
func (g *hooksRPCClient) OnSharedChannelsProfileImageSyncMsg(user *model.User, rc *model.RemoteCluster) error {
_args := &Z_OnSharedChannelsProfileImageSyncMsgArgs{user, rc}
_returns := &Z_OnSharedChannelsProfileImageSyncMsgReturns{}
if g.implemented[OnSharedChannelsProfileImageSyncMsgID] {
if err := g.client.Call("Plugin.OnSharedChannelsProfileImageSyncMsg", _args, _returns); err != nil {
g.log.Error("RPC call OnSharedChannelsProfileImageSyncMsg to plugin failed.", mlog.Err(err))
}
}
return _returns.A
}
func (s *hooksRPCServer) OnSharedChannelsProfileImageSyncMsg(args *Z_OnSharedChannelsProfileImageSyncMsgArgs, returns *Z_OnSharedChannelsProfileImageSyncMsgReturns) error {
if hook, ok := s.impl.(interface {
OnSharedChannelsProfileImageSyncMsg(user *model.User, rc *model.RemoteCluster) error
}); ok {
returns.A = hook.OnSharedChannelsProfileImageSyncMsg(args.A, args.B)
returns.A = encodableError(returns.A)
} else {
return encodableError(fmt.Errorf("Hook OnSharedChannelsProfileImageSyncMsg called but not implemented."))
}
return nil
}
type Z_RegisterCommandArgs struct {
A *model.Command
}

Просмотреть файл

@@ -58,6 +58,8 @@ const (
OnSharedChannelsSyncMsgID = 40
OnSharedChannelsPingID = 41
PreferencesHaveChangedID = 42
OnSharedChannelsAttachmentSyncMsgID = 43
OnSharedChannelsProfileImageSyncMsgID = 44
TotalHooksID = iota
)
@@ -362,4 +364,22 @@ type Hooks interface {
//
// Minimum server version: 9.5
PreferencesHaveChanged(c *Context, preferences []model.Preference)
// OnSharedChannelsAttachmentSyncMsg is invoked for plugins that wish to receive synchronization messages from the
// Shared Channels service for which they have been invited via InviteRemote. Each call represents one file attachment
// to be synchronized.
//
// The cursor will be advanced based on the timestamp returned if no error is returned.
//
// Minimum server version: 9.5
OnSharedChannelsAttachmentSyncMsg(fi *model.FileInfo, post *model.Post, rc *model.RemoteCluster) error
// OnSharedChannelsProfileImageSyncMsg is invoked for plugins that wish to receive synchronization messages from the
// Shared Channels service for which they have been invited via InviteRemote. Each call represents one user profile
// image that should be synchronized. `App.GetProfileImage` can be used to fetch the image bytes.
//
// The cursor will be advanced based on the timestamp returned if no error is returned.
//
// Minimum server version: 9.5
OnSharedChannelsProfileImageSyncMsg(user *model.User, rc *model.RemoteCluster) error
}

Просмотреть файл

@@ -270,3 +270,17 @@ func (hooks *hooksTimerLayer) PreferencesHaveChanged(c *Context, preferences []m
hooks.hooksImpl.PreferencesHaveChanged(c, preferences)
hooks.recordTime(startTime, "PreferencesHaveChanged", true)
}
func (hooks *hooksTimerLayer) OnSharedChannelsAttachmentSyncMsg(fi *model.FileInfo, post *model.Post, rc *model.RemoteCluster) error {
startTime := timePkg.Now()
_returnsA := hooks.hooksImpl.OnSharedChannelsAttachmentSyncMsg(fi, post, rc)
hooks.recordTime(startTime, "OnSharedChannelsAttachmentSyncMsg", _returnsA == nil)
return _returnsA
}
func (hooks *hooksTimerLayer) OnSharedChannelsProfileImageSyncMsg(user *model.User, rc *model.RemoteCluster) error {
startTime := timePkg.Now()
_returnsA := hooks.hooksImpl.OnSharedChannelsProfileImageSyncMsg(user, rc)
hooks.recordTime(startTime, "OnSharedChannelsProfileImageSyncMsg", _returnsA == nil)
return _returnsA
}

Просмотреть файл

@@ -311,6 +311,20 @@ func (_m *Hooks) OnSendDailyTelemetry() {
_m.Called()
}
// OnSharedChannelsAttachmentSyncMsg provides a mock function with given fields: fi, post, rc
func (_m *Hooks) OnSharedChannelsAttachmentSyncMsg(fi *model.FileInfo, post *model.Post, rc *model.RemoteCluster) error {
ret := _m.Called(fi, post, rc)
var r0 error
if rf, ok := ret.Get(0).(func(*model.FileInfo, *model.Post, *model.RemoteCluster) error); ok {
r0 = rf(fi, post, rc)
} else {
r0 = ret.Error(0)
}
return r0
}
// OnSharedChannelsPing provides a mock function with given fields: rc
func (_m *Hooks) OnSharedChannelsPing(rc *model.RemoteCluster) bool {
ret := _m.Called(rc)
@@ -325,6 +339,20 @@ func (_m *Hooks) OnSharedChannelsPing(rc *model.RemoteCluster) bool {
return r0
}
// OnSharedChannelsProfileImageSyncMsg provides a mock function with given fields: user, rc
func (_m *Hooks) OnSharedChannelsProfileImageSyncMsg(user *model.User, rc *model.RemoteCluster) error {
ret := _m.Called(user, rc)
var r0 error
if rf, ok := ret.Get(0).(func(*model.User, *model.RemoteCluster) error); ok {
r0 = rf(user, rc)
} else {
r0 = ret.Error(0)
}
return r0
}
// OnSharedChannelsSyncMsg provides a mock function with given fields: msg, rc
func (_m *Hooks) OnSharedChannelsSyncMsg(msg *model.SyncMsg, rc *model.RemoteCluster) (model.SyncResponse, error) {
ret := _m.Called(msg, rc)

Просмотреть файл

@@ -151,6 +151,14 @@ type PreferencesHaveChangedIFace interface {
PreferencesHaveChanged(c *Context, preferences []model.Preference)
}
type OnSharedChannelsAttachmentSyncMsgIFace interface {
OnSharedChannelsAttachmentSyncMsg(fi *model.FileInfo, post *model.Post, rc *model.RemoteCluster) error
}
type OnSharedChannelsProfileImageSyncMsgIFace interface {
OnSharedChannelsProfileImageSyncMsg(user *model.User, rc *model.RemoteCluster) error
}
type HooksAdapter struct {
implemented map[int]struct{}
productHooks any
@@ -470,6 +478,24 @@ func NewAdapter(productHooks any) (*HooksAdapter, error) {
return nil, errors.New("hook has PreferencesHaveChanged method but does not implement plugin.PreferencesHaveChanged interface")
}
// Assessing the type of the productHooks if it individually implements OnSharedChannelsAttachmentSyncMsg interface.
tt = reflect.TypeOf((*OnSharedChannelsAttachmentSyncMsgIFace)(nil)).Elem()
if ft.Implements(tt) {
a.implemented[OnSharedChannelsAttachmentSyncMsgID] = struct{}{}
} else if _, ok := ft.MethodByName("OnSharedChannelsAttachmentSyncMsg"); ok {
return nil, errors.New("hook has OnSharedChannelsAttachmentSyncMsg method but does not implement plugin.OnSharedChannelsAttachmentSyncMsg interface")
}
// Assessing the type of the productHooks if it individually implements OnSharedChannelsProfileImageSyncMsg interface.
tt = reflect.TypeOf((*OnSharedChannelsProfileImageSyncMsgIFace)(nil)).Elem()
if ft.Implements(tt) {
a.implemented[OnSharedChannelsProfileImageSyncMsgID] = struct{}{}
} else if _, ok := ft.MethodByName("OnSharedChannelsProfileImageSyncMsg"); ok {
return nil, errors.New("hook has OnSharedChannelsProfileImageSyncMsg method but does not implement plugin.OnSharedChannelsProfileImageSyncMsg interface")
}
return a, nil
}
@@ -778,3 +804,21 @@ func (a *HooksAdapter) PreferencesHaveChanged(c *Context, preferences []model.Pr
a.productHooks.(PreferencesHaveChangedIFace).PreferencesHaveChanged(c, preferences)
}
func (a *HooksAdapter) OnSharedChannelsAttachmentSyncMsg(fi *model.FileInfo, post *model.Post, rc *model.RemoteCluster) error {
if _, ok := a.implemented[OnSharedChannelsAttachmentSyncMsgID]; !ok {
panic("product hooks must implement OnSharedChannelsAttachmentSyncMsg")
}
return a.productHooks.(OnSharedChannelsAttachmentSyncMsgIFace).OnSharedChannelsAttachmentSyncMsg(fi, post, rc)
}
func (a *HooksAdapter) OnSharedChannelsProfileImageSyncMsg(user *model.User, rc *model.RemoteCluster) error {
if _, ok := a.implemented[OnSharedChannelsProfileImageSyncMsgID]; !ok {
panic("product hooks must implement OnSharedChannelsProfileImageSyncMsg")
}
return a.productHooks.(OnSharedChannelsProfileImageSyncMsgIFace).OnSharedChannelsProfileImageSyncMsg(user, rc)
}