Status: 50%
OVERVIEW
This document describes the main design and implementation decisions behind the "Group Mentions” feature. This feature provides ways for a MM user to mention groups and notify their members as well as to invite groups (and hence their members) to their channel and/or team.
GOALS
describe the changes and additions to the backend architecture (API and Storage)
describe the UX changes (webapp and redux)
describe the mobile changes.
SCOPE
In:
ability to mention group(s) in a channel
ability to notify the members of the group(s) that are being mentioned
ability to enable/disable the referencing (mention or invite) of a group in the System Console
display a warning if the group mention will trigger notifications to more than X number of users
ability to invite group(s) to a team using the “Invite Members/Guests” flow and to add to a team the members of the invited group(s)
ability to invite a single group to a channel using a “/invite” command and to add the members of this group to the channel
ability to enable or disable notifications per group
Out:
TBD
BACKGROUND READING
TERMINOLOGY
“Group-constrained” - when a group is linked to a channel or team and syncing its group members is turned on.
SPECIFICATIONS
High-level Architecture
Group Mentions
We can split the group mentioning flow into two phases: Build Suggestions and Notify Members. We will detail the design and the API, storage and client supporting changes for both of them.
Phase 1: Build Suggestions
Design
The flow of actions for this phase will be:
we fetch the group(s) objects from the server and use them to populate the client state
we filter the client state if the current channel or team is group-constrained or not and select the groups that fulfill the right conditions (see below)
we populate the mentions suggestion list with the names of the groups obtained in the previous step.
Group-Constrained Channel/Team Status
A channel or a team can be in two states:
constrained to the group(s)
not constrained by any group.
Depending if the current channel and/or the containing team is group constrained , we can have the following group mentioning cases:
If the current channel is constrained by the group(s), the user in the channel can only mention one of these groups.
Otherwise, if the current team is constrained to one or more groups, the user can only mention one or more of these groups.
If neither the current channel is constrained, nor the current team, then the user can mention any group constrained to any channel/group in the system. (currently all groups in MM are linked groups).
While we do not have a good grasp of many groups we can have in an org, we made the assumption that the number is small enough where we could fetch them from the server more than once during a session (we optimize this action by retrieving only the mentionable ones). The group mention flow is initiated from a channel's textbox; it is an expensive operation to repeatedly fetch the group(s) from the server as the user types - we will fetch the groups and populate the client state (depending if the channel/team is group-constrained or not) once per team initialization (which means that if we switch teams in the work session we will fetch the teams from the server again).
Future Work: Ideally, the groups will need to be fetched only once, at server start, not at every team change (and then only updated based on group-related System Console actions).
Duplicate group names
When we enable group mentioning on a group in the System Console, we are also generating the actual group name property from the group’s display name (e.g. from “software developers” to “@software-developers”). This happens at the server-side and since we enforce the uniqueness of the name
column in the UserGroups table, there is a potential of erroring by throwing a SQL exception if there is already a group with the same name already stored.
Future Work: Fully address the duplicate group name case. One solution would be to surface the duplicate error in the UI and allow the user to specify a different (custom) group name if the current one is a duplicate of another.
Groups with no team members
When we build the list of groups to mention, the groups are added to the list if the channel/team are group-constrained or not. However, it could be that for some of these groups none of their members are members of the current team. Since the members of these groups are not going to be notified, one solution is to avoid selecting them for inclusion in the mentions suggestion list to begin with. The current plan is to include these groups in the suggestion list.
Future Work: Filter out the groups that have no members in the current team from inclusion in the mentions suggestion list. Another proposed solution is to add an invite flow: “invite them now” quick link.
UI/X (Webapp)
Group Mention Settings Toggle Panel
we will add a new “Group Mention Settings” toggle widget containing a toggle in the Group Configuration details panel in the System Console. We will change the group states on the server at every UI toggle action (there is no Save action).
Future Work: converting this toggle into a proper “validate and update on Save" panel - the server state gets updated only when we click Save in the Group Configuration panel
Channel Textbox Suggestions List
when displaying the group mention in the suggestion list, we plan to include the group name and the group display name. There has been discussion to also display the member count (e.g. : “@software-developers - software developers - 4 members”)
Future work: Add a member count to the @group-name like : “@software-developers - 4 members”
UI/X (Redux)
Selectors:
searchAssociatedGroupsForReferenceLocal
- allows for searching of mentionable groups based on the user entered text
getAssociatedGroupsForReference
- returns the list of groups that constrain a channel and/or team (or not). If the current user’s role does not have USE_GROUP_MENTIONS permission, it will return an empty list.
getGroupsAssociatedToTeamForReference
getGroupsAssociatedToChannelForReference
getAllAssociatedGroupsForReference
Actions:
getGroups
patchGroup
getAllGroupsAssociatedToChannelsInTeam
REST API
we will add the following new endpoints:
Team : …/ groups_by_channels
getGroupsAssociatedToChannelsByTeam
(GET) - returns for a team, a map of channels constrained by groups and the corresponding groups.
we will update the following
GetGroups*
API endpoints with the additionalfilter_allow_reference
filter (default is false), to be able to retrieve only the groups that are enabled for mentions and invites.
GetGroupsByChannel
GetGroupsByTeam
GetGroupsAssociatedToChannelsByTeam
GetGroups
Storage
we will add a new SQL stored-procedure:
getGroupsAssociatedToChannelsByTeam
Tickets
Display group mentions in suggestions list in the main channel textbox
https://mattermost.atlassian.net/browse/MM-23016
Enable or Disable group mentions
https://mattermost.atlassian.net/browse/MM-23015
WebApp - Highlight Group Names in chat window
https://mattermost.atlassian.net/browse/MM-23159
Phase 2: Notify Members
After the groups have been selected from the suggestion list in the channel textbox, we need to notify their members about the mention.
Design
TODO - Describe Notifications phase design
Warning Modal
in the notification phase, when the aggregated number of group members to mention is above a certain threshold, we are showing a warning modal (see wireframe), the text message in the modal includes the user count from the largest group in the collection. This is a compromise solution, due to performance constraints - fetching the accurate count, including membership overlaps, from the server would introduce a delay in sending the notification.
Future work: Investigate a better solution?
UI/X(Webapp)
TODO - Describe Notifications phase design
UI/X(Redux)
TODO - Describe Notifications phase design
REST API
we will add the following new endpoints:
channel: “.../ member_counts_by_group/" channelMemberCountsByGroup`
(GET)
since we extend the range of calls to the GetGroups* methods from the SystemConsole to the chat-facing area will remove the permission check from the following API calls:
GetGroups
GetGroupsForTeam
…
Storage:
we will add the following new stored procedures:
GetMemberCountsByGroup
- returns a slice of ChannelMemberCountByGroup
for a given channel which contains the number of channel members for each group and optionally the number of unique timezones present for each group in the channel
GetMemberUsersNotInChannel
-
Tickets
Group Mentions - Show a confirmation dialog when mentioning a group with too many users
https://mattermost.atlassian.net/browse/MM-23264
Send notifications to the @-mentioned group members
https://mattermost.atlassian.net/browse/MM-23017
Supporting Work
Storage
we will add a new column to the UserGroups table:
AllowReference : boolean
Permissions
we will add a new permission USE_GROUP_MENTIONS
Tickets
Create use_group_mentions permission
https://mattermost.atlassian.net/browse/MM-23019
Websockets updates
Ticket: Ensure websockets are updating the referenceable groups (et al) in Redux for group-mentions
https://mattermost.atlassian.net/browse/MM-23395
CLI
Out of scope.
Configuration
None.
Plugins
Out of scope.
CREDITS
Thanks to Martin, Hossein, Farhan and Scott for great suggestions and brainstorming.