Suspend/resume a flow by sending approval URL via slack direct message

Using slack resource it sends a direct message with URL to approval page where you can resume or cancel the flow

Script· approval slack Verified

by mrl5 · 10/31/2022

The script

Submitted by hugo989 Bun
Verified 4 days ago
1
import { getResumeUrls } from "windmill-client@1";
2
import { WebClient } from "@slack/web-api";
3

4
type Slack = {
5
  token: string;
6
};
7
export async function main(approver_emails: string[], slack: Slack) {
8
  throwOnInvalidApprovers(approver_emails);
9

10
  const client = new WebClient(slack.token);
11
  const usersData = await Promise.all(
12
    approver_emails.map((email) => getUserData(client, email)),
13
  );
14
  console.log(usersData);
15
  const dmPromises = usersData.map((userData) =>
16
    sendDirectMessage(client, userData),
17
  );
18

19
  const results = await Promise.all(dmPromises);
20
  return results;
21
}
22

23
interface UserData {
24
  id: string;
25
  email: string;
26
  real_name: string;
27
}
28

29
async function getUserData(client: WebClient, email: string): UserData {
30
  try {
31
    const response = await client.users.lookupByEmail({ email: email });
32

33
    const { id, real_name } = response.user;
34
    return { id, email, real_name };
35
  } catch (err) {
36
    return handleApiResponse(email, err);
37
  }
38
}
39

40
async function sendDirectMessage(client: WebClient, userData: UserData) {
41
  const text = await getApprovalMsg(userData.email);
42

43
  const { ok, ts, channel } = await client.chat.postMessage({
44
    channel: userData.id,
45
    text,
46
  });
47
  return { ok, ts, channel, email: userData.email };
48
}
49

50
async function getApprovalMsg(to_email) {
51
  const { approvalPage } = await getResumeUrls(to_email);
52
  return `There is a Windmill flow at ${Bun.env
53
    .WM_FLOW_PATH} run by ${Bun.env.WM_USERNAME} waiting for your approval to resume.
54

55
In order to resume or cancel the flow go to ${approvalPage}`;
56
}
57

58
function throwOnInvalidApprovers(approvers: string[]) {
59
  if (!Array.isArray(approvers) || approvers.length === 0) {
60
    throw new Error("Expected at least one approver email");
61
  }
62
}
63

64
function handleApiResponse(email, error) {
65
  return Promise.reject({ email, err_msg: error.message });
66
}
67

Other submissions
  • Submitted by mrl5 Deno
    Created 396 days ago
    1
    import { getResumeUrls } from "https://deno.land/x/[email protected]/mod.ts";
    2
    import { WebClient } from "https://deno.land/x/[email protected]/mod.ts";
    3
    
    
    4
    type Slack = {
    5
      token: string;
    6
    };
    7
    export async function main(approver_emails: string[], slack: Slack) {
    8
      throwOnInvalidApprovers(approver_emails);
    9
    
    
    10
      const client = new WebClient(slack.token);
    11
      const usersData = await Promise.all(
    12
        approver_emails.map((email) => getUserData(client, email)),
    13
      );
    14
      console.log(usersData);
    15
      const dmPromises = usersData.map((userData) =>
    16
        sendDirectMessage(client, userData),
    17
      );
    18
    
    
    19
      const results = await Promise.all(dmPromises);
    20
      return results;
    21
    }
    22
    
    
    23
    interface UserData {
    24
      id: string;
    25
      email: string;
    26
      real_name: string;
    27
    }
    28
    
    
    29
    async function getUserData(client: WebClient, email: string): UserData {
    30
      try {
    31
        const response = await client.users.lookupByEmail({ email: email });
    32
    
    
    33
        const { id, real_name } = response.user;
    34
        return { id, email, real_name };
    35
      } catch (err) {
    36
        return handleApiResponse(email, err);
    37
      }
    38
    }
    39
    
    
    40
    async function sendDirectMessage(client: WebClient, userData: UserData) {
    41
      const text = await getApprovalMsg(userData.email);
    42
    
    
    43
      const { ok, ts, channel } = await client.chat.postMessage({
    44
        channel: userData.id,
    45
        text,
    46
      });
    47
      return { ok, ts, channel, email: userData.email };
    48
    }
    49
    
    
    50
    async function getApprovalMsg(to_email) {
    51
      const { approvalPage } = await getResumeUrls(to_email);
    52
      return `There is a Windmill flow at ${Deno.env.get(
    53
        "WM_FLOW_PATH",
    54
      )} run by ${Deno.env.get("WM_USERNAME")} waiting for your approval to resume.
    55
    
    
    56
    In order to resume or cancel the flow go to ${approvalPage}`;
    57
    }
    58
    
    
    59
    function throwOnInvalidApprovers(approvers: string[]) {
    60
      if (!Array.isArray(approvers) || approvers.length === 0) {
    61
        throw new Error("Expected at least one approver email");
    62
      }
    63
    }
    64
    
    
    65
    function handleApiResponse(email, error) {
    66
      return Promise.reject({ email, err_msg: error.message });
    67
    }
    68