Send comments to Slack

🚧

Pre-requisites

Users should have a custom field SlackID

📘

How to apply this rule?

Send comments to Slack using Webhook

1270

🚧

Warning: sample URL!

Please make sure to replace https://hooks.slack.com/services/xxxxx/yyyyyy/zzzzzzzzztGRAKwHLfm4kw with your Slack Webhook URL.

Filter by General.Project.Name is optional

{
  "pipeline": [
    {
      "type": "source:targetprocess:EntityChanged",
      "entityTypes": [
        "Comment"
      ],
      "modifications": {
        "created": true,
        "deleted": false,
        "updated": [
          "Description"
        ]
      }
    },
    {
      "or": [
        {
          "and": [
            {
              "target": {
                "type": "field",
                "name": "Name",
                "target": {
                  "type": "field",
                  "name": "Project",
                  "target": {
                    "type": "field",
                    "name": "General",
                    "target": {
                      "type": "pipelineBlockOutput"
                    }
                  }
                }
              },
              "value": {
                "type": "constant",
                "value": "Mobile"
              },
              "operator": {
                "type": "is"
              }
            }
          ]
        }
      ],
      "type": "filter:Relational"
    },
    {
      "type": "action:JavaScript",
      "script": "const 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// CHANGE TOKEN\nconst bot_token = 'xoxb-0123456789012-xxxxxxxxxxxxx-yyyyyyyyyyyyyyyyyyyyyyyy';\nconst headers = {\n  'Authorization': `Bearer ${bot_token}`\n};\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\");\nconst quote = x => `\"${x}\"`;\nconst users = await api.queryAsync(\"Users\", {\n  select: \"{ login, slackID }\",\n  where: `login in [${logins.map(quote)}]`\n});\n\nconst getSlackIdByLogin = login => users.find(x => x.login === login).slackID;\nconst link = `<${args.AccountBaseUrl}/entity/${args.Current.General.Id}|${args.Current.General.Name}>`;\nconst message = args.Author.FullName + \" has commented on \" + link + \": \" + description\n  .replace(/@user:(.[^[]+)\\[.*?\\]/g, (_, login) => `<@${getSlackIdByLogin(login)}>`);\n\nreturn {\n  command: \"SendHttpRequest\",\n  payload: {\n    url: \"https://slack.com/api/chat.postMessage\",\n    headers: headers,\n    body: {\n      \"text\": message,\n      \"icon_emoji\": \":bee:\",\n      \"username\": \"Targetprocess BOT\",\n      \"channel\": \"C04CLGNMCN5\"\n    }\n  }\n};"
    }
  ]
}

Send comments to Slack using Slack Web API

1270

🚧

Warning: sample TOKEN!

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

Filter by General.Project.Name is optional

{
  "pipeline": [
    {
      "type": "source:targetprocess:EntityChanged",
      "entityTypes": [
        "Comment"
      ],
      "modifications": {
        "created": true,
        "deleted": false,
        "updated": [
          "Description"
        ]
      }
    },
    {
      "or": [
        {
          "and": [
            {
              "target": {
                "type": "field",
                "name": "Name",
                "target": {
                  "type": "field",
                  "name": "Project",
                  "target": {
                    "type": "field",
                    "name": "General",
                    "target": {
                      "type": "pipelineBlockOutput"
                    }
                  }
                }
              },
              "value": {
                "type": "constant",
                "value": "Mobile"
              },
              "operator": {
                "type": "is"
              }
            }
          ]
        }
      ],
      "type": "filter:Relational"
    },
    {
      "type": "action:JavaScript",
      "script": "const 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// CHANGE TOKEN\nconst bot_token = 'xoxb-0123456789012-xxxxxxxxxxxxx-yyyyyyyyyyyyyyyyyyyyyyyy';\nconst headers = {\n  'Authorization': `Bearer ${bot_token}`\n};\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\");\nconst quote = x => `\"${x}\"`;\nconst users = await api.queryAsync(\"Users\", {\n  select: \"{ login, slackID }\",\n  where: `login in [${logins.map(quote)}]`\n});\n\nconst getSlackIdByLogin = login => users.find(x => x.login === login).slackID;\nconst link = `<${args.AccountBaseUrl}/entity/${args.Current.General.Id}|${args.Current.General.Name}>`;\nconst message = args.Author.FullName + \" has commented on \" + link + \": \" + description\n  .replace(/@user:(.[^[]+)\\[.*?\\]/g, (_, login) => `<@${getSlackIdByLogin(login)}>`);\n\nreturn {\n  command: \"SendHttpRequest\",\n  payload: {\n    url: \"https://slack.com/api/chat.postMessage\",\n    headers: headers,\n    body: {\n      \"text\": message,\n      \"icon_emoji\": \":bee:\",\n      \"username\": \"Targetprocess BOT\",\n      \"channel\": \"C04CLGNMCN5\"\n    }\n  }\n};"
    }
  ]
}