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>
Этот коммит содержится в:
@@ -271,9 +271,15 @@ type AppIface interface {
|
||||
MoveChannel(c request.CTX, team *model.Team, channel *model.Channel, user *model.User) *model.AppError
|
||||
// NotifySessionsExpired is called periodically from the job server to notify any mobile sessions that have expired.
|
||||
NotifySessionsExpired() error
|
||||
// OnSharedChannelsPing is called by the Shared Channels service for a registered plugin wto check that the plugin
|
||||
// OnSharedChannelsAttachmentSyncMsg is called by the Shared Channels service for a registered plugin when a file attachment
|
||||
// needs to be synchronized.
|
||||
OnSharedChannelsAttachmentSyncMsg(fi *model.FileInfo, post *model.Post, rc *model.RemoteCluster) error
|
||||
// OnSharedChannelsPing is called by the Shared Channels service for a registered plugin to check that the plugin
|
||||
// is still responding and has a connection to any upstream services it needs (e.g. MS Graph API).
|
||||
OnSharedChannelsPing(rc *model.RemoteCluster) bool
|
||||
// OnSharedChannelsProfileImageSyncMsg is called by the Shared Channels service for a registered plugin when a user's
|
||||
// profile image needs to be synchronized.
|
||||
OnSharedChannelsProfileImageSyncMsg(user *model.User, rc *model.RemoteCluster) error
|
||||
// OnSharedChannelsSyncMsg is called by the Shared Channels service for a registered plugin when there is new content
|
||||
// that needs to be synchronized.
|
||||
OnSharedChannelsSyncMsg(msg *model.SyncMsg, rc *model.RemoteCluster) (model.SyncResponse, error)
|
||||
|
||||
@@ -12858,6 +12858,28 @@ func (a *OpenTracingAppLayer) NotifySharedChannelUserUpdate(user *model.User) {
|
||||
a.app.NotifySharedChannelUserUpdate(user)
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) OnSharedChannelsAttachmentSyncMsg(fi *model.FileInfo, post *model.Post, rc *model.RemoteCluster) error {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.OnSharedChannelsAttachmentSyncMsg")
|
||||
|
||||
a.ctx = newCtx
|
||||
a.app.Srv().Store().SetContext(newCtx)
|
||||
defer func() {
|
||||
a.app.Srv().Store().SetContext(origCtx)
|
||||
a.ctx = origCtx
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
resultVar0 := a.app.OnSharedChannelsAttachmentSyncMsg(fi, post, rc)
|
||||
|
||||
if resultVar0 != nil {
|
||||
span.LogFields(spanlog.Error(resultVar0))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return resultVar0
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) OnSharedChannelsPing(rc *model.RemoteCluster) bool {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.OnSharedChannelsPing")
|
||||
@@ -12875,6 +12897,28 @@ func (a *OpenTracingAppLayer) OnSharedChannelsPing(rc *model.RemoteCluster) bool
|
||||
return resultVar0
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) OnSharedChannelsProfileImageSyncMsg(user *model.User, rc *model.RemoteCluster) error {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.OnSharedChannelsProfileImageSyncMsg")
|
||||
|
||||
a.ctx = newCtx
|
||||
a.app.Srv().Store().SetContext(newCtx)
|
||||
defer func() {
|
||||
a.app.Srv().Store().SetContext(origCtx)
|
||||
a.ctx = origCtx
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
resultVar0 := a.app.OnSharedChannelsProfileImageSyncMsg(user, rc)
|
||||
|
||||
if resultVar0 != nil {
|
||||
span.LogFields(spanlog.Error(resultVar0))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return resultVar0
|
||||
}
|
||||
|
||||
func (a *OpenTracingAppLayer) OnSharedChannelsSyncMsg(msg *model.SyncMsg, rc *model.RemoteCluster) (model.SyncResponse, error) {
|
||||
origCtx := a.ctx
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.OnSharedChannelsSyncMsg")
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/mattermost/mattermost/server/v8/platform/services/remotecluster"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
)
|
||||
|
||||
func (a *App) RegisterPluginForSharedChannels(opts model.RegisterPluginOpts) (remoteID string, err error) {
|
||||
@@ -27,6 +28,11 @@ func (a *App) RegisterPluginForSharedChannels(opts model.RegisterPluginOpts) (re
|
||||
|
||||
// if plugin is already registered then treat this as an update.
|
||||
if rc != nil {
|
||||
a.Log().Debug("Plugin already registered for Shared Channels",
|
||||
mlog.String("plugin_id", opts.PluginID),
|
||||
mlog.String("remote_id", rc.RemoteId),
|
||||
)
|
||||
|
||||
rc.DisplayName = opts.Displayname
|
||||
rc.Options = opts.GetOptionFlags()
|
||||
|
||||
@@ -51,6 +57,11 @@ func (a *App) RegisterPluginForSharedChannels(opts model.RegisterPluginOpts) (re
|
||||
return "", err
|
||||
}
|
||||
|
||||
a.Log().Debug("Registered new plugin for Shared Channels",
|
||||
mlog.String("plugin_id", opts.PluginID),
|
||||
mlog.String("remote_id", rcSaved.RemoteId),
|
||||
)
|
||||
|
||||
return rcSaved.RemoteId, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/plugin"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/request"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/store"
|
||||
@@ -301,17 +302,19 @@ func (a *App) SyncSharedChannel(channelID string) error {
|
||||
|
||||
// Hooks
|
||||
|
||||
var ErrPluginUnavailable = errors.New("plugin unavialable")
|
||||
var ErrPluginUnavailable = errors.New("plugin unavailable")
|
||||
|
||||
func getPluginHooks(env *plugin.Environment, pluginID string) (plugin.Hooks, error) {
|
||||
if env == nil {
|
||||
return nil, ErrPluginUnavailable
|
||||
}
|
||||
return env.HooksForPlugin(pluginID)
|
||||
}
|
||||
|
||||
// OnSharedChannelsSyncMsg is called by the Shared Channels service for a registered plugin when there is new content
|
||||
// that needs to be synchronized.
|
||||
func (a *App) OnSharedChannelsSyncMsg(msg *model.SyncMsg, rc *model.RemoteCluster) (model.SyncResponse, error) {
|
||||
pluginsEnvironment := a.GetPluginsEnvironment()
|
||||
if pluginsEnvironment == nil {
|
||||
return model.SyncResponse{}, fmt.Errorf("cannot deliver sync msg to plugin %s: %w", rc.PluginID, ErrPluginUnavailable)
|
||||
}
|
||||
|
||||
pluginHooks, err := pluginsEnvironment.HooksForPlugin(rc.PluginID)
|
||||
pluginHooks, err := getPluginHooks(a.GetPluginsEnvironment(), rc.PluginID)
|
||||
if err != nil {
|
||||
return model.SyncResponse{}, fmt.Errorf("cannot deliver sync msg to plugin %s: %w", rc.PluginID, err)
|
||||
}
|
||||
@@ -319,16 +322,10 @@ func (a *App) OnSharedChannelsSyncMsg(msg *model.SyncMsg, rc *model.RemoteCluste
|
||||
return pluginHooks.OnSharedChannelsSyncMsg(msg, rc)
|
||||
}
|
||||
|
||||
// OnSharedChannelsPing is called by the Shared Channels service for a registered plugin wto check that the plugin
|
||||
// OnSharedChannelsPing is called by the Shared Channels service for a registered plugin to check that the plugin
|
||||
// is still responding and has a connection to any upstream services it needs (e.g. MS Graph API).
|
||||
func (a *App) OnSharedChannelsPing(rc *model.RemoteCluster) bool {
|
||||
pluginsEnvironment := a.GetPluginsEnvironment()
|
||||
if pluginsEnvironment == nil {
|
||||
a.Log().Error("Ping for shared channels cannot get plugins env")
|
||||
return false
|
||||
}
|
||||
|
||||
pluginHooks, err := pluginsEnvironment.HooksForPlugin(rc.PluginID)
|
||||
pluginHooks, err := getPluginHooks(a.GetPluginsEnvironment(), rc.PluginID)
|
||||
if err != nil {
|
||||
a.Log().Error("Ping for shared channels cannot get plugin hooks", mlog.String("plugin_id", rc.PluginID), mlog.Err(err))
|
||||
return false
|
||||
@@ -336,3 +333,25 @@ func (a *App) OnSharedChannelsPing(rc *model.RemoteCluster) bool {
|
||||
|
||||
return pluginHooks.OnSharedChannelsPing(rc)
|
||||
}
|
||||
|
||||
// OnSharedChannelsAttachmentSyncMsg is called by the Shared Channels service for a registered plugin when a file attachment
|
||||
// needs to be synchronized.
|
||||
func (a *App) OnSharedChannelsAttachmentSyncMsg(fi *model.FileInfo, post *model.Post, rc *model.RemoteCluster) error {
|
||||
pluginHooks, err := getPluginHooks(a.GetPluginsEnvironment(), rc.PluginID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot deliver file attachment sync msg to plugin %s: %w", rc.PluginID, err)
|
||||
}
|
||||
|
||||
return pluginHooks.OnSharedChannelsAttachmentSyncMsg(fi, post, rc)
|
||||
}
|
||||
|
||||
// OnSharedChannelsProfileImageSyncMsg is called by the Shared Channels service for a registered plugin when a user's
|
||||
// profile image needs to be synchronized.
|
||||
func (a *App) OnSharedChannelsProfileImageSyncMsg(user *model.User, rc *model.RemoteCluster) error {
|
||||
pluginHooks, err := getPluginHooks(a.GetPluginsEnvironment(), rc.PluginID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot deliver user profile image sync msg to plugin %s: %w", rc.PluginID, err)
|
||||
}
|
||||
|
||||
return pluginHooks.OnSharedChannelsProfileImageSyncMsg(user, rc)
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user