Send mentions to Slack directly

🚧

Pre-requisites

Users should have a custom field SlackID.
Slack App should be configured to send messages with Slack Web Api.

πŸ“˜

How to apply this rule?

1270

🚧

Warning: sample TOKEN!

Please make sure to replace token xoxb-0123456789012-xxxxxxxxxxxxx-yyyyyyyyyyyyyyyyyyyyyyyy with your Slack Bot token.

{ "pipeline": [ { "type": "source:targetprocess:EntityChanged", "entityTypes": [ "comment" ], "modifications": { "created": true, "deleted": false, "updated": false } }, { "or": [ { "and": [ { "value": { "type": "constant", "value": "&#64;user&#58;" }, "target": { "name": "Description", "type": "field", "target": { "type": "pipelineBlockOutput" } }, "operator": { "type": "contains" } } ] }, { "and": [ { "value": { "type": "constant", "value": "@user:" }, "target": { "name": "Description", "type": "field", "target": { "type": "pipelineBlockOutput" } }, "operator": { "type": "contains" } } ] } ], "type": "filter:Relational" }, { "type": "action:JavaScript", "script": "//WHEN Comment with @mention is created\n//THEN Send Private Slack message to mentioned users\nconst generalID = args.Current.General.Id;\nconst generalName = args.Current.General.Name;\nconst authorName = args.Author.FullName;\nconst tpURL = args.AccountBaseUrl;\n\n// CHANGE TOKEN\nconst bot_token = 'xoxb-0123456789012-xxxxxxxxxxxxx-yyyyyyyyyyyyyyyyyyyyyyyy';\nconst headers = {\n 'Authorization': `Bearer ${bot_token}`\n};\n\nconst MARKDOWN_MARK = \"<!--markdown-->\";\n\nconst isMarkdown = desc => desc.startsWith(MARKDOWN_MARK);\nconst preprocessMarkdown = desc => desc.replace(MARKDOWN_MARK, \"\");\nconst preprocessHtml = desc => decodeHtmlText(removeHtmlTags(desc));\nconst removeHtmlTags = desc => desc.replace(/<\\/?[^>]+(>|$)/g, \"\");\nconst decodeHtmlText = desc => desc.replace(/&#(\\d+);/g, (_, code) => String.fromCharCode(code));\n\nconst rawDescription = args.Current.Description;\nconst description = isMarkdown(rawDescription) ?\n preprocessMarkdown(rawDescription) :\n preprocessHtml(rawDescription);\n\nfunction findLogins(desc) {\n const result = [];\n const regex = /@user:(.+?)[[]/g;\n\n let match;\n while ((match = regex.exec(desc)) !== null) {\n const login = match[1];\n if (!result.includes(login)) {\n result.push(login);\n }\n }\n\n return result;\n}\n\nconst logins = findLogins(description);\n\nconst api = context.getService(\"targetprocess/api/v2\");\n\nconst generalType = await api.getByIdAsync(\"General\", generalID, {\n select: \"entityType.name\"\n});\n\nconst quote = x => `\"${x}\"`;\nconst users = await api.queryAsync(\"Users\", {\n select: \"{ login, slackId, name }\",\n where: `login in [${logins.map(quote)}]`\n});\n\n// What should we do if user with target login wasn't found?\nconst getSlackIdByLogin = login => users.find(x => x.login === login).slackId;\nconst getUserNameByLogin = login => users.find(x => x.login === login).name;\nconst message = description\n .replace(/@user:(.+?)\\[.*?\\]/g, (_, login) => {\n const slackId = getSlackIdByLogin(login);\n return slackId ? `<@${slackId}>` : getUserNameByLogin(login);\n });\n\n\nconst slackIds = users.filter(function (user) {\n return user.slackId;\n});\nconsole.log(slackIds);\nreturn slackIds.map(x => ({\n command: 'SendHttpRequest',\n payload: {\n url: 'https://slack.com/api/chat.postMessage',\n headers: headers,\n body: {\n channel: x.slackId,\n text: `${authorName} mentioned you in ${generalType[0]} *#${generalID}* <${tpURL}/entity/${generalID}|${generalName}>:\\n${message}`\n }\n }\n}\n)\n)" } ] }