ADR-137: Technical Assessment for the new Friend Request

More details about this document
Latest published version:
https://adr.decentraland.org/adr/ADR-137
Authors:
sandrade-dcl
lorux0
Feedback:
GitHub decentraland/adr (pull requests, new issue, open issues)
Edit this documentation:
GitHub View commits View commits on githistory.xyz

Need

This is a technical proposal for the needs described here: PRD: New Friend Requests

The intention of this document is:

Involved teams

This initiative will require a cross team effort that will include the following teams:

The different responsibilities will be covered in more detail in the analysis of each part of the feature. A tag to the respective team will be placed next to each functionality.

Approach

For this to work we need to synchronize the information between the Renderer, Kernel and Matrix servers.

Due to the current architecture implemented in the backend side, the idea would be to use always Kernel as a bridge between the Renderer and the Matrix server. So any communication needed between both sides will be done through messages in Kernel↔Renderer and the message exchange is defined by RPC calls.

In terms of needed communications, we have identified the next main dependencies between Client and Backend:

Send a Friend Request

kernelrendererkernelrendererThe user sends a friend request from the pop-up.Ask the server to create the friend request.In case of success, create a new entry in the SENT requests list.In case of error, show the error.SendFriendRequest(SendFriendRequestPayload{ userId:'0x...', messageBody='hello!' })AddUserProfilesToCatalog(addUserProfilesPayload)SendFriendRequestReply({ message: { reply: SendFriendRequestReplyOk | error: int }})
SendFriendRequestPayload {
  string user_id = 1;
  string message_body = 2;
}
SendFriendRequestReplyOk {
  FriendRequestInfo friend_request = 1; // Friend request info on the request you've sent to a user
}
SendFriendRequestReply {
  oneof message {
    SendFriendRequestReplyOk reply = 1;
    FriendshipErrorCode error = 2;
  }
}

Cancel a Friend Request

kernelrendererkernelrendererThe user cancels a friend request from the list.Ask the server to cancel the friend request.In case of success, remove the entry from the SENT requests list.In case of error, show the error.CancelFriendRequest(CancelFriendRequestPayload{ friendRequestId: '<id>' })CancelFriendRequestReply({ message: { reply: CancelFriendRequestReplyOk | error: int }})
CancelFriendRequestPayload {
  string friend_request_id = 1;
}
CancelFriendRequestReplyOk {
  FriendRequestInfo friend_request = 1; // Friend request info on the request you've canceled
}
CancelFriendRequestReply {
  oneof message {
    CancelFriendRequestReplyOk reply = 1;
    FriendshipErrorCode error = 2;
  }
}

Accept a Friend Request

kernelrendererkernelrendererThe user accepts a friend request from the pop-up.Ask the server to accept the friend request.In case of success, add a new entry in the notifications panel and remove the new entry from the RECEIVED requests list.In case of error, show the error.In case of success, if the friend request has a non-empty message body, it must be registered as part of the messages history of that user.Display the unseen message as usual.AcceptFriendRequest(AcceptFriendRequestPayload{ friendRequestId: '<id>'})AcceptFriendRequestReply({ message: { reply: AcceptFriendRequestReplyOk | error: int }})Add the chat message and increase the unseen notifications counter for that specific user.
AcceptFriendRequestPayload {
  string friend_request_id = 1;
}
AcceptFriendRequestReplyOk {
  FriendRequestInfo friend_request = 1;
}
AcceptFriendRequestReply {
  oneof message {
    AcceptFriendRequestReplyOk reply = 1;
    FriendshipErrorCode error = 2;
  }
}

Reject a Friend Request

kernelrendererkernelrendererThe user rejects a friend request from the pop-up.Ask the server to reject the friend request.In case of success, remove the new entry from the RECEIVED requests list.In case of error, show the error.RejectFriendRequest(RejectFriendRequestPayload{ friendRequestId: '<id>'})RejectFriendRequestReply({ message: { reply: RejectFriendRequestReplyOk | error: int }})
RejectFriendRequestPayload {
  string friend_request_id = 1;
}
RejectFriendRequestReplyOk {
  FriendRequestInfo friend_request = 1;
}
RejectFriendRequestReply {
  oneof message {
    RejectFriendRequestReplyOk reply = 1;
    FriendshipErrorCode error = 2;
  }
}

