Feature/oc 1316 add support for system message to single user (#1351)

* add public func to lookup a ChatClient by its clientId

* add facility to send a system message directly to a user

* add clientId field to UserEvent

* implement simple http endpoint to send a message to a user

* let mux handle new directSystemMessageToUser endpoint

* add ClientId to UserEvents across the codebase

* render body of system-message to client

* add clientId to Chat-Message

* add tests showing how url-parsing should work

* add simple rest endpoint helpers for parameter-parsing and easy routing

* use newly added rest-endpoint helper to rout to Client-Messaging controller

* use safe "ReadRestUrlParameter" to parse ClientId

* remove empty HandleFunc in router

* set Header directly to prevent built-in (platform-dependent) canonicalization to kick in

* fix typo in "Parameter" message

* remove debug-logging of HTTP headers in REST-helpers

* convert to uint32 to prevent overruns when converting to wraptype uint later on

* resolve linter-ouchies

* resolve linter potential nil-deref warning

* document the SendSystemMessageToClient endpoint in swaggerdoc

* remove clientId assignment causing potential nil dereference in userDisabledEvent-case

as the clientId isn't relevant here anyway

* make findClientById private, so its not accessible outside of core/chat

* remove redundant string type hint

* Update PR based on linter requirements

Co-authored-by: Raffael Rehberger <raffael@rtrace.io>
Co-authored-by: Gabe Kangas <gabek@real-ity.com>
This commit is contained in:
Ruffy
2021-09-13 10:26:28 +02:00
committed by GitHub
parent 608888317b
commit 9c484efd36
11 changed files with 211 additions and 0 deletions

View File

@@ -41,6 +41,12 @@ func GetClientsForUser(userID string) ([]*Client, error) {
return clients[userID], nil
}
// FindClientByID will return a single connected client by ID.
func FindClientByID(clientID uint) (*Client, bool) {
client, found := _server.clients[clientID]
return client, found
}
// GetClients will return all the current chat clients connected.
func GetClients() []*Client {
clients := []*Client{}
@@ -105,6 +111,13 @@ func SendAllWelcomeMessage() {
_server.sendAllWelcomeMessage()
}
// SendSystemMessageToClient will send a single message to a single connected chat client.
func SendSystemMessageToClient(clientID uint, text string) {
if client, foundClient := FindClientByID(clientID); foundClient {
_server.sendSystemMessageToClient(client, text)
}
}
// Broadcast will send all connected clients the outbound object provided.
func Broadcast(event events.OutboundEvent) error {
return _server.Broadcast(event.GetBroadcastPayload())

View File

@@ -66,6 +66,7 @@ func (s *Server) userNameChanged(eventData chatClientEvent) {
// Send chat user name changed webhook
receivedEvent.User = savedUser
receivedEvent.ClientID = eventData.client.id
webhooks.SendChatEventUsernameChanged(receivedEvent)
}
@@ -77,6 +78,7 @@ func (s *Server) userMessageSent(eventData chatClientEvent) {
}
event.SetDefaults()
event.ClientID = eventData.client.id
// Ignore empty messages
if event.Empty() {

View File

@@ -36,6 +36,7 @@ type Event struct {
// UserEvent is an event with an associated user.
type UserEvent struct {
User *user.User `json:"user"`
ClientID uint `json:"clientId"`
HiddenAt *time.Time `json:"hiddenAt,omitempty"`
}

View File

@@ -115,6 +115,7 @@ func (s *Server) sendUserJoinedMessage(c *Client) {
userJoinedEvent := events.UserJoinedEvent{}
userJoinedEvent.SetDefaults()
userJoinedEvent.User = c.User
userJoinedEvent.ClientID = c.id
if err := s.Broadcast(userJoinedEvent.GetBroadcastPayload()); err != nil {
log.Errorln("error adding client to chat server", err)
@@ -317,6 +318,7 @@ func (s *Server) sendSystemMessageToClient(c *Client, message string) {
},
}
clientMessage.SetDefaults()
clientMessage.RenderBody()
s.Send(clientMessage.GetBroadcastPayload(), c)
}

View File

@@ -12,6 +12,7 @@ func SendChatEvent(chatEvent *events.UserMessageEvent) {
EventData: &WebhookChatMessage{
User: chatEvent.User,
Body: chatEvent.Body,
ClientID: chatEvent.ClientID,
RawBody: chatEvent.RawBody,
ID: chatEvent.ID,
Visible: chatEvent.HiddenAt == nil,

View File

@@ -23,6 +23,7 @@ type WebhookEvent struct {
// WebhookChatMessage represents a single chat message sent as a webhook payload.
type WebhookChatMessage struct {
User *user.User `json:"user,omitempty"`
ClientID uint `json:"clientId,omitempty"`
Body string `json:"body,omitempty"`
RawBody string `json:"rawBody,omitempty"`
ID string `json:"id,omitempty"`