]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Add notification plugin hook
authorChocobozzz <me@florianbigard.com>
Wed, 3 Aug 2022 09:33:43 +0000 (11:33 +0200)
committerChocobozzz <me@florianbigard.com>
Wed, 3 Aug 2022 09:33:43 +0000 (11:33 +0200)
23 files changed:
server/lib/notifier/notifier.ts
server/lib/notifier/shared/abuse/abstract-new-abuse-message.ts
server/lib/notifier/shared/abuse/abuse-state-change-for-reporter.ts
server/lib/notifier/shared/abuse/new-abuse-for-moderators.ts
server/lib/notifier/shared/blacklist/new-auto-blacklist-for-moderators.ts
server/lib/notifier/shared/blacklist/new-blacklist-for-owner.ts
server/lib/notifier/shared/blacklist/unblacklist-for-owner.ts
server/lib/notifier/shared/comment/comment-mention.ts
server/lib/notifier/shared/comment/new-comment-for-video-owner.ts
server/lib/notifier/shared/common/abstract-notification.ts
server/lib/notifier/shared/follow/auto-follow-for-instance.ts
server/lib/notifier/shared/follow/follow-for-instance.ts
server/lib/notifier/shared/follow/follow-for-user.ts
server/lib/notifier/shared/instance/new-peertube-version-for-admins.ts
server/lib/notifier/shared/instance/new-plugin-version-for-admins.ts
server/lib/notifier/shared/instance/registration-for-moderators.ts
server/lib/notifier/shared/video-publication/abstract-owned-video-publication.ts
server/lib/notifier/shared/video-publication/import-finished-for-owner.ts
server/lib/notifier/shared/video-publication/new-video-for-subscribers.ts
server/lib/notifier/shared/video-publication/studio-edition-finished-for-owner.ts
server/tests/fixtures/peertube-plugin-test/main.js
server/tests/plugins/action-hooks.ts
shared/models/plugins/server/server-hook.model.ts

index a6f13780b424d5d3585e31ce11746cb7108dfa76..d1c4c0215328bd2d2591565277f104750dec042b 100644 (file)
@@ -7,12 +7,12 @@ import { MAbuseFull, MAbuseMessage, MActorFollowFull, MApplication, MPlugin } fr
 import { MCommentOwnerVideo, MVideoAccountLight, MVideoFullLight } from '../../types/models/video'
 import { JobQueue } from '../job-queue'
 import { PeerTubeSocket } from '../peertube-socket'
