views:

91

answers:

2

Following the directions provided in this related question, I was able to send html formated mail messages. Now the question is this: How should I modify the following code, in order to attach one or more files (of any type) to this message?

library(sendmailR)

from <- "<[email protected]>"
to <- c("<[email protected]>","<[email protected]>")
subject <- iconv("Message Title", to = "utf8")

msg <- "<hr size='2' width='33%' style='text-align: left;'><font size='2'>
  <i>This email was sent automatically using <a href='http://finzi.psych.upenn.edu/R/library/sendmailR/html/00Index.html' rel='nofollow' target='_blank'>sendmailR</a>.<br>
  Please do not reply directly to this e-mail.</i></font>"

msg <- iconv(msg, to = "utf8")

sapply(to,function(x) sendmail(from, x, subject, msg, control=list(smtpServer="###.###.###.###"), headers=list("Content-Type"="text/html; charset=UTF-8; format=flowed")))
+1  A: 

I would give up on using R for this. Working, cross-platform, stable solutions for doing this in Python exist, and you can call Python from R.

If I had to fit a mixed effects model in a Python program I'd call R to do it - if I want to do a systems task like send email in R I'll call Python to do it. Its worth learning if you don't know it yet.

Spacedman
If external tools are allowed, it is easier to just run `writeLines(message,p<-pipe('mutt -s blah -a att.ext -- [email protected]'));close(p)`. There is a Windows port of mutt, so it is cross-platform.
mbq
+2  A: 

A working (for me at least) function:

sendMessage<-function(contents,subject,from,to,attMIME,attachment,control){    
    require('sendmailR');
    require('base64');

msgTemplate<-'This is a multi-part message in MIME format.
--|-|-|-|
Content-Type: text/html; charset=UTF-8; format=flowed
%s
--|-|-|-|
Content-Type: %s;
 name="%s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="%s"

%s
--|-|-|-|--';

encAtt<-tempfile(); encode(attachment,encAtt);
paste(scan(encAtt,character(),quiet=T),collapse="\n")->encAtt;
sprintf(msgTemplate,contents,attMIME,attachment,attachment,encAtt)->msg;

sendmail(from,to,subject,msg,control,headers=list("Content-Type"='multipart/mixed;boundary="|-|-|-|"'));
}

Can be used like this:

png('a.png');hist(rnorm(700));dev.off()
sendMessage('<htm><head></head><body>Here you have a <b>nice</b> histogram:</body></html>',
'Nice picture',
'[email protected]',
'[email protected]',
'image/png',
'a.png',list(smtpServer="..."))

Be warned that message sent by this example will probably be marked as spam, since it is a short text and a big picture -- nevertheless for larger messages and, let's say, pdf attachments it should go through. If not, you may consider adding also a text version of the message.

EDIT: The most deep insight on how to make MIME messages can be found here.

mbq
I suppose I'm in one of my 'slow-witted' days. I must admit that I didn't understand if I can do it or not. If you think that it's possible, could you please use my example and transform it appropriately?
gd047
Certainly you can, you must just squeeze the message and attachment(s) into this crazy format and pass it as an actual message. I am planning to edit it to usable code, still this will take some time because now I have some other things to do.
mbq
Ok, extended now.
mbq
Hmmm. Error in waitFor(code) : SMTP Error: 5.7.1 Unable to relay for [email protected]
gd047
As long as you really tried [email protected], I am not surprised. If not, this is a network error or bad SMTP configuration.
mbq
One of the problems had to do with the use of 'control'. I used `sendMessage<-function(contents,subject,from,to,attMIME,attachment,ctrl)` and `sendmail(from,to,subject,msg,control=ctrl...` Now when I use google's smtpServer I get indeed a message with an attached picture, but I dont get the message body !!!
gd047
I have found out where the problem is. I think I can work it out.
gd047