From 65b76c2712eea4daa1633e4652fa3cd51037e854 Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Fri, 27 Jan 2017 15:58:50 -0500 Subject: PLT-5225 Added separate post types for certain system messages (#5193) * Added separate post types for system_join_leave and system_add_remove posts * Added username prop to channel deleted posts * Changed slack import to properly generate the new join/leave messages * Added username prop to channel update posts * Moved Post(AddTo/RemoveFrom)ChanneMessage into app package --- api/channel.go | 5 +- app/channel.go | 130 +++++++++++++++++++++++++++++++------------ app/slackimport.go | 13 ++++- model/post.go | 10 +++- store/sql_post_store.go | 3 +- store/sql_post_store_test.go | 2 +- 6 files changed, 119 insertions(+), 44 deletions(-) diff --git a/api/channel.go b/api/channel.go index 474c41d07..c5ec36d4b 100644 --- a/api/channel.go +++ b/api/channel.go @@ -4,7 +4,6 @@ package api import ( - "fmt" "net/http" "strconv" "strings" @@ -644,7 +643,7 @@ func addMember(c *Context, w http.ResponseWriter, r *http.Request) { return } - go app.PostUserAddRemoveMessage(c.Session.UserId, channel.Id, channel.TeamId, fmt.Sprintf(utils.T("api.channel.add_member.added"), nUser.Username, oUser.Username), model.POST_ADD_REMOVE) + go app.PostAddToChannelMessage(oUser, nUser, channel) app.UpdateChannelLastViewedAt([]string{id}, oUser.Id) w.Write([]byte(cm.ToJson())) @@ -697,7 +696,7 @@ func removeMember(c *Context, w http.ResponseWriter, r *http.Request) { return } - go app.PostUserAddRemoveMessage(c.Session.UserId, channel.Id, channel.TeamId, fmt.Sprintf(utils.T("api.channel.remove_member.removed"), user.Username), model.POST_ADD_REMOVE) + go app.PostRemoveFromChannelMessage(c.Session.UserId, user, channel) result := make(map[string]string) result["channel_id"] = channel.Id diff --git a/app/channel.go b/app/channel.go index c9199f829..818e241b7 100644 --- a/app/channel.go +++ b/app/channel.go @@ -91,49 +91,39 @@ func JoinDefaultChannels(teamId string, user *model.User, channelRole string) *m if result := <-Srv.Store.Channel().GetByName(teamId, "town-square", true); result.Err != nil { err = result.Err } else { - cm := &model.ChannelMember{ChannelId: result.Data.(*model.Channel).Id, UserId: user.Id, + townSquare := result.Data.(*model.Channel) + + cm := &model.ChannelMember{ChannelId: townSquare.Id, UserId: user.Id, Roles: channelRole, NotifyProps: model.GetDefaultChannelNotifyProps()} if cmResult := <-Srv.Store.Channel().SaveMember(cm); cmResult.Err != nil { err = cmResult.Err } - post := &model.Post{ - ChannelId: result.Data.(*model.Channel).Id, - Message: fmt.Sprintf(utils.T("api.channel.join_channel.post_and_forget"), user.Username), - Type: model.POST_JOIN_LEAVE, - UserId: user.Id, + if err := postJoinChannelMessage(user, townSquare); err != nil { + l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) } InvalidateCacheForChannelMembers(result.Data.(*model.Channel).Id) - - if _, err := CreatePost(post, teamId, false); err != nil { - l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) - } } if result := <-Srv.Store.Channel().GetByName(teamId, "off-topic", true); result.Err != nil { err = result.Err } else { - cm := &model.ChannelMember{ChannelId: result.Data.(*model.Channel).Id, UserId: user.Id, + offTopic := result.Data.(*model.Channel) + + cm := &model.ChannelMember{ChannelId: offTopic.Id, UserId: user.Id, Roles: channelRole, NotifyProps: model.GetDefaultChannelNotifyProps()} if cmResult := <-Srv.Store.Channel().SaveMember(cm); cmResult.Err != nil { err = cmResult.Err } - post := &model.Post{ - ChannelId: result.Data.(*model.Channel).Id, - Message: fmt.Sprintf(utils.T("api.channel.join_channel.post_and_forget"), user.Username), - Type: model.POST_JOIN_LEAVE, - UserId: user.Id, + if err := postJoinChannelMessage(user, offTopic); err != nil { + l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) } InvalidateCacheForChannelMembers(result.Data.(*model.Channel).Id) - - if _, err := CreatePost(post, teamId, false); err != nil { - l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) - } } return err @@ -276,6 +266,9 @@ func DeleteChannel(channel *model.Channel, userId string) *model.AppError { Message: fmt.Sprintf(T("api.channel.delete_channel.archived"), user.Username), Type: model.POST_CHANNEL_DELETED, UserId: userId, + Props: model.StringInterface{ + "username": user.Username, + }, } if _, err := CreatePost(post, channel.TeamId, false); err != nil { @@ -423,6 +416,7 @@ func PostUpdateChannelHeaderMessage(userId string, channelId string, teamId stri Type: model.POST_HEADER_CHANGE, UserId: userId, Props: model.StringInterface{ + "username": user.Username, "old_header": oldChannelHeader, "new_header": newChannelHeader, }, @@ -459,6 +453,7 @@ func PostUpdateChannelPurposeMessage(userId string, channelId string, teamId str Type: model.POST_PURPOSE_CHANGE, UserId: userId, Props: model.StringInterface{ + "username": user.Username, "old_purpose": oldChannelPurpose, "new_purpose": newChannelPurpose, }, @@ -487,6 +482,7 @@ func PostUpdateChannelDisplayNameMessage(userId string, channelId string, teamId Type: model.POST_DISPLAYNAME_CHANGE, UserId: userId, Props: model.StringInterface{ + "username": user.Username, "old_displayname": oldChannelDisplayName, "new_displayname": newChannelDisplayName, }, @@ -588,7 +584,10 @@ func JoinChannel(channel *model.Channel, userId string) *model.AppError { if _, err := AddUserToChannel(user, channel); err != nil { return err } - PostUserAddRemoveMessage(userId, channel.Id, channel.TeamId, fmt.Sprintf(utils.T("api.channel.join_channel.post_and_forget"), user.Username), model.POST_JOIN_LEAVE) + + if err := postJoinChannelMessage(user, channel); err != nil { + return err + } } else { return model.NewLocAppError("JoinChannel", "api.channel.join_channel.permissions.app_error", nil, "") } @@ -597,6 +596,24 @@ func JoinChannel(channel *model.Channel, userId string) *model.AppError { return nil } +func postJoinChannelMessage(user *model.User, channel *model.Channel) *model.AppError { + post := &model.Post{ + ChannelId: channel.Id, + Message: fmt.Sprintf(utils.T("api.channel.join_channel.post_and_forget"), user.Username), + Type: model.POST_JOIN_CHANNEL, + UserId: user.Id, + Props: model.StringInterface{ + "username": user.Username, + }, + } + + if _, err := CreatePost(post, channel.TeamId, false); err != nil { + return model.NewLocAppError("postJoinChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error()) + } + + return nil +} + func LeaveChannel(channelId string, userId string) *model.AppError { sc := Srv.Store.Channel().Get(channelId, true) uc := Srv.Store.User().Get(userId) @@ -629,7 +646,62 @@ func LeaveChannel(channelId string, userId string) *model.AppError { return err } - go PostUserAddRemoveMessage(userId, channel.Id, channel.TeamId, fmt.Sprintf(utils.T("api.channel.leave.left"), user.Username), model.POST_JOIN_LEAVE) + go postLeaveChannelMessage(user, channel) + } + + return nil +} + +func postLeaveChannelMessage(user *model.User, channel *model.Channel) *model.AppError { + post := &model.Post{ + ChannelId: channel.Id, + Message: fmt.Sprintf(utils.T("api.channel.leave.left"), user.Username), + Type: model.POST_LEAVE_CHANNEL, + UserId: user.Id, + Props: model.StringInterface{ + "username": user.Username, + }, + } + + if _, err := CreatePost(post, channel.TeamId, false); err != nil { + return model.NewLocAppError("postLeaveChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error()) + } + + return nil +} + +func PostAddToChannelMessage(user *model.User, addedUser *model.User, channel *model.Channel) *model.AppError { + post := &model.Post{ + ChannelId: channel.Id, + Message: fmt.Sprintf(utils.T("api.channel.add_member.added"), addedUser.Username, user.Username), + Type: model.POST_ADD_TO_CHANNEL, + UserId: user.Id, + Props: model.StringInterface{ + "username": user.Username, + "addedUsername": addedUser.Username, + }, + } + + if _, err := CreatePost(post, channel.TeamId, false); err != nil { + return model.NewLocAppError("postAddToChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error()) + } + + return nil +} + +func PostRemoveFromChannelMessage(removerUserId string, removedUser *model.User, channel *model.Channel) *model.AppError { + post := &model.Post{ + ChannelId: channel.Id, + Message: fmt.Sprintf(utils.T("api.channel.remove_member.removed"), removedUser.Username), + Type: model.POST_REMOVE_FROM_CHANNEL, + UserId: removerUserId, + Props: model.StringInterface{ + "removedUsername": removedUser.Username, + }, + } + + if _, err := CreatePost(post, channel.TeamId, false); err != nil { + return model.NewLocAppError("postRemoveFromChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error()) } return nil @@ -667,20 +739,6 @@ func RemoveUserFromChannel(userIdToRemove string, removerUserId string, channel return nil } -func PostUserAddRemoveMessage(userId, channelId, teamId, message, postType string) *model.AppError { - post := &model.Post{ - ChannelId: channelId, - Message: message, - Type: postType, - UserId: userId, - } - if _, err := CreatePost(post, teamId, false); err != nil { - return model.NewLocAppError("PostUserAddRemoveMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error()) - } - - return nil -} - func GetNumberOfChannelsOnTeam(teamId string) (int, *model.AppError) { // Get total number of channels on current team if result := <-Srv.Store.Channel().GetTeamChannels(teamId); result.Err != nil { diff --git a/app/slackimport.go b/app/slackimport.go index 3289f140e..e4beb3d3d 100644 --- a/app/slackimport.go +++ b/app/slackimport.go @@ -307,12 +307,23 @@ func SlackAddPosts(teamId string, channel *model.Channel, posts []SlackPost, use l4g.Debug(utils.T("api.slackimport.slack_add_posts.user_no_exists.debug"), sPost.User) continue } + + var postType string + if sPost.SubType == "channel_join" { + postType = model.POST_JOIN_CHANNEL + } else { + postType = model.POST_LEAVE_CHANNEL + } + newPost := model.Post{ UserId: users[sPost.User].Id, ChannelId: channel.Id, Message: sPost.Text, CreateAt: SlackConvertTimeStamp(sPost.TimeStamp), - Type: model.POST_JOIN_LEAVE, + Type: postType, + Props: model.StringInterface{ + "username": users[sPost.User].Username, + }, } ImportPost(&newPost) case sPost.Type == "message" && sPost.SubType == "me_message": diff --git a/model/post.go b/model/post.go index 668c4db61..a7729e0c4 100644 --- a/model/post.go +++ b/model/post.go @@ -14,8 +14,12 @@ const ( POST_DEFAULT = "" POST_SLACK_ATTACHMENT = "slack_attachment" POST_SYSTEM_GENERIC = "system_generic" - POST_JOIN_LEAVE = "system_join_leave" - POST_ADD_REMOVE = "system_add_remove" + POST_JOIN_LEAVE = "system_join_leave" // Deprecated, use POST_JOIN_CHANNEL or POST_LEAVE_CHANNEL instead + POST_JOIN_CHANNEL = "system_join_channel" + POST_LEAVE_CHANNEL = "system_leave_channel" + POST_ADD_REMOVE = "system_add_remove" // Deprecated, use POST_ADD_TO_CHANNEL or POST_REMOVE_FROM_CHANNEL instead + POST_ADD_TO_CHANNEL = "system_add_to_channel" + POST_REMOVE_FROM_CHANNEL = "system_remove_from_channel" POST_HEADER_CHANGE = "system_header_change" POST_DISPLAYNAME_CHANGE = "system_displayname_change" POST_PURPOSE_CHANGE = "system_purpose_change" @@ -121,6 +125,8 @@ func (o *Post) IsValid() *AppError { // should be removed once more message types are supported if !(o.Type == POST_DEFAULT || o.Type == POST_JOIN_LEAVE || o.Type == POST_ADD_REMOVE || + o.Type == POST_JOIN_CHANNEL || o.Type == POST_LEAVE_CHANNEL || + o.Type == POST_REMOVE_FROM_CHANNEL || o.Type == POST_ADD_TO_CHANNEL || o.Type == POST_SLACK_ATTACHMENT || o.Type == POST_HEADER_CHANGE || o.Type == POST_PURPOSE_CHANGE || o.Type == POST_DISPLAYNAME_CHANGE || o.Type == POST_CHANNEL_DELETED) { return NewLocAppError("Post.IsValid", "model.post.is_valid.type.app_error", nil, "id="+o.Type) diff --git a/store/sql_post_store.go b/store/sql_post_store.go index ed87b01f7..a8fe52380 100644 --- a/store/sql_post_store.go +++ b/store/sql_post_store.go @@ -93,7 +93,8 @@ func (s SqlPostStore) Save(post *model.Post) StoreChannel { } else { time := post.UpdateAt - if post.Type != model.POST_JOIN_LEAVE && post.Type != model.POST_ADD_REMOVE { + if post.Type != model.POST_JOIN_LEAVE && post.Type != model.POST_JOIN_CHANNEL && post.Type != model.POST_LEAVE_CHANNEL && + post.Type != model.POST_ADD_REMOVE && post.Type != model.POST_ADD_TO_CHANNEL && post.Type != model.POST_REMOVE_FROM_CHANNEL { s.GetMaster().Exec("UPDATE Channels SET LastPostAt = :LastPostAt, TotalMsgCount = TotalMsgCount + 1 WHERE Id = :ChannelId", map[string]interface{}{"LastPostAt": time, "ChannelId": post.ChannelId}) } else { // don't update TotalMsgCount for unimportant messages so that the channel isn't marked as unread diff --git a/store/sql_post_store_test.go b/store/sql_post_store_test.go index e3886c6bc..7416e0ab7 100644 --- a/store/sql_post_store_test.go +++ b/store/sql_post_store_test.go @@ -799,7 +799,7 @@ func TestPostStoreSearch(t *testing.T) { o1a.ChannelId = c1.Id o1a.UserId = model.NewId() o1a.Message = "corey mattermost new york" - o1a.Type = model.POST_JOIN_LEAVE + o1a.Type = model.POST_JOIN_CHANNEL o1a = (<-store.Post().Save(o1a)).Data.(*model.Post) o2 := &model.Post{} -- cgit v1.2.3-1-g7c22