aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2022-08-03 11:33:43 +0200
committerChocobozzz <me@florianbigard.com>2022-08-03 11:33:43 +0200
commit785f1897a42984ece9c6f65829d195d67e331d95 (patch)
tree1cb3b33cfc797b8f1abbab90749c1e3187bbd311
parent0260dc8aca952f9412a8620e433b9e16e675696e (diff)
downloadPeerTube-785f1897a42984ece9c6f65829d195d67e331d95.tar.gz
PeerTube-785f1897a42984ece9c6f65829d195d67e331d95.tar.zst
PeerTube-785f1897a42984ece9c6f65829d195d67e331d95.zip
Add notification plugin hook
-rw-r--r--server/lib/notifier/notifier.ts15
-rw-r--r--server/lib/notifier/shared/abuse/abstract-new-abuse-message.ts4
-rw-r--r--server/lib/notifier/shared/abuse/abuse-state-change-for-reporter.ts4
-rw-r--r--server/lib/notifier/shared/abuse/new-abuse-for-moderators.ts4
-rw-r--r--server/lib/notifier/shared/blacklist/new-auto-blacklist-for-moderators.ts4
-rw-r--r--server/lib/notifier/shared/blacklist/new-blacklist-for-owner.ts4
-rw-r--r--server/lib/notifier/shared/blacklist/unblacklist-for-owner.ts4
-rw-r--r--server/lib/notifier/shared/comment/comment-mention.ts4
-rw-r--r--server/lib/notifier/shared/comment/new-comment-for-video-owner.ts4
-rw-r--r--server/lib/notifier/shared/common/abstract-notification.ts2
-rw-r--r--server/lib/notifier/shared/follow/auto-follow-for-instance.ts4
-rw-r--r--server/lib/notifier/shared/follow/follow-for-instance.ts4
-rw-r--r--server/lib/notifier/shared/follow/follow-for-user.ts4
-rw-r--r--server/lib/notifier/shared/instance/new-peertube-version-for-admins.ts4
-rw-r--r--server/lib/notifier/shared/instance/new-plugin-version-for-admins.ts4
-rw-r--r--server/lib/notifier/shared/instance/registration-for-moderators.ts4
-rw-r--r--server/lib/notifier/shared/video-publication/abstract-owned-video-publication.ts4
-rw-r--r--server/lib/notifier/shared/video-publication/import-finished-for-owner.ts4
-rw-r--r--server/lib/notifier/shared/video-publication/new-video-for-subscribers.ts4
-rw-r--r--server/lib/notifier/shared/video-publication/studio-edition-finished-for-owner.ts4
-rw-r--r--server/tests/fixtures/peertube-plugin-test/main.js1
-rw-r--r--server/tests/plugins/action-hooks.ts11
-rw-r--r--shared/models/plugins/server/server-hook.model.ts3
23 files changed, 61 insertions, 43 deletions
diff --git a/server/lib/notifier/notifier.ts b/server/lib/notifier/notifier.ts
index a6f13780b..d1c4c0215 100644
--- a/server/lib/notifier/notifier.ts
+++ b/server/lib/notifier/notifier.ts
@@ -7,12 +7,12 @@ import { MAbuseFull, MAbuseMessage, MActorFollowFull, MApplication, MPlugin } fr
7import { MCommentOwnerVideo, MVideoAccountLight, MVideoFullLight } from '../../types/models/video' 7import { MCommentOwnerVideo, MVideoAccountLight, MVideoFullLight } from '../../types/models/video'
8import { JobQueue } from '../job-queue' 8import { JobQueue } from '../job-queue'
9import { PeerTubeSocket } from '../peertube-socket' 9import { PeerTubeSocket } from '../peertube-socket'
10import { Hooks } from '../plugins/hooks'
10import { 11import {
11 AbstractNotification, 12 AbstractNotification,
12 AbuseStateChangeForReporter, 13 AbuseStateChangeForReporter,
13 AutoFollowForInstance, 14 AutoFollowForInstance,
14 CommentMention, 15 CommentMention,
15 StudioEditionFinishedForOwner,
16 FollowForInstance, 16 FollowForInstance,
17 FollowForUser, 17 FollowForUser,
18 ImportFinishedForOwner, 18 ImportFinishedForOwner,
@@ -31,6 +31,7 @@ import {
31 OwnedPublicationAfterScheduleUpdate, 31 OwnedPublicationAfterScheduleUpdate,
32 OwnedPublicationAfterTranscoding, 32 OwnedPublicationAfterTranscoding,
33 RegistrationForModerators, 33 RegistrationForModerators,
34 StudioEditionFinishedForOwner,
34 UnblacklistForOwner 35 UnblacklistForOwner
35} from './shared' 36} from './shared'
36 37
@@ -222,15 +223,21 @@ class Notifier {
222 for (const user of users) { 223 for (const user of users) {
223 const setting = object.getSetting(user) 224 const setting = object.getSetting(user)
224 225
225 if (this.isWebNotificationEnabled(setting)) { 226 const webNotificationEnabled = this.isWebNotificationEnabled(setting)
226 const notification = await object.createNotification(user) 227 const emailNotificationEnabled = this.isEmailEnabled(user, setting)
228 const notification = object.createNotification(user)
229
230 if (webNotificationEnabled) {
231 await notification.save()
227 232
228 PeerTubeSocket.Instance.sendNotification(user.id, notification) 233 PeerTubeSocket.Instance.sendNotification(user.id, notification)
229 } 234 }
230 235
231 if (this.isEmailEnabled(user, setting)) { 236 if (emailNotificationEnabled) {
232 toEmails.push(user.email) 237 toEmails.push(user.email)
233 } 238 }
239
240 Hooks.runAction('action:notifier.notification.created', { webNotificationEnabled, emailNotificationEnabled, user, notification })
234 } 241 }
235 242
236 for (const to of toEmails) { 243 for (const to of toEmails) {
diff --git a/server/lib/notifier/shared/abuse/abstract-new-abuse-message.ts b/server/lib/notifier/shared/abuse/abstract-new-abuse-message.ts
index a7292de69..1dc1ccfc2 100644
--- a/server/lib/notifier/shared/abuse/abstract-new-abuse-message.ts
+++ b/server/lib/notifier/shared/abuse/abstract-new-abuse-message.ts
@@ -21,8 +21,8 @@ export abstract class AbstractNewAbuseMessage extends AbstractNotification <NewA
21 return user.NotificationSetting.abuseNewMessage 21 return user.NotificationSetting.abuseNewMessage
22 } 22 }
23 23
24 async createNotification (user: MUserWithNotificationSetting) { 24 createNotification (user: MUserWithNotificationSetting) {
25 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 25 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
26 type: UserNotificationType.ABUSE_NEW_MESSAGE, 26 type: UserNotificationType.ABUSE_NEW_MESSAGE,
27 userId: user.id, 27 userId: user.id,
28 abuseId: this.abuse.id 28 abuseId: this.abuse.id
diff --git a/server/lib/notifier/shared/abuse/abuse-state-change-for-reporter.ts b/server/lib/notifier/shared/abuse/abuse-state-change-for-reporter.ts
index d92f7a13b..97e896c6a 100644
--- a/server/lib/notifier/shared/abuse/abuse-state-change-for-reporter.ts
+++ b/server/lib/notifier/shared/abuse/abuse-state-change-for-reporter.ts
@@ -32,8 +32,8 @@ export class AbuseStateChangeForReporter extends AbstractNotification <MAbuseFul
32 return [ this.user ] 32 return [ this.user ]
33 } 33 }
34 34
35 async createNotification (user: MUserWithNotificationSetting) { 35 createNotification (user: MUserWithNotificationSetting) {
36 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 36 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
37 type: UserNotificationType.ABUSE_STATE_CHANGE, 37 type: UserNotificationType.ABUSE_STATE_CHANGE,
38 userId: user.id, 38 userId: user.id,
39 abuseId: this.abuse.id 39 abuseId: this.abuse.id
diff --git a/server/lib/notifier/shared/abuse/new-abuse-for-moderators.ts b/server/lib/notifier/shared/abuse/new-abuse-for-moderators.ts
index c3c7c5515..7d86fb55f 100644
--- a/server/lib/notifier/shared/abuse/new-abuse-for-moderators.ts
+++ b/server/lib/notifier/shared/abuse/new-abuse-for-moderators.ts
@@ -28,8 +28,8 @@ export class NewAbuseForModerators extends AbstractNotification <NewAbusePayload
28 return this.moderators 28 return this.moderators
29 } 29 }
30 30
31 async createNotification (user: MUserWithNotificationSetting) { 31 createNotification (user: MUserWithNotificationSetting) {
32 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 32 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
33 type: UserNotificationType.NEW_ABUSE_FOR_MODERATORS, 33 type: UserNotificationType.NEW_ABUSE_FOR_MODERATORS,
34 userId: user.id, 34 userId: user.id,
35 abuseId: this.payload.abuseInstance.id 35 abuseId: this.payload.abuseInstance.id
diff --git a/server/lib/notifier/shared/blacklist/new-auto-blacklist-for-moderators.ts b/server/lib/notifier/shared/blacklist/new-auto-blacklist-for-moderators.ts
index a92a49a0c..ad2cc00ea 100644
--- a/server/lib/notifier/shared/blacklist/new-auto-blacklist-for-moderators.ts
+++ b/server/lib/notifier/shared/blacklist/new-auto-blacklist-for-moderators.ts
@@ -26,8 +26,8 @@ export class NewAutoBlacklistForModerators extends AbstractNotification <MVideoB
26 return this.moderators 26 return this.moderators
27 } 27 }
28 28
29 async createNotification (user: MUserWithNotificationSetting) { 29 createNotification (user: MUserWithNotificationSetting) {
30 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 30 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
31 type: UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS, 31 type: UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS,
32 userId: user.id, 32 userId: user.id,
33 videoBlacklistId: this.payload.id 33 videoBlacklistId: this.payload.id
diff --git a/server/lib/notifier/shared/blacklist/new-blacklist-for-owner.ts b/server/lib/notifier/shared/blacklist/new-blacklist-for-owner.ts
index 45bc30eb2..342b69ec7 100644
--- a/server/lib/notifier/shared/blacklist/new-blacklist-for-owner.ts
+++ b/server/lib/notifier/shared/blacklist/new-blacklist-for-owner.ts
@@ -28,8 +28,8 @@ export class NewBlacklistForOwner extends AbstractNotification <MVideoBlacklistV
28 return [ this.user ] 28 return [ this.user ]
29 } 29 }
30 30
31 async createNotification (user: MUserWithNotificationSetting) { 31 createNotification (user: MUserWithNotificationSetting) {
32 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 32 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
33 type: UserNotificationType.BLACKLIST_ON_MY_VIDEO, 33 type: UserNotificationType.BLACKLIST_ON_MY_VIDEO,
34 userId: user.id, 34 userId: user.id,
35 videoBlacklistId: this.payload.id 35 videoBlacklistId: this.payload.id
diff --git a/server/lib/notifier/shared/blacklist/unblacklist-for-owner.ts b/server/lib/notifier/shared/blacklist/unblacklist-for-owner.ts
index 21f5a1c2d..e6f90e23c 100644
--- a/server/lib/notifier/shared/blacklist/unblacklist-for-owner.ts
+++ b/server/lib/notifier/shared/blacklist/unblacklist-for-owner.ts
@@ -28,8 +28,8 @@ export class UnblacklistForOwner extends AbstractNotification <MVideoFullLight>
28 return [ this.user ] 28 return [ this.user ]
29 } 29 }
30 30
31 async createNotification (user: MUserWithNotificationSetting) { 31 createNotification (user: MUserWithNotificationSetting) {
32 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 32 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
33 type: UserNotificationType.UNBLACKLIST_ON_MY_VIDEO, 33 type: UserNotificationType.UNBLACKLIST_ON_MY_VIDEO,
34 userId: user.id, 34 userId: user.id,
35 videoId: this.payload.id 35 videoId: this.payload.id
diff --git a/server/lib/notifier/shared/comment/comment-mention.ts b/server/lib/notifier/shared/comment/comment-mention.ts
index ecd1687b4..3074e97db 100644
--- a/server/lib/notifier/shared/comment/comment-mention.ts
+++ b/server/lib/notifier/shared/comment/comment-mention.ts
@@ -71,8 +71,8 @@ export class CommentMention extends AbstractNotification <MCommentOwnerVideo, MU
71 return this.users 71 return this.users
72 } 72 }
73 73
74 async createNotification (user: MUserWithNotificationSetting) { 74 createNotification (user: MUserWithNotificationSetting) {
75 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 75 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
76 type: UserNotificationType.COMMENT_MENTION, 76 type: UserNotificationType.COMMENT_MENTION,
77 userId: user.id, 77 userId: user.id,
78 commentId: this.payload.id 78 commentId: this.payload.id
diff --git a/server/lib/notifier/shared/comment/new-comment-for-video-owner.ts b/server/lib/notifier/shared/comment/new-comment-for-video-owner.ts
index 757502703..4f96439a3 100644
--- a/server/lib/notifier/shared/comment/new-comment-for-video-owner.ts
+++ b/server/lib/notifier/shared/comment/new-comment-for-video-owner.ts
@@ -38,8 +38,8 @@ export class NewCommentForVideoOwner extends AbstractNotification <MCommentOwner
38 return [ this.user ] 38 return [ this.user ]
39 } 39 }
40 40
41 async createNotification (user: MUserWithNotificationSetting) { 41 createNotification (user: MUserWithNotificationSetting) {
42 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 42 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
43 type: UserNotificationType.NEW_COMMENT_ON_MY_VIDEO, 43 type: UserNotificationType.NEW_COMMENT_ON_MY_VIDEO,
44 userId: user.id, 44 userId: user.id,
45 commentId: this.payload.id 45 commentId: this.payload.id
diff --git a/server/lib/notifier/shared/common/abstract-notification.ts b/server/lib/notifier/shared/common/abstract-notification.ts
index 53e2e02d5..79403611e 100644
--- a/server/lib/notifier/shared/common/abstract-notification.ts
+++ b/server/lib/notifier/shared/common/abstract-notification.ts
@@ -13,7 +13,7 @@ export abstract class AbstractNotification <T, U = MUserWithNotificationSetting>
13 abstract getSetting (user: U): UserNotificationSettingValue 13 abstract getSetting (user: U): UserNotificationSettingValue
14 abstract getTargetUsers (): U[] 14 abstract getTargetUsers (): U[]
15 15
16 abstract createNotification (user: U): Promise<UserNotificationModelForApi> 16 abstract createNotification (user: U): UserNotificationModelForApi
17 abstract createEmail (to: string): EmailPayload | Promise<EmailPayload> 17 abstract createEmail (to: string): EmailPayload | Promise<EmailPayload>
18 18
19 isDisabled (): boolean | Promise<boolean> { 19 isDisabled (): boolean | Promise<boolean> {
diff --git a/server/lib/notifier/shared/follow/auto-follow-for-instance.ts b/server/lib/notifier/shared/follow/auto-follow-for-instance.ts
index 01d2b3563..ab9747ba8 100644
--- a/server/lib/notifier/shared/follow/auto-follow-for-instance.ts
+++ b/server/lib/notifier/shared/follow/auto-follow-for-instance.ts
@@ -24,8 +24,8 @@ export class AutoFollowForInstance extends AbstractNotification <MActorFollowFul
24 return this.admins 24 return this.admins
25 } 25 }
26 26
27 async createNotification (user: MUserWithNotificationSetting) { 27 createNotification (user: MUserWithNotificationSetting) {
28 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 28 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
29 type: UserNotificationType.AUTO_INSTANCE_FOLLOWING, 29 type: UserNotificationType.AUTO_INSTANCE_FOLLOWING,
30 userId: user.id, 30 userId: user.id,
31 actorFollowId: this.actorFollow.id 31 actorFollowId: this.actorFollow.id
diff --git a/server/lib/notifier/shared/follow/follow-for-instance.ts b/server/lib/notifier/shared/follow/follow-for-instance.ts
index a4a2fbf53..777a12ef4 100644
--- a/server/lib/notifier/shared/follow/follow-for-instance.ts
+++ b/server/lib/notifier/shared/follow/follow-for-instance.ts
@@ -32,8 +32,8 @@ export class FollowForInstance extends AbstractNotification <MActorFollowFull> {
32 return this.admins 32 return this.admins
33 } 33 }
34 34
35 async createNotification (user: MUserWithNotificationSetting) { 35 createNotification (user: MUserWithNotificationSetting) {
36 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 36 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
37 type: UserNotificationType.NEW_INSTANCE_FOLLOWER, 37 type: UserNotificationType.NEW_INSTANCE_FOLLOWER,
38 userId: user.id, 38 userId: user.id,
39 actorFollowId: this.actorFollow.id 39 actorFollowId: this.actorFollow.id
diff --git a/server/lib/notifier/shared/follow/follow-for-user.ts b/server/lib/notifier/shared/follow/follow-for-user.ts
index e579d4487..697c82cdd 100644
--- a/server/lib/notifier/shared/follow/follow-for-user.ts
+++ b/server/lib/notifier/shared/follow/follow-for-user.ts
@@ -45,8 +45,8 @@ export class FollowForUser extends AbstractNotification <MActorFollowFull> {
45 return [ this.user ] 45 return [ this.user ]
46 } 46 }
47 47
48 async createNotification (user: MUserWithNotificationSetting) { 48 createNotification (user: MUserWithNotificationSetting) {
49 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 49 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
50 type: UserNotificationType.NEW_FOLLOW, 50 type: UserNotificationType.NEW_FOLLOW,
51 userId: user.id, 51 userId: user.id,
52 actorFollowId: this.actorFollow.id 52 actorFollowId: this.actorFollow.id
diff --git a/server/lib/notifier/shared/instance/new-peertube-version-for-admins.ts b/server/lib/notifier/shared/instance/new-peertube-version-for-admins.ts
index 6b5ac808a..f5646c666 100644
--- a/server/lib/notifier/shared/instance/new-peertube-version-for-admins.ts
+++ b/server/lib/notifier/shared/instance/new-peertube-version-for-admins.ts
@@ -30,8 +30,8 @@ export class NewPeerTubeVersionForAdmins extends AbstractNotification <NewPeerTu
30 return this.admins 30 return this.admins
31 } 31 }
32 32
33 async createNotification (user: MUserWithNotificationSetting) { 33 createNotification (user: MUserWithNotificationSetting) {
34 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 34 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
35 type: UserNotificationType.NEW_PEERTUBE_VERSION, 35 type: UserNotificationType.NEW_PEERTUBE_VERSION,
36 userId: user.id, 36 userId: user.id,
37 applicationId: this.payload.application.id 37 applicationId: this.payload.application.id
diff --git a/server/lib/notifier/shared/instance/new-plugin-version-for-admins.ts b/server/lib/notifier/shared/instance/new-plugin-version-for-admins.ts
index 874b10a3d..547c6726c 100644
--- a/server/lib/notifier/shared/instance/new-plugin-version-for-admins.ts
+++ b/server/lib/notifier/shared/instance/new-plugin-version-for-admins.ts
@@ -26,8 +26,8 @@ export class NewPluginVersionForAdmins extends AbstractNotification <MPlugin> {
26 return this.admins 26 return this.admins
27 } 27 }
28 28
29 async createNotification (user: MUserWithNotificationSetting) { 29 createNotification (user: MUserWithNotificationSetting) {
30 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 30 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
31 type: UserNotificationType.NEW_PLUGIN_VERSION, 31 type: UserNotificationType.NEW_PLUGIN_VERSION,
32 userId: user.id, 32 userId: user.id,
33 pluginId: this.plugin.id 33 pluginId: this.plugin.id
diff --git a/server/lib/notifier/shared/instance/registration-for-moderators.ts b/server/lib/notifier/shared/instance/registration-for-moderators.ts
index 2a48ef2fa..e92467424 100644
--- a/server/lib/notifier/shared/instance/registration-for-moderators.ts
+++ b/server/lib/notifier/shared/instance/registration-for-moderators.ts
@@ -25,8 +25,8 @@ export class RegistrationForModerators extends AbstractNotification <MUserDefaul
25 return this.moderators 25 return this.moderators
26 } 26 }
27 27
28 async createNotification (user: MUserWithNotificationSetting) { 28 createNotification (user: MUserWithNotificationSetting) {
29 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 29 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
30 type: UserNotificationType.NEW_USER_REGISTRATION, 30 type: UserNotificationType.NEW_USER_REGISTRATION,
31 userId: user.id, 31 userId: user.id,
32 accountId: this.payload.Account.id 32 accountId: this.payload.Account.id
diff --git a/server/lib/notifier/shared/video-publication/abstract-owned-video-publication.ts b/server/lib/notifier/shared/video-publication/abstract-owned-video-publication.ts
index 37435f898..a940cde69 100644
--- a/server/lib/notifier/shared/video-publication/abstract-owned-video-publication.ts
+++ b/server/lib/notifier/shared/video-publication/abstract-owned-video-publication.ts
@@ -27,8 +27,8 @@ export abstract class AbstractOwnedVideoPublication extends AbstractNotification
27 return [ this.user ] 27 return [ this.user ]
28 } 28 }
29 29
30 async createNotification (user: MUserWithNotificationSetting) { 30 createNotification (user: MUserWithNotificationSetting) {
31 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 31 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
32 type: UserNotificationType.MY_VIDEO_PUBLISHED, 32 type: UserNotificationType.MY_VIDEO_PUBLISHED,
33 userId: user.id, 33 userId: user.id,
34 videoId: this.payload.id 34 videoId: this.payload.id
diff --git a/server/lib/notifier/shared/video-publication/import-finished-for-owner.ts b/server/lib/notifier/shared/video-publication/import-finished-for-owner.ts
index 9f374b6f9..3bd64692f 100644
--- a/server/lib/notifier/shared/video-publication/import-finished-for-owner.ts
+++ b/server/lib/notifier/shared/video-publication/import-finished-for-owner.ts
@@ -32,8 +32,8 @@ export class ImportFinishedForOwner extends AbstractNotification <ImportFinished
32 return [ this.user ] 32 return [ this.user ]
33 } 33 }
34 34
35 async createNotification (user: MUserWithNotificationSetting) { 35 createNotification (user: MUserWithNotificationSetting) {
36 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 36 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
37 type: this.payload.success 37 type: this.payload.success
38 ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS 38 ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS
39 : UserNotificationType.MY_VIDEO_IMPORT_ERROR, 39 : UserNotificationType.MY_VIDEO_IMPORT_ERROR,
diff --git a/server/lib/notifier/shared/video-publication/new-video-for-subscribers.ts b/server/lib/notifier/shared/video-publication/new-video-for-subscribers.ts
index 4253a0930..df7a5561d 100644
--- a/server/lib/notifier/shared/video-publication/new-video-for-subscribers.ts
+++ b/server/lib/notifier/shared/video-publication/new-video-for-subscribers.ts
@@ -30,8 +30,8 @@ export class NewVideoForSubscribers extends AbstractNotification <MVideoAccountL
30 return this.users 30 return this.users
31 } 31 }
32 32
33 async createNotification (user: MUserWithNotificationSetting) { 33 createNotification (user: MUserWithNotificationSetting) {
34 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 34 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
35 type: UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION, 35 type: UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION,
36 userId: user.id, 36 userId: user.id,
37 videoId: this.payload.id 37 videoId: this.payload.id
diff --git a/server/lib/notifier/shared/video-publication/studio-edition-finished-for-owner.ts b/server/lib/notifier/shared/video-publication/studio-edition-finished-for-owner.ts
index ee3027245..f36399f05 100644
--- a/server/lib/notifier/shared/video-publication/studio-edition-finished-for-owner.ts
+++ b/server/lib/notifier/shared/video-publication/studio-edition-finished-for-owner.ts
@@ -27,8 +27,8 @@ export class StudioEditionFinishedForOwner extends AbstractNotification <MVideoF
27 return [ this.user ] 27 return [ this.user ]
28 } 28 }
29 29
30 async createNotification (user: MUserWithNotificationSetting) { 30 createNotification (user: MUserWithNotificationSetting) {
31 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 31 const notification = UserNotificationModel.build<UserNotificationModelForApi>({
32 type: UserNotificationType.MY_VIDEO_STUDIO_EDITION_FINISHED, 32 type: UserNotificationType.MY_VIDEO_STUDIO_EDITION_FINISHED,
33 userId: user.id, 33 userId: user.id,
34 videoId: this.payload.id 34 videoId: this.payload.id
diff --git a/server/tests/fixtures/peertube-plugin-test/main.js b/server/tests/fixtures/peertube-plugin-test/main.js
index 8d7584eba..b3febfa12 100644
--- a/server/tests/fixtures/peertube-plugin-test/main.js
+++ b/server/tests/fixtures/peertube-plugin-test/main.js
@@ -1,6 +1,7 @@
1async function register ({ registerHook, registerSetting, settingsManager, storageManager, peertubeHelpers }) { 1async function register ({ registerHook, registerSetting, settingsManager, storageManager, peertubeHelpers }) {
2 const actionHooks = [ 2 const actionHooks = [
3 'action:application.listening', 3 'action:application.listening',
4 'action:notifier.notification.created',
4 5
5 'action:api.video.updated', 6 'action:api.video.updated',
6 'action:api.video.deleted', 7 'action:api.video.deleted',
diff --git a/server/tests/plugins/action-hooks.ts b/server/tests/plugins/action-hooks.ts
index 209db95a4..405f81d7c 100644
--- a/server/tests/plugins/action-hooks.ts
+++ b/server/tests/plugins/action-hooks.ts
@@ -17,8 +17,8 @@ describe('Test plugin action hooks', function () {
17 let videoUUID: string 17 let videoUUID: string
18 let threadId: number 18 let threadId: number
19 19
20 function checkHook (hook: ServerHookName) { 20 function checkHook (hook: ServerHookName, strictCount = true) {
21 return servers[0].servers.waitUntilLog('Run hook ' + hook) 21 return servers[0].servers.waitUntilLog('Run hook ' + hook, 1, strictCount)
22 } 22 }
23 23
24 before(async function () { 24 before(async function () {
@@ -225,6 +225,13 @@ describe('Test plugin action hooks', function () {
225 }) 225 })
226 }) 226 })
227 227
228 describe('Notification hook', function () {
229
230 it('Should run action:notifier.notification.created', async function () {
231 await checkHook('action:notifier.notification.created', false)
232 })
233 })
234
228 after(async function () { 235 after(async function () {
229 await cleanupTests(servers) 236 await cleanupTests(servers)
230 }) 237 })
diff --git a/shared/models/plugins/server/server-hook.model.ts b/shared/models/plugins/server/server-hook.model.ts
index 5f3a5be10..c8e879323 100644
--- a/shared/models/plugins/server/server-hook.model.ts
+++ b/shared/models/plugins/server/server-hook.model.ts
@@ -112,6 +112,9 @@ export const serverActionHookObject = {
112 // Fired when the application has been loaded and is listening HTTP requests 112 // Fired when the application has been loaded and is listening HTTP requests
113 'action:application.listening': true, 113 'action:application.listening': true,
114 114
115 // Fired when a new notification is created
116 'action:notifier.notification.created': true,
117
115 // API actions hooks give access to the original express `req` and `res` parameters 118 // API actions hooks give access to the original express `req` and `res` parameters
116 119
117 // Fired when a local video is updated 120 // Fired when a local video is updated