//native
import { getResumeUrls } from "windmill-client@1";
type Gmail = {
token: string;
};
export async function main(
gmail_auth: Gmail,
approver_emails: string[],
subject = "Resume Windmill flow",
) {
throwOnInvalidApprovers(approver_emails);
const token = gmail_auth["token"];
const email_promises = approver_emails.map((to_email) =>
sendEmail(token, to_email, subject),
);
const results = await Promise.all(email_promises);
return results;
}
async function sendEmail(
gmail_token: string,
to_email: string,
subject: string,
): Promise<object> {
const email = await getEmailBody(to_email, subject);
const SEND_EMAIL_URL = `https://gmail.googleapis.com/gmail/v1/users/me/messages/send`;
const body = {
raw: email,
};
const response = await fetch(SEND_EMAIL_URL, {
method: "POST",
body: JSON.stringify(body),
headers: {
Authorization: `Bearer ${gmail_token}`,
},
});
const response_json = await response.json();
return handleSendEmailResult(response_json, to_email);
}
async function getEmailBody(to_email: string, subject: string) {
const { approvalPage } = await getResumeUrls(to_email);
const message = `There is a Windmill flow at ${Bun.env[
"WM_FLOW_PATH"
]} run by ${Bun.env["WM_USERNAME"]} waiting for your approval to resume.
In order to resume or cancel the flow go to ${approvalPage}`;
const email_body = `From: <me>\nTo: <${to_email}>\nSubject: ${subject}\n\r ${message}`;
return base64UrlEncode(email_body);
}
function throwOnInvalidApprovers(approvers: string[]) {
if (!Array.isArray(approvers) || approvers.length === 0) {
throw new Error("Expected at least one approver email");
}
}
async function handleSendEmailResult(result: object, to_email: string) {
if (Object.keys(result).includes("error")) {
return Promise.reject({ wm_to_email: to_email, ...result });
}
return result;
}
function base64UrlEncode(data: string | Uint8Array) {
const bytes =
typeof data === "string" ? new TextEncoder().encode(data) : data;
let binary = "";
for (let i = 0; i < bytes.length; i++) {
binary += String.fromCharCode(bytes[i]);
}
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}
Submitted by hugo989 7 days ago