6

How to send rmarkdown generated documents as a body in an email, using R?

I have successfully tried knitr with mailR, but when instead generating the html-report with the (new) rmarkdown-package it fails.

library(mailR)
send.mail(
  from = "FROM@gmail.com",
  to = "TO@gmail.com",
  subject = "MyMail",
  html = T,
  inline = T,
  body = "my_report.html",
  smtp = list(host.name = "smtp.gmail.com", port = 465,
    user.name = "USERNAME", passed = "PASSWORD", ssl = T),
  authenticate = T,
  send = T
)

error:

org.apache.commons.mail.EmailException: Building the MimeMessage failed
    at org.apache.commons.mail.ImageHtmlEmail.buildMimeMessage(ImageHtmlEmail.java:110)
    at org.apache.commons.mail.Email.send(Email.java:1436)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at RJavaTools.invokeMethod(RJavaTools.java:386)
Caused by: java.io.IOException: Cant resolve the following file resource :/Users/USERNAME/myfolder/./data:image/png;base64,iVBORw0KGg …

(…)

… SuQmCC
    at org.apache.commons.mail.resolver.DataSourceFileResolver.resolve(DataSourceFileResolver.java:105)
    at org.apache.commons.mail.resolver.DataSourceFileResolver.resolve(DataSourceFileResolver.java:79)
    at org.apache.commons.mail.ImageHtmlEmail.replacePattern(ImageHtmlEmail.java:149)
    at org.apache.commons.mail.ImageHtmlEmail.buildMimeMessage(ImageHtmlEmail.java:103)
    ... 6 more
Error: EmailException (Java): Building the MimeMessage failed

I guess it has to do with the following line: Cant resolve the following file resource :/Users/USERNAME/myfolder/./data:image/png;base64?

I'm more than grateful for any kind of guidance.

reinholdsson
  • 859
  • 7
  • 18
  • I get similar messages when the html file contains images, even if it is generated using the (old) markdown package. – gd047 Jun 22 '14 at 07:35
  • In cases where images are not included in the message body, very often I get the following failure: "org.apache.commons.mail.EmailException: Sending the email to the following server failed : aspmx.l.google.com:25. Our system has detected that this message is likely unsolicited mail. To reduce the amount of spam sent to Gmail, this message has been blocked" – gd047 Jun 22 '14 at 08:09

2 Answers2

10

mailR currently does not support resolving inline images encoded using the data URI scheme (http://en.wikipedia.org/wiki/Data_URI_scheme).

For the time being, I suggest the following solution to address your problem. In the future, I will look into getting mailr to support this natively.

First off, create the HTML file from the R terminal (the important thing here is that options does not include "base64_images" --- see ?markdown::markdownHTMLOptions):

library(knitr)
knit2html("my_report.Rmd",options="")

Now you can send the resulting HTML file via mailR:

send.mail(from = "FROM@gmail.com",
          to = "TO@gmail.com",
          subject = "MyMail",
          html = T,
          inline = T,
          body = "my_report.html",
          smtp = list(host.name = "smtp.gmail.com", port = 465, user.name = "USERNAME", passwd = "PASSWORD", ssl = T),
          authenticate = T,
          send = T)
Rahul Premraj
  • 1,595
  • 14
  • 13
  • 2
    Thanks! I'm looking forward for future native support. – reinholdsson Jun 23 '14 at 15:39
  • @RahulPremraj can I use file.choose() or fileInput from shiny to attach files? – Apricot Jul 05 '16 at 09:41
  • 1
    @Rahul Premraj I just tried your workaround, and I get an error telling me to use rmarkdown::render instead of knitr::knit2html. I tried using the same syntax with that function, and it's not working. Can you please post an updated workaround that works with the render function? BTW, thanks for that mailR package - it's fantastic! – Chris Newton Feb 10 '17 at 18:44
  • @ChrisNewton You have to remove the markdown YAML header in the my_report.Rmd file. Otherwise knitr e.g. ```knit2html("my_report.Rmd",options="")``` cannot render the markdown file. – jburkhardt Mar 06 '18 at 15:45
  • Updated workaround: markdownToHTML("MyReport.Rmd", output="MyReport.html", options=c("toc", "use_xhtml", "smartypants", "mathjax", "highlight_code")) send.mail(from = "myemail@example.com", to = "myemail@example.com", subject = "Email with a Markdown document in HTML at the message body", body = "MyReport.html", html = TRUE, inline = TRUE, smtp = list(host.name = "localhost"), send = TRUE) (i.e. avoid the option "base64_images", & place images in the same folder where the html is) – Xavier de Pedro Puente Aug 06 '18 at 11:10
0

You can also create the html from R itself. Example here also (sorry for duplication, but formating in the reply to a previous comment was not nicely readable, I reckon)

A workaround/solution I did was to set the param:

  #------------------
  if (!require(pacman)) install.packages("pacman"); library(pacman)
  p_load("mailR")
  p_load("markdown")
  markdownToHTML("MyReport.Rmd", 
                 output="MyReport.html", 
                 options=c("toc", "use_xhtml", "smartypants", "mathjax", "highlight_code"))

  send.mail(from = "myemail@example.com",
            to = c("myemail@example.com", 
                   "myotheremail@example.com"),
            subject = "Email with a Markdown document in HTML at the message body",
            body = "MyReport.html",
            html = TRUE,
            inline = TRUE,
            smtp = list(host.name = "localhost"),
            send = TRUE)
  #------------------

(or choose your own param set for the options of markdownToHTML, while ensuring that you avoid adding the "base64_images")

This way, I managed to send the html and get the report to show in the body of the email the images included in your report. The images were places in the same folder where the html was generated.

I hope this helps.