github.com/levb/mattermost-server@v5.3.1+incompatible/model/websocket_message.go (about) 1 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package model 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "io" 10 ) 11 12 const ( 13 WEBSOCKET_EVENT_TYPING = "typing" 14 WEBSOCKET_EVENT_POSTED = "posted" 15 WEBSOCKET_EVENT_POST_EDITED = "post_edited" 16 WEBSOCKET_EVENT_POST_DELETED = "post_deleted" 17 WEBSOCKET_EVENT_CHANNEL_CONVERTED = "channel_converted" 18 WEBSOCKET_EVENT_CHANNEL_CREATED = "channel_created" 19 WEBSOCKET_EVENT_CHANNEL_DELETED = "channel_deleted" 20 WEBSOCKET_EVENT_CHANNEL_UPDATED = "channel_updated" 21 WEBSOCKET_EVENT_CHANNEL_MEMBER_UPDATED = "channel_member_updated" 22 WEBSOCKET_EVENT_DIRECT_ADDED = "direct_added" 23 WEBSOCKET_EVENT_GROUP_ADDED = "group_added" 24 WEBSOCKET_EVENT_NEW_USER = "new_user" 25 WEBSOCKET_EVENT_ADDED_TO_TEAM = "added_to_team" 26 WEBSOCKET_EVENT_LEAVE_TEAM = "leave_team" 27 WEBSOCKET_EVENT_UPDATE_TEAM = "update_team" 28 WEBSOCKET_EVENT_DELETE_TEAM = "delete_team" 29 WEBSOCKET_EVENT_USER_ADDED = "user_added" 30 WEBSOCKET_EVENT_USER_UPDATED = "user_updated" 31 WEBSOCKET_EVENT_USER_ROLE_UPDATED = "user_role_updated" 32 WEBSOCKET_EVENT_MEMBERROLE_UPDATED = "memberrole_updated" 33 WEBSOCKET_EVENT_USER_REMOVED = "user_removed" 34 WEBSOCKET_EVENT_PREFERENCE_CHANGED = "preference_changed" 35 WEBSOCKET_EVENT_PREFERENCES_CHANGED = "preferences_changed" 36 WEBSOCKET_EVENT_PREFERENCES_DELETED = "preferences_deleted" 37 WEBSOCKET_EVENT_EPHEMERAL_MESSAGE = "ephemeral_message" 38 WEBSOCKET_EVENT_STATUS_CHANGE = "status_change" 39 WEBSOCKET_EVENT_HELLO = "hello" 40 WEBSOCKET_EVENT_WEBRTC = "webrtc" 41 WEBSOCKET_AUTHENTICATION_CHALLENGE = "authentication_challenge" 42 WEBSOCKET_EVENT_REACTION_ADDED = "reaction_added" 43 WEBSOCKET_EVENT_REACTION_REMOVED = "reaction_removed" 44 WEBSOCKET_EVENT_RESPONSE = "response" 45 WEBSOCKET_EVENT_EMOJI_ADDED = "emoji_added" 46 WEBSOCKET_EVENT_CHANNEL_VIEWED = "channel_viewed" 47 WEBSOCKET_EVENT_PLUGIN_STATUSES_CHANGED = "plugin_statuses_changed" 48 WEBSOCKET_EVENT_PLUGIN_ENABLED = "plugin_enabled" 49 WEBSOCKET_EVENT_PLUGIN_DISABLED = "plugin_disabled" 50 WEBSOCKET_EVENT_ROLE_UPDATED = "role_updated" 51 WEBSOCKET_EVENT_LICENSE_CHANGED = "license_changed" 52 WEBSOCKET_EVENT_CONFIG_CHANGED = "config_changed" 53 ) 54 55 type WebSocketMessage interface { 56 ToJson() string 57 IsValid() bool 58 EventType() string 59 } 60 61 type WebsocketBroadcast struct { 62 OmitUsers map[string]bool `json:"omit_users"` // broadcast is omitted for users listed here 63 UserId string `json:"user_id"` // broadcast only occurs for this user 64 ChannelId string `json:"channel_id"` // broadcast only occurs for users in this channel 65 TeamId string `json:"team_id"` // broadcast only occurs for users in this team 66 ContainsSanitizedData bool `json:"-"` 67 ContainsSensitiveData bool `json:"-"` 68 } 69 70 type precomputedWebSocketEventJSON struct { 71 Event json.RawMessage 72 Data json.RawMessage 73 Broadcast json.RawMessage 74 } 75 76 type WebSocketEvent struct { 77 Event string `json:"event"` 78 Data map[string]interface{} `json:"data"` 79 Broadcast *WebsocketBroadcast `json:"broadcast"` 80 Sequence int64 `json:"seq"` 81 82 precomputedJSON *precomputedWebSocketEventJSON 83 } 84 85 // PrecomputeJSON precomputes and stores the serialized JSON for all fields other than Sequence. 86 // This makes ToJson much more efficient when sending the same event to multiple connections. 87 func (m *WebSocketEvent) PrecomputeJSON() { 88 event, _ := json.Marshal(m.Event) 89 data, _ := json.Marshal(m.Data) 90 broadcast, _ := json.Marshal(m.Broadcast) 91 m.precomputedJSON = &precomputedWebSocketEventJSON{ 92 Event: json.RawMessage(event), 93 Data: json.RawMessage(data), 94 Broadcast: json.RawMessage(broadcast), 95 } 96 } 97 98 func (m *WebSocketEvent) Add(key string, value interface{}) { 99 m.Data[key] = value 100 } 101 102 func NewWebSocketEvent(event, teamId, channelId, userId string, omitUsers map[string]bool) *WebSocketEvent { 103 return &WebSocketEvent{Event: event, Data: make(map[string]interface{}), 104 Broadcast: &WebsocketBroadcast{TeamId: teamId, ChannelId: channelId, UserId: userId, OmitUsers: omitUsers}} 105 } 106 107 func (o *WebSocketEvent) IsValid() bool { 108 return o.Event != "" 109 } 110 111 func (o *WebSocketEvent) EventType() string { 112 return o.Event 113 } 114 115 func (o *WebSocketEvent) ToJson() string { 116 if o.precomputedJSON != nil { 117 return fmt.Sprintf(`{"event": %s, "data": %s, "broadcast": %s, "seq": %d}`, o.precomputedJSON.Event, o.precomputedJSON.Data, o.precomputedJSON.Broadcast, o.Sequence) 118 } 119 b, _ := json.Marshal(o) 120 return string(b) 121 } 122 123 func WebSocketEventFromJson(data io.Reader) *WebSocketEvent { 124 var o *WebSocketEvent 125 json.NewDecoder(data).Decode(&o) 126 return o 127 } 128 129 type WebSocketResponse struct { 130 Status string `json:"status"` 131 SeqReply int64 `json:"seq_reply,omitempty"` 132 Data map[string]interface{} `json:"data,omitempty"` 133 Error *AppError `json:"error,omitempty"` 134 } 135 136 func (m *WebSocketResponse) Add(key string, value interface{}) { 137 m.Data[key] = value 138 } 139 140 func NewWebSocketResponse(status string, seqReply int64, data map[string]interface{}) *WebSocketResponse { 141 return &WebSocketResponse{Status: status, SeqReply: seqReply, Data: data} 142 } 143 144 func NewWebSocketError(seqReply int64, err *AppError) *WebSocketResponse { 145 return &WebSocketResponse{Status: STATUS_FAIL, SeqReply: seqReply, Error: err} 146 } 147 148 func (o *WebSocketResponse) IsValid() bool { 149 return o.Status != "" 150 } 151 152 func (o *WebSocketResponse) EventType() string { 153 return WEBSOCKET_EVENT_RESPONSE 154 } 155 156 func (o *WebSocketResponse) ToJson() string { 157 b, _ := json.Marshal(o) 158 return string(b) 159 } 160 161 func WebSocketResponseFromJson(data io.Reader) *WebSocketResponse { 162 var o *WebSocketResponse 163 json.NewDecoder(data).Decode(&o) 164 return o 165 }