From b6ae2178833c7f1cd96e0de2503a9a79277f442c Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Thu, 26 Aug 2021 15:24:12 -0400 Subject: [PATCH] MM-37372 Do not autofollow threads started by webhooks/bots for user who created them (#18276) * Do not autofollow threads started by webhooks/bots for user who created them * Add test --- app/notification.go | 6 ++++-- app/notification_test.go | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/app/notification.go b/app/notification.go index f57dcd3c45..a7d0319f10 100644 --- a/app/notification.go +++ b/app/notification.go @@ -201,9 +201,11 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod if *a.Config().ServiceSettings.ThreadAutoFollow && post.RootId != "" { var rootMentions *ExplicitMentions if parentPostList != nil { - threadParticipants[parentPostList.Posts[parentPostList.Order[0]].UserId] = true + rootPost := parentPostList.Posts[parentPostList.Order[0]] + if rootPost.GetProp("from_webhook") != "true" { + threadParticipants[rootPost.UserId] = true + } if channel.Type != model.ChannelTypeDirect { - rootPost := parentPostList.Posts[parentPostList.Order[0]] rootMentions = getExplicitMentions(rootPost, keywords, groups) for id := range rootMentions.Mentions { threadParticipants[id] = true diff --git a/app/notification_test.go b/app/notification_test.go index f82027849e..635589080c 100644 --- a/app/notification_test.go +++ b/app/notification_test.go @@ -2705,4 +2705,47 @@ func TestReplyPostNotificationsWithCRT(t *testing.T) { // Then: last post is still marked as unread require.Equal(t, int64(1), thread.UnreadReplies) }) + + t.Run("Replies to post created by webhook should not auto-follow webhook creator", func(t *testing.T) { + th := Setup(t).InitBasic() + defer th.TearDown() + + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.ServiceSettings.ThreadAutoFollow = true + *cfg.ServiceSettings.CollapsedThreads = model.CollapsedThreadsDefaultOn + }) + + user := th.BasicUser + + rootPost := &model.Post{ + UserId: user.Id, + ChannelId: th.BasicChannel.Id, + Message: "a message", + Props: model.StringInterface{"from_webhook": "true", "override_username": "a bot"}, + } + + rootPost, appErr := th.App.CreatePostMissingChannel(th.Context, rootPost, false) + require.Nil(t, appErr) + + childPost := &model.Post{ + UserId: th.BasicUser2.Id, + ChannelId: th.BasicChannel.Id, + RootId: rootPost.Id, + Message: "a reply", + } + childPost, appErr = th.App.CreatePostMissingChannel(th.Context, childPost, false) + require.Nil(t, appErr) + + postList := model.PostList{ + Order: []string{rootPost.Id, childPost.Id}, + Posts: map[string]*model.Post{rootPost.Id: rootPost, childPost.Id: childPost}, + } + mentions, err := th.App.SendNotifications(childPost, th.BasicTeam, th.BasicChannel, th.BasicUser2, &postList, true) + require.NoError(t, err) + assert.False(t, utils.StringInSlice(user.Id, mentions)) + + membership, err := th.App.GetThreadMembershipForUser(user.Id, rootPost.Id) + assert.Error(t, err) + assert.Nil(t, membership) + }) }