How to send email from R and Gmail

See how to automate sending email with the R language, a Gmail account, and the gmailr R package

How to send email from R and Gmail

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 (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.

Enable API in the Google Developers Console dashboard 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.

Option to create authorization credentials for the Gmail API. 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.

Creating a client ID for the Gmail API 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.

Button to configure consent screen 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.

Icon for downloading JSON file 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 


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("") %>%
from("") %>%
subject("My test message") %>%

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


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("<p>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.</p>
<p><i>Data from the U.S. Bureau of Labor Statistics.</i></p>")
my_html_message <- mime() %>%
to("") %>%
from("") %>%
subject("My test 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 ("")
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("") %>%
from("") %>%
subject("My text message with attached graph") %>%
text_body(msg_text) %>%
attach_part(msg_text) %>%

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 video page on InfoWorld or check out the Do More With R YouTube playlist.

Copyright © 2019 IDG Communications, Inc.