From 59d0ecca67b24e71fb68497457b62eac1653c836 Mon Sep 17 00:00:00 2001 From: Joan Sanchez Date: Mon, 20 Jan 2020 07:33:24 +0100 Subject: [PATCH] send message to worker or channel --- back/methods/chat/send.js | 96 +++++++++++++++ back/methods/chat/sendCheckingPresence.js | 52 ++++++++ back/methods/chat/sendMessage.js | 138 ---------------------- back/models/chat.js | 3 +- db/changes/10140-kings/00-department.sql | 2 + 5 files changed, 152 insertions(+), 139 deletions(-) create mode 100644 back/methods/chat/send.js create mode 100644 back/methods/chat/sendCheckingPresence.js delete mode 100644 back/methods/chat/sendMessage.js create mode 100644 db/changes/10140-kings/00-department.sql diff --git a/back/methods/chat/send.js b/back/methods/chat/send.js new file mode 100644 index 000000000..7a441fcba --- /dev/null +++ b/back/methods/chat/send.js @@ -0,0 +1,96 @@ +const request = require('request-promise-native'); +module.exports = Self => { + Self.remoteMethodCtx('send', { + description: 'Send a RocketChat message', + accessType: 'WRITE', + accepts: [{ + arg: 'to', + type: 'String', + required: true, + description: 'user (@) or channel (#) to send the message' + }, { + arg: 'message', + type: 'String', + required: true, + description: 'The message' + }], + returns: { + type: 'Object', + root: true + }, + http: { + path: `/send`, + verb: 'POST' + } + }); + + Self.send = async(ctx, to, message) => { + const models = Self.app.models; + const accessToken = ctx.req.accessToken; + const sender = await models.Account.findById(accessToken.userId); + const recipient = to.replace('@', ''); + + if (sender.name != recipient) + return sendMessage(to, `@${sender.name}: ${message}`); + }; + + async function sendMessage(name, message) { + const models = Self.app.models; + const chatConfig = await models.ChatConfig.findOne(); + + if (!Self.token) + Self.token = await login(); + + const uri = `${chatConfig.uri}/chat.postMessage`; + return makeRequest(uri, { + 'channel': name, + 'text': message + }).catch(async error => { + if (error.statusCode === 401 && !Self.loginAttempted) { + Self.token = await login(); + Self.loginAttempted = true; + + return sendMessage(name, message); + } + + throw new Error(error.message); + }); + } + + /** + * Returns a rocketchat token + * @return {Object} userId and authToken + */ + async function login() { + const models = Self.app.models; + const chatConfig = await models.ChatConfig.findOne(); + const uri = `${chatConfig.uri}/login`; + return makeRequest(uri, { + user: chatConfig.user, + password: chatConfig.password + }).then(res => res.data); + } + + function makeRequest(uri, body) { + if (process.env.NODE_ENV !== 'production') { + return new Promise(resolve => { + return resolve({statusCode: 200, message: 'Fake notification sent'}); + }); + } + + const options = { + method: 'POST', + uri: uri, + body: body, + headers: {'content-type': 'application/json'}, + json: true + }; + + if (Self.token) { + options.headers['X-Auth-Token'] = Self.token.authToken; + options.headers['X-User-Id'] = Self.token.userId; + } + + return request(options); + } +}; diff --git a/back/methods/chat/sendCheckingPresence.js b/back/methods/chat/sendCheckingPresence.js new file mode 100644 index 000000000..a91faa0d8 --- /dev/null +++ b/back/methods/chat/sendCheckingPresence.js @@ -0,0 +1,52 @@ +const request = require('request-promise-native'); +module.exports = Self => { + Self.remoteMethodCtx('sendCheckingPresence', { + description: 'Send a RocketChat message', + accessType: 'WRITE', + accepts: [{ + arg: 'workerId', + type: 'Number', + required: true, + description: 'The worker id of the destinatary' + }, { + arg: 'message', + type: 'String', + required: true, + description: 'The message' + }], + returns: { + type: 'Object', + root: true + }, + http: { + path: `/sendCheckingPresence`, + verb: 'POST' + } + }); + + Self.sendCheckingPresence = async(ctx, workerId, message) => { + const models = Self.app.models; + const account = await models.Account.findById(workerId); + + const query = `SELECT worker_isWorking(?) isWorking`; + const result = await Self.rawSql(query, [workerId]); + + if (result.isWorking) { + const username = `@${account.name}`; + + return await Self.send(ctx, username, message); + } else { + const workerDepartment = await models.WorkerDepartment.findById(workerId, { + include: { + relation: 'department' + } + }); + const department = workerDepartment.department; + const channelName = department.chatChannelName; + const room = `#${channelName}`; + + + return await Self.send(ctx, room, message); + } + }; +}; diff --git a/back/methods/chat/sendMessage.js b/back/methods/chat/sendMessage.js deleted file mode 100644 index a861ba07e..000000000 --- a/back/methods/chat/sendMessage.js +++ /dev/null @@ -1,138 +0,0 @@ -const request = require('request-promise-native'); -module.exports = Self => { - Self.remoteMethodCtx('sendMessage', { - description: 'Send a RocketChat message', - accessType: 'WRITE', - accepts: [{ - arg: 'to', - type: 'String', - required: true, - description: 'user (@) or channel (#) to send the message' - }, { - arg: 'message', - type: 'String', - required: true, - description: 'The message' - }], - returns: { - type: 'Object', - root: true - }, - http: { - path: `/sendMessage`, - verb: 'POST' - } - }); - - Self.sendMessage = async(ctx, to, message) => { - const models = Self.app.models; - const accessToken = ctx.req.accessToken; - const sender = await models.Account.findById(accessToken.userId); - const recipient = to.replace('@', ''); - - if (sender.name != recipient) - return sendMessage(sender, to, `@${sender.name}: ${message} `); - }; - - async function sendMessage(sender, channel, message) { - const config = await getConfig(); - - const avatar = `${config.host}/avatar/${sender.name}`; - const uri = `${config.api}/chat.postMessage`; - return sendAuth(uri, { - 'channel': channel, - 'avatar': avatar, - 'text': message - }).catch(async error => { - if (error.statusCode === 401 && !this.resendAttempted) { - this.resendAttempted = true; - - return sendMessage(sender, channel, message); - } - - throw new Error(error.message); - }); - } - - /** - * Returns a rocketchat token - * @return {Object} userId and authToken - */ - async function getAuthToken() { - if (!this.auth || this.auth && !this.auth.authToken) { - const config = await getConfig(); - const uri = `${config.api}/login`; - const res = await send(uri, { - user: config.user, - password: config.password - }); - - this.auth = res.data; - } - - return this.auth; - } - - /** - * Returns a rocketchat config - * @return {Object} Auth config - */ - async function getConfig() { - if (!this.chatConfig) { - const models = Self.app.models; - - this.chatConfig = await models.ChatConfig.findOne(); - } - - return this.chatConfig; - } - - /** - * Send unauthenticated request - * @param {*} uri - Request uri - * @param {*} body - Request params - * @param {*} options - Request options - * - * @return {Object} Request response - */ - async function send(uri, body, options) { - if (process.env.NODE_ENV !== 'production') { - return new Promise(resolve => { - return resolve({statusCode: 200, message: 'Fake notification sent'}); - }); - } - - const defaultOptions = { - method: 'POST', - uri: uri, - body: body, - headers: {'content-type': 'application/json'}, - json: true - }; - - if (options) Object.assign(defaultOptions, options); - - return request(defaultOptions); - } - - /** - * Send authenticated request - * @param {*} uri - Request uri - * @param {*} body - Request params - * - * @return {Object} Request response - */ - async function sendAuth(uri, body) { - const login = await getAuthToken(); - const options = { - headers: {'content-type': 'application/json'} - }; - - if (login) { - options.headers['X-Auth-Token'] = login.authToken; - options.headers['X-User-Id'] = login.userId; - } - - return send(uri, body, options); - } -}; diff --git a/back/models/chat.js b/back/models/chat.js index 8086c6d3d..ab23ef713 100644 --- a/back/models/chat.js +++ b/back/models/chat.js @@ -1,3 +1,4 @@ module.exports = Self => { - require('../methods/chat/sendMessage')(Self); + require('../methods/chat/send')(Self); + require('../methods/chat/sendCheckingPresence')(Self); }; diff --git a/db/changes/10140-kings/00-department.sql b/db/changes/10140-kings/00-department.sql new file mode 100644 index 000000000..90135b91e --- /dev/null +++ b/db/changes/10140-kings/00-department.sql @@ -0,0 +1,2 @@ +ALTER TABLE `vn`.`department` +ADD COLUMN `chatChannelName` VARCHAR(45) NULL AFTER `path`;