Received Friend Request (push notifications)

kernelrendererkernelrendererDuring the session.An user sends us a friend request.Create a new entry in the RECEIVED requests list.Add a new entry in the notifications panel.AddUserProfilesToCatalog(addUserProfilesPayload)ReceiveFriendRequest(RendererReceiveFriendRequestPayload{ friend_request: {...}} )
RendererReceiveFriendRequestPayload {
    FriendRequestInfo friend_request = 1;
}

Canceled Friend Request (push notifications)

kernelrendererkernelrendererDuring the session.An user cancels us a friend request.AddUserProfilesToCatalog(addUserProfilesPayload)CancelFriendRequest(RendererCancelFriendRequestPayload{ <'id'> } )
RendererCancelFriendRequestPayload {
    string user_id = 1;
}

Rejected Friend Request (push notifications)

kernelrendererkernelrendererDuring the session.An user rejects us a friend request.AddUserProfilesToCatalog(addUserProfilesPayload)RejectFriendRequest(RendererRejectFriendRequestPayload{ <'id'> } )
RendererRejectFriendRequestPayload {
    string user_id = 1;
}

Approved Friend Request (push notifications)

kernelrendererkernelrendererDuring the session.An user approves us a friend request.AddUserProfilesToCatalog(addUserProfilesPayload)ApproveFriendRequest(RendererApproveFriendRequestPayload{ <'id'> } )
RendererApproveFriendRequestPayload {
    string user_id = 1;
}

Get Friend Request List

kernelrendererkernelrendererRequest the first (50) sent/received requests to the server.Needed to fill in the UI info later.Show online/offline status of each request.The user clicks on "show more requests".Requests the next 30 friend requests to server.GetFriendRequests(GetFriendRequestsPayload{ sentLimit: 50, sentSkip: 0, receivedLimit: 50, receivedSkip: 0 })AddUserProfilesToCatalog(addUserProfilesPayload)GetFriendRequestsReply({ message: { reply: GetFriendRequestsReplyOk | error: int }})UpdateUserPresence(userPresencePayload)GetFriendRequests(GetFriendRequestsPayload{sentLimit: 30, sentSkip: 50, receivedLimit: 30, receivedSkip: 50})AddUserProfilesToCatalog(addUserProfilesPayload)GetFriendRequestsReply({ message: { reply: GetFriendRequestsReplyOk | error: int }})UpdateUserPresence(userPresencePayload)
GetFriendRequestsPayload {
  int32 sent_limit = 1; // Max amount of entries of sent friend requests to request
  int32 sent_skip = 2; // The amount of entries of sent friend requests to skip
  int32 received_limit = 3; // Max amount of entries of received friend requests to request
  int32 received_skip = 4; // The amount of entries of received friend requests to skip
}
GetFriendRequestsReplyOk {
  repeated FriendRequestInfo requested_to = 1; // Friend request info on the requests you've sent to users
  repeated FriendRequestInfo requested_from = 2; // Friend request info on the requests you've received from users
  int32 total_received_friend_requests = 3; // Total amount of friend requests received
  int32 total_sent_friend_requests = 4; // Total amount of friend requests sent
}
GetFriendRequestsReply {
  oneof message {
    GetFriendRequestsReplyOk reply = 1;
    FriendshipErrorCode error = 2;
  }
}

Common Payloads

FriendRequestInfo {
  string friend_request_id = 1;
  uint64 timestamp = 2;
  string from = 3;
  string to = 4;
  optional string message_body = 5;
}
FriendshipErrorCode {
  FEC_TOO_MANY_REQUESTS_SENT = 0; // Any uncategorized friend request related error
  FEC_NOT_ENOUGH_TIME_PASSED = 1;
  FEC_BLOCKED_USER = 2;
  FEC_NON_EXISTING_USER = 3;
  FEC_INVALID_REQUEST = 4;
  FEC_UNKNOWN = 5;
}

License

Copyright and related rights waived via CC0-1.0. DRAFT Review