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