2010-11-22 32 views
10

Sospecho fuertemente que la respuesta más votada será "esa es la herramienta incorrecta para el trabajo". Reconozco que R puede no ser particularmente adecuado para enviar y recibir correos electrónicos, pero es el lenguaje de guiones que mejor conozco. Espero encontrar una forma de enviar y recibir correos electrónicos cortos en R. ¿Alguien sabe una forma establecida de hacerlo en una plataforma Windows? Podría usar una combinación de BLAT y GetMail, pero se preferiría una solución R nativa.¿Cómo puedo enviar/recibir (SMTP/POP3) correo electrónico usando R?

Editar: Una solución aceptable debe poder interactuar con los servidores que requieren SSL.

Editar 2: Proporciono mi puñalada en una respuesta del 80%. Lamentablemente, no se demuestra una forma nativa. En su lugar, utilizo una combinación profana de llamadas al sistema y programas de línea de comandos que probablemente no sea compatible en todas las plataformas. R llamadas nativas requerirán profundizar en la forma en que los servidores POP3 les gusta hablar con los clientes conectados y una comprensión de SSL que no tengo actualmente. Otras respuestas son aún alentadas.

##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)) 
} 

caso de uso: En pocas palabras, tengo que tener R sea capaz de enviar un mensaje cuyo contenido se determina en el guión R en otro lugar a un servidor SMTP. Los participantes recibirán el correo electrónico y responderán a él. Necesito recuperar su respuesta de mi servidor POP3 y almacenarla en una estructura de datos R para que pueda realizar el procesamiento posterior en ella. En la práctica, estoy estableciendo una forma de hacer un muestreo de experiencia por medio de R. Es decir, R puede enviar un correo electrónico a un participante "¿Cómo estás hoy (1 = malo, 7 = excelente)?" El participante puede responder "4" y puedo hacer coincidir la pregunta formulada, la respuesta, etc. en una base de datos para el análisis estadístico.

+1

similares (pero no una causa duplicado de SSL) http://stackoverflow.com/questions/2885660/how-to-send-email-with-attachment-from-r-in-windows y http://stackoverflow.com/questions/3572607/sendmailr-part2 -sending-files-as-mail-attachments – Marek

+1

¿Qué pasa con el tono de Edit2 y Edit3? ¿Es realmente necesario? –

+2

En una nota al margen, Perl (y por extensión Python) sigue siendo un lenguaje de scripting principal utilizado como back-end para muchos sitios web. Contiene una gran cantidad de funciones para enviar y recibir correos electrónicos (automatizados) (muchas listas de correo aprovechan estas funcionalidades en Perl). También soy programador por necesidad, pero estoy feliz de haber aprendido a trabajar con más de una "herramienta" (es decir, el lenguaje). A largo plazo, parece una mejor forma de hacerlo. Además, Perl y R pueden estar vinculados. O Python fuera de curso, también puede hacerlo. –

Respuesta

11

Tirando de mensajes desde un servidor pop

Para tomar una puñalada en la implementación de @JorisMeys idea de tomar ventaja de otros idiomas, me tomó una puñalada en la tira de correo de Gmail (a través de SSL) utilizando Python y el rJython paquete. Jython es Python implementado en la máquina virtual Java, por lo que usar rJython me parece un poco como usar R para llamar a Java que luego se hace pasar por Python.

Encuentro rJython bastante fácil para cosas simples, pero como no soy muy versado en objetos S4 y (r) Java, a veces me cuesta manipular adecuadamente los objetos de retorno de rJython. Pero funciona. Aquí está una construcción básica que se tire de un único mensaje desde una cuenta de Gmail:

library(rJython) 

rJython <- rJython(modules = "poplib") 

rJython$exec("import poplib") 
rJython$exec("M = poplib.POP3_SSL('pop.gmail.com', 995)") 
rJython$exec("M.user(\'[email protected]\')") 
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 
+0

Gracias por señalarme en esta dirección. Voy a probar esto pronto para ver si averiguo cómo enviar correo usando. Prefiero este enfoque a los hacks de línea de comando que estaba armando. – russellpierce

+0

esto es realmente un gran comienzo. ¿Hay alguna manera de mejorar la respuesta? – IndranilGayen

7

Mire el paquete sendmailR en CRAN.

+2

sendmailR parece enviar solo correo; tampoco es compatible con SSL. – russellpierce

+3

Así que escriba un parche para ello. –

+10

Eso no está dentro de mi conjunto de habilidades. Conozco mis limitaciones y estaba buscando una solución que funcione dentro de ellos. No soy un programador de oficio, soy uno por necesidad. – russellpierce

1

Con el paquete mailR (http://rpremraj.github.io/mailR/), puede enviar mensajes de correo electrónico con SSL:

send.mail(from = "[email protected]", 
      to = c("[email protected]", "[email protected]"), 
      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) 
+0

Aunque mi necesidad inmediata de esto ha pasado, le di un giro al paquete mailR en un sistema Windows 7 x64. Se realizó como se anuncia sin ningún tipo de manipulación de mi parte para que funcione. Me pregunto si lo veremos en CRAN pronto. – russellpierce

+0

... ¿algún plan para implementar una forma de recibir los correos electrónicos? – russellpierce

+1

mailR ya está en CRAN (http://cran.r-project.org/web/packages/mailR/index.html). Consideraré agregar soporte para recibir correos electrónicos en el futuro ... –

Cuestiones relacionadas