【问题标题】:How to send an email with attachment from R in windows如何在 Windows 中从 R 发送带有附件的电子邮件
【发布时间】:2011-02-22 13:27:54
【问题描述】:

我有一个从 Windows 机器上运行的预定 R 脚本。

完成后,我希望此脚本能够自动发送附有日志文件的电子邮件。

shell() 与其他一些脚本一起使用可能是可能的,但我想知道在 R 中是否有更好的解决方案。 谢谢。

【问题讨论】:

  • 当你写 shell() 时,我想你的意思是 system()
  • 嗨 Ahala,我希望 Stedy 解决方案会有所帮助。我可能会问,你用什么来安排 R 脚本?谢谢。
  • Tal,在 Windows 中使用计划任务(我认为该条目类似于 R CMD BATCH script.R),在 *NIX 系统上执行 cron。

标签: r email sendmailr


【解决方案1】:

sendmailR 在 Windows 7 上为我工作。我引用了 http://cran.es.r-project.org/web/packages/sendmailR/sendmailR.pdf

smtpServer= Outlook 2010 的信息位于文件 -> 帐户设置 -> 帐户设置 -> 双击您的帐户 -> “服务器”框中的文本

library(sendmailR)

#set working directory
setwd("C:/workingdirectorypath")

#####send plain email

from <- "you@account.com"
to <- "recipient@account.com"
subject <- "Email Subject"
body <- "Email body."                     
mailControl=list(smtpServer="serverinfo")

sendmail(from=from,to=to,subject=subject,msg=body,control=mailControl)

#####send same email with attachment

#needs full path if not in working directory
attachmentPath <- "subfolder/log.txt"

#same as attachmentPath if using working directory
attachmentName <- "log.txt"

#key part for attachments, put the body and the mime_part in a list for msg
attachmentObject <- mime_part(x=attachmentPath,name=attachmentName)
bodyWithAttachment <- list(body,attachmentObject)

sendmail(from=from,to=to,subject=subject,msg=bodyWithAttachment,control=mailControl)

另外,可以通过在msg列表中添加另一个mime_part来发送多个文件,如下(我也压缩过):

attachmentObject <- mime_part(x="subfolder/log.txt",name="log.txt")
attachmentObject2 <- mime_part(x="subfolder/log2.txt",name="log2.txt")
bodyWithAttachment <- list(body,attachmentObject,attachmentObject2)

【讨论】:

  • 你能在“电子邮件正文”中使用html吗?可以使用 utf-8 编码(多语言文本)吗?
  • 我不知道。试试看。
  • 如何为gmail配置serverinfo部分?
  • 我认为 sendmailR 不接受身份验证(用户/密码) - 为此我使用 mailR。
  • @Andreas 你的说法似乎是真的statistik.tu-dortmund.de/~olafm/software/sendmailR
【解决方案2】:

使用mailR - 它适用于身份验证、附件,它会自动发送 txt 消息以及 html 等。

mailR 需要 rJava,这有时会有点痛苦。在windows上我没有任何问题。在 ubuntu 上,这解决了我遇到的一个问题:

sudo apt-get install openjdk-jdk 

在R中

install.packages("devtools", dep = T)
library(devtools)
install_github("rpremraj/mailR")

