diff --git a/.gitignore b/.gitignore index 9c55f2708..0ab845e4e 100644 --- a/.gitignore +++ b/.gitignore @@ -45,5 +45,6 @@ plugins/* !plugins/talk-plugin-deep-reply-count !plugins/talk-plugin-subscriber !plugins/talk-plugin-flag-details +!plugins/talk-plugin-slack-notifications **/node_modules/* diff --git a/plugins/talk-plugin-slack-notifications/.eslintrc.json b/plugins/talk-plugin-slack-notifications/.eslintrc.json new file mode 100644 index 000000000..78f7c2397 --- /dev/null +++ b/plugins/talk-plugin-slack-notifications/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "@coralproject/eslint-config-talk" +} diff --git a/plugins/talk-plugin-slack-notifications/index.js b/plugins/talk-plugin-slack-notifications/index.js new file mode 100644 index 000000000..1f2a73ff0 --- /dev/null +++ b/plugins/talk-plugin-slack-notifications/index.js @@ -0,0 +1,5 @@ +const hooks = require('./server/hooks'); + +module.exports = { + hooks, +}; diff --git a/plugins/talk-plugin-slack-notifications/package.json b/plugins/talk-plugin-slack-notifications/package.json new file mode 100644 index 000000000..6792e77fa --- /dev/null +++ b/plugins/talk-plugin-slack-notifications/package.json @@ -0,0 +1,9 @@ +{ + "name": "@coralproject/talk-plugin-slack-notifications", + "pluginName": "talk-plugin-slack-notifications", + "version": "0.0.1", + "description": "Posts new comments to Slack via a webhook", + "main": "index.js", + "author": "The Coral Project Team ", + "license": "Apache-2.0" +} diff --git a/plugins/talk-plugin-slack-notifications/server/config.js b/plugins/talk-plugin-slack-notifications/server/config.js new file mode 100644 index 000000000..7571565b0 --- /dev/null +++ b/plugins/talk-plugin-slack-notifications/server/config.js @@ -0,0 +1,11 @@ +const config = { + SLACK_WEBHOOK_URL: process.env.TALK_SLACK_WEBHOOK_URL, + SLACK_WEBHOOK_TIMEOUT: process.env.TALK_SLACK_WEBHOOK_TIMEOUT || 5000, +}; + +if (process.env.NODE_ENV !== 'test' && !config.SLACK_WEBHOOK_URL) { + // TODO this error should point users to Talk's Slack app once that's in place + throw new Error('Please set the TALK_SLACK_WEBHOOK_URL environment variable to use the slack-notifications plugin.'); +} + +module.exports = config; diff --git a/plugins/talk-plugin-slack-notifications/server/hooks.js b/plugins/talk-plugin-slack-notifications/server/hooks.js new file mode 100644 index 000000000..bda9dc4f5 --- /dev/null +++ b/plugins/talk-plugin-slack-notifications/server/hooks.js @@ -0,0 +1,46 @@ +const fetch = require('node-fetch'); +const {SLACK_WEBHOOK_URL, SLACK_WEBHOOK_TIMEOUT} = require('./config'); +const debug = require('debug')('talk:plugin:slack-notifications'); + +// We don't add the hooks during _test_ as the Slack API is not available. +if (process.env.NODE_ENV === 'test') { + return null; +} + +module.exports = { + RootMutation: { + createComment: { + async post(_, {input}, context, _info, result) { + debug(`Posting notification to Slack webhook: ${SLACK_WEBHOOK_URL}`); + const { + comment: { + body: text, + created_at: createdAt + } + } = result; + const username = context.user.username; + process.nextTick(async () => { + const response = await fetch(SLACK_WEBHOOK_URL, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + timeout: SLACK_WEBHOOK_TIMEOUT, + body: JSON.stringify({ + attachments: [{ + text: text, + footer: `Comment by ${username}`, + ts: Math.floor(Date.parse(createdAt) / 1000), + }] + }), + }); + if (!response.ok) { + const responseText = await response.text(); + console.trace(`Posting to Slack failed with HTTP code ${response.status} and body '${responseText}'`); + } + }); + return result; + }, + }, + }, +};