List Slack channels and send shared message to selected channels

json · 182 lines
1
{
2
  "summary": "List Slack channels and send shared message to selected channels",
3
  "value": {
4
    "modules": [
5
      {
6
        "id": "a",
7
        "value": {
8
          "tag": "",
9
          "lock": "{\n  \"version\": \"3\",\n  \"packages\": {\n    \"specifiers\": {\n      \"npm:@slack/web-api\": \"npm:@slack/web-api@7.0.2\"\n    },\n    \"npm\": {\n      \"@slack/logger@4.0.0\": {\n        \"integrity\": \"sha512-Wz7QYfPAlG/DR+DfABddUZeNgoeY7d1J39OCR2jR+v7VBsB8ezulDK5szTnDDPDwLH5IWhLvXIHlCFZV7MSKgA==\",\n        \"dependencies\": {\n          \"@types/node\": \"@types/node@20.11.28\"\n        }\n      },\n      \"@slack/types@2.11.0\": {\n        \"integrity\": \"sha512-UlIrDWvuLaDly3QZhCPnwUSI/KYmV1N9LyhuH6EDKCRS1HWZhyTG3Ja46T3D0rYfqdltKYFXbJSSRPwZpwO0cQ==\",\n        \"dependencies\": {}\n      },\n      \"@slack/web-api@7.0.2\": {\n        \"integrity\": \"sha512-nY1KO+7i4iURihThS1kMOElzesx4jqRJtkxLS9FOT8Debh7vQAzzbzxpMB4QauSs15030eyJ16HCf1IfCT4BKQ==\",\n        \"dependencies\": {\n          \"@slack/logger\": \"@slack/logger@4.0.0\",\n          \"@slack/types\": \"@slack/types@2.11.0\",\n          \"@types/node\": \"@types/node@20.11.28\",\n          \"axios\": \"axios@1.6.8\",\n          \"eventemitter3\": \"eventemitter3@5.0.1\",\n          \"form-data\": \"form-data@4.0.0\",\n          \"is-electron\": \"is-electron@2.2.2\",\n          \"is-stream\": \"is-stream@2.0.1\",\n          \"p-queue\": \"p-queue@6.6.2\",\n          \"p-retry\": \"p-retry@4.6.2\",\n          \"retry\": \"retry@0.13.1\"\n        }\n      },\n      \"@types/node@20.11.28\": {\n        \"integrity\": \"sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==\",\n        \"dependencies\": {\n          \"undici-types\": \"undici-types@5.26.5\"\n        }\n      },\n      \"@types/retry@0.12.0\": {\n        \"integrity\": \"sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==\",\n        \"dependencies\": {}\n      },\n      \"asynckit@0.4.0\": {\n        \"integrity\": \"sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==\",\n        \"dependencies\": {}\n      },\n      \"axios@1.6.8\": {\n        \"integrity\": \"sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==\",\n        \"dependencies\": {\n          \"follow-redirects\": \"follow-redirects@1.15.6\",\n          \"form-data\": \"form-data@4.0.0\",\n          \"proxy-from-env\": \"proxy-from-env@1.1.0\"\n        }\n      },\n      \"combined-stream@1.0.8\": {\n        \"integrity\": \"sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==\",\n        \"dependencies\": {\n          \"delayed-stream\": \"delayed-stream@1.0.0\"\n        }\n      },\n      \"delayed-stream@1.0.0\": {\n        \"integrity\": \"sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==\",\n        \"dependencies\": {}\n      },\n      \"eventemitter3@4.0.7\": {\n        \"integrity\": \"sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==\",\n        \"dependencies\": {}\n      },\n      \"eventemitter3@5.0.1\": {\n        \"integrity\": \"sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==\",\n        \"dependencies\": {}\n      },\n      \"follow-redirects@1.15.6\": {\n        \"integrity\": \"sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==\",\n        \"dependencies\": {}\n      },\n      \"form-data@4.0.0\": {\n        \"integrity\": \"sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==\",\n        \"dependencies\": {\n          \"asynckit\": \"asynckit@0.4.0\",\n          \"combined-stream\": \"combined-stream@1.0.8\",\n          \"mime-types\": \"mime-types@2.1.35\"\n        }\n      },\n      \"is-electron@2.2.2\": {\n        \"integrity\": \"sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==\",\n        \"dependencies\": {}\n      },\n      \"is-stream@2.0.1\": {\n        \"integrity\": \"sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==\",\n        \"dependencies\": {}\n      },\n      \"mime-db@1.52.0\": {\n        \"integrity\": \"sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==\",\n        \"dependencies\": {}\n      },\n      \"mime-types@2.1.35\": {\n        \"integrity\": \"sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==\",\n        \"dependencies\": {\n          \"mime-db\": \"mime-db@1.52.0\"\n        }\n      },\n      \"p-finally@1.0.0\": {\n        \"integrity\": \"sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==\",\n        \"dependencies\": {}\n      },\n      \"p-queue@6.6.2\": {\n        \"integrity\": \"sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==\",\n        \"dependencies\": {\n          \"eventemitter3\": \"eventemitter3@4.0.7\",\n          \"p-timeout\": \"p-timeout@3.2.0\"\n        }\n      },\n      \"p-retry@4.6.2\": {\n        \"integrity\": \"sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==\",\n        \"dependencies\": {\n          \"@types/retry\": \"@types/retry@0.12.0\",\n          \"retry\": \"retry@0.13.1\"\n        }\n      },\n      \"p-timeout@3.2.0\": {\n        \"integrity\": \"sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==\",\n        \"dependencies\": {\n          \"p-finally\": \"p-finally@1.0.0\"\n        }\n      },\n      \"proxy-from-env@1.1.0\": {\n        \"integrity\": \"sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==\",\n        \"dependencies\": {}\n      },\n      \"retry@0.13.1\": {\n        \"integrity\": \"sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==\",\n        \"dependencies\": {}\n      },\n      \"undici-types@5.26.5\": {\n        \"integrity\": \"sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==\",\n        \"dependencies\": {}\n      }\n    }\n  },\n  \"remote\": {}\n}\n",
10
          "path": "f/bd/fancy_script",
11
          "type": "rawscript",
12
          "content": "import { WebClient as SlackWebClient } from \"npm:@slack/web-api\";\n\ntype Slack = {\n  token: string\n\n}\n\nexport async function main(slackResource: Slack) {\n  \n  // Initialize the Slack WebClient with the provided token\n  const slackClient = new SlackWebClient(slackResource.token);\n\n  try {\n    // Call the conversations.list method to get all channels\n    const listResult = await slackClient.conversations.list();\n\n    // Check if the listResult was successful and channels are present\n    if (listResult.ok && listResult.channels) {\n      // Initialize an array to hold the channels with their last message date and external member status\n      const channelsInfo = [];\n\n      // Iterate over each channel to fetch the last message's date, check for external members\n      for (const channel of listResult.channels) {\n        // Initialize external as false\n        let external = false;\n\n        // Call the conversations.members method to get all members of the channel\n        const membersResult = await slackClient.conversations.members({\n          channel: channel.id,\n        });\n\n        // Check if the membersResult was successful and members are present\n        if (membersResult.ok && membersResult.members) {\n          // Iterate over each member to fetch their user info\n          for (const memberId of membersResult.members) {\n            const userInfo = await slackClient.users.info({ user: memberId });\n\n            // Check if the userInfo was successful and user info is present\n            if (userInfo.ok && userInfo.user) {\n              if (userInfo.user.profile && userInfo.user.profile.email) {\n                // Check if the email domain is not orvanta.dev\n                if (!userInfo.user.profile.email.endsWith(\"@orvanta.dev\")) {\n                  external = true;\n                }\n              } else {\n                // Assume external if the email is not available\n                external = true;\n              }\n            }\n          }\n        }\n\n        // Call the conversations.history method to get the last message of the channel\n        const historyResult = await slackClient.conversations.history({\n          channel: channel.id,\n          limit: 1, // We only need the last message\n        });\n\n        // Initialize the lastMessageDate\n        let lastMessageDate = \"No messages found\";\n\n        // Check if the historyResult was successful and messages are present\n        if (\n          historyResult.ok && historyResult.messages &&\n          historyResult.messages.length > 0\n        ) {\n          // Convert the timestamp to a Date object\n          const date = new Date(\n            parseFloat(historyResult.messages[0].ts) * 1000,\n          );\n\n          // Format the Date object to \"YYYYMMDD\"\n          const year = date.getFullYear();\n          const month = (date.getMonth() + 1).toString().padStart(2, \"0\"); // Pad with zero if needed\n          const day = date.getDate().toString().padStart(2, \"0\"); // Pad with zero if needed\n\n          lastMessageDate = `${year}${month}${day}`;\n        }\n\n        // Add the channel info to the array\n        channelsInfo.push({\n          id: channel.id,\n          name: channel.name,\n          lastMessageDate: lastMessageDate,\n          external: external\n        });\n      }\n\n      // Return the list of channels with the date of the last message, external member status\n      return channelsInfo;\n    } else {\n      // Return an error message if the listResult was not successful or channels are not present\n      return \"Failed to retrieve channels or no channels found.\";\n    }\n  } catch (error) {\n    // Return the error if the API call fails\n    return `Error retrieving channels: ${error}`;\n  }\n}",
13
          "language": "deno",
14
          "input_transforms": {
15
            "slackResource": {
16
              "expr": "flow_input[\"Slack Account\"]",
17
              "type": "javascript"
18
            }
19
          }
20
        },
21
        "summary": "List Slack workspace channels details",
22
        "cache_ttl": 86400
23
      },
24
      {
25
        "id": "b",
26
        "value": {
27
          "tag": "",
28
          "lock": "{\n  \"dependencies\": {\n    \"@orvanta/client\": \"latest\"\n  }\n}\n//bun.lockb\nIyEvdXNyL2Jpbi9lbnYgYnVuCmJ1bi1sb2NrZmlsZS1mb3JtYXQtdjAKAgAAAKoiPgowraNIV/YbdVnh+LgyY/DkJ6xScN74aT4cpHm+VwQAAAAAAAACAAAAAAAAAAgAAAAAAAAACAAAAAAAAACAAAAAAAAAAHoCAAAAAAAAAAAAAAAAAAAAAAAAAAAPAACAAAAAAAAAAACZDWdj94+o/wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAA8AAABIAACAAQAAACMBAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAP4P/gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQD+D/4BAAABAAAAAAAAAAAAAAAE/BbN0p1svim5jy76XasEicp8K4fMFg4GUGpLf3LVtNZwjo2cNY1t+ko5ATf1RcvMjCqkaHEugwwhcCBLiFgHQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMACAAAAAAAA1AIAAAAAAAAKPHNyYy5pbnN0YWxsLmxvY2tmaWxlLlRyZWU+IDIwIHNpemVvZiwgNCBhbGlnbm9mCgAAAAAAAAAA/v////////8AAAAAAQAAAAADAAAAAAAABAMAAAAAAAAKPHUzMj4gNCBzaXplb2YsIDQgYWxpZ25vZgoAAAAAADADAAAAAAAANAMAAAAAAAAKPHUzMj4gNCBzaXplb2YsIDQgYWxpZ25vZgoAAQAAAGgDAAAAAAAAggMAAAAAAAAKPFsyNl11OD4gMjYgc2l6ZW9mLCAxIGFsaWdub2YKAAAAAAAAAAAADwAAgJkNZ2P3j6j/AgJsYXRlc3QAAMwDAAAAAAAAzAMAAAAAAAAKPHNyYy5pbnN0YWxsLnNlbXZlci5FeHRlcm5hbFN0cmluZz4gMTYgc2l6ZW9mLCA4IGFsaWdub2YK+AMAAAAAAABPBAAAAAAAAAo8dTg+IDEgc2l6ZW9mLCAxIGFsaWdub2YKAAB3aW5kbWlsbC1jbGllbnRodHRwczovL3JlZ2lzdHJ5Lm5wbWpzLm9yZy93aW5kbWlsbC1jbGllbnQvLS93aW5kbWlsbC1jbGllbnQtMS4yOTEuMS50Z3oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
29
          "type": "rawscript",
30
          "content": "import * as orvantaClient from \"@orvanta/client\"\n\nexport async function main(slack_channels, max_date: string, internal: boolean, partners) {\n  const resumeUrls = await orvantaClient.getResumeUrls(\"approver1\")\n\n  // Define a filter function for channels\n  const filterChannels = (channel) => {\n    // If max_date is not provided, return all channels based on the internal flag\n    if (!max_date) return internal ? !channel.external : channel.external;\n\n    // If max_date is provided, format it and filter channels by date as well\n    const maxDateFormatted = new Date(max_date).toISOString().slice(0, 10).replace(/-/g, '');\n    return (internal ? !channel.external : channel.external) && channel.lastMessageDate >= maxDateFormatted;\n  };\n\n  // Filter channels based on the external attribute and, if applicable, the max_date\n  // Adjust the logic to also consider the internal flag and exclude partners\n  const filteredChannels = slack_channels\n    .filter(filterChannels)\n    .filter(channel => !partners.includes(channel.name)) // Exclude channels that are in the \"partners\" array\n    .map(channel => channel.name);\n\n  return {\n    resume: resumeUrls['resume'],\n    enums: {\n      Channels: filteredChannels\n    },\n  }\n}",
31
          "language": "bun",
32
          "input_transforms": {
33
            "internal": {
34
              "expr": "flow_input[\"Internal Channels Only\"]",
35
              "type": "javascript"
36
            },
37
            "max_date": {
38
              "expr": "flow_input[\"Max date last message sent\"]",
39
              "type": "javascript"
40
            },
41
            "partners": {
42
              "expr": "flow_input[\"Exclude those partners?\"]",
43
              "type": "javascript"
44
            },
45
            "slack_channels": {
46
              "expr": "results.a",
47
              "type": "javascript"
48
            }
49
          }
50
        },
51
        "summary": "Approval - Pick channels to send message to",
52
        "suspend": {
53
          "timeout": 1800,
54
          "resume_form": {
55
            "schema": {
56
              "type": "object",
57
              "order": [
58
                "Channels"
59
              ],
60
              "$schema": "https://json-schema.org/draft/2020-12/schema",
61
              "required": [],
62
              "properties": {
63
                "Channels": {
64
                  "type": "array",
65
                  "items": {
66
                    "type": "string"
67
                  },
68
                  "default": [],
69
                  "description": "Channels to send message to"
70
                }
71
              }
72
            }
73
          },
74
          "required_events": 1
75
        }
76
      },
77
      {
78
        "id": "c",
79
        "value": {
80
          "type": "forloopflow",
81
          "modules": [
82
            {
83
              "id": "d",
84
              "mock": {
85
                "enabled": false,
86
                "return_value": {
87
                  "example": "value"
88
                }
89
              },
90
              "value": {
91
                "tag": "",
92
                "lock": "{\n  \"version\": \"3\",\n  \"redirects\": {\n    \"https://deno.land/x/url_join/mod.ts\": \"https://deno.land/x/url_join@1.0.0/mod.ts\"\n  },\n  \"remote\": {\n    \"https://deno.land/std@0.86.0/_util/assert.ts\": \"2f868145a042a11d5ad0a3c748dcf580add8a0dbc0e876eaa0026303a5488f58\",\n    \"https://deno.land/std@0.86.0/_util/os.ts\": \"e282950a0eaa96760c0cf11e7463e66babd15ec9157d4c9ed49cc0925686f6a7\",\n    \"https://deno.land/std@0.86.0/path/_constants.ts\": \"1247fee4a79b70c89f23499691ef169b41b6ccf01887a0abd131009c5581b853\",\n    \"https://deno.land/std@0.86.0/path/_interface.ts\": \"1fa73b02aaa24867e481a48492b44f2598cd9dfa513c7b34001437007d3642e4\",\n    \"https://deno.land/std@0.86.0/path/_util.ts\": \"f4fa69aa3cbbd8568763bfc43c7236875015ba343602d8bafd332b4b4243681b\",\n    \"https://deno.land/std@0.86.0/path/common.ts\": \"eaf03d08b569e8a87e674e4e265e099f237472b6fd135b3cbeae5827035ea14a\",\n    \"https://deno.land/std@0.86.0/path/glob.ts\": \"4a524c1c9da3e79a9fdabdc6e850cd9e41bdf31e442856ffa19c5b123268ca95\",\n    \"https://deno.land/std@0.86.0/path/mod.ts\": \"4465dc494f271b02569edbb4a18d727063b5dbd6ed84283ff906260970a15d12\",\n    \"https://deno.land/std@0.86.0/path/posix.ts\": \"1408f8ba482a4dc5fc0a7cd7be28bbbff9608d2b3b5ffdcf288ae1228d959add\",\n    \"https://deno.land/std@0.86.0/path/separator.ts\": \"8fdcf289b1b76fd726a508f57d3370ca029ae6976fcde5044007f062e643ff1c\",\n    \"https://deno.land/std@0.86.0/path/win32.ts\": \"6ca052f54500f00cd7a5172fde62900626ab620dcd5bdcf4e6f5695d001ddef6\",\n    \"https://deno.land/x/axiod@0.20.0-0/helpers.ts\": \"b54a9c892383b24e29ed3fe55b11c6b521120c83c8e3d090bd6c09a86b37ccc6\",\n    \"https://deno.land/x/axiod@0.20.0-0/interfaces.ts\": \"03598d6a8fba71dc1e0a76a04f67d60edc3fcd85a541c68649f95f2369dfef13\",\n    \"https://deno.land/x/axiod@0.20.0-0/mod.ts\": \"398b246ecb262c272b96488986f137150c5a95d843f766cf101b92b10c05f751\",\n    \"https://deno.land/x/p_queue@1.0.0/lower-bound.ts\": \"a92a58dcaed46d3a463d006a0f01a8c8916e75d0bf848fc329bd874784626e35\",\n    \"https://deno.land/x/p_queue@1.0.0/mod.ts\": \"2436c6441f5f4237e9fadf61c5e31444ef40daa72ac932167af4a9996bb5a550\",\n    \"https://deno.land/x/p_queue@1.0.0/options.ts\": \"46d9d76b1dd15899d1c6fe4fb4ffa521427c1b34944ca9e68b2c887318befbf6\",\n    \"https://deno.land/x/p_queue@1.0.0/priority-queue.ts\": \"bcd2f7ad381e44ea7b27fdf69211ec0475bbc3823b7908e828b91d52a36d7205\",\n    \"https://deno.land/x/p_queue@1.0.0/queue.ts\": \"63c39e7a946e8cc8e30cf8beaa37f69c03df84c5298d43af0cb0bcf6f60b2917\",\n    \"https://deno.land/x/p_retried@1.0.3/mod.ts\": \"fdd7d45c724da554533fd8c20c44f719408f3fbea790a4a63ddf3da5891d2b54\",\n    \"https://deno.land/x/p_retried@1.0.4/mod.ts\": \"ff57cb6aab30460f28bb3d8eabf24f6993442662ad5a39aa31c70a412fb0f1c0\",\n    \"https://deno.land/x/p_timeout@1.0.1/mod.ts\": \"1a55ad8ab0c22383f8766639babe3adc6d87348576700c5779531456f0428111\",\n    \"https://deno.land/x/retried@1.0.1/lib/retried.ts\": \"39c96ea907b701963ab4cf037877903b7b262b7166b508911bd207e996131ac1\",\n    \"https://deno.land/x/retried@1.0.1/lib/retryOperation.ts\": \"fcc0c800876bc17e472ec00fd8336a7f33a72109cabaffd376ca34c748d745ff\",\n    \"https://deno.land/x/retried@1.0.1/mod.ts\": \"7a67cb9b3edf0696f8ebe2ad3b57d681ddbb39c5c24e06a3631805dea9933105\",\n    \"https://deno.land/x/slack_logger@3.0.0/mod.ts\": \"a729c62c2cf2aef8b4d1b344fddee4565cc805e3224d0ec5c6653e3c55d6944d\",\n    \"https://deno.land/x/slack_types@3.0.0/mod.ts\": \"743d0591cba6fc72d39da13e9c10dbab940f5c1df8da17c5e8a6be5e4e3de3b5\",\n    \"https://deno.land/x/slack_web_api@1.0.0/config.ts\": \"1cb64abe2ee35ee19ca4090477c8a0588ce22504c58970e8b4ab1ab1c999e805\",\n    \"https://deno.land/x/slack_web_api@1.0.0/mod.ts\": \"63f2df24ce2dbdbcd51e065a04a671d8d601df3b68c13801b3a3e4712e8d5d8e\",\n    \"https://deno.land/x/slack_web_api@1.0.0/src/WebClient.ts\": \"b77f9a3169f002fa32fbc3e4f8fb1038be30ff6a3097c5992147a6d0859db646\",\n    \"https://deno.land/x/slack_web_api@1.0.0/src/errors.ts\": \"608bdfdb39b57c1b35edf970be14e97fb9a2f656af1472ef941fb2730934309a\",\n    \"https://deno.land/x/slack_web_api@1.0.0/src/helpers.ts\": \"14f2afe96a0adfaae03d0d59fc004472f3724c8a6779be2aef4abb15582bc751\",\n    \"https://deno.land/x/slack_web_api@1.0.0/src/instrument.ts\": \"7951c76f943c9d73fb491fc2dd021c6d189e4c1849fef8248dc9ddd8dce7bae5\",\n    \"https://deno.land/x/slack_web_api@1.0.0/src/logger.ts\": \"6c38cf2709a0176fb590c95eb18ba44b0b9da87783631a3772c22a6b4725062e\",\n    \"https://deno.land/x/slack_web_api@1.0.0/src/methods.ts\": \"f902e8d684a095e96161108204e340b76fc24b87daa942db9295cf70bd362f99\",\n    \"https://deno.land/x/slack_web_api@1.0.0/src/retry-policies.ts\": \"b4b5658fa120e6287ec48e6ea13c1a2ba9f5481bb1d8220fb5f602db21b26e8e\",\n    \"https://deno.land/x/url_join@1.0.0/mod.ts\": \"d3c7007e3ab15594e54d5b90dce623b3e274a726e0cdf57858e7ecab77a0166c\"\n  }\n}\n",
93
                "path": "hub/1410/slack/send_message_to_channel",
94
                "type": "rawscript",
95
                "content": "import { WebClient as SlackWebClient } from \"https://deno.land/x/slack_web_api@1.0.0/mod.ts\";\n\ntype Slack = {\n  token: string;\n};\n\nexport async function main(\n  text: string,\n  channel: string,\n  slackResource: Slack,\n): Promise<string> { // Specify the return type as Promise<string> since the function is async and returns a string\n  const web = new SlackWebClient(slackResource.token);\n\n  const slackFormattedText = text\n    .replace(/\\[([^\\]]+)\\]\\((http[s]?:\\/\\/[^\\)]+)\\)/g, \"<$2|$1>\") // Convert markdown links to Slack's format\n    .replace(/\\*\\*([^\\*]+)\\*\\*/g, \"*$1*\"); // Convert markdown bold to Slack's format (Slack uses single * for bold)\n\n  // Send the message to the specified Slack channel\n  await web.chat.postMessage({\n    channel,\n    text: slackFormattedText,\n    mrkdwn: true, // Enable markdown (Mrkdwn) formatting for the message\n  });\n\n  // Return the channel ID if the message was successfully sent\n  return channel;\n}\n",
96
                "language": "deno",
97
                "input_transforms": {
98
                  "text": {
99
                    "expr": "flow_input[\"Slack message\"]",
100
                    "type": "javascript"
101
                  },
102
                  "channel": {
103
                    "expr": "flow_input.iter.value",
104
                    "type": "javascript"
105
                  },
106
                  "slackResource": {
107
                    "expr": "flow_input[\"Slack Account\"]",
108
                    "type": "javascript"
109
                  }
110
                }
111
              },
112
              "summary": "Send to Slack channel from markdown format"
113
            }
114
          ],
115
          "iterator": {
116
            "expr": "resume[\"Channels\"]",
117
            "type": "javascript"
118
          },
119
          "parallel": false,
120
          "skip_failures": true
121
        },
122
        "summary": "Send message to selected channels"
123
      }
124
    ],
125
    "concurrency_time_window_s": 0
126
  },
127
  "description": "This flow lists all channels from a Slack workspace (you can exclude internal or external ones with other members than your company) and uses an approval step to select channels to send a message to.",
128
  "schema": {
129
    "type": "object",
130
    "order": [
131
      "Internal Channels Only",
132
      "Max date last message sent",
133
      "Slack Account",
134
      "Slack message",
135
      "Exclude those partners?"
136
    ],
137
    "$schema": "https://json-schema.org/draft/2020-12/schema",
138
    "required": [
139
      "Slack message",
140
      "Slack Account"
141
    ],
142
    "properties": {
143
      "Slack Account": {
144
        "type": "object",
145
        "format": "resource-slack",
146
        "required": [],
147
        "properties": {},
148
        "description": "Needed scopes are: chat:write:user ; users:read ; users:read.email ; channels:read"
149
      },
150
      "Slack message": {
151
        "type": "string",
152
        "format": "",
153
        "default": "",
154
        "description": ""
155
      },
156
      "Internal Channels Only": {
157
        "type": "boolean",
158
        "format": "",
159
        "default": false,
160
        "description": "If set to false, the flow will return Clients or Partners shared channels"
161
      },
162
      "Exclude those partners?": {
163
        "type": "array",
164
        "items": {
165
          "type": "string"
166
        },
167
        "format": "",
168
        "default": [
169
          "example-channel-with-partner",
170
          "provider-channel"
171
        ],
172
        "description": "Those channels will not be suggested in the sending list"
173
      },
174
      "Max date last message sent": {
175
        "type": "string",
176
        "format": "date-time",
177
        "default": "",
178
        "description": ""
179
      }
180
    }
181
  }
182
}
Orvanta Hub — community scripts, flows, apps & resource types.