0

Send Email

by
Published today

Send an email from the connected mailbox, with optional cc/bcc, reply-to and file attachments from object storage (about 3 MB in total). Requires Mail.Send (a connection default); a shared mailbox also needs Mail.Send.Shared, not a default.

Script outlook Verified

The script

Submitted by hugo989 Bun
Verified 5 hours ago
1
import * as wmill from "windmill-client"
2
import { S3Object } from "windmill-client"
3

4
/**
5
 * Send Email
6
 * Send an email from the connected mailbox, with optional cc/bcc, reply-to and file attachments from object storage (about 3 MB in total). Requires Mail.Send (a connection default); a shared mailbox also needs Mail.Send.Shared, not a default.
7
 */
8
export async function main(
9
  auth: RT.Outlook,
10
  to: string[],
11
  subject: string,
12
  body: string,
13
  content_type: "HTML" | "Text" = "HTML",
14
  cc: string[] | undefined,
15
  bcc: string[] | undefined,
16
  reply_to: string[] | undefined,
17
  attachments: S3Object[] | undefined,
18
  save_to_sent_items: boolean = true,
19
  mailbox: string | undefined
20
) {
21
  const base = `https://graph.microsoft.com/v1.0/${
22
    mailbox != null && mailbox !== ""
23
      ? `users/${encodeURIComponent(mailbox)}`
24
      : "me"
25
  }`
26
  const recipients = (addresses: string[] | undefined) =>
27
    (addresses ?? [])
28
      .filter((a) => a != null && a.trim() !== "")
29
      .map((address) => ({ emailAddress: { address } }))
30

31
  const files = []
32
  for (const file of attachments ?? []) {
33
    const bytes = await wmill.loadS3File(file)
34
    if (!bytes) throw new Error(`Could not load ${file.s3}`)
35
    files.push({
36
      "@odata.type": "#microsoft.graph.fileAttachment",
37
      name: file.s3.split("/").pop(),
38
      contentBytes: Buffer.from(bytes).toString("base64"),
39
    })
40
  }
41

42
  const response = await fetch(`${base}/sendMail`, {
43
    method: "POST",
44
    headers: {
45
      Authorization: `Bearer ${auth.token}`,
46
      "Content-Type": "application/json",
47
      Accept: "application/json",
48
    },
49
    body: JSON.stringify({
50
      message: {
51
        subject,
52
        body: { contentType: content_type, content: body },
53
        toRecipients: recipients(to),
54
        ccRecipients: recipients(cc),
55
        bccRecipients: recipients(bcc),
56
        replyTo: recipients(reply_to),
57
        attachments: files,
58
      },
59
      saveToSentItems: save_to_sent_items,
60
    }),
61
  })
62

63
  if (!response.ok) {
64
    throw new Error(`${response.status} ${await response.text()}`)
65
  }
66

67
  // 202 Accepted with an empty body
68
  return { success: true }
69
}
70