diff --git a/server/models/Integration.js b/server/models/Integration.js index 9251ba7c..24d7ac4a 100644 --- a/server/models/Integration.js +++ b/server/models/Integration.js @@ -1,5 +1,6 @@ // @flow import { DataTypes, sequelize } from '../sequelize'; +import events from '../events'; const Integration = sequelize.define('integration', { id: { @@ -32,4 +33,16 @@ Integration.associate = models => { }); }; +Integration.addHook('afterCreate', async model => { + events.add({ name: 'integrations.create', model }); +}); + +Integration.addHook('afterUpdate', model => + events.add({ name: 'integrations.update', model }) +); + +Integration.addHook('afterDestroy', model => + events.add({ name: 'integrations.delete', model }) +); + export default Integration; diff --git a/server/services/slack/index.js b/server/services/slack/index.js index b2e5fd21..cb2113be 100644 --- a/server/services/slack/index.js +++ b/server/services/slack/index.js @@ -1,13 +1,62 @@ // @flow import type { Event } from '../../events'; -import { Document, Integration } from '../../models'; +import { Document, Integration, Collection } from '../../models'; import { presentSlackAttachment } from '../../presenters'; -const Slack = { - on: async (event: Event) => { - if (event.name !== 'documents.publish' && event.name !== 'documents.update') - return; +class Slack { + on = async (event: Event) => { + switch (event.name) { + case 'documents.publish': + case 'documents.update': + return this.documentUpdated(event); + case 'integrations.create': + return this.integrationCreated(event); + default: + } + }; + integrationCreated = async (event: Event) => { + const integration = await Integration.findOne({ + where: { + id: event.model.id, + service: 'slack', + type: 'post', + }, + include: [ + { + model: Collection, + required: true, + as: 'collection', + }, + ], + }); + if (!integration) return; + + const collection = integration.collection; + if (!collection) return; + + await fetch(integration.settings.url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + text: `👋 Hey there! When documents are published or updated in the *${ + collection.name + }* collection on Outline they will be posted to this channel!`, + attachments: [ + { + color: collection.color, + title: collection.name, + title_link: `${process.env.URL}${collection.getUrl()}`, + text: collection.description, + }, + ], + }), + }); + }; + + documentUpdated = async (event: Event) => { const document = await Document.findById(event.model.id); if (!document) return; @@ -37,7 +86,7 @@ const Slack = { attachments: [presentSlackAttachment(document)], }), }); - }, -}; + }; +} -export default Slack; +export default new Slack();