{emayili}
is a package for sending emails from R. The
design goals are:
The package name is an adaption of the Zulu word for email, imeyili.
The documentation for {emayili}
can be found here.
Get the stable version from CRAN.
install.packages("emayili")
Or grab it directly from GitHub.
# Install from the master branch.
::install_github("datawookie/emayili")
remotes# Install from the development branch.
::install_github("datawookie/emayili", ref = "dev") remotes
Load the library.
library(emayili)
packageVersion("emayili")
[1] '0.7.17'
Create a message object.
<- envelope() email
The message has class envelope
.
class(email)
[1] "envelope"
Add addresses for the sender and recipient.
<- email %>%
email from("alice@yahoo.com") %>%
to("bob@google.com") %>%
cc("craig@google.com")
There are also bcc()
and reply()
functions
for setting the Bcc
and Reply-To
fields.
You can supply multiple addresses in a variety of formats:
envelope() %>% to("bob@google.com, craig@google.com, erin@gmail.com")
envelope() %>% to("bob@google.com", "craig@google.com", "erin@gmail.com")
envelope() %>% to(c("bob@google.com", "craig@google.com", "erin@gmail.com"))
Add a subject.
<- email %>% subject("This is a plain text message!") email
Add a text body.
<- email %>% text("Hello!") email
You can use html()
to add an HTML body. It accepts
either a vector of characters or a tagList()
from
{htmltools}
.
library(htmltools)
<- email %>% html(
email tagList(
h2("Hello"),
p("World!")
) )
Add an attachment.
<- email %>% attachment("image.jpg") email
You can also create the message in a single command:
<- envelope(
email to = "bob@google.com",
from = "alice@yahoo.com",
subject = "This is a plain text message!",
text = "Hello!"
)
Simply printing a message displays the header information.
email
Date: Sat, 19 Aug 2023 04:44:05 GMT
X-Mailer: {emayili}-0.7.17
MIME-Version: 1.0
From: alice@yahoo.com
To: bob@google.com
Cc: craig@google.com
Subject: This is a plain text message!
You can identify emails which have been sent using
{emayili}
by the presence of an X-Mailer
header which includes both the package name and version.
If you want to see the complete MIME object, just convert to a string.
You can also call the print()
method and specify
details = TRUE
.
You can set the envelope.details
option to assert that
the details should always be printed.
# Always print envelope details.
#
options(envelope.details = TRUE)
By default the results returned by most of the methods are invisible.
You can make them visible via the envelope.invisible
(default: TRUE
).
# Always show envelope.
#
options(envelope.invisible = FALSE)
You can use {glue}
syntax to interpolate content into
the body of a message.
<- "Alice"
name
envelope() %>%
text("Hello {{name}}!")
Date: Sat, 19 Aug 2023 04:44:05 GMT
X-Mailer: {emayili}-0.7.17
MIME-Version: 1.0
Content-Type: text/plain;
charset=utf-8;
format=flowed
Content-Transfer-Encoding: 7bit
Content-MD5: nhjeY5ZYMzru+kSCGUzNKg==
Hello Alice!
You can render Markdown straight into a message.
Use either plain Markdown.
envelope() %>%
# Render plain Markdown from a character vector.
render(
"Check out [`{emayili}`](https://cran.r-project.org/package=emayili)."
)
Date: Sat, 19 Aug 2023 04:44:05 GMT
X-Mailer: {emayili}-0.7.17
MIME-Version: 1.0
Content-Type: text/html;
charset=utf-8
<html><body><p>Check out <a href="https://cran.r-project.org/package=emayili"><code>{emayili}</code></a>.</p></body></html>
Or R Markdown.
envelope() %>%
# Render R Markdown from a file.
render("message.Rmd")
In both cases the function will accept either a file path or a character vector containing Markdown text.
Interpolation also works with render()
.
When you render an R Markdown document the resulting HTML includes CSS from three sources:
{rmarkdown}
.You can control which of these propagate to the message using the
include_css
parameter which, by default, is set to
c("rmd", "bootstrap", "highlight")
.
🚨 Note: Gmail doesn’t like the Bootstrap CSS. If you want
your styling to work on Gmail you should set
include_css = c("rmd", "highlight")
.
You can insert extra CSS into your rendered messages.
envelope() %>%
render("message.Rmd", css_files = "extra.css")
If you are having trouble getting this to work with Gmail then it might be worthwhile taking a look at their CSS support.
Adding an inline image to an HTML message is possible. There are two ways to achieve this.
1. Base64 Encoding
First you’ll need to Base64 encode the image.
<- base64enc::base64encode("image.jpg") img_base64
Then create the HTML message body.
<- sprintf('<html><body><img src="data:image/jpeg;base64,%s"></body></html>', img_base64) html_body
And finally add it to the email.
<- envelope() %>% html(html_body) email
Note: It’s important that you specify the appropriate media
type (image/jpeg
for JPEG and image/png
for
PNG).
2. Using a CID
Unfortunately some mail clients (like Gmail) will not display Base64 encoded images. In this case using a CID is a working alternative.
First create the message body which references an image by CID.
<- '<html><body><img src="cid:image"></body></html>' html_body
Then attach the image and specify the cid
argument.
<- envelope() %>%
email html(html_body) %>%
attachment(path = "image.jpg", cid = "image")
Create a SMTP server object.
<- server(
smtp host = "smtp.gmail.com",
port = 465,
username = "bob@gmail.com",
password = "bd40ef6d4a9413de9c1318a65cbae5d7"
)
It’s bad practice to include credentials in a script. A better
approach would be to keep the credentials in your .Renviron
file.
GMAIL_USERNAME="bob@gmail.com"
GMAIL_PASSWORD="bd40ef6d4a9413de9c1318a65cbae5d7"
You can then pull these variables into R using
Sys.getenv()
and then create the server object.
<- server(
smtp host = "smtp.gmail.com",
port = 465,
username = Sys.getenv("GMAIL_USERNAME"),
password = Sys.getenv("GMAIL_PASSWORD")
)
If you’re trying to send email with a host that uses the STARTTLS security protocol (like Gmail, Yahoo! or AOL), then it will most probably be blocked due to insufficient security. In order to circumvent this, you can grant access to less secure apps. See the links below for specifics:
Gmail has recently changed their authentication procedure. If you are having trouble connecting to the Gmail SMTP server then take a look at this.
Send the message.
smtp(email, verbose = TRUE)
To see the guts of the message as passed to the SMTP server:
print(email, details = TRUE)
Both transport-level encryption and end-to-end email encryption are supported. An SMTP connection can be initiated on port 465 (SMTPS, see RFC 8314) or 587 (SMTP-MSA, see RFC 6409), enabling transport-level encryption. Public-key cryptography (via GnuPG) can be used to sign and/or encrypt message contents for end-to-end encryption.
The following (draft) standards documents relate to emails:
There is a selection of other R packages which also send emails:
You can find the test coverage report at Codecov. For
development purposes it’s more convenient to use the {covr}
package.
Generate a coverage report.
library(covr)
# Tests that are skipped on CRAN should still be included in coverage report.
#
Sys.setenv(NOT_CRAN = "true")
report()
Calculate test coverage.
<- package_coverage() coverage
Coverage statistics as a data frame.
as.data.frame(coverage)
Show lines without coverage.
zero_coverage(coverage)
Check spelling.
::spell_check_package() spelling
Quick local checks.
::check() devtools
Remote checks (take longer but more thorough).
::check_win_devel()
devtools
# Check for a specific platform.
#
::check(platform = "debian-gcc-devel")
rhub::check_on_windows(check_args = "--force-multiarch")
rhub::check_on_solaris()
rhub
# Check on a bunch of platforms.
#
::check_for_cran()
rhub
# Check on important platforms.
#
::check_for_cran(platforms = c(
rhub"debian-gcc-release",
"ubuntu-gcc-release",
"macos-m1-bigsur-release",
"windows-x86_64-release",
NULL
))