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