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