From c3be726326fb091d536fe98afea830faaefb8524 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Sat, 1 Nov 2025 04:44:31 +0900 Subject: [PATCH] appview/notify: notify users mentioned on PR comments Change-Id: wlxznsqvuwrqzlzuqtoquwooymxpvwyu Signed-off-by: Seongmin Lee --- appview/notify/db/db.go | 12 +++++++++++- appview/notify/merged_notifier.go | 4 ++-- appview/notify/notifier.go | 7 ++++--- appview/notify/posthog/notifier.go | 7 ++++--- appview/pulls/pulls.go | 12 +++++++++++- 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/appview/notify/db/db.go b/appview/notify/db/db.go index 56591ed0..ee815905 100644 --- a/appview/notify/db/db.go +++ b/appview/notify/db/db.go @@ -239,7 +239,7 @@ func (n *databaseNotifier) NewPull(ctx context.Context, pull *models.Pull) { ) } -func (n *databaseNotifier) NewPullComment(ctx context.Context, comment *models.PullComment) { +func (n *databaseNotifier) NewPullComment(ctx context.Context, comment *models.PullComment, mentions []syntax.DID) { pull, err := db.GetPull(n.db, syntax.ATURI(comment.RepoAt), comment.PullId, @@ -283,6 +283,16 @@ func (n *databaseNotifier) NewPullComment(ctx context.Context, comment *models.P issueId, pullId, ) + n.notifyEvent( + actorDid, + mentions, + models.NotificationTypeUserMentioned, + entityType, + entityId, + repoId, + issueId, + pullId, + ) } func (n *databaseNotifier) UpdateProfile(ctx context.Context, profile *models.Profile) { diff --git a/appview/notify/merged_notifier.go b/appview/notify/merged_notifier.go index 93809863..deaf57e5 100644 --- a/appview/notify/merged_notifier.go +++ b/appview/notify/merged_notifier.go @@ -82,8 +82,8 @@ func (m *mergedNotifier) NewPull(ctx context.Context, pull *models.Pull) { m.fanout("NewPull", ctx, pull) } -func (m *mergedNotifier) NewPullComment(ctx context.Context, comment *models.PullComment) { - m.fanout("NewPullComment", ctx, comment) +func (m *mergedNotifier) NewPullComment(ctx context.Context, comment *models.PullComment, mentions []syntax.DID) { + m.fanout("NewPullComment", ctx, comment, mentions) } func (m *mergedNotifier) NewPullState(ctx context.Context, actor syntax.DID, pull *models.Pull) { diff --git a/appview/notify/notifier.go b/appview/notify/notifier.go index b7058188..72462ce0 100644 --- a/appview/notify/notifier.go +++ b/appview/notify/notifier.go @@ -22,7 +22,7 @@ type Notifier interface { DeleteFollow(ctx context.Context, follow *models.Follow) NewPull(ctx context.Context, pull *models.Pull) - NewPullComment(ctx context.Context, comment *models.PullComment) + NewPullComment(ctx context.Context, comment *models.PullComment, mentions []syntax.DID) NewPullState(ctx context.Context, actor syntax.DID, pull *models.Pull) UpdateProfile(ctx context.Context, profile *models.Profile) @@ -51,8 +51,9 @@ func (m *BaseNotifier) DeleteIssue(ctx context.Context, issue *models.Issue) func (m *BaseNotifier) NewFollow(ctx context.Context, follow *models.Follow) {} func (m *BaseNotifier) DeleteFollow(ctx context.Context, follow *models.Follow) {} -func (m *BaseNotifier) NewPull(ctx context.Context, pull *models.Pull) {} -func (m *BaseNotifier) NewPullComment(ctx context.Context, models *models.PullComment) {} +func (m *BaseNotifier) NewPull(ctx context.Context, pull *models.Pull) {} +func (m *BaseNotifier) NewPullComment(ctx context.Context, models *models.PullComment, mentions []syntax.DID) { +} func (m *BaseNotifier) NewPullState(ctx context.Context, actor syntax.DID, pull *models.Pull) {} func (m *BaseNotifier) UpdateProfile(ctx context.Context, profile *models.Profile) {} diff --git a/appview/notify/posthog/notifier.go b/appview/notify/posthog/notifier.go index aefd5d75..4ca57511 100644 --- a/appview/notify/posthog/notifier.go +++ b/appview/notify/posthog/notifier.go @@ -86,13 +86,14 @@ func (n *posthogNotifier) NewPull(ctx context.Context, pull *models.Pull) { } } -func (n *posthogNotifier) NewPullComment(ctx context.Context, comment *models.PullComment) { +func (n *posthogNotifier) NewPullComment(ctx context.Context, comment *models.PullComment, mentions []syntax.DID) { err := n.client.Enqueue(posthog.Capture{ DistinctId: comment.OwnerDid, Event: "new_pull_comment", Properties: posthog.Properties{ - "repo_at": comment.RepoAt, - "pull_id": comment.PullId, + "repo_at": comment.RepoAt, + "pull_id": comment.PullId, + "mentions": mentions, }, }) if err != nil { diff --git a/appview/pulls/pulls.go b/appview/pulls/pulls.go index bb4c71fb..254f8ee4 100644 --- a/appview/pulls/pulls.go +++ b/appview/pulls/pulls.go @@ -691,6 +691,7 @@ func (s *Pulls) RepoPulls(w http.ResponseWriter, r *http.Request) { } func (s *Pulls) PullComment(w http.ResponseWriter, r *http.Request) { + l := s.logger.With("handler", "PullComment") user := s.oauth.GetUser(r) f, err := s.repoResolver.Resolve(r) if err != nil { @@ -788,7 +789,16 @@ func (s *Pulls) PullComment(w http.ResponseWriter, r *http.Request) { return } - s.notifier.NewPullComment(r.Context(), comment) + rawMentions := markup.FindUserMentions(comment.Body) + idents := s.idResolver.ResolveIdents(r.Context(), rawMentions) + l.Debug("parsed mentions", "raw", rawMentions, "idents", idents) + var mentions []syntax.DID + for _, ident := range idents { + if ident != nil && !ident.Handle.IsInvalidHandle() { + mentions = append(mentions, ident.DID) + } + } + s.notifier.NewPullComment(r.Context(), comment, mentions) s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d#comment-%d", f.OwnerSlashRepo(), pull.PullId, commentId)) return -- 2.43.0