// @flow import type { DocumentEvent, CollectionEvent, Event } from "../events"; import mailer from "../mailer"; import { Document, Team, Collection, User, NotificationSetting, } from "../models"; import { Op } from "../sequelize"; export default class Notifications { async on(event: Event) { switch (event.name) { case "documents.publish": case "documents.update": return this.documentUpdated(event); case "collections.create": return this.collectionCreated(event); default: } } async documentUpdated(event: DocumentEvent) { // lets not send a notification on every autosave update if (event.data && event.data.autosave) return; // wait until the user has finished editing if (event.data && !event.data.done) return; const document = await Document.findByPk(event.documentId); if (!document) return; const { collection } = document; if (!collection) return; const team = await Team.findByPk(document.teamId); if (!team) return; const notificationSettings = await NotificationSetting.findAll({ where: { userId: { [Op.ne]: document.lastModifiedById, }, teamId: document.teamId, event: event.name, }, include: [ { model: User, required: true, as: "user", }, ], }); const eventName = event.name === "documents.publish" ? "published" : "updated"; notificationSettings.forEach((setting) => { // For document updates we only want to send notifications if // the document has been edited by the user with this notification setting // This could be replaced with ability to "follow" in the future if ( event.name === "documents.update" && !document.collaboratorIds.includes(setting.userId) ) { return; } mailer.documentNotification({ to: setting.user.email, eventName, document, team, collection, actor: document.updatedBy, unsubscribeUrl: setting.unsubscribeUrl, }); }); } async collectionCreated(event: CollectionEvent) { const collection = await Collection.findByPk(event.collectionId, { include: [ { model: User, required: true, as: "user", }, ], }); if (!collection) return; if (collection.private) return; const notificationSettings = await NotificationSetting.findAll({ where: { userId: { [Op.ne]: collection.createdById, }, teamId: collection.teamId, event: event.name, }, include: [ { model: User, required: true, as: "user", }, ], }); notificationSettings.forEach((setting) => mailer.collectionNotification({ to: setting.user.email, eventName: "created", collection, actor: collection.user, unsubscribeUrl: setting.unsubscribeUrl, }) ); } }