diff options
-rw-r--r-- | server/lib/notifier.ts | 2 | ||||
-rw-r--r-- | server/models/video/video-comment.ts | 40 | ||||
-rw-r--r-- | server/tests/api/users/user-notifications.ts | 14 |
3 files changed, 41 insertions, 15 deletions
diff --git a/server/lib/notifier.ts b/server/lib/notifier.ts index d1b331346..2fa320cd7 100644 --- a/server/lib/notifier.ts +++ b/server/lib/notifier.ts | |||
@@ -148,6 +148,8 @@ class Notifier { | |||
148 | 148 | ||
149 | private async notifyOfCommentMention (comment: VideoCommentModel) { | 149 | private async notifyOfCommentMention (comment: VideoCommentModel) { |
150 | const usernames = comment.extractMentions() | 150 | const usernames = comment.extractMentions() |
151 | logger.debug('Extracted %d username from comment %s.', usernames.length, comment.url, { usernames, text: comment.text }) | ||
152 | |||
151 | let users = await UserModel.listByUsernames(usernames) | 153 | let users = await UserModel.listByUsernames(usernames) |
152 | 154 | ||
153 | if (comment.Video.isOwned()) { | 155 | if (comment.Video.isOwned()) { |
diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts index cf6278da7..1163f9a0e 100644 --- a/server/models/video/video-comment.ts +++ b/server/models/video/video-comment.ts | |||
@@ -466,31 +466,41 @@ export class VideoCommentModel extends Model<VideoCommentModel> { | |||
466 | } | 466 | } |
467 | 467 | ||
468 | extractMentions () { | 468 | extractMentions () { |
469 | if (!this.text) return [] | 469 | let result: string[] = [] |
470 | 470 | ||
471 | const localMention = `@(${actorNameAlphabet}+)` | 471 | const localMention = `@(${actorNameAlphabet}+)` |
472 | const remoteMention = `${localMention}@${CONFIG.WEBSERVER.HOST}` | 472 | const remoteMention = `${localMention}@${CONFIG.WEBSERVER.HOST}` |
473 | 473 | ||
474 | const mentionRegex = this.isOwned() | ||
475 | ? '(?:(?:' + remoteMention + ')|(?:' + localMention + '))' // Include local mentions? | ||
476 | : '(?:' + remoteMention + ')' | ||
477 | |||
478 | const firstMentionRegex = new RegExp(`^${mentionRegex} `, 'g') | ||
479 | const endMentionRegex = new RegExp(` ${mentionRegex}$`, 'g') | ||
474 | const remoteMentionsRegex = new RegExp(' ' + remoteMention + ' ', 'g') | 480 | const remoteMentionsRegex = new RegExp(' ' + remoteMention + ' ', 'g') |
475 | const localMentionsRegex = new RegExp(' ' + localMention + ' ', 'g') | ||
476 | const firstMentionRegex = new RegExp('^(?:(?:' + remoteMention + ')|(?:' + localMention + ')) ', 'g') | ||
477 | const endMentionRegex = new RegExp(' (?:(?:' + remoteMention + ')|(?:' + localMention + '))$', 'g') | ||
478 | 481 | ||
479 | return uniq( | 482 | result = result.concat( |
480 | [].concat( | 483 | regexpCapture(this.text, firstMentionRegex) |
481 | regexpCapture(this.text, remoteMentionsRegex) | 484 | .map(([ , username1, username2 ]) => username1 || username2), |
482 | .map(([ , username ]) => username), | ||
483 | 485 | ||
484 | regexpCapture(this.text, localMentionsRegex) | 486 | regexpCapture(this.text, endMentionRegex) |
485 | .map(([ , username ]) => username), | 487 | .map(([ , username1, username2 ]) => username1 || username2), |
488 | |||
489 | regexpCapture(this.text, remoteMentionsRegex) | ||
490 | .map(([ , username ]) => username) | ||
491 | ) | ||
486 | 492 | ||
487 | regexpCapture(this.text, firstMentionRegex) | 493 | // Include local mentions |
488 | .map(([ , username1, username2 ]) => username1 || username2), | 494 | if (this.isOwned()) { |
495 | const localMentionsRegex = new RegExp(' ' + localMention + ' ', 'g') | ||
489 | 496 | ||
490 | regexpCapture(this.text, endMentionRegex) | 497 | result = result.concat( |
491 | .map(([ , username1, username2 ]) => username1 || username2) | 498 | regexpCapture(this.text, localMentionsRegex) |
499 | .map(([ , username ]) => username) | ||
492 | ) | 500 | ) |
493 | ) | 501 | } |
502 | |||
503 | return uniq(result) | ||
494 | } | 504 | } |
495 | 505 | ||
496 | toFormattedJSON () { | 506 | toFormattedJSON () { |
diff --git a/server/tests/api/users/user-notifications.ts b/server/tests/api/users/user-notifications.ts index 5260d64cc..72b6a0aa2 100644 --- a/server/tests/api/users/user-notifications.ts +++ b/server/tests/api/users/user-notifications.ts | |||
@@ -506,6 +506,20 @@ describe('Test users notifications', function () { | |||
506 | await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root') | 506 | await removeAccountFromAccountBlocklist(servers[ 0 ].url, userAccessToken, 'root') |
507 | }) | 507 | }) |
508 | 508 | ||
509 | it('Should not send a new mention notification if the remote account mention a local account', async function () { | ||
510 | this.timeout(20000) | ||
511 | |||
512 | const resVideo = await uploadVideo(servers[0].url, servers[0].accessToken, { name: 'super video' }) | ||
513 | const uuid = resVideo.body.video.uuid | ||
514 | |||
515 | await waitJobs(servers) | ||
516 | const resThread = await addVideoCommentThread(servers[1].url, servers[1].accessToken, uuid, '@user_1 hello') | ||
517 | const threadId = resThread.body.comment.id | ||
518 | |||
519 | await waitJobs(servers) | ||
520 | await checkCommentMention(baseParams, uuid, threadId, threadId, 'super root 2 name', 'absence') | ||
521 | }) | ||
522 | |||
509 | it('Should send a new mention notification after local comments', async function () { | 523 | it('Should send a new mention notification after local comments', async function () { |
510 | this.timeout(10000) | 524 | this.timeout(10000) |
511 | 525 | ||