+import { Hooks } from '../plugins/hooks'
 import {
   AbstractNotification,
   AbuseStateChangeForReporter,
   AutoFollowForInstance,
   CommentMention,
-  StudioEditionFinishedForOwner,
   FollowForInstance,
   FollowForUser,
   ImportFinishedForOwner,
@@ -31,6 +31,7 @@ import {
   OwnedPublicationAfterScheduleUpdate,
   OwnedPublicationAfterTranscoding,
   RegistrationForModerators,
+  StudioEditionFinishedForOwner,
   UnblacklistForOwner
 } from './shared'
 
@@ -222,15 +223,21 @@ class Notifier {
     for (const user of users) {
       const setting = object.getSetting(user)
 
-      if (this.isWebNotificationEnabled(setting)) {
-        const notification = await object.createNotification(user)
+      const webNotificationEnabled = this.isWebNotificationEnabled(setting)
+      const emailNotificationEnabled = this.isEmailEnabled(user, setting)
+      const notification = object.createNotification(user)
+
+      if (webNotificationEnabled) {
+        await notification.save()
 
         PeerTubeSocket.Instance.sendNotification(user.id, notification)
       }
 
-      if (this.isEmailEnabled(user, setting)) {
+      if (emailNotificationEnabled) {
         toEmails.push(user.email)
       }
+
+      Hooks.runAction('action:notifier.notification.created', { webNotificationEnabled, emailNotificationEnabled, user, notification })
     }
 
     for (const to of toEmails) {
index a7292de6952acb770f93fc64ffe0e3f80aa7da72..1dc1ccfc2359b12d487f6e661a03afe71fd14cbe 100644 (file)
@@ -21,8 +21,8 @@ export abstract class AbstractNewAbuseMessage extends AbstractNotification <NewA
     return user.NotificationSetting.abuseNewMessage
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.ABUSE_NEW_MESSAGE,
       userId: user.id,
       abuseId: this.abuse.id
index d92f7a13ba701100903675a55b3e560ea91e391e..97e896c6a667f6a119b31f7b9f293dcc76795c02 100644 (file)
@@ -32,8 +32,8 @@ export class AbuseStateChangeForReporter extends AbstractNotification <MAbuseFul
     return [ this.user ]
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.ABUSE_STATE_CHANGE,
       userId: user.id,
       abuseId: this.abuse.id
index c3c7c5515691ff203ca5744aa1da309ffd55b053..7d86fb55f5caacc9debf8f7658e8e925165760c7 100644 (file)
@@ -28,8 +28,8 @@ export class NewAbuseForModerators extends AbstractNotification <NewAbusePayload
     return this.moderators
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.NEW_ABUSE_FOR_MODERATORS,
       userId: user.id,
       abuseId: this.payload.abuseInstance.id
index a92a49a0c7b5e0f2e28162398eb092939824ba13..ad2cc00ea984805a32db6fdb2804cae1926fdb3d 100644 (file)
@@ -26,8 +26,8 @@ export class NewAutoBlacklistForModerators extends AbstractNotification <MVideoB
     return this.moderators
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS,
       userId: user.id,
       videoBlacklistId: this.payload.id
index 45bc30eb298dfb2fd2df82296ba25c3edad90ba0..342b69ec7843e913032d7fdb326bbd71cbbde219 100644 (file)
@@ -28,8 +28,8 @@ export class NewBlacklistForOwner extends AbstractNotification <MVideoBlacklistV
     return [ this.user ]
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.BLACKLIST_ON_MY_VIDEO,
       userId: user.id,
       videoBlacklistId: this.payload.id
index 21f5a1c2d29640c706a6104f56ce016af5bc9433..e6f90e23cd93b28e3827493f92bc1dfce1726369 100644 (file)
@@ -28,8 +28,8 @@ export class UnblacklistForOwner extends AbstractNotification <MVideoFullLight>
     return [ this.user ]
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.UNBLACKLIST_ON_MY_VIDEO,
       userId: user.id,
       videoId: this.payload.id
index ecd1687b478762306a6b30b6daffc6c22d0ce53c..3074e97db6a55b0c36ebe43bef0728a85d15cb75 100644 (file)
@@ -71,8 +71,8 @@ export class CommentMention extends AbstractNotification <MCommentOwnerVideo, MU
     return this.users
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.COMMENT_MENTION,
       userId: user.id,
       commentId: this.payload.id
index 7575027038988f087f0323f3db6111b708de7876..4f96439a30bd2e4b6a026eb0a2905685f2511c58 100644 (file)
@@ -38,8 +38,8 @@ export class NewCommentForVideoOwner extends AbstractNotification <MCommentOwner
     return [ this.user ]
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.NEW_COMMENT_ON_MY_VIDEO,
       userId: user.id,
       commentId: this.payload.id
index 53e2e02d536da68e39d676778c4932c76d0ee500..79403611e7479ac1b826179095e2779f9916a8e4 100644 (file)
@@ -13,7 +13,7 @@ export abstract class AbstractNotification <T, U = MUserWithNotificationSetting>
   abstract getSetting (user: U): UserNotificationSettingValue
   abstract getTargetUsers (): U[]
 
-  abstract createNotification (user: U): Promise<UserNotificationModelForApi>
+  abstract createNotification (user: U): UserNotificationModelForApi
   abstract createEmail (to: string): EmailPayload | Promise<EmailPayload>
 
   isDisabled (): boolean | Promise<boolean> {
index 01d2b3563190f5faa93d43fd8088b385d776af24..ab9747ba88dae95972ac6066e708455bfc96b6fb 100644 (file)
@@ -24,8 +24,8 @@ export class AutoFollowForInstance extends AbstractNotification <MActorFollowFul
     return this.admins
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.AUTO_INSTANCE_FOLLOWING,
       userId: user.id,
       actorFollowId: this.actorFollow.id
index a4a2fbf53717093836c85d03d2984fbd42386491..777a12ef4940f8781a541d791661954015afa6ca 100644 (file)
@@ -32,8 +32,8 @@ export class FollowForInstance extends AbstractNotification <MActorFollowFull> {
     return this.admins
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.NEW_INSTANCE_FOLLOWER,
       userId: user.id,
       actorFollowId: this.actorFollow.id
index e579d448770b89d152ad0401a785797e90e5b3dd..697c82cddd4be81be03a3703e1bd973e55606860 100644 (file)
@@ -45,8 +45,8 @@ export class FollowForUser extends AbstractNotification <MActorFollowFull> {
     return [ this.user ]
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.NEW_FOLLOW,
       userId: user.id,
       actorFollowId: this.actorFollow.id
index 6b5ac808a0b47ff8ca7a0c48a9a21b39b380e085..f5646c666922c29415789f34fe3de9220af33b3c 100644 (file)
@@ -30,8 +30,8 @@ export class NewPeerTubeVersionForAdmins extends AbstractNotification <NewPeerTu
     return this.admins
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.NEW_PEERTUBE_VERSION,
       userId: user.id,
       applicationId: this.payload.application.id
index 874b10a3deeff276b4372dec9b3b3e8d508b3cf5..547c6726c0b551c99294b34de5ebf1a004ad167c 100644 (file)
@@ -26,8 +26,8 @@ export class NewPluginVersionForAdmins extends AbstractNotification <MPlugin> {
     return this.admins
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.NEW_PLUGIN_VERSION,
       userId: user.id,
       pluginId: this.plugin.id
index 2a48ef2fa51dd1c00185366c55e5c4c14dedd599..e9246742421555d08c3f50beff52fd715f5e535f 100644 (file)
@@ -25,8 +25,8 @@ export class RegistrationForModerators extends AbstractNotification <MUserDefaul
     return this.moderators
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.NEW_USER_REGISTRATION,
       userId: user.id,
       accountId: this.payload.Account.id
index 37435f898f99ce9dadc2f193e7e28cf0dfde0ec8..a940cde69ddfd497ce6234bf64628da94ea85e37 100644 (file)
@@ -27,8 +27,8 @@ export abstract class AbstractOwnedVideoPublication extends AbstractNotification
     return [ this.user ]
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.MY_VIDEO_PUBLISHED,
       userId: user.id,
       videoId: this.payload.id
index 9f374b6f9554979f56e52c067380fb927d158d72..3bd64692fd9e19151bc108470ac803cfa1103f67 100644 (file)
@@ -32,8 +32,8 @@ export class ImportFinishedForOwner extends AbstractNotification <ImportFinished
     return [ this.user ]
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: this.payload.success
         ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS
         : UserNotificationType.MY_VIDEO_IMPORT_ERROR,
index 4253a0930fae7f67bee165d896acea8b39a7dd1e..df7a5561d7a848219af88a78ad97e00cae4ebe17 100644 (file)
@@ -30,8 +30,8 @@ export class NewVideoForSubscribers extends AbstractNotification <MVideoAccountL
     return this.users
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION,
       userId: user.id,
       videoId: this.payload.id
index ee3027245008bb9fef7a2860db6c6c560f1c6565..f36399f05a4c689dc4feb146353d4056a3483357 100644 (file)
@@ -27,8 +27,8 @@ export class StudioEditionFinishedForOwner extends AbstractNotification <MVideoF
     return [ this.user ]
   }
 
-  async createNotification (user: MUserWithNotificationSetting) {
-    const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
+  createNotification (user: MUserWithNotificationSetting) {
+    const notification = UserNotificationModel.build<UserNotificationModelForApi>({
       type: UserNotificationType.MY_VIDEO_STUDIO_EDITION_FINISHED,
       userId: user.id,
       videoId: this.payload.id
index 8d7584eba2ea40d61fb0c7170c7b26953182c387..b3febfa12b7360b53c1ad8987444f33a1332649c 100644 (file)
@@ -1,6 +1,7 @@
 async function register ({ registerHook, registerSetting, settingsManager, storageManager, peertubeHelpers }) {
   const actionHooks = [
     'action:application.listening',
+    'action:notifier.notification.created',
 
     'action:api.video.updated',
     'action:api.video.deleted',
index 209db95a44b835c4bab13ca9fdcf1d0711fabc74..405f81d7c3299cb1427db9f6d1367b93f950b443 100644 (file)
@@ -17,8 +17,8 @@ describe('Test plugin action hooks', function () {
   let videoUUID: string
   let threadId: number
 
-  function checkHook (hook: ServerHookName) {
-    return servers[0].servers.waitUntilLog('Run hook ' + hook)
+  function checkHook (hook: ServerHookName, strictCount = true) {
+    return servers[0].servers.waitUntilLog('Run hook ' + hook, 1, strictCount)
   }
 
   before(async function () {
@@ -225,6 +225,13 @@ describe('Test plugin action hooks', function () {
     })
   })
 
+  describe('Notification hook', function () {
+
+    it('Should run action:notifier.notification.created', async function () {
+      await checkHook('action:notifier.notification.created', false)
+    })
+  })
+
   after(async function () {
     await cleanupTests(servers)
   })
index 5f3a5be10dd29614b5ac0317005a60824fbfd594..c8e879323e2a41c937196f94cd1dd50df507ffb9 100644 (file)
@@ -112,6 +112,9 @@ export const serverActionHookObject = {
   // Fired when the application has been loaded and is listening HTTP requests
   'action:application.listening': true,
 
+  // Fired when a new notification is created
+  'action:notifier.notification.created': true,
+
   // API actions hooks give access to the original express `req` and `res` parameters
 
   // Fired when a local video is updated