// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. syntax = "proto3"; package mattermost.pluginapi.v1; option go_package = "github.com/mattermost/mattermost/server/public/pluginapi/grpc/generated/go/pluginapiv1"; import "google/protobuf/struct.proto"; import "common.proto"; import "hooks_common.proto"; import "api_remaining.proto"; import "file.proto"; import "post.proto"; import "user.proto"; // ============================================================================== // COMMAND, WEBSOCKET, CLUSTER, SHARED CHANNELS, AND SUPPORT HOOK MESSAGES // ============================================================================== // // This file defines request/response messages for command execution, WebSocket events, // cluster events, shared channels, and support data generation hooks. // // Covered hooks (from server/public/plugin/hooks.go): // - ExecuteCommand(c *Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) // - OnPluginClusterEvent(c *Context, ev model.PluginClusterEvent) // - OnWebSocketConnect(webConnID, userID string) // - OnWebSocketDisconnect(webConnID, userID string) // - WebSocketMessageHasBeenPosted(webConnID, userID string, req *model.WebSocketRequest) // - OnSharedChannelsSyncMsg(msg *model.SyncMsg, rc *model.RemoteCluster) (model.SyncResponse, error) // - OnSharedChannelsPing(rc *model.RemoteCluster) bool // - OnSharedChannelsAttachmentSyncMsg(fi *model.FileInfo, post *model.Post, rc *model.RemoteCluster) error // - OnSharedChannelsProfileImageSyncMsg(user *model.User, rc *model.RemoteCluster) error // - GenerateSupportData(c *Context) ([]*model.FileData, error) // // NOTE: ServeHTTP and ServeMetrics are deferred to Phase 8 (HTTP streaming). // These hooks require HTTP request/response streaming over gRPC. // // SHARED TYPES: // - CommandArgs, CommandResponse, PluginClusterEvent are imported from api_remaining.proto // - FileInfo, Post, User are imported from their respective proto files // // ============================================================================== // ----------------------------------------------------------------------------- // Model Types (types not already defined elsewhere) // ----------------------------------------------------------------------------- // WebSocketRequest represents a WebSocket message request from a client. // Maps to model.WebSocketRequest in Go (server/public/model/websocket_request.go). // // Note: Server-provided fields (Session, T, Locale) are not passed over the wire. message WebSocketRequest { // Sequence number incremented for every request int64 seq = 1; // The action to perform (e.g., "get_statuses", "user_typing") string action = 2; // Action metadata google.protobuf.Struct data = 3; } // SyncMsgJson wraps a serialized model.SyncMsg as JSON bytes. // SyncMsg is a complex type with nested maps and slices of various models // (User, Post, Reaction, Status, MembershipChangeMsg, PostAcknowledgement). // Using a JSON blob avoids creating extensive proto definitions and provides // flexibility for changes in the SyncMsg structure. message SyncMsgJson { // JSON-encoded model.SyncMsg bytes sync_msg_json = 1; } // SyncResponse represents the response to a shared channels synchronization event. // Maps to model.SyncResponse in Go (server/public/model/shared_channel.go). message SyncResponse { // Timestamp of the last user update processed int64 users_last_update_at = 1; // User IDs that failed to sync repeated string user_errors = 2; // User IDs that were successfully synced repeated string users_syncd = 3; // Timestamp of the last post update processed int64 posts_last_update_at = 4; // Post IDs that failed to sync repeated string post_errors = 5; // Timestamp of the last reaction update processed int64 reactions_last_update_at = 6; // Reaction post IDs that failed to sync repeated string reaction_errors = 7; // Timestamp of the last acknowledgement update processed int64 acknowledgements_last_update_at = 8; // Acknowledgement IDs that failed to sync repeated string acknowledgement_errors = 9; // User IDs for which status sync failed repeated string status_errors = 10; } // RemoteCluster represents a remote cluster for shared channels. // Maps to model.RemoteCluster in Go (server/public/model/remote_cluster.go). message RemoteCluster { // Unique identifier for the remote cluster string remote_id = 1; // Deprecated: remote_team_id is no longer used string remote_team_id = 2; // Internal name of the remote cluster string name = 3; // Display name shown to users string display_name = 4; // URL of the remote Mattermost server string site_url = 5; // Default team ID for the remote cluster string default_team_id = 6; // Timestamp when the remote cluster was created int64 create_at = 7; // Timestamp when the remote cluster was deleted (0 if active) int64 delete_at = 8; // Timestamp of last successful ping int64 last_ping_at = 9; // Timestamp of last global user sync int64 last_global_user_sync_at = 10; // Authentication token (sensitive, may be empty in responses) string token = 11; // Token from the remote cluster (sensitive, may be empty) string remote_token = 12; // Space-separated list of topics string topics = 13; // ID of the user who created the remote cluster string creator_id = 14; // Plugin ID if sync messages are delivered via plugin API string plugin_id = 15; // Bit-flag options uint32 options = 16; } // ----------------------------------------------------------------------------- // ExecuteCommand Hook // Signature: ExecuteCommand(c *Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) // Executes a registered slash command. // // Note: Uses CommandArgs and CommandResponse from api_remaining.proto // ----------------------------------------------------------------------------- message ExecuteCommandRequest { RequestContext context = 1; // Plugin context with session/request metadata PluginContext plugin_context = 2; // The command arguments (from api_remaining.proto) CommandArgs args = 3; } message ExecuteCommandResponse { // Error returned by the plugin (null on success) AppError error = 1; // The command response (may be null if only error is returned) // Note: Uses CommandResponse from api_remaining.proto CommandResponse response = 2; } // ----------------------------------------------------------------------------- // OnPluginClusterEvent Hook // Signature: OnPluginClusterEvent(c *Context, ev model.PluginClusterEvent) // Receives intra-cluster plugin events. This is a notification hook. // // Note: Uses PluginClusterEvent from api_remaining.proto // ----------------------------------------------------------------------------- message OnPluginClusterEventRequest { RequestContext context = 1; // Plugin context with session/request metadata PluginContext plugin_context = 2; // The cluster event (from api_remaining.proto) PluginClusterEvent event = 3; } message OnPluginClusterEventResponse { // No error field because the Go signature has no return value. // Hook failures are logged but do not affect server operation. } // ----------------------------------------------------------------------------- // OnWebSocketConnect Hook // Signature: OnWebSocketConnect(webConnID, userID string) // Invoked when a new WebSocket connection is opened. No Context parameter. // ----------------------------------------------------------------------------- message OnWebSocketConnectRequest { RequestContext context = 1; // The WebSocket connection ID string web_conn_id = 2; // The ID of the user who connected string user_id = 3; } message OnWebSocketConnectResponse { // No error field because the Go signature has no return value. // Hook failures are logged but do not affect server operation. } // ----------------------------------------------------------------------------- // OnWebSocketDisconnect Hook // Signature: OnWebSocketDisconnect(webConnID, userID string) // Invoked when a WebSocket connection is closed. No Context parameter. // ----------------------------------------------------------------------------- message OnWebSocketDisconnectRequest { RequestContext context = 1; // The WebSocket connection ID string web_conn_id = 2; // The ID of the user who disconnected string user_id = 3; } message OnWebSocketDisconnectResponse { // No error field because the Go signature has no return value. // Hook failures are logged but do not affect server operation. } // ----------------------------------------------------------------------------- // WebSocketMessageHasBeenPosted Hook // Signature: WebSocketMessageHasBeenPosted(webConnID, userID string, req *model.WebSocketRequest) // Invoked when a WebSocket message is received. No Context parameter. // ----------------------------------------------------------------------------- message WebSocketMessageHasBeenPostedRequest { RequestContext context = 1; // The WebSocket connection ID string web_conn_id = 2; // The ID of the user who sent the message string user_id = 3; // The WebSocket request WebSocketRequest request = 4; } message WebSocketMessageHasBeenPostedResponse { // No error field because the Go signature has no return value. // Hook failures are logged but do not affect server operation. } // ----------------------------------------------------------------------------- // OnSharedChannelsSyncMsg Hook // Signature: OnSharedChannelsSyncMsg(msg *model.SyncMsg, rc *model.RemoteCluster) (model.SyncResponse, error) // Receives shared channels sync messages. // ----------------------------------------------------------------------------- message OnSharedChannelsSyncMsgRequest { RequestContext context = 1; // The sync message as JSON (complex nested structure) SyncMsgJson sync_msg = 2; // The remote cluster that sent the message RemoteCluster remote_cluster = 3; } message OnSharedChannelsSyncMsgResponse { // Error returned by the plugin (null on success) AppError error = 1; // The sync response SyncResponse response = 2; } // ----------------------------------------------------------------------------- // OnSharedChannelsPing Hook // Signature: OnSharedChannelsPing(rc *model.RemoteCluster) bool // Health check for shared channels plugin. Returns true if healthy. // ----------------------------------------------------------------------------- message OnSharedChannelsPingRequest { RequestContext context = 1; // The remote cluster performing the ping RemoteCluster remote_cluster = 2; } message OnSharedChannelsPingResponse { // True if the plugin is healthy, false otherwise bool healthy = 1; } // ----------------------------------------------------------------------------- // OnSharedChannelsAttachmentSyncMsg Hook // Signature: OnSharedChannelsAttachmentSyncMsg(fi *model.FileInfo, post *model.Post, rc *model.RemoteCluster) error // Receives file attachment sync messages from shared channels. // ----------------------------------------------------------------------------- message OnSharedChannelsAttachmentSyncMsgRequest { RequestContext context = 1; // The file info to sync FileInfo file_info = 2; // The post the file is attached to Post post = 3; // The remote cluster that sent the message RemoteCluster remote_cluster = 4; } message OnSharedChannelsAttachmentSyncMsgResponse { // Error returned by the plugin (null on success) AppError error = 1; } // ----------------------------------------------------------------------------- // OnSharedChannelsProfileImageSyncMsg Hook // Signature: OnSharedChannelsProfileImageSyncMsg(user *model.User, rc *model.RemoteCluster) error // Receives profile image sync messages from shared channels. // ----------------------------------------------------------------------------- message OnSharedChannelsProfileImageSyncMsgRequest { RequestContext context = 1; // The user whose profile image should be synced User user = 2; // The remote cluster that sent the message RemoteCluster remote_cluster = 3; } message OnSharedChannelsProfileImageSyncMsgResponse { // Error returned by the plugin (null on success) AppError error = 1; } // ----------------------------------------------------------------------------- // GenerateSupportData Hook // Signature: GenerateSupportData(c *Context) ([]*model.FileData, error) // Generates plugin support data for inclusion in Support Packets. // ----------------------------------------------------------------------------- message GenerateSupportDataRequest { RequestContext context = 1; // Plugin context with session/request metadata PluginContext plugin_context = 2; } message GenerateSupportDataResponse { // Error returned by the plugin (null on success) AppError error = 1; // Files to include in the support packet // Note: Uses FileData from file.proto repeated FileData files = 2; }