14

I strongly suspect the most upvoted answer will be "that is the wrong tool for the job". I acknowledge that R may not be particularly well suited for sending and receiving email but it is the scripting language I know best. I am hoping to find a way to send and receive short emails in R. Does anybody know an established way to do this on a Windows platform? I might be able to use a combination of BLAT and GetMail but a native R solution would be preferred.

Edit: An acceptable solution should be able to interface with servers that require SSL.

Edit 2: I provide my stab at a 80% answer. Sadly an R native way is not demonstrated. Instead I use an unholy combination of system calls and command line programs that is likely to not be compatible across platforms. R native calls will require digging into the way POP3 servers like to talk to connected clients and an understanding of SSL that I don't currently have. Other answers are still encouraged.

##Note: Other programs are wrapped in R functions and system calls.
#They each have their own licenses which may or may not allow the use suggested here
#Programs used here:
#STunnel: http://www.stunnel.org/; Provides an SSL tunnel but requires OpenSSL 
#OpenSSL: http://www.openssl.org/; OpenSSL to actually provide SSL
#   Note that these .dlls should be placed with the stunnel exe.
#   Also note that libssl32.dll may need to be renamed from ssleay32.dll
#Microsoft Visual C++ 2008 Redistributable (may be required for the SSL .dlls to work correctly)
#Blat: http://www.blat.net; a public domain SMTP sending program
#Getmail is free for non-commercial use. If you use it in a business environment, then a fee of $50 USD is payable to Tim Charron. 

#Stunnel is a TSR, so it will need to be killed from the task manager if there is an issue.  If you are willing to install it as a service you may be able to tweak my code to start and stop the service.  
#My current code does not create .conf file for stunnel the way a full version ought.  Check http://spampal.sanesecurity.com/manual_eng/servers/stunnel/stunnel.htm#sconfig21 to create the appropriate configuration file.

#Set the config values as appropriate
##Config##
BLAT.loc <- "c:/Programming/R/Rmail/blat262/full/blat.exe"
GetMail.loc <- "C:/Programming/R/RMail/getmail133/getmail.exe"
stunnel.loc <- "C:/Programming/R/RMail/stunnel/stunnel-4.11.exe"

#The set mail function assigns the username and password to be used as well as the smtp and pop3 servers it starts stunnel (and assumes that the stunnel.conf file is present and set correctly).
setMail <- function(user,pw,SSL=FALSE,smtp="127.0.0.1:259",pop3="127.0.0.1:1109")
{
    if (SSL==TRUE)
    {
        print("Starting stunnel; you will need to kill this from the task-manager")
        system(stunnel.loc,wait=FALSE)
        Sys.sleep(2) #Give it time to start 
    }
    return(list(user=user,pw=pw,smtp=smtp,pop3=pop3,SSL=SSL))
}

#function to send mail, myMail is the resulting list from setMail
sendmail <- function(myMail, to, subject, msg,VERBOSE=FALSE)
{
    writeLines(msg, "out.txt", sep = "\n", useBytes = FALSE)
      targ <- paste(getwd(),"/out.txt",sep="")
    call <- paste(BLAT.loc, ' "',targ,'" -subject "',subject,'" -to ',to," -u ",myMail$user," -pw ",myMail$pw, " -f ",myMail$user, " -debug -server ",myMail$smtp,sep="")
    res <- system(call,intern=TRUE)
    if (VERBOSE) {return(res)}
}

#function to get mail, myMail is the resulting list from setMail; it returns a list with one element that contains everything unparsed, another list provides the number of messages remaining on the server.
getmail <- function(myMail,VERBOSE=FALSE)
{      
    unlink("MSG1.txt") #drop previous get
    #download next message
    call <- paste(GetMail.loc," -u ",myMail$user," -pw ",myMail$pw," -s ",strsplit(myMail$pop3,":")[[1]][1],
        " -port ",strsplit(myMail$pop3,":")[[1]][2]," -n 1",sep="")
    res <- system(call,intern=TRUE)
    if (VERBOSE) {print(res)}
    nmsgtxt <- res[grep("messages on the server.",res)]
    nstart <- regexpr("There are",nmsgtxt)
    nend <- regexpr("messages on the server.",nmsgtxt)
    nmess <- as.numeric(substr(nmsgtxt,10,nend-1))-1
      x <- readLines("MSG1.txt",-1)
    return(list(message=x,remaining=nmess))
}

Usage case: Simply put, I need to have R be able to send a message whose content is determined elsewhere in the R script to an SMTP server. Participants will receive the email and respond to it. I need to retrieve their response from my POP3 server and store it in an R data structure so that I can perform post processing on it. In practice, I'm establishing a way to do experience sampling via R. That is, R can email a participant "How are you today (1 = Bad; 7 = Great)?" The participant can respond "4", and I can match the question asked, the response, and so on in a database for statistical analysis.

