See how to automate sending email with the R language, a Gmail account, and the gmailr R package
At some point in your R life, you will likely want to share results of your analysis with non-R-using colleagues. There are lots of ways to do this. One of the easiest (and least expensive) is emailing your results.
But itโs kind of sad to automate your entire analysis workflow, only to manually craft and send an email at the end. Fortunately, you donโt have to. There are several R packages that let you send email directly from an R script. In this article, Iโll demo one of them: gmailr by Jim Hester, whoโs now a software engineer at RStudio.
Obviously, youโll need a Gmail account, which is free to set up if you donโt have one. Then, before you can use that account from R, youโll need to set it up for API access. Hereโs how.
Go to console.developers.google.com (yes, thatโs a sub-subdomain). If you donโt already have a developer project, youโll be asked to create one.ย
At the top of your dashboard, you should see a choice to โEnable APIs and Services.โ Click that.
Sharon Machlis, IDG
You have an option to enable APIs in the Google Developers Console dashboard.
Next youโll want to search for the Gmail API. Click on that and then click Enable.ย
The R script will need credentials, so click Create Credentials at the top right.
Sharon Machlis IDG
Creating authorization credentials for the Gmail API.
According to Jim Hesterโs instructions, we need a client ID, so Iโll choose Client ID.
Sharon Machlis, IDG
Create a client ID.
Now itโs asking for an application type. Since โR scriptโ isnโt here, I want to choose โOther.โ But all the radio buttons are greyed out. Thatโs because I havenโt configured the consent screen. Thatโs easy to miss if youโre focused on the radio-button choices; itโs at the top right. Click on that.
Sharon Machlis, IDG
Donโt forget to configure your consent screen before choosing your application type.
Your email address should be in the consent-screen form already. The only other requirement is a name for the application. You can call it anything you like.
Jim says the rest of the defaults are fine, so scroll down and save. Now you should be able to select Application type Other, give the application a name, and click Create.
The console should then give youย a client ID and client secret.ย You can use them by adding them to your R environment if you want. But Jim suggests downloading the JSON file instead. You can download that to your R project working directory, and remember the file name you give it.
Sharon Machlis, IDG
You can download a JSON file with your Gmail API credentials.
That finishes setup on the Google side, and itโs finally time for some R code.ย
First, make sure youโve got the gmailr package installed. Itโs available on CRAN, so you can install it with install.packages("gmailr"). Then load the package in your script with library(gmailr).
Before doing anything else, youโll want to set up your working R session to use your downloaded JSON credentials file. You can do that with the use_secret_file() function, and the name of your JSON file as the argument. If I called my JSON credentials file DoMoreWithR.json, the command would beย
use_secret_file("DoMoreWithR.json")
Actually sending a message is fairly easy.
For some sample data, Iย downloaded monthly U.S. unemployment rates and then created a text string called latest_msg with info about the latest unemployment rate. Note that in the code below I use the glue package to assemble the character string I want for my message, but thatโs because I like doing it that way; paste() or paste0() work equally well.
You can use any R-generated data youโd like in your email message. If youโd like to follow along with mine, here is the code (youโll need the pacman package installed):
pacman::p_load(quantmod, glue, xts, dplyr, ggplot2)
getSymbols("UNRATE", src="FRED")
unemployment <- coredata(UNRATE)
month_starting <- index(UNRATE)
series_length <- length(unemployment)
latest_msg <- glue("The latest US unemployment rate was {unemployment[series_length]}, in the month starting {month_starting[series_length]}. That's {unemployment[series_length] - unemployment[series_length - 1]} percentage points difference from the prior month.")
Next, I want to create a MIME email object, and then add a to address, a from address, subject text, and my message body.
my_email_message <- mime() %>%
to("some_email_address@somedomain.com") %>%
from("domorewithr@gmail.com") %>%
subject("My test message") %>%
text_body(latest_msg)
If you do this and then check the structure of my_email_messageย with str(my_text_message) you would see that itโs a list with a class of mime.
After creating your MIME message object, you can send it with the send_message() function. The argument is just the name of my MIME object, in this case my_email_message. So the full command in this case is
send_message(my_email_message)
When you run send_message() the first time, youโll likely be asked if you want to cache authorization between R sessions. I suggest you say yes. The first time you run this, youโll also be asked in your browser to authorize your R script to use your Google account.
There is more you can do with gmailr. One option is to create an HTML message, so you can use markup like bold and italic.
Here my message body includes HTML-like paragraph marks and bold and italic, and Iโll send it to my work address.ย
html_msg_text <- glue("The latest US unemployment rate was
<b>{unemployment[series_length]}</b>, in the month starting
{month_starting[series_length]}. That's
{unemployment[series_length] - unemployment[series_length - 1]}
percentage points difference from the prior month.
<i>Data from the U.S. Bureau of Labor Statistics.</i>
")
my_html_message <- mime() %>%
to("sharon_machlis@idg.co") %>%
from("domorewithr@gmail.com") %>%
subject("My test message") %>%
html_body(html_msg_text)
send_message(my_html_message)
Unfortunately, I donโt know a way to easily include an image generated from R directly in the message body. But itโs pretty straightforward to include one as an attachment.ย
At the top of the script below, Iโm turning my unemployment rate data into a data frame with metrics from 2000 and later, so I can use ggplot to graph it, and then save the graph to a file.ย
This next part of the code is whatโs important to know for email, though. First, like before, Iโm creating a text string for my message text with the glue package. Whatโs new is the last two lines of code creating my MIME object. That last line, attach_file(), attaches my PNG file to the email. The line before is important if you want text to show up in the body of the email. Without using both text_body() and attach_part() for the body text, text wonโt show up when you attach a file. Just something to remember.
Then I can use the same send_message() function to send it.
un_df <- data.frame(month_starting, unemployment) %>%
filter(month_starting >= as.Date("2000-01-01")) %>%
rename(unemployment = UNRATE)
mygraph <- ggplot(un_df, aes(month_starting, unemployment)) +
geom_line() +
ggtitle("US Monthly Unemployment") +
xlab("Month Starting") +
ylab ("")
ggsave("unemployment_graph.png")
msg_text <- glue("The latest US unemployment rate was {unemployment[series_length]}, in the month starting {month_starting[series_length]}. That's {unemployment[series_length] - unemployment[series_length - 1]} percentage points difference from the prior month. A graph of the data since January 2000 is attached.")
message2 <- mime() %>%
to("sharon_machlis@idg.com") %>%
from("domorewithr@gmail.com") %>%
subject("My text message with attached graph") %>%
text_body(msg_text) %>%
attach_part(msg_text) %>%
attach_file("unemployment_graph.png")
send_message(message2)
If you want, you can use the function create_draft()ย to create a draft message in your Gmail account, if youโd like to check how it looks before sending it out. In this case, create_draft(message2) would create a draft of my file-attachment message.
If youโd like to see how all this looks in action, check out the video at the top of this article. And for more R tips, head to the Do More With R YouTube playlist.


