Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gmailR - send multiple emails through R with attachment

Tags:

r

purrr

I have figured out how to sent a single email through R with an attachment and have the body of the email show up (seems to be a common problem). However, I'd like to follow Jenny Bryan's method of sending multiple emails while also attaching a file.

Sending a single email with attachment and a message.

msg <- "this is the message of the email"
test_email <- mime() %>%
  to("[email protected]") %>%
  from("from@gmail") %>%
  subject("subject goes here") %>%
  body(msg) %>%
  attach_file("29697.html", type = "html")
test_email <- attach_part(test_email, msg)
send_message(test_email)

To mimic the above code, but with Jenny's example, I have the following:

addresses <- read_csv("addresses.csv") #contains a column for 'name' and 'email'
email_sender <- 'First Last <[email protected]>' # your Gmail address
msg <- "this is the message of the email"

edat <- addresses %>%
  mutate(
    To = sprintf('%s <%s>', name, email),
    From = email_sender,
    Subject = sprintf('Mark for %s', name),
    body = msg,
    attach_file = sprintf('%s.html, type = html', name))

edat <- edat %>%
  select(To, From, Subject, body, attach_file)

emails <- edat %>%
  pmap(mime)

safe_send_message <- safely(send_message)

sent_mail <- emails %>%
  map(safe_send_message)

The above example creates a list to form the components of the mime file structure that gmailR uses, however, it does not attach the file like the single example above does. I've attempted to structure the attach_file function similarly, however, it does not place it in the list item for the mime in a similar way as calling it alone like the single example above where it puts it in the parts section of the list item. Thanks in advance if anyone has run into this.

like image 814
ML DeBusk-Lane Avatar asked Mar 02 '26 07:03

ML DeBusk-Lane


1 Answers

Using code from dipetkov's suggestion, I modified it to include both an attachment and the message to send a single email.

library("tidyverse")
library("gmailr")

msg <- "this is the message of the email"

prepare_and_send <- function(sender, recipient,
                             title, text,
                             attachment) {
  email <- mime() %>%
    to(recipient) %>%
    from(sender) %>%
    subject(title) %>%
    html_body(text) %>%
    attach_file(attachment, type = "html")
  email <- attach_part(email, msg) %>%
    send_message() 
}

# Test that function works to send one email
prepare_and_send("sender@gmail", "to@gmail", "some subject",
                 "some text", "20558.html")

Taking this a step further, I modified it a bit more to iterate through a series of emails held in the 'addresses' dataframe.

#Iterate it ----
addresses %>%
  mutate(
    to = sprintf('%s <%s>', name, email),
    from = email_sender,
    subject = sprintf('Mark for %s', name),
    html_body = msg,
    attachment = sprintf('%s.html', name)) %>%
  mutate(x = pmap(list(from, to, subject, html_body, attachment),
                  safely(prepare_and_send)))
like image 200
ML DeBusk-Lane Avatar answered Mar 03 '26 21:03

ML DeBusk-Lane



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!