russellpierce
  • 4,583
  • 2
  • 32
  • 44
  • 1
    Similar (but not a duplicate cause of SSL) http://stackoverflow.com/questions/2885660/how-to-send-email-with-attachment-from-r-in-windows and http://stackoverflow.com/questions/3572607/sendmailr-part2-sending-files-as-mail-attachments – Marek Nov 22 '10 at 08:56
  • 1
    What's up with the tone of Edit2 and Edit3? Is that really called for? – Dirk Eddelbuettel Nov 22 '10 at 13:41
  • 2
    On a sidenote, Perl (and by extension Python) is still a main scripting language used as backend for many websites. It contains a wealth of functions for (automated) sending and receiving e-mails (many mailing lists take advantage of these functionalities in Perl). I'm a programmer by necessity as well, but I'm happy I learned to work with more than one "tool" (i.e. language). In the long run, that seems a better way to go. Plus, Perl and R can be linked. Or Python off course, it can do that too. – Joris Meys Nov 22 '10 at 13:46
  • Can you give a use case for the 'receiving' part (which certainly seems to be the hard part)? Perhaps someone would give you an answer that solved your problem if not your specific question ... – Ben Bolker Nov 22 '10 at 15:08
  • And *receiving* is just sloppy lingo. *Receiving mail* is what `sendmail`, `qmail`, `exim`, `Exchange`, ... do. He wants to *interface* a mail server / mail store via the imap or pop protocols. In other words, extend R with existing library functionality. Which is doable. – Dirk Eddelbuettel Nov 22 '10 at 15:39
  • 2
    I understand that you need a cross-platform tool. You should settle down with some *NIX app, and try to run it within Windows. `mutt` is a good alternative, and you can run it through CygWin... it's not the most elegant solution, but currently `sendmailR` doesn't support SSL. – aL3xa Nov 22 '10 at 19:40
  • 1
    As a non-specialist, I appologize for my 'sloppy' use of the term receiving. By receiving I meant transferring an email from the mail server, e.g. a POP3 server, to the local machine. Something that is 'doable' in R, but there appears to be no current library or library in development that does it (which is part of what I wanted to determine before I reinvented the wheel). – russellpierce Nov 23 '10 at 01:36
  • I appreciate that you toned down the inappropriate language in your most recent edits. – Dirk Eddelbuettel Nov 23 '10 at 01:59
  • You're welcome; however, I reject the notion that there was anything inappropriate in the original text. – russellpierce Nov 23 '10 at 02:35

3 Answers3

12

Pulling messages from a Pop server

To take a stab at implementing @JorisMeys idea of taking advantage of other languages, I took a stab at pulling mail from Gmail (over ssl) using Python and the rJython package. Jython is Python implemented on the Java virtual machine, so using rJython feels to me a bit like using R to call Java that then pretends to be Python.

I find rJython pretty easy for simple things, but since I'm not well versed in S4 objects and (r)Java I sometimes struggle to properly manipulate the return objects from rJython. But, it works. Here's a basic construct that will pull a single message from a Gmail account:

library(rJython)

rJython <- rJython( modules = "poplib")

rJython$exec("import poplib")
rJython$exec("M = poplib.POP3_SSL('pop.gmail.com', 995)")
rJython$exec("M.user(\'yourGmailAddy@gmail.com\')")
rJython$exec("M.pass_(\'yourGmailPassword\')")
rJython$exec("numMessages = len(M.list()[1])")
numMessages <- rJython$get("numMessages")$getValue()

# grab message number one. Loop here if you
# want more messages
rJython$exec("msg = M.retr(1)[1]")
emailContent <- rJython$get("msg")

# turn the message into a list
contentList <- as.list(emailContent)
# so we have an R list... of Java objects
# To get a more native R list we have to
# yank the string from each Java item

messageToList <- function(contentList){
  outList <- list()
  for (i in 1:length(contentList)){
    outList[i] <- contentList[[i]]$toString()
  }
  outList
}

messageAsList <- messageToList(contentList)
messageAsList
JD Long
  • 59,675
  • 58
  • 202
  • 294
  • Thanks for pointing me in this direction. I'll try this out soon to see if I work out how to send mail using it. I much prefer this approach to the command line hacks I was putting together. – russellpierce Nov 23 '10 at 01:50
  • this is really great start. Is there a way to enhance the response? – Indranil Gayen Oct 23 '16 at 13:05
8

Look at the sendmailR package on CRAN.

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • 2
    sendmailR seems to only send mail; it doesn't support SSL either. – russellpierce Nov 22 '10 at 03:31
  • 11
    That is not within my skill set. I know my limitations and was looking for a solution that would work within them. I am not a programmer by trade, I am one by necessity. – russellpierce Nov 22 '10 at 08:18
2

With the mailR package (http://rpremraj.github.io/mailR/), you could send emails with SSL:

send.mail(from = "sender@gmail.com",
          to = c("recipient1@gmail.com", "recipient2@gmail.com"),
          subject = "Subject of the email",
          body = "<html>The apache logo - <img src=\"http://www.apache.org/images/asf_logo_wide.gif\"></html>",
          html = TRUE,
          smtp = list(host.name = "smtp.gmail.com", port = 465, user.name = "gmail_username", passwd = "password", ssl = TRUE),
          attach.files = c("./download.log", "upload.log"),
          authenticate = TRUE,
          send = TRUE)
Rahul Premraj
  • 1,595
  • 14
  • 13
  • Although my immediate need for this has past, I gave the mailR package a whirl on a Windows 7 x64 system. It performed as advertised without any fiddling on my part to make it work. I wonder if we'll be seeing it on CRAN anytime soon. – russellpierce May 27 '14 at 19:06
  • ... any plans on implementing a way to receive the emails? – russellpierce May 27 '14 at 19:10
  • 1
    mailR is already on CRAN (http://cran.r-project.org/web/packages/mailR/index.html). I will consider adding support to receive emails in the future... – Rahul Premraj May 27 '14 at 19:53