问题
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("to@gmail.com") %>%
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 <from@gmail.com>' # 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.
回答1:
Sometimes it is easier, though perhaps not quite as elegant, to write a function that performs the action of interest for one row of the tibble. And then use map/map2/pmap
or walk/walk2/pwalk
to apply that function repeatedly.
library("tidyverse")
library("gmailr")
# Create two empty attachment files needed for example
file.create("A.html")
#> [1] TRUE
file.create("B.html")
#> [1] TRUE
test_send_message <- function(msg) {
# Doesn't actually send any emails
print(strwrap(as.character(msg)))
}
prepare_and_send <- function(sender, recepient,
title, text,
attachment) {
email <- mime() %>%
to(sender) %>%
from(recepient) %>%
subject(title) %>%
text_body(text) %>%
attach_file(attachment, type = "html") %>%
test_send_message()
}
# Test that function works to send one email
prepare_and_send("to@gmail.com", "from@gmail", "some subject",
"some text", "A.html")
#> [1] "MIME-Version: 1.0\r Date: Mon, 18 Mar 2019 21:32:20 GMT\r To:"
#> [2] "to@gmail.com\r From: from@gmail\r Subject: some subject\r"
#> [3] "Content-Type: multipart/mixed;"
#> [4] "boundary=2c47d060a267bfdca54a1fdfe0c4ecaf\r Content-Disposition:"
#> [5] "inline\r \r MIME-Version: 1.0\r Date: Mon, 18 Mar 2019 21:32:20 GMT\r"
#> [6] "Content-Type: text/plain; charset=utf-8; format=flowed\r"
#> [7] "Content-Transfer-Encoding: quoted-printable\r Content-Disposition:"
#> [8] "inline\r \r some text\r --2c47d060a267bfdca54a1fdfe0c4ecaf\r"
#> [9] "MIME-Version: 1.0\r Date: Mon, 18 Mar 2019 21:32:20 GMT\r"
#> [10] "Content-Type: html; name=A.html\r Content-Transfer-Encoding:"
#> [11] "base64\r Content-Disposition: inline; filename=A.html;"
#> [12] "modification-date=Mon, 18 Mar 2019 21:32:20 GMT\r \r \r"
#> [13] "--2c47d060a267bfdca54a1fdfe0c4ecaf--\r"
# Then try to send multiple emails
addresses <- tribble(
~name, ~email,
"A", "a@gmail.com",
"B", "b@gmail.com"
)
email_sender <- 'First Last <from@gmail.com>'
msg <- "this is the message of the email"
addresses %>%
mutate(
To = sprintf('%s <%s>', name, email),
From = email_sender,
Subject = sprintf('Mark for %s', name),
body = msg,
attachment = sprintf('%s.html', name)) %>%
mutate(x = pmap(list(To, From, Subject, body, attachment),
safely(prepare_and_send)))
#> [1] "MIME-Version: 1.0\r Date: Mon, 18 Mar 2019 21:32:20 GMT\r To: A"
#> [2] "<a@gmail.com>\r From: First Last <from@gmail.com>\r Subject: Mark"
#> [3] "for A\r Content-Type: multipart/mixed;"
#> [4] "boundary=bd435d3f3bb00aee58b776142a512702\r Content-Disposition:"
#> [5] "inline\r \r MIME-Version: 1.0\r Date: Mon, 18 Mar 2019 21:32:20 GMT\r"
#> [6] "Content-Type: text/plain; charset=utf-8; format=flowed\r"
#> [7] "Content-Transfer-Encoding: quoted-printable\r Content-Disposition:"
#> [8] "inline\r \r this is the message of the email\r"
#> [9] "--bd435d3f3bb00aee58b776142a512702\r MIME-Version: 1.0\r Date: Mon,"
#> [10] "18 Mar 2019 21:32:20 GMT\r Content-Type: html; name=A.html\r"
#> [11] "Content-Transfer-Encoding: base64\r Content-Disposition: inline;"
#> [12] "filename=A.html; modification-date=Mon, 18 Mar 2019 21:32:20 GMT\r"
#> [13] "\r \r --bd435d3f3bb00aee58b776142a512702--\r"
#> [1] "MIME-Version: 1.0\r Date: Mon, 18 Mar 2019 21:32:20 GMT\r To: B"
#> [2] "<b@gmail.com>\r From: First Last <from@gmail.com>\r Subject: Mark"
#> [3] "for B\r Content-Type: multipart/mixed;"
#> [4] "boundary=aa10620651c2281647a4fba0dc392694\r Content-Disposition:"
#> [5] "inline\r \r MIME-Version: 1.0\r Date: Mon, 18 Mar 2019 21:32:20 GMT\r"
#> [6] "Content-Type: text/plain; charset=utf-8; format=flowed\r"
#> [7] "Content-Transfer-Encoding: quoted-printable\r Content-Disposition:"
#> [8] "inline\r \r this is the message of the email\r"
#> [9] "--aa10620651c2281647a4fba0dc392694\r MIME-Version: 1.0\r Date: Mon,"
#> [10] "18 Mar 2019 21:32:20 GMT\r Content-Type: html; name=B.html\r"
#> [11] "Content-Transfer-Encoding: base64\r Content-Disposition: inline;"
#> [12] "filename=B.html; modification-date=Mon, 18 Mar 2019 21:32:20 GMT\r"
#> [13] "\r \r --aa10620651c2281647a4fba0dc392694--\r"
#> # A tibble: 2 x 8
#> name email To From Subject body attachment x
#> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <list>
#> 1 A a@gmai~ A <a@gm~ First Last~ Mark f~ this is the~ A.html <list~
#> 2 B b@gmai~ B <b@gm~ First Last~ Mark f~ this is the~ B.html <list~
Created on 2019-03-18 by the reprex package (v0.2.1)
回答2:
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)))
来源:https://stackoverflow.com/questions/55226676/gmailr-send-multiple-emails-through-r-with-attachment