]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/lib/notifier/notifier.ts
Rename studio to editor
[github/Chocobozzz/PeerTube.git] / server / lib / notifier / notifier.ts
CommitLineData
d26836cd
C
1import { MUser, MUserDefault } from '@server/types/models/user'
2import { MVideoBlacklistLightVideo, MVideoBlacklistVideo } from '@server/types/models/video/video-blacklist'
3import { UserNotificationSettingValue } from '../../../shared/models/users'
4import { logger } from '../../helpers/logger'
5import { CONFIG } from '../../initializers/config'
6import { MAbuseFull, MAbuseMessage, MActorFollowFull, MApplication, MPlugin } from '../../types/models'
7import { MCommentOwnerVideo, MVideoAccountLight, MVideoFullLight } from '../../types/models/video'
8import { JobQueue } from '../job-queue'
9import { PeerTubeSocket } from '../peertube-socket'
10import {
11 AbstractNotification,
12 AbuseStateChangeForReporter,
13 AutoFollowForInstance,
14 CommentMention,
92e66e04 15 StudioEditionFinishedForOwner,
d26836cd
C
16 FollowForInstance,
17 FollowForUser,
18 ImportFinishedForOwner,
19 ImportFinishedForOwnerPayload,
20 NewAbuseForModerators,
21 NewAbuseMessageForModerators,
22 NewAbuseMessageForReporter,
23 NewAbusePayload,
24 NewAutoBlacklistForModerators,
25 NewBlacklistForOwner,
26 NewCommentForVideoOwner,
27 NewPeerTubeVersionForAdmins,
28 NewPluginVersionForAdmins,
29 NewVideoForSubscribers,
30 OwnedPublicationAfterAutoUnblacklist,
31 OwnedPublicationAfterScheduleUpdate,
32 OwnedPublicationAfterTranscoding,
33 RegistrationForModerators,
34 UnblacklistForOwner
35} from './shared'
36
37class Notifier {
38
39 private readonly notificationModels = {
40 newVideo: [ NewVideoForSubscribers ],
41 publicationAfterTranscoding: [ OwnedPublicationAfterTranscoding ],
42 publicationAfterScheduleUpdate: [ OwnedPublicationAfterScheduleUpdate ],
43 publicationAfterAutoUnblacklist: [ OwnedPublicationAfterAutoUnblacklist ],
44 newComment: [ CommentMention, NewCommentForVideoOwner ],
45 newAbuse: [ NewAbuseForModerators ],
46 newBlacklist: [ NewBlacklistForOwner ],
47 unblacklist: [ UnblacklistForOwner ],
48 importFinished: [ ImportFinishedForOwner ],
49 userRegistration: [ RegistrationForModerators ],
50 userFollow: [ FollowForUser ],
51 instanceFollow: [ FollowForInstance ],
52 autoInstanceFollow: [ AutoFollowForInstance ],
53 newAutoBlacklist: [ NewAutoBlacklistForModerators ],
54 abuseStateChange: [ AbuseStateChangeForReporter ],
55 newAbuseMessage: [ NewAbuseMessageForReporter, NewAbuseMessageForModerators ],
56 newPeertubeVersion: [ NewPeerTubeVersionForAdmins ],
1808a1f8 57 newPluginVersion: [ NewPluginVersionForAdmins ],
92e66e04 58 videoStudioEditionFinished: [ StudioEditionFinishedForOwner ]
d26836cd
C
59 }
60
61 private static instance: Notifier
62
63 private constructor () {
64 }
65
66 notifyOnNewVideoIfNeeded (video: MVideoAccountLight): void {
67 const models = this.notificationModels.newVideo
68
69 this.sendNotifications(models, video)
70 .catch(err => logger.error('Cannot notify subscribers of new video %s.', video.url, { err }))
71 }
72
73 notifyOnVideoPublishedAfterTranscoding (video: MVideoFullLight): void {
74 const models = this.notificationModels.publicationAfterTranscoding
75
76 this.sendNotifications(models, video)
77 .catch(err => logger.error('Cannot notify owner that its video %s has been published after transcoding.', video.url, { err }))
78 }
79
80 notifyOnVideoPublishedAfterScheduledUpdate (video: MVideoFullLight): void {
81 const models = this.notificationModels.publicationAfterScheduleUpdate
82
83 this.sendNotifications(models, video)
84 .catch(err => logger.error('Cannot notify owner that its video %s has been published after scheduled update.', video.url, { err }))
85 }
86
87 notifyOnVideoPublishedAfterRemovedFromAutoBlacklist (video: MVideoFullLight): void {
88 const models = this.notificationModels.publicationAfterAutoUnblacklist
89
90 this.sendNotifications(models, video)
91 .catch(err => {
92 logger.error('Cannot notify owner that its video %s has been published after removed from auto-blacklist.', video.url, { err })
93 })
94 }
95
96 notifyOnNewComment (comment: MCommentOwnerVideo): void {
97 const models = this.notificationModels.newComment
98
99 this.sendNotifications(models, comment)
100 .catch(err => logger.error('Cannot notify of new comment.', comment.url, { err }))
101 }
102
103 notifyOnNewAbuse (payload: NewAbusePayload): void {
104 const models = this.notificationModels.newAbuse
105
106 this.sendNotifications(models, payload)
107 .catch(err => logger.error('Cannot notify of new abuse %d.', payload.abuseInstance.id, { err }))
108 }
109
110 notifyOnVideoAutoBlacklist (videoBlacklist: MVideoBlacklistLightVideo): void {
111 const models = this.notificationModels.newAutoBlacklist
112
113 this.sendNotifications(models, videoBlacklist)
114 .catch(err => logger.error('Cannot notify of auto-blacklist of video %s.', videoBlacklist.Video.url, { err }))
115 }
116
117 notifyOnVideoBlacklist (videoBlacklist: MVideoBlacklistVideo): void {
118 const models = this.notificationModels.newBlacklist
119
120 this.sendNotifications(models, videoBlacklist)
121 .catch(err => logger.error('Cannot notify video owner of new video blacklist of %s.', videoBlacklist.Video.url, { err }))
122 }
123
124 notifyOnVideoUnblacklist (video: MVideoFullLight): void {
125 const models = this.notificationModels.unblacklist
126
127 this.sendNotifications(models, video)
128 .catch(err => logger.error('Cannot notify video owner of unblacklist of %s.', video.url, { err }))
129 }
130
131 notifyOnFinishedVideoImport (payload: ImportFinishedForOwnerPayload): void {
132 const models = this.notificationModels.importFinished
133
134 this.sendNotifications(models, payload)
135 .catch(err => {
136 logger.error('Cannot notify owner that its video import %s is finished.', payload.videoImport.getTargetIdentifier(), { err })
137 })
138 }
139
140 notifyOnNewUserRegistration (user: MUserDefault): void {
141 const models = this.notificationModels.userRegistration
142
143 this.sendNotifications(models, user)
144 .catch(err => logger.error('Cannot notify moderators of new user registration (%s).', user.username, { err }))
145 }
146
147 notifyOfNewUserFollow (actorFollow: MActorFollowFull): void {
148 const models = this.notificationModels.userFollow
149
150 this.sendNotifications(models, actorFollow)
151 .catch(err => {
152 logger.error(
153 'Cannot notify owner of channel %s of a new follow by %s.',
154 actorFollow.ActorFollowing.VideoChannel.getDisplayName(),
155 actorFollow.ActorFollower.Account.getDisplayName(),
156 { err }
157 )
158 })
159 }
160
161 notifyOfNewInstanceFollow (actorFollow: MActorFollowFull): void {
162 const models = this.notificationModels.instanceFollow
163
164 this.sendNotifications(models, actorFollow)
165 .catch(err => logger.error('Cannot notify administrators of new follower %s.', actorFollow.ActorFollower.url, { err }))
166 }
167
168 notifyOfAutoInstanceFollowing (actorFollow: MActorFollowFull): void {
169 const models = this.notificationModels.autoInstanceFollow
170
171 this.sendNotifications(models, actorFollow)
172 .catch(err => logger.error('Cannot notify administrators of auto instance following %s.', actorFollow.ActorFollowing.url, { err }))
173 }
174
175 notifyOnAbuseStateChange (abuse: MAbuseFull): void {
176 const models = this.notificationModels.abuseStateChange
177
178 this.sendNotifications(models, abuse)
179 .catch(err => logger.error('Cannot notify of abuse %d state change.', abuse.id, { err }))
180 }
181
182 notifyOnAbuseMessage (abuse: MAbuseFull, message: MAbuseMessage): void {
183 const models = this.notificationModels.newAbuseMessage
184
185 this.sendNotifications(models, { abuse, message })
186 .catch(err => logger.error('Cannot notify on new abuse %d message.', abuse.id, { err }))
187 }
188
189 notifyOfNewPeerTubeVersion (application: MApplication, latestVersion: string) {
190 const models = this.notificationModels.newPeertubeVersion
191
192 this.sendNotifications(models, { application, latestVersion })
193 .catch(err => logger.error('Cannot notify on new PeerTubeb version %s.', latestVersion, { err }))
194 }
195
196 notifyOfNewPluginVersion (plugin: MPlugin) {
197 const models = this.notificationModels.newPluginVersion
198
199 this.sendNotifications(models, plugin)
200 .catch(err => logger.error('Cannot notify on new plugin version %s.', plugin.name, { err }))
201 }
202
92e66e04
C
203 notifyOfFinishedVideoStudioEdition (video: MVideoFullLight) {
204 const models = this.notificationModels.videoStudioEditionFinished
1808a1f8
C
205
206 this.sendNotifications(models, video)
92e66e04 207 .catch(err => logger.error('Cannot notify on finished studio edition %s.', video.url, { err }))
1808a1f8
C
208 }
209
d26836cd
C
210 private async notify <T> (object: AbstractNotification<T>) {
211 await object.prepare()
212
213 const users = object.getTargetUsers()
214
215 if (users.length === 0) return
216 if (await object.isDisabled()) return
217
218 object.log()
219
220 const toEmails: string[] = []
221
222 for (const user of users) {
223 const setting = object.getSetting(user)
224
225 if (this.isWebNotificationEnabled(setting)) {
226 const notification = await object.createNotification(user)
227
228 PeerTubeSocket.Instance.sendNotification(user.id, notification)
229 }
230
231 if (this.isEmailEnabled(user, setting)) {
232 toEmails.push(user.email)
233 }
234 }
235
236 for (const to of toEmails) {
237 const payload = await object.createEmail(to)
238 JobQueue.Instance.createJob({ type: 'email', payload })
239 }
240 }
241
242 private isEmailEnabled (user: MUser, value: UserNotificationSettingValue) {
243 if (CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION === true && user.emailVerified === false) return false
244
245 return value & UserNotificationSettingValue.EMAIL
246 }
247
248 private isWebNotificationEnabled (value: UserNotificationSettingValue) {
249 return value & UserNotificationSettingValue.WEB
250 }
251
252 private async sendNotifications <T> (models: (new (payload: T) => AbstractNotification<T>)[], payload: T) {
253 for (const model of models) {
254 // eslint-disable-next-line new-cap
255 await this.notify(new model(payload))
256 }
257 }
258
259 static get Instance () {
260 return this.instance || (this.instance = new this())
261 }
262}
263
264// ---------------------------------------------------------------------------
265
266export {
267 Notifier
268}