github.com/dschalla/mattermost-server@v4.8.1-rc1+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_DELETED = "channel_deleted" 18 WEBSOCKET_EVENT_CHANNEL_CREATED = "channel_created" 19 WEBSOCKET_EVENT_CHANNEL_UPDATED = "channel_updated" 20 WEBSOCKET_EVENT_DIRECT_ADDED = "direct_added" 21 WEBSOCKET_EVENT_GROUP_ADDED = "group_added" 22 WEBSOCKET_EVENT_NEW_USER = "new_user" 23 WEBSOCKET_EVENT_ADDED_TO_TEAM = "added_to_team" 24 WEBSOCKET_EVENT_LEAVE_TEAM = "leave_team" 25 WEBSOCKET_EVENT_UPDATE_TEAM = "update_team" 26 WEBSOCKET_EVENT_DELETE_TEAM = "delete_team" 27 WEBSOCKET_EVENT_USER_ADDED = "user_added" 28 WEBSOCKET_EVENT_USER_UPDATED = "user_updated" 29 WEBSOCKET_EVENT_USER_ROLE_UPDATED = "user_role_updated" 30 WEBSOCKET_EVENT_MEMBERROLE_UPDATED = "memberrole_updated" 31 WEBSOCKET_EVENT_USER_REMOVED = "user_removed" 32 WEBSOCKET_EVENT_PREFERENCE_CHANGED = "preference_changed" 33 WEBSOCKET_EVENT_PREFERENCES_CHANGED = "preferences_changed" 34 WEBSOCKET_EVENT_PREFERENCES_DELETED = "preferences_deleted" 35 WEBSOCKET_EVENT_EPHEMERAL_MESSAGE = "ephemeral_message" 36 WEBSOCKET_EVENT_STATUS_CHANGE = "status_change" 37 WEBSOCKET_EVENT_HELLO = "hello" 38 WEBSOCKET_EVENT_WEBRTC = "webrtc" 39 WEBSOCKET_AUTHENTICATION_CHALLENGE = "authentication_challenge" 40 WEBSOCKET_EVENT_REACTION_ADDED = "reaction_added" 41 WEBSOCKET_EVENT_REACTION_REMOVED = "reaction_removed" 42 WEBSOCKET_EVENT_RESPONSE = "response" 43 WEBSOCKET_EVENT_EMOJI_ADDED = "emoji_added" 44 WEBSOCKET_EVENT_CHANNEL_VIEWED = "channel_viewed" 45 WEBSOCKET_EVENT_PLUGIN_ACTIVATED = "plugin_activated" // EXPERIMENTAL - SUBJECT TO CHANGE 46 WEBSOCKET_EVENT_PLUGIN_DEACTIVATED = "plugin_deactivated" // EXPERIMENTAL - SUBJECT TO CHANGE 47 ) 48 49 type WebSocketMessage interface { 50 ToJson() string 51 IsValid() bool 52 EventType() string 53 } 54 55 type WebsocketBroadcast struct { 56 OmitUsers map[string]bool `json:"omit_users"` // broadcast is omitted for users listed here 57 UserId string `json:"user_id"` // broadcast only occurs for this user 58 ChannelId string `json:"channel_id"` // broadcast only occurs for users in this channel 59 TeamId string `json:"team_id"` // broadcast only occurs for users in this team 60 } 61 62 type precomputedWebSocketEventJSON struct { 63 Event json.RawMessage 64 Data json.RawMessage 65 Broadcast json.RawMessage 66 } 67 68 type WebSocketEvent struct { 69 Event string `json:"event"` 70 Data map[string]interface{} `json:"data"` 71 Broadcast *WebsocketBroadcast `json:"broadcast"` 72 Sequence int64 `json:"seq"` 73 74 precomputedJSON *precomputedWebSocketEventJSON 75 } 76 77 // PrecomputeJSON precomputes and stores the serialized JSON for all fields other than Sequence. 78 // This makes ToJson much more efficient when sending the same event to multiple connections. 79 func (m *WebSocketEvent) PrecomputeJSON() { 80 event, _ := json.Marshal(m.Event) 81 data, _ := json.Marshal(m.Data) 82 broadcast, _ := json.Marshal(m.Broadcast) 83 m.precomputedJSON = &precomputedWebSocketEventJSON{ 84 Event: json.RawMessage(event), 85 Data: json.RawMessage(data), 86 Broadcast: json.RawMessage(broadcast), 87 } 88 } 89 90 func (m *WebSocketEvent) Add(key string, value interface{}) { 91 m.Data[key] = value 92 } 93 94 func NewWebSocketEvent(event, teamId, channelId, userId string, omitUsers map[string]bool) *WebSocketEvent { 95 return &WebSocketEvent{Event: event, Data: make(map[string]interface{}), 96 Broadcast: &WebsocketBroadcast{TeamId: teamId, ChannelId: channelId, UserId: userId, OmitUsers: omitUsers}} 97 } 98 99 func (o *WebSocketEvent) IsValid() bool { 100 return o.Event != "" 101 } 102 103 func (o *WebSocketEvent) EventType() string { 104 return o.Event 105 } 106 107 func (o *WebSocketEvent) ToJson() string { 108 if o.precomputedJSON != nil { 109 return fmt.Sprintf(`{"event": %s, "data": %s, "broadcast": %s, "seq": %d}`, o.precomputedJSON.Event, o.precomputedJSON.Data, o.precomputedJSON.Broadcast, o.Sequence) 110 } 111 b, _ := json.Marshal(o) 112 return string(b) 113 } 114 115 func WebSocketEventFromJson(data io.Reader) *WebSocketEvent { 116 var o *WebSocketEvent 117 json.NewDecoder(data).Decode(&o) 118 return o 119 } 120 121 type WebSocketResponse struct { 122 Status string `json:"status"` 123 SeqReply int64 `json:"seq_reply,omitempty"` 124 Data map[string]interface{} `json:"data,omitempty"` 125 Error *AppError `json:"error,omitempty"` 126 } 127 128 func (m *WebSocketResponse) Add(key string, value interface{}) { 129 m.Data[key] = value 130 } 131 132 func NewWebSocketResponse(status string, seqReply int64, data map[string]interface{}) *WebSocketResponse { 133 return &WebSocketResponse{Status: status, SeqReply: seqReply, Data: data} 134 } 135 136 func NewWebSocketError(seqReply int64, err *AppError) *WebSocketResponse { 137 return &WebSocketResponse{Status: STATUS_FAIL, SeqReply: seqReply, Error: err} 138 } 139 140 func (o *WebSocketResponse) IsValid() bool { 141 return o.Status != "" 142 } 143 144 func (o *WebSocketResponse) EventType() string { 145 return WEBSOCKET_EVENT_RESPONSE 146 } 147 148 func (o *WebSocketResponse) ToJson() string { 149 b, _ := json.Marshal(o) 150 return string(b) 151 } 152 153 func WebSocketResponseFromJson(data io.Reader) *WebSocketResponse { 154 var o *WebSocketResponse 155 json.NewDecoder(data).Decode(&o) 156 return o 157 }