]>
Commit | Line | Data |
---|---|---|
cef534ed C |
1 | import { UserNotificationSettingValue, UserNotificationType, UserRight } from '../../shared/models/users' |
2 | import { logger } from '../helpers/logger' | |
3 | import { VideoModel } from '../models/video/video' | |
4 | import { Emailer } from './emailer' | |
5 | import { UserNotificationModel } from '../models/account/user-notification' | |
6 | import { VideoCommentModel } from '../models/video/video-comment' | |
7 | import { UserModel } from '../models/account/user' | |
8 | import { PeerTubeSocket } from './peertube-socket' | |
6dd9de95 | 9 | import { CONFIG } from '../initializers/config' |
cef534ed | 10 | import { VideoPrivacy, VideoState } from '../../shared/models/videos' |
cef534ed C |
11 | import { VideoBlacklistModel } from '../models/video/video-blacklist' |
12 | import * as Bluebird from 'bluebird' | |
dc133480 C |
13 | import { VideoImportModel } from '../models/video/video-import' |
14 | import { AccountBlocklistModel } from '../models/account/account-blocklist' | |
453e83ea C |
15 | import { |
16 | MCommentOwnerVideo, | |
17 | MVideo, | |
18 | MVideoAbuseVideo, | |
19 | MVideoAccountLight, | |
20 | MVideoBlacklistVideo, | |
21 | MVideoFullLight | |
22 | } from '../typings/models/video' | |
23 | import { MUser, MUserAccount, MUserWithNotificationSetting, UserNotificationModelForApi } from '@server/typings/models/user' | |
24 | import { MActorFollowActors, MActorFollowFull } from '../typings/models' | |
f7cc67b4 | 25 | import { ActorFollowModel } from '../models/activitypub/actor-follow' |
453e83ea C |
26 | import { MVideoImportVideo } from '@server/typings/models/video/video-import' |
27 | import { AccountModel } from '@server/models/account/account' | |
cef534ed C |
28 | |
29 | class Notifier { | |
30 | ||
31 | private static instance: Notifier | |
32 | ||
33 | private constructor () {} | |
34 | ||
453e83ea | 35 | notifyOnNewVideoIfNeeded (video: MVideoAccountLight): void { |
7ccddd7b | 36 | // Only notify on public and published videos which are not blacklisted |
5b77537c | 37 | if (video.privacy !== VideoPrivacy.PUBLIC || video.state !== VideoState.PUBLISHED || video.isBlacklisted()) return |
cef534ed C |
38 | |
39 | this.notifySubscribersOfNewVideo(video) | |
40 | .catch(err => logger.error('Cannot notify subscribers of new video %s.', video.url, { err })) | |
41 | } | |
42 | ||
453e83ea | 43 | notifyOnVideoPublishedAfterTranscoding (video: MVideoFullLight): void { |
7ccddd7b JM |
44 | // don't notify if didn't wait for transcoding or video is still blacklisted/waiting for scheduled update |
45 | if (!video.waitTranscoding || video.VideoBlacklist || video.ScheduleVideoUpdate) return | |
dc133480 C |
46 | |
47 | this.notifyOwnedVideoHasBeenPublished(video) | |
7ccddd7b JM |
48 | .catch(err => logger.error('Cannot notify owner that its video %s has been published after transcoding.', video.url, { err })) |
49 | } | |
50 | ||
453e83ea | 51 | notifyOnVideoPublishedAfterScheduledUpdate (video: MVideoFullLight): void { |
7ccddd7b JM |
52 | // don't notify if video is still blacklisted or waiting for transcoding |
53 | if (video.VideoBlacklist || (video.waitTranscoding && video.state !== VideoState.PUBLISHED)) return | |
54 | ||
55 | this.notifyOwnedVideoHasBeenPublished(video) | |
56 | .catch(err => logger.error('Cannot notify owner that its video %s has been published after scheduled update.', video.url, { err })) | |
57 | } | |
58 | ||
453e83ea | 59 | notifyOnVideoPublishedAfterRemovedFromAutoBlacklist (video: MVideoFullLight): void { |
7ccddd7b JM |
60 | // don't notify if video is still waiting for transcoding or scheduled update |
61 | if (video.ScheduleVideoUpdate || (video.waitTranscoding && video.state !== VideoState.PUBLISHED)) return | |
62 | ||
63 | this.notifyOwnedVideoHasBeenPublished(video) | |
64 | .catch(err => logger.error('Cannot notify owner that its video %s has been published after removed from auto-blacklist.', video.url, { err })) // tslint:disable-line:max-line-length | |
dc133480 C |
65 | } |
66 | ||
453e83ea | 67 | notifyOnNewComment (comment: MCommentOwnerVideo): void { |
cef534ed | 68 | this.notifyVideoOwnerOfNewComment(comment) |
f7cc67b4 C |
69 | .catch(err => logger.error('Cannot notify video owner of new comment %s.', comment.url, { err })) |
70 | ||
71 | this.notifyOfCommentMention(comment) | |
72 | .catch(err => logger.error('Cannot notify mentions of comment %s.', comment.url, { err })) | |
cef534ed C |
73 | } |
74 | ||
453e83ea | 75 | notifyOnNewVideoAbuse (videoAbuse: MVideoAbuseVideo): void { |
cef534ed C |
76 | this.notifyModeratorsOfNewVideoAbuse(videoAbuse) |
77 | .catch(err => logger.error('Cannot notify of new video abuse of video %s.', videoAbuse.Video.url, { err })) | |
78 | } | |
79 | ||
453e83ea | 80 | notifyOnVideoAutoBlacklist (video: MVideo): void { |
7ccddd7b JM |
81 | this.notifyModeratorsOfVideoAutoBlacklist(video) |
82 | .catch(err => logger.error('Cannot notify of auto-blacklist of video %s.', video.url, { err })) | |
83 | } | |
84 | ||
453e83ea | 85 | notifyOnVideoBlacklist (videoBlacklist: MVideoBlacklistVideo): void { |
cef534ed C |
86 | this.notifyVideoOwnerOfBlacklist(videoBlacklist) |
87 | .catch(err => logger.error('Cannot notify video owner of new video blacklist of %s.', videoBlacklist.Video.url, { err })) | |
88 | } | |
89 | ||
453e83ea | 90 | notifyOnVideoUnblacklist (video: MVideo): void { |
cef534ed | 91 | this.notifyVideoOwnerOfUnblacklist(video) |
7ccddd7b | 92 | .catch(err => logger.error('Cannot notify video owner of unblacklist of %s.', video.url, { err })) |
cef534ed C |
93 | } |
94 | ||
453e83ea | 95 | notifyOnFinishedVideoImport (videoImport: MVideoImportVideo, success: boolean): void { |
dc133480 C |
96 | this.notifyOwnerVideoImportIsFinished(videoImport, success) |
97 | .catch(err => logger.error('Cannot notify owner that its video import %s is finished.', videoImport.getTargetIdentifier(), { err })) | |
98 | } | |
99 | ||
453e83ea | 100 | notifyOnNewUserRegistration (user: MUserAccount): void { |
f7cc67b4 C |
101 | this.notifyModeratorsOfNewUserRegistration(user) |
102 | .catch(err => logger.error('Cannot notify moderators of new user registration (%s).', user.username, { err })) | |
103 | } | |
104 | ||
453e83ea | 105 | notifyOfNewUserFollow (actorFollow: MActorFollowFull): void { |
f7cc67b4 C |
106 | this.notifyUserOfNewActorFollow(actorFollow) |
107 | .catch(err => { | |
108 | logger.error( | |
109 | 'Cannot notify owner of channel %s of a new follow by %s.', | |
110 | actorFollow.ActorFollowing.VideoChannel.getDisplayName(), | |
111 | actorFollow.ActorFollower.Account.getDisplayName(), | |
883993c8 | 112 | { err } |
f7cc67b4 C |
113 | ) |
114 | }) | |
115 | } | |
116 | ||
453e83ea | 117 | notifyOfNewInstanceFollow (actorFollow: MActorFollowActors): void { |
883993c8 C |
118 | this.notifyAdminsOfNewInstanceFollow(actorFollow) |
119 | .catch(err => { | |
120 | logger.error('Cannot notify administrators of new follower %s.', actorFollow.ActorFollower.url, { err }) | |
121 | }) | |
122 | } | |
123 | ||
453e83ea | 124 | private async notifySubscribersOfNewVideo (video: MVideoAccountLight) { |
cef534ed C |
125 | // List all followers that are users |
126 | const users = await UserModel.listUserSubscribersOf(video.VideoChannel.actorId) | |
127 | ||
128 | logger.info('Notifying %d users of new video %s.', users.length, video.url) | |
129 | ||
130 | function settingGetter (user: UserModel) { | |
131 | return user.NotificationSetting.newVideoFromSubscription | |
132 | } | |
133 | ||
134 | async function notificationCreator (user: UserModel) { | |
135 | const notification = await UserNotificationModel.create({ | |
136 | type: UserNotificationType.NEW_VIDEO_FROM_SUBSCRIPTION, | |
137 | userId: user.id, | |
138 | videoId: video.id | |
139 | }) | |
453e83ea | 140 | notification.Video = video as VideoModel |
cef534ed C |
141 | |
142 | return notification | |
143 | } | |
144 | ||
145 | function emailSender (emails: string[]) { | |
146 | return Emailer.Instance.addNewVideoFromSubscriberNotification(emails, video) | |
147 | } | |
148 | ||
149 | return this.notify({ users, settingGetter, notificationCreator, emailSender }) | |
150 | } | |
151 | ||
453e83ea | 152 | private async notifyVideoOwnerOfNewComment (comment: MCommentOwnerVideo) { |
f7cc67b4 C |
153 | if (comment.Video.isOwned() === false) return |
154 | ||
cef534ed C |
155 | const user = await UserModel.loadByVideoId(comment.videoId) |
156 | ||
157 | // Not our user or user comments its own video | |
158 | if (!user || comment.Account.userId === user.id) return | |
159 | ||
dc133480 C |
160 | const accountMuted = await AccountBlocklistModel.isAccountMutedBy(user.Account.id, comment.accountId) |
161 | if (accountMuted) return | |
162 | ||
cef534ed C |
163 | logger.info('Notifying user %s of new comment %s.', user.username, comment.url) |
164 | ||
165 | function settingGetter (user: UserModel) { | |
166 | return user.NotificationSetting.newCommentOnMyVideo | |
167 | } | |
168 | ||
169 | async function notificationCreator (user: UserModel) { | |
170 | const notification = await UserNotificationModel.create({ | |
171 | type: UserNotificationType.NEW_COMMENT_ON_MY_VIDEO, | |
172 | userId: user.id, | |
173 | commentId: comment.id | |
174 | }) | |
453e83ea | 175 | notification.Comment = comment as VideoCommentModel |
cef534ed C |
176 | |
177 | return notification | |
178 | } | |
179 | ||
180 | function emailSender (emails: string[]) { | |
181 | return Emailer.Instance.addNewCommentOnMyVideoNotification(emails, comment) | |
182 | } | |
183 | ||
184 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) | |
185 | } | |
186 | ||
453e83ea | 187 | private async notifyOfCommentMention (comment: MCommentOwnerVideo) { |
41d71344 C |
188 | const extractedUsernames = comment.extractMentions() |
189 | logger.debug( | |
190 | 'Extracted %d username from comment %s.', extractedUsernames.length, comment.url, | |
191 | { usernames: extractedUsernames, text: comment.text } | |
192 | ) | |
1f6d57e3 | 193 | |
41d71344 | 194 | let users = await UserModel.listByUsernames(extractedUsernames) |
f7cc67b4 C |
195 | |
196 | if (comment.Video.isOwned()) { | |
197 | const userException = await UserModel.loadByVideoId(comment.videoId) | |
198 | users = users.filter(u => u.id !== userException.id) | |
199 | } | |
200 | ||
201 | // Don't notify if I mentioned myself | |
202 | users = users.filter(u => u.Account.id !== comment.accountId) | |
203 | ||
cef534ed C |
204 | if (users.length === 0) return |
205 | ||
f7cc67b4 C |
206 | const accountMutedHash = await AccountBlocklistModel.isAccountMutedByMulti(users.map(u => u.Account.id), comment.accountId) |
207 | ||
208 | logger.info('Notifying %d users of new comment %s.', users.length, comment.url) | |
209 | ||
210 | function settingGetter (user: UserModel) { | |
211 | if (accountMutedHash[user.Account.id] === true) return UserNotificationSettingValue.NONE | |
212 | ||
213 | return user.NotificationSetting.commentMention | |
214 | } | |
215 | ||
216 | async function notificationCreator (user: UserModel) { | |
217 | const notification = await UserNotificationModel.create({ | |
218 | type: UserNotificationType.COMMENT_MENTION, | |
219 | userId: user.id, | |
220 | commentId: comment.id | |
221 | }) | |
453e83ea | 222 | notification.Comment = comment as VideoCommentModel |
f7cc67b4 C |
223 | |
224 | return notification | |
225 | } | |
226 | ||
227 | function emailSender (emails: string[]) { | |
228 | return Emailer.Instance.addNewCommentMentionNotification(emails, comment) | |
229 | } | |
230 | ||
231 | return this.notify({ users, settingGetter, notificationCreator, emailSender }) | |
232 | } | |
233 | ||
453e83ea | 234 | private async notifyUserOfNewActorFollow (actorFollow: MActorFollowFull) { |
f7cc67b4 C |
235 | if (actorFollow.ActorFollowing.isOwned() === false) return |
236 | ||
237 | // Account follows one of our account? | |
238 | let followType: 'account' | 'channel' = 'channel' | |
239 | let user = await UserModel.loadByChannelActorId(actorFollow.ActorFollowing.id) | |
240 | ||
241 | // Account follows one of our channel? | |
242 | if (!user) { | |
243 | user = await UserModel.loadByAccountActorId(actorFollow.ActorFollowing.id) | |
244 | followType = 'account' | |
245 | } | |
246 | ||
247 | if (!user) return | |
248 | ||
f7cc67b4 C |
249 | const followerAccount = actorFollow.ActorFollower.Account |
250 | ||
251 | const accountMuted = await AccountBlocklistModel.isAccountMutedBy(user.Account.id, followerAccount.id) | |
252 | if (accountMuted) return | |
253 | ||
254 | logger.info('Notifying user %s of new follower: %s.', user.username, followerAccount.getDisplayName()) | |
255 | ||
256 | function settingGetter (user: UserModel) { | |
257 | return user.NotificationSetting.newFollow | |
258 | } | |
259 | ||
260 | async function notificationCreator (user: UserModel) { | |
261 | const notification = await UserNotificationModel.create({ | |
262 | type: UserNotificationType.NEW_FOLLOW, | |
263 | userId: user.id, | |
264 | actorFollowId: actorFollow.id | |
265 | }) | |
453e83ea | 266 | notification.ActorFollow = actorFollow as ActorFollowModel |
f7cc67b4 C |
267 | |
268 | return notification | |
269 | } | |
270 | ||
271 | function emailSender (emails: string[]) { | |
272 | return Emailer.Instance.addNewFollowNotification(emails, actorFollow, followType) | |
273 | } | |
274 | ||
275 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) | |
276 | } | |
277 | ||
453e83ea | 278 | private async notifyAdminsOfNewInstanceFollow (actorFollow: MActorFollowActors) { |
883993c8 C |
279 | const admins = await UserModel.listWithRight(UserRight.MANAGE_SERVER_FOLLOW) |
280 | ||
281 | logger.info('Notifying %d administrators of new instance follower: %s.', admins.length, actorFollow.ActorFollower.url) | |
282 | ||
283 | function settingGetter (user: UserModel) { | |
284 | return user.NotificationSetting.newInstanceFollower | |
285 | } | |
286 | ||
287 | async function notificationCreator (user: UserModel) { | |
288 | const notification = await UserNotificationModel.create({ | |
289 | type: UserNotificationType.NEW_INSTANCE_FOLLOWER, | |
290 | userId: user.id, | |
291 | actorFollowId: actorFollow.id | |
292 | }) | |
453e83ea | 293 | notification.ActorFollow = actorFollow as ActorFollowModel |
883993c8 C |
294 | |
295 | return notification | |
296 | } | |
297 | ||
298 | function emailSender (emails: string[]) { | |
299 | return Emailer.Instance.addNewInstanceFollowerNotification(emails, actorFollow) | |
300 | } | |
301 | ||
302 | return this.notify({ users: admins, settingGetter, notificationCreator, emailSender }) | |
303 | } | |
304 | ||
453e83ea | 305 | private async notifyModeratorsOfNewVideoAbuse (videoAbuse: MVideoAbuseVideo) { |
f7cc67b4 C |
306 | const moderators = await UserModel.listWithRight(UserRight.MANAGE_VIDEO_ABUSES) |
307 | if (moderators.length === 0) return | |
308 | ||
309 | logger.info('Notifying %s user/moderators of new video abuse %s.', moderators.length, videoAbuse.Video.url) | |
cef534ed C |
310 | |
311 | function settingGetter (user: UserModel) { | |
312 | return user.NotificationSetting.videoAbuseAsModerator | |
313 | } | |
314 | ||
315 | async function notificationCreator (user: UserModel) { | |
453e83ea | 316 | const notification: UserNotificationModelForApi = await UserNotificationModel.create({ |
cef534ed C |
317 | type: UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS, |
318 | userId: user.id, | |
319 | videoAbuseId: videoAbuse.id | |
320 | }) | |
321 | notification.VideoAbuse = videoAbuse | |
322 | ||
323 | return notification | |
324 | } | |
325 | ||
326 | function emailSender (emails: string[]) { | |
327 | return Emailer.Instance.addVideoAbuseModeratorsNotification(emails, videoAbuse) | |
328 | } | |
329 | ||
f7cc67b4 | 330 | return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender }) |
cef534ed C |
331 | } |
332 | ||
453e83ea | 333 | private async notifyModeratorsOfVideoAutoBlacklist (video: MVideo) { |
7ccddd7b JM |
334 | const moderators = await UserModel.listWithRight(UserRight.MANAGE_VIDEO_BLACKLIST) |
335 | if (moderators.length === 0) return | |
336 | ||
337 | logger.info('Notifying %s moderators of video auto-blacklist %s.', moderators.length, video.url) | |
338 | ||
339 | function settingGetter (user: UserModel) { | |
340 | return user.NotificationSetting.videoAutoBlacklistAsModerator | |
341 | } | |
342 | async function notificationCreator (user: UserModel) { | |
343 | ||
344 | const notification = await UserNotificationModel.create({ | |
345 | type: UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS, | |
346 | userId: user.id, | |
347 | videoId: video.id | |
348 | }) | |
453e83ea | 349 | notification.Video = video as VideoModel |
7ccddd7b JM |
350 | |
351 | return notification | |
352 | } | |
353 | ||
354 | function emailSender (emails: string[]) { | |
355 | return Emailer.Instance.addVideoAutoBlacklistModeratorsNotification(emails, video) | |
356 | } | |
357 | ||
358 | return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender }) | |
359 | } | |
360 | ||
453e83ea | 361 | private async notifyVideoOwnerOfBlacklist (videoBlacklist: MVideoBlacklistVideo) { |
cef534ed C |
362 | const user = await UserModel.loadByVideoId(videoBlacklist.videoId) |
363 | if (!user) return | |
364 | ||
365 | logger.info('Notifying user %s that its video %s has been blacklisted.', user.username, videoBlacklist.Video.url) | |
366 | ||
367 | function settingGetter (user: UserModel) { | |
368 | return user.NotificationSetting.blacklistOnMyVideo | |
369 | } | |
370 | ||
371 | async function notificationCreator (user: UserModel) { | |
372 | const notification = await UserNotificationModel.create({ | |
373 | type: UserNotificationType.BLACKLIST_ON_MY_VIDEO, | |
374 | userId: user.id, | |
375 | videoBlacklistId: videoBlacklist.id | |
376 | }) | |
453e83ea | 377 | notification.VideoBlacklist = videoBlacklist as VideoBlacklistModel |
cef534ed C |
378 | |
379 | return notification | |
380 | } | |
381 | ||
382 | function emailSender (emails: string[]) { | |
383 | return Emailer.Instance.addVideoBlacklistNotification(emails, videoBlacklist) | |
384 | } | |
385 | ||
386 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) | |
387 | } | |
388 | ||
453e83ea | 389 | private async notifyVideoOwnerOfUnblacklist (video: MVideo) { |
cef534ed C |
390 | const user = await UserModel.loadByVideoId(video.id) |
391 | if (!user) return | |
392 | ||
393 | logger.info('Notifying user %s that its video %s has been unblacklisted.', user.username, video.url) | |
394 | ||
395 | function settingGetter (user: UserModel) { | |
396 | return user.NotificationSetting.blacklistOnMyVideo | |
397 | } | |
398 | ||
399 | async function notificationCreator (user: UserModel) { | |
400 | const notification = await UserNotificationModel.create({ | |
401 | type: UserNotificationType.UNBLACKLIST_ON_MY_VIDEO, | |
402 | userId: user.id, | |
403 | videoId: video.id | |
404 | }) | |
453e83ea | 405 | notification.Video = video as VideoModel |
cef534ed C |
406 | |
407 | return notification | |
408 | } | |
409 | ||
410 | function emailSender (emails: string[]) { | |
411 | return Emailer.Instance.addVideoUnblacklistNotification(emails, video) | |
412 | } | |
413 | ||
414 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) | |
415 | } | |
416 | ||
453e83ea | 417 | private async notifyOwnedVideoHasBeenPublished (video: MVideoFullLight) { |
dc133480 C |
418 | const user = await UserModel.loadByVideoId(video.id) |
419 | if (!user) return | |
420 | ||
421 | logger.info('Notifying user %s of the publication of its video %s.', user.username, video.url) | |
422 | ||
423 | function settingGetter (user: UserModel) { | |
424 | return user.NotificationSetting.myVideoPublished | |
425 | } | |
426 | ||
427 | async function notificationCreator (user: UserModel) { | |
428 | const notification = await UserNotificationModel.create({ | |
429 | type: UserNotificationType.MY_VIDEO_PUBLISHED, | |
430 | userId: user.id, | |
431 | videoId: video.id | |
432 | }) | |
453e83ea | 433 | notification.Video = video as VideoModel |
dc133480 C |
434 | |
435 | return notification | |
436 | } | |
437 | ||
438 | function emailSender (emails: string[]) { | |
439 | return Emailer.Instance.myVideoPublishedNotification(emails, video) | |
440 | } | |
441 | ||
442 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) | |
443 | } | |
444 | ||
453e83ea | 445 | private async notifyOwnerVideoImportIsFinished (videoImport: MVideoImportVideo, success: boolean) { |
dc133480 C |
446 | const user = await UserModel.loadByVideoImportId(videoImport.id) |
447 | if (!user) return | |
448 | ||
449 | logger.info('Notifying user %s its video import %s is finished.', user.username, videoImport.getTargetIdentifier()) | |
450 | ||
451 | function settingGetter (user: UserModel) { | |
452 | return user.NotificationSetting.myVideoImportFinished | |
453 | } | |
454 | ||
455 | async function notificationCreator (user: UserModel) { | |
456 | const notification = await UserNotificationModel.create({ | |
457 | type: success ? UserNotificationType.MY_VIDEO_IMPORT_SUCCESS : UserNotificationType.MY_VIDEO_IMPORT_ERROR, | |
458 | userId: user.id, | |
459 | videoImportId: videoImport.id | |
460 | }) | |
453e83ea | 461 | notification.VideoImport = videoImport as VideoImportModel |
dc133480 C |
462 | |
463 | return notification | |
464 | } | |
465 | ||
466 | function emailSender (emails: string[]) { | |
467 | return success | |
468 | ? Emailer.Instance.myVideoImportSuccessNotification(emails, videoImport) | |
469 | : Emailer.Instance.myVideoImportErrorNotification(emails, videoImport) | |
470 | } | |
471 | ||
472 | return this.notify({ users: [ user ], settingGetter, notificationCreator, emailSender }) | |
473 | } | |
474 | ||
453e83ea | 475 | private async notifyModeratorsOfNewUserRegistration (registeredUser: MUserAccount) { |
f7cc67b4 C |
476 | const moderators = await UserModel.listWithRight(UserRight.MANAGE_USERS) |
477 | if (moderators.length === 0) return | |
478 | ||
479 | logger.info( | |
480 | 'Notifying %s moderators of new user registration of %s.', | |
453e83ea | 481 | moderators.length, registeredUser.username |
f7cc67b4 C |
482 | ) |
483 | ||
484 | function settingGetter (user: UserModel) { | |
485 | return user.NotificationSetting.newUserRegistration | |
486 | } | |
487 | ||
488 | async function notificationCreator (user: UserModel) { | |
489 | const notification = await UserNotificationModel.create({ | |
490 | type: UserNotificationType.NEW_USER_REGISTRATION, | |
491 | userId: user.id, | |
492 | accountId: registeredUser.Account.id | |
493 | }) | |
453e83ea | 494 | notification.Account = registeredUser.Account as AccountModel |
f7cc67b4 C |
495 | |
496 | return notification | |
497 | } | |
498 | ||
499 | function emailSender (emails: string[]) { | |
500 | return Emailer.Instance.addNewUserRegistrationNotification(emails, registeredUser) | |
501 | } | |
502 | ||
503 | return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender }) | |
504 | } | |
505 | ||
cef534ed | 506 | private async notify (options: { |
453e83ea C |
507 | users: MUserWithNotificationSetting[], |
508 | notificationCreator: (user: MUserWithNotificationSetting) => Promise<UserNotificationModelForApi>, | |
cef534ed | 509 | emailSender: (emails: string[]) => Promise<any> | Bluebird<any>, |
453e83ea | 510 | settingGetter: (user: MUserWithNotificationSetting) => UserNotificationSettingValue |
cef534ed C |
511 | }) { |
512 | const emails: string[] = [] | |
513 | ||
514 | for (const user of options.users) { | |
515 | if (this.isWebNotificationEnabled(options.settingGetter(user))) { | |
516 | const notification = await options.notificationCreator(user) | |
517 | ||
518 | PeerTubeSocket.Instance.sendNotification(user.id, notification) | |
519 | } | |
520 | ||
521 | if (this.isEmailEnabled(user, options.settingGetter(user))) { | |
522 | emails.push(user.email) | |
523 | } | |
524 | } | |
525 | ||
526 | if (emails.length !== 0) { | |
527 | await options.emailSender(emails) | |
528 | } | |
529 | } | |
530 | ||
453e83ea | 531 | private isEmailEnabled (user: MUser, value: UserNotificationSettingValue) { |
1ed9b8ee | 532 | if (CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION === true && user.emailVerified === false) return false |
cef534ed | 533 | |
2f1548fd | 534 | return value & UserNotificationSettingValue.EMAIL |
cef534ed C |
535 | } |
536 | ||
537 | private isWebNotificationEnabled (value: UserNotificationSettingValue) { | |
2f1548fd | 538 | return value & UserNotificationSettingValue.WEB |
cef534ed C |
539 | } |
540 | ||
541 | static get Instance () { | |
542 | return this.instance || (this.instance = new this()) | |
543 | } | |
544 | } | |
545 | ||
546 | // --------------------------------------------------------------------------- | |
547 | ||
548 | export { | |
549 | Notifier | |
550 | } |