(如果您在使用 rJava 时遇到问题 - 在终端中尝试 sudo R CMD javareconf

mailR 易于使用,并且在 github 页面上有详细记录。

文档中的示例

library(mailR)
send.mail(from = "sender@gmail.com",
          to = c("recipient1@gmail.com", "recipient2@gmail.com"),
          subject = "Subject of the email",
          body = "Body of the email",
          smtp = list(host.name = "smtp.gmail.com", port = 465, user.name = "gmail_username", passwd = "password", ssl = TRUE),
          authenticate = TRUE,
          send = TRUE,
          attach.files = c("./download.log", "upload.log", "https://dl.dropboxusercontent.com/u/5031586/How%20to%20use%20the%20Public%20folder.rtf"),
          file.names = c("Download log.log", "Upload log.log", "DropBox File.rtf"), # optional parameter
          file.descriptions = c("Description for download log", "Description for upload log", "DropBox File"), # optional parameter
          debug = TRUE)

注意:您的 smtp 服务器可能会发现过度使用可疑。例如,情况就是这样。邮箱因此,在发送了几封邮件后,您可能必须登录gmail account 并查看该帐户是否已被暂时禁用。另请注意,如果您使用带有双重身份验证的 gmail 帐户,则需要使用an application specific password

【讨论】:

  • 也许您可以包含文档中的示例来演示代码的外观。其他答案成功包含示例。
  • @Andreas 对于附件,我尝试使用允许用户选择文件而不是硬编码文件名的 fileInput 函数...但它返回错误Error in file.exists: invalid 'file' argument...有什么想法吗?
【解决方案3】:

你愿意接受 Twitter 消息吗?您可以使用 Rcurl 将更新发布到 twitter,然后可以将其作为文本转发到您的手机,或通过通知设置转发到您的电子邮件。

请看这里:http://www.sakana.fr/blog/2007/03/18/scripting-twitter-with-curl/

【讨论】:

【解决方案4】:

您查看过sendmailR 包了吗?它允许 SMTP 提交消息,您可能可以编辑该功能以允许附件。再说一次,如果它只有一个日志文件,那么就像你提到的那样使用shell() 可能是值得的。

【讨论】:

    【解决方案5】:

    对于 Windows,可能会一起解析一个 VB 脚本(参见例如 http://www.paulsadowski.com/wsh/cdo.htm),然后通过 shell 调用它。

    这可能看起来像这样:

    SendMail <- function(from="me@my-server.de",to="me@my-server.de",text="Hallo",subject="Sag Hallo",smtp="smtp.my.server.de",user="me.myself.and.i",pw="123"){
    require(stringr)
    part1 <- "Const cdoSendUsingPickup = 1 'Send message using the local SMTP service pickup directory. 
    Const cdoSendUsingPort = 2 'Send the message using the network (SMTP over the network). 
    Const cdoAnonymous = 0 'Do not authenticate
    Const cdoBasic = 1 'basic (clear-text) authentication 
    Const cdoNTLM = 2 'NTLM "
    
    part2 <- paste(paste("Set objMessage = CreateObject(",'"',"CDO.Message",'"',")" ,sep=""),
    paste("objMessage.Subject = ",'"',subject,'"',sep=""),
    paste("objMessage.From = ",'"',from,'"',sep=""),
    paste("objMessage.To = ",'"',to,'"',sep=""),
    paste("objMessage.TextBody = ",'"',text,'"',sep=""),
    sep="\n")
    
    part3 <- paste(
    "'==This section provides the configuration information for the remote SMTP server. 
    
    objMessage.Configuration.Fields.Item _ 
    (\"http://schemas.microsoft.com/cdo/configuration/sendusing\") = 2
    
    'Name or IP of Remote SMTP Server 
    objMessage.Configuration.Fields.Item _ 
    (\"http://schemas.microsoft.com/cdo/configuration/smtpserver\") = ",'"',smtp,'"'," 
    
    'Type of authentication, NONE, Basic (Base64 encoded), NTLM 
    objMessage.Configuration.Fields.Item _ 
    (\"http://schemas.microsoft.com/cdo/configuration/smtpauthenticate\") = cdoBasic 
    
    'Your UserID on the SMTP server 
    objMessage.Configuration.Fields.Item _ 
    (\"http://schemas.microsoft.com/cdo/configuration/sendusername\") = ",'"',user,'"'," 
    
    'Your password on the SMTP server 
    objMessage.Configuration.Fields.Item _ 
    (\"http://schemas.microsoft.com/cdo/configuration/sendpassword\") = ",'"',pw,'"', "
    
    'Server port (typically 25) 
    objMessage.Configuration.Fields.Item _ 
    (\"http://schemas.microsoft.com/cdo/configuration/smtpserverport\") = 25 
    
    'Use SSL for the connection (False or True) 
    objMessage.Configuration.Fields.Item _ 
    (\"http://schemas.microsoft.com/cdo/configuration/smtpusessl\") = False 
    
    'Connection Timeout in seconds (the maximum time CDO will try to establish a connection to the SMTP server) 
    objMessage.Configuration.Fields.Item _ 
    (\"http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout\") = 60 
    objMessage.Configuration.Fields.Update
    
    '==End remote SMTP server configuration section== 
    
    objMessage.Send 
    ",sep="")
    
    vbsscript <- paste(part1,part2,part3,sep="\n\n\n")
    str_split(vbsscript,"\n")
    writeLines(vbsscript, "sendmail.vbs")
    shell("sendmail.vbs")
    unlink("sendmail.vbs")
    }
    

    【讨论】:

    • 非常感谢,这就像做梦一样!这是我发现在 R(在 Windows 上)中工作的唯一方法。正如 Paul 的网页中所解释的,如果您使用 gmail,则需要将服务器端口设置为 465,并将“使用 SSL”选项设置为 True。我用下面的代码来调用它:SendMail(from="dag.hjermann@gmail.com",to="dhj@niva.no",text="Hallo", subject="Sag Hallo",smtp="smtp.gmail.com",user="dag.hjermann@gmail.com",pw="********")当然要插入你的真实密码……另外,R的工作目录必须在硬盘(C:)的某个地方。
    • 这太棒了!可以添加附件吗?我的 VB 经验非常有限……所以,这就是我要问的原因。
    • 乐于助人 :-) ... jip,虽然我自己从未尝试过,但似乎可行,请参见此处:paulsadowski.com/wsh/cdo.htm,标题为“发送带有附件的文本电子邮件”...可以在函数中包含相关行。
    【解决方案6】:

    只是想提醒那些想要一个名为 twilio 的服务的自我通知功能的人,他们提供免费服务来向您自己的手机发送短信。此处提供了使用 R 的演练https://dreamtolearn.com/ryan/data_analytics_viz/78

    附上示例代码,只需将凭据替换为您自己的即可。

    library(jsonlite)
    library(XML)
    library(httr)
    library(rjson)
    library(RCurl)
    options(RCurlOptions = list(cainfo = system.file("CurlSSL", "cacert.pem", package = "RCurl")))
    
    authenticate_twilio <- "https://[ACCOUNT SID]:[AUTH TOKEN]@api.twilio.com/2010-04-01/Accounts"
    authenticate_response <- getURL(authenticate_twilio)
    print(authenticate_response)
    
    postForm("https://[ACCOUNT SID]:[AUTH TOKEN]@api.twilio.com/2010-04-01/Accounts/[ACCOUNT SID]/Messages.XML",.params = c(From = "+1[twilio phone#]", To = "+1[self phone#]",Body = "Hello from twilio"))
    

    【讨论】:

      【解决方案7】:

      虽然晚了,但您可以通过正确使用 RDCOMClient 来避免使用 vbscript,如 R-Help 中的this example

      > sendEmail(ema = "r-help at r-project.org", 
              name = "R-help mailing list",
              subject = "How to send Email from R using the RDCOMClient"
              msgBody = "here is the body of the message")
      
      The package RDCOMClient is available at http://www.omegahat.org/RDCOMClient.
      
      "sendEmail" <-
      function(ema, name, subject, msgBody, deliverNow = TRUE)
      {
         require(RDCOMClient)
      
         ema <- paste("SMPT:", ema, sep="")   ## prepend protocol to address
      
         ## create an e-mail session 
         session <- COMCreate("Mapi.Session") 
         session$Logon()
      
         ## add a message to the outbox collection of messages
         outbox <- session[["Outbox"]]
         msg <- outbox[["Messages"]]$Add(subject, msgBody)
      
         ## add recipient's name  (TODO: addMultiple() or loop, if many recipients)
         msg[["Recipients"]]$Add(name, ema) 
         msg$Send()
         if(deliverNow)
            msg$DeliverNow()
      
         session$Logoff()   ## wrap up
      }
      

      【讨论】:

        【解决方案8】:

        这是一个简单的代码sn-p,用于使用“mailR”包发送电子邮件

        library(mailR)
        
        # 1. Sender
        sender <- "x@me.com"
        
        # 2. Recipients
        recipients <- c("y@you.com", "z@our.com")
        
        # 3. Attached files
        list_files_attached_location <- c("mtcars.csv")
        list_files_attached_names <- c("mtcars name")
        list_files_attached_description <- c("mtcars desc")
        
        # 4. Send email
        tryCatch({
          send.mail(from = sender,
                    to = recipients,
                    subject = "Your subject",
                    body = "Your mail body",
                    smtp = list(
                      host.name = "smtp.gmail.com", 
                      port = 465,
                      user.name = sender,
                      passwd = "psw", 
                      ssl = TRUE),
                    authenticate = TRUE,
                    send = TRUE,
                    attach.files = list_files_attached_location,
                    file.names = list_files_attached_names,
                    file.descriptions = list_files_attached_description,
                    debug = TRUE
          )
        }, 
        error = function(e) {
          print(e)
          stop()
        })
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-23
          • 1970-01-01
          • 2015-09-09
          • 2016-07-04
          • 1970-01-01
          相关资源
          最近更新 更多