---
title: "Managing emails with Outlook"
author: Hong Ooi
output:
    rmarkdown::html_vignette:
        toc: true
vignette: >
    %\VignetteIndexEntry{Managing emails with Outlook}
    %\VignetteEngine{knitr::rmarkdown}
    %\VignetteEncoding{utf8}
---

This vignette describes how to use Microsoft365R to interact with [Outlook](https://www.microsoft.com/en-au/microsoft-365/outlook/email-and-calendar-software-microsoft-outlook) for managing and sending email. See the "Authenticating to Microsoft 365" vignette for more details on authentication if required.

Note that Microsoft365R only works with your _primary_ Outlook (Microsoft Exchange) account. It does not support other email providers that you may have connected to your Outlook account, eg Gmail.


## Outlook client

To access your Outlook inbox, call either `get_personal_outlook()` or `get_business_outlook()`. The first one is for your personal account, and the second is for your work & school account. They return objects of R6 class `ms_outlook`, which has methods for drafting new emails, listing emails in your Inbox, and working with folders.

```r
outl <- get_personal_outlook()
outlb <- get_business_outlook()

# list the most recent emails in your Inbox
outl$list_emails()

# create and send a new email
outl$create_email("Hello from R", subject="Hello", to="bob@example.com")$send()

# list your mail folders
outl$list_folders()

# get some common folders
inbox <- outl$get_inbox()
drafts <- outl$get_drafts()
sent <- outl$get_sent_items()
deleted <- outl$get_deleted_items()

# get a specific folder by name
folder <- outl$get_folder("myfolder")
```

## Writing emails

To write a new email, call the `create_email()` method as noted above; this returns an object of R6 class `ms_outlook_email`. You can create a blank email which you then edit using the object's methods, or supply the details in the `create_email()` call itself. The message will be saved in the Drafts folder.

```r
# create a draft email
em <- outl$create_email("Hello from R", subject="Hello",
    to="bob@example.com", cc="charlie@example.com")

# or: create a blank draft, then add details
em <- outl$create_email()
em$set_body("Hello from R")
em$set_subject("Hello")
em$set_recipients(to="bob@example.com", cc="charlie@example.com")

# alternatively, use method chaining to achieve the same thing
em <- outl$
    create_email()$
    set_body("Hello from R")$
    set_subject("Hello")$
    set_recipients(to="bob@example.com", cc="charlie@example.com")
```

In the example above, the email has a plain text message body which is the default. To create an email in HTML format, set the `content_type` argument to "html".

```r
em <- outl$create_email("<h2>Hello world!</h2>", content_type="html")
```

However, Microsoft365R also supports using the blastula and emayili packages to write nicely-formatted HTML emails. In particular, blastula lets you compose your email in Markdown, which is often easier than writing raw HTML.

```r
bl_body <- "## Hello!

This is an email message that was generated by the blastula package.

We can use **Markdown** formatting with the `md()` function.

Cheers,

The blastula team"

library(blastula)
bl_em <- compose_email(
    body=md(bl_body),
    footer=md("sent via Microsoft365R")
)
em <- outl$create_email(bl_em, subject="Hello", to="bob@example.com")
```

Once the message is created, you send it with its `send()` method. Sending an email will move it to the Sent Items folder.

```r
em$send()
```

### Attachments

You can add file attachments to a draft email with the `add_attachment()` method. The attachment can be located on your local machine or in OneDrive/SharePoint. In the latter case, you should supply a drive item object, along with the details for how it should be shared: a OneDrive/Sharepoint file is actually attached as a shared link, and you can specify things like whether to make a viewable or editable link, the expiry time, whether a password is required, and so on.

```r
# attach a file on your local machine
em$add_attachment("mydocument.docx")

# attach a file in OneDrive/SharePoint: an editable link, valid for 1 month
item <- get_sharepoint_site("My site")$
    get_drive()$
    get_item("Documents/myproject.pptx")
em$att_attachment(item, type="edit", expiry="1 month")
```

The "OneDrive and SharePoint" vignette has more information on drive item objects, including the arguments for creating shared links.

You can also add an image file as an _inline_ attachment with the `add_image()` method. The image will be placed at the end of the message body, which should be in HTML format. Currently Microsoft365R does minimal formatting of the inline image; for more control over layout details, consider using the similar feature in the blastula package.

```r
# add an inline image: note the email message body must be HTML
em <- create_email("See picture below", content_type="html")
em$add_image("mypicture.jpg")

# or with blastula
library(blastula)
bl_body <- md(c(
    "See picture below",
    add_image("mypicture.jpg")
))
bl_em <- compose_email(bl_body)
em <- outl$create_email(bl_em)
```

### Other methods

In addition to the methods noted above, an email message object has the following methods for editing its contents:

- `add_recipients(to, cc, from)`: Adds recipients to the email. Unlike `set_recipients()` which was used before, this will retain any existing recipients rather than deleting them.
- `set_reply_to()`: Sets the reply-to email address for the email.


## Managing your emails

The Outlook client `list_emails()` method by default returns a list of the 50 most recent emails in your Inbox, sorted by date received. Each email is an object of class `ms_outlook_email`, the same as for messages that you send. You can customise the list to set the number of emails returned, and the criterion for retrieving them: by date, sender or subject.

```r
# a list of 50 email objects
outl$list_emails()

# 100 most recent emails
outl$list_emails(n=100)

# 50 emails, sorted by sender in ascending order
outl$list_emails(by="from")

# 200 emails, sorted by subject in descending order
outl$list_emails(by="subject desc", n=200)
```

A specific email object can be retrieved with `get_email()`. However, as this requires knowing its Outlook message ID, it will usually be easier to examine the result of `list_emails()` to get the email desired.

You can list the attachments for an email with `list_attachments()`, retrieve the metadata for an attachment with `get_attachment()`, and download the attachment with `download_attachment()`. Note that these methods work both for messages that you send, and those that you've received.

```r
# get the most recent email
em <- outl$list_emails()[[1]]

# a list of the attachments for the email
em$list_attachments()

# get a single attachment object
em$get_attachment("myfile.csv")

# download it
em$download_attachment("myfile.csv")
```

To delete an email, simply call its `delete()` method. By default, this will prompt you for confirmation first. The email will be moved to the Deleted Items folder.

```r
em$delete()
```

### Replying to an email

An email object has `create_reply()`, `create_reply_all()` and `create_forward()` methods for creating replies and forwarding.  The first argument is the reply comment, which is inserted above the quoted message body of the original email. Each of these creates a new draft email, and the methods described in "Writing emails" above apply here as well.

```r
# get the most recent email in the Inbox
em <- outl$list_emails()[[1]]

# draft a reply to it, adding an attachment
repl <- em$create_reply("See attached report")$
    add_attachment("report.md")

# reply-all, setting the reply-to address
repl_all <- em$create_reply_all("Please do not reply")$
    set_reply_to("do_not_reply@example.com")

# or forward it
fwd <- em$create_forward("FYI", to="mallory@example.com")
```

As with drafting new emails, you send a reply by calling its `send()` method:

```r
repl$send()
repl_all$send()
fwd$send()
```

Also as with writing new emails, you can use blastula and emayili to create the reply comment:

```r
library(blastula)
bl_repl <- compose_email(
    body=md("This is a **good idea!**"),
    footer=md("sent via Microsoft365R")
)
em$create_reply(bl_repl)
```

### Working with folders

Microsoft365R provides a rich set of tools for managing your email folders. A folder is represented by an object of R6 class `ms_outlook_folder`, which has methods for listing emails, drafting replies, and copying and moving items.

```r
# list all the folders in your account
outl$list_folders()

# get a folder by name
folder <- outl$get_folder("myfolder")

# you can also get nested folders
folder2 <- outl$get_folder("top level")$get_folder("2nd level")

# create a new folder
outl$create_folder("test folder")

# delete it
outl$delete_folder("test folder")
```

In addition, the Outlook client object provides some convenience functions for retrieving well-known folders: `get_inbox()`, `get_drafts()`, `get_sent_items()`, and `get_deleted_items()`.

To list the emails in a folder, call its `list_emails()` method. This has the same arguments as the `list_emails()` method for the Outlook client object; in fact, the latter simply calls the folder method for the Inbox folder.

```r
# list all the emails in the Inbox -- the same as outl$list_emails()
outl$get_inbox()$list_emails()

# list all the emails in a specific folder
out$get_folder("myfolder")$list_emails()
```

Similarly, to create a new draft email in a folder, call its `create_email()` method. Again, this has the same arguments as the Outlook client object method, which calls the folder method for the Drafts folder.

```r
# create a new email in Drafts  -- same as outl$create_email()
outl$get_drafts()$create_email("Hello from R")

# create a new email in a specific folder
outl$get_folder("myfolder")$create_email("Hello from R")
```

You can move and copy folder items by calling their `move()` and `copy()` methods. This works for both emails and (nested) folders. The destination should be another folder object.

```r
destfolder <- outl$get_folder("my archive")

# copying an email
em <- outl$list_emails()[[1]]
em$copy(destfolder)

# moving a folder
folder <- outl$get_folder("test folder")
folder$move(destfolder)
```