Отправить вложение в R с помощью gmail

Я хочу отправить электронное письмо в R с вложением с помощью gmail. Я обнаружил , что sendmailR не работает с gmail, потому что он требует аутентификации (я не мог заставить его работать с gmail, поэтому я предполагаю, что это правда, если кто-то не скажет мне, что я ошибаюсь, и в этом случае я опубликую вывод R и сообщение об ошибке для этого). Я нашел фрагмент кода здесь (ссылка). Поскольку сайт предполагает, что код не отформатирован для отправки вложений, но я получил его для отправки электронная почта. Я хотел бы расширить этот код для отправки вложений (в переписке по электронной почте автор этого кода не смог расширить код для отправки вложений).

Я хочу отправлять электронные письма с помощью R с помощью gmail. Я пользователь windows 7 С бета-версией 2.14 R.

код, который отправляет электронные письма, но не вложения:

require(rJython) 
rJython <- rJython() 
rJython$exec( "import smtplib" ) 
rJython$exec("from email.MIMEText import MIMEText") 
rJython$exec("import email.utils") 

mail<-c( 
#Email settings 
"fromaddr = 'bigbird@gmail.com'", 
"toaddrs  = 'oscarthegrouch@gmail.com'", 
"msg = MIMEText('This is the body of the message.')", 
"msg['From'] = email.utils.formataddr(('sender name', fromaddr))", 
"msg['To'] = email.utils.formataddr(('recipient name', toaddrs))", 
"msg['Subject'] = 'Simple test message'", 

#SMTP server credentials 
"username = 'bigbird@gmail.com'", 
"password = 'pw'", 

#Set SMTP server and send email, e.g., google mail SMTP server 
"server = smtplib.SMTP('smtp.gmail.com:587')", 
"server.ehlo()", 
"server.starttls()", 
"server.ehlo()", 
"server.login(username,password)", 
"server.sendmail(fromaddr, toaddrs, msg.as_string())", 
"server.quit()") 

jython.exec(rJython,mail) 

обратите внимание, что это сообщение перекрестно опубликовано на talkstats.com - ... Я не получил ответа там (просто члены говорят мне, что они хотят, чтобы они может помочь.) Если я получу работоспособное решение, я также опубликую его там.

8 ответов


вы используете код Jython внутри своей среды R, поэтому вы ищете способ отправить вложение с помощью языка Jython, а не R.

поскольку Jython в основном Python, вот способ отправить электронное письмо с вложением с Python:как отправить вложения электронной почты с помощью Python.

вам просто нужно будет взломать этот код в свой.


найден ответ, который работает и работает хорошо here:
http://r.789695.n4.nabble.com/Email-out-of-R-code-td3530671.html

спасибо nutterb за ответ из списка rhelp. Спасибо всем, кто пытался мне помочь и был терпелив с моим незнанием python.


Вариант 1: Для sendmailR, похоже, у вас возникли проблемы с добавлением порта 25. Вы должны иметь возможность указать порт назначения через sendmail_options(smtpPort = 587) перед использованием .

Я не уверен, что это решит ваши другие проблемы, но он должен получить правильный порт.


Вариант 2: если вы хотите вызвать скрипт Python, этот выглядит наиболее актуальным. Вы можете найти, что проще всего сделать замену токена, т. е. возьмите базовый скрипт, поместите строки, которые вы просто найдете (т. е. токены) и замените (т. е. подстановку нужных строк), а затем выполните пересмотренный скрипт.

например, используя скрипт по ссылке выше (сохраненный в локальном каталоге как "sendmail_base.py):

BasePy  = scan("sendmail_base.py", what = "character", sep = "\n")
OutPy = gsub("your_email@gmail.com", "yourRealEmailAddress", InFile)
OutPy = gsub("your_password", "yourRealPassword", OutFile)

и так далее, заменяя заголовок, получателя и т. д., с текстовыми строками, которые вы хотите использовать, и то же самое для спецификации имени файла вложения. Наконец, вы можете сохранить выведите в новый файл Python и выполните его:

cat(OutPy, file = "sendmail_new.py", sep = "\n")
system("chmod u+x sendmail_new.py; ./sendmail_new.py")

хотя это очень наивный подход, он прост и отладка скрипта включает в себя только изучение того, работает ли ваша выходная программа Python и генерирует ли R правильную выходную программу Python. Это контрастирует с отладкой того, что происходит с передачей объектов R В и из различных пакетов и языков.


я наткнулся на этот код сегодня из rhelp listserve. Может быть, это поможет:

send.email <- function(to, from, subject, message, attachment=NULL, username, password,
                   server="smtp.gmail.com:587", confirmBeforeSend=TRUE){
 # to: a list object of length 1. Using list("Recipient" ="recip@somewhere.net")       will     send the message to the address but
 # the name will appear instead of the address.
 # from: a list object of length 1. Same behavior as 'to'
 # subject: Character(1) giving the subject line.
 # message: Character(1) giving the body of the message
 # attachment: Character(1) giving the location of the attachment
 # username: character(1) giving the username. If missing and you are using Windows, R     will prompt you for the username.
 # password: character(1) giving the password. If missing and you are using Windows, R     will prompt you for the password.
 # server: character(1) giving the smtp server.
 # confirmBeforeSend: Logical. If True, a dialog box appears seeking confirmation         before sending the e-mail. This is to
 # prevent me to send multiple updates to a collaborator while I am working interactively.

 if (!is.list(to) | !is.list(from)) stop("'to' and 'from' must be lists")
 if (length(from) > 1) stop("'from' must have length 1")
 if (length(to) >  1) stop("'send.email' currently only supports one recipient e-mail     address")
 if (length(attachment) > 1) stop("'send.email' can currently send only one attachment")
 if (length(message) > 1){
 stop("'message' must be of length 1")
 message <- paste(message, collapse="\n\n")
 }

 if (is.null(names(to))) names(to) <- to
 if (is.null(names(from))) names(from) <- from
 if (!is.null(attachment)) if (!file.exists(attachment)) stop(paste("'",
attachment, "' does not exist!", sep=""))

 if (missing(username)) username <- winDialogString("Please enter your
e-mail username", "")
 if (missing(password)) password <- winDialogString("Please enter your
e-mail password", "")

 require(rJython)
 rJython <- rJython()

 rJython$exec("import smtplib")
 rJython$exec("import os")
 rJython$exec("from email.MIMEMultipart import MIMEMultipart")
 rJython$exec("from email.MIMEBase import MIMEBase")
 rJython$exec("from email.MIMEText import MIMEText")
 rJython$exec("from email.Utils import COMMASPACE, formatdate")
 rJython$exec("from email import Encoders")
 rJython$exec("import email.utils")

 mail<-c(
 #Email settings
 paste("fromaddr = '", from, "'", sep=""),
 paste("toaddrs = '", to, "'", sep=""),
 "msg = MIMEMultipart()",
 paste("msg.attach(MIMEText('", message, "'))", sep=""),
 paste("msg['From'] = email.utils.formataddr(('", names(from), "',
fromaddr))", sep=""),
 paste("msg['To'] = email.utils.formataddr(('", names(to), "',
toaddrs))",
sep=""), 
 paste("msg['Subject'] = '", subject, "'", sep=""))

 if (!is.null(attachment)){
 mail <- c(mail,
 paste("f = '", attachment, "'", sep=""),
 "part=MIMEBase('application', 'octet-stream')",
 "part.set_payload(open(f, 'rb').read())",
 "Encoders.encode_base64(part)",
 "part.add_header('Content-Disposition', 'attachment;
filename=\"%s\"' %
os.path.basename(f))",
 "msg.attach(part)")
 }

#SMTP server credentials
 mail <- c(mail, 
 paste("username = '", username, "'", sep=""),
 paste("password = '", password, "'", sep=""),

#Set SMTP server and send email, e.g., google mail SMTP server
 paste("server = smtplib.SMTP('", server, "')", sep=""),
 "server.ehlo()",
 "server.starttls()",
 "server.ehlo()",
 "server.login(username,password)",
 "server.sendmail(fromaddr, toaddrs, msg.as_string())",
 "server.quit()")

 message.details <-
 paste("To: ", names(to), " (", unlist(to), ")", "\n",
 "From: ", names(from), " (", unlist(from), ")",
"\n",
 "Using server: ", server, "\n",
 "Subject: ", subject, "\n",
 "With Attachments: ", attachment, "\n",
 "And the message:\n", message, "\n", sep="")

 if (confirmBeforeSend)
 SEND <- winDialog("yesnocancel", paste("Are you sure you want to send
this e-mail to ", unlist(to), "?", sep=""))
 else SEND <- "YES"

 if (SEND %in% "YES"){
 jython.exec(rJython,mail)
 cat(message.details)
 }
     else cat("E-mail Delivery was Canceled by the User")

Теперь я попробую:

x<-paste(getwd(),"/Eercise 6.doc",sep="")
send.email(list("bigbird@gmail.com"), list("bigbird@gmail.com"), 'dogs', 
            'I sent it!', attachment=x, 'bigbird@gmail.com', 'mypassword',
                       server="smtp.gmail.com:587", confirmBeforeSend=FALSE)

И ОШИБКА:

> x<-paste(getwd(),"/Eercise 6.doc",sep="")
>send.email(list("bigbird@gmail.com"), list("bigbird@gmail.com"), 'dogs', 
+            'I sent it!', attachment=x, 'bigbird@gmail.com', 'mypassword',
+                       server="smtp.gmail.com:587", confirmBeforeSend=FALSE)
Error in .jcall("RJavaTools", "Ljava/lang/Object;", "invokeMethod", cl,  : 
  SyntaxError: ("mismatched character '\n' expecting '''", ('<string>', 15,  
      52, "\tpart.add_header('Content-Disposition', 'attachment;\n"))

взгляните на пакет sendmailR, который может отправлять вложения. Сделать sendmail работа с gmail на Mac потребует некоторых дополнительных возиться, но вы можете найти инструкции, чтобы сделать это с помощью поиска google.


вы можете дать новому пакету mailR снимок, который позволяет авторизацию SMTP:http://rpremraj.github.io/mailR/

затем должен работать следующий вызов:

27/05/14: пример редактирования ниже, чтобы продемонстрировать, как вложения могут быть отправлены через R:

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"),
          file.names = c("Download log", "Upload log"), # optional parameter
          file.descriptions = c("Description for download log", "Description for upload log"))

для работы с Gmail с помощью R Лучший рабочий пример доступен здесь. Это основное, как показано ниже:

  1. проект в консоли разработчиков Google для управления использованием API Gmail

  2. пакет gmailr R от Jim Hester, который обертывает API Gmail (разработка на GitHub)

  3. пакеты plyr и dplyr для обработки данных (сделайте это с базой R, Если вы предпочитаю)

  4. адреса.csv файл, содержащий адреса электронной почты, идентифицированные ключом. В нашем случае-имена студентов.

  5. метки.csv файл, содержащий переменные биты письма, которое вы планируете отправить, включая тот же идентифицирующий ключ, что и выше. В нашем случае, домашние задания.

  6. скрипт send-email-with-r.r


вставка здесь для удобства кода из one ссылке выше

send.email <- function(to, from, subject,
  message, attachment=NULL,
  username, password,
  server="smtp.gmail.com:587",
  confirmBeforeSend=TRUE){
  # to: a list object of length 1.  Using list("Recipient" = "recip@somewhere.net") will send the message to the address but
  #     the name will appear instead of the address.
  # from: a list object of length 1.  Same behavior as 'to'
  # subject: Character(1) giving the subject line.
  # message: Character(1) giving the body of the message
  # attachment: Character(1) giving the location of the attachment
  # username: character(1) giving the username.  If missing and you are using Windows, R will prompt you for the username.
  # password: character(1) giving the password.  If missing and you are using Windows, R will prompt you for the password.
  # server: character(1) giving the smtp server.
  # confirmBeforeSend: Logical.  If True, a dialog box appears seeking confirmation before sending the e-mail.  This is to
  #                    prevent me to send multiple updates to a collaborator while I am working interactively.  

  if (!is.list(to) | !is.list(from)) stop("'to' and 'from' must be lists")
  if (length(from) > 1) stop("'from' must have length 1")
  if (length(to) > 1) stop("'send.email' currently only supports one recipient e-mail address")
  if (length(attachment) > 1) stop("'send.email' can currently send only one attachment")
  if (length(message) > 1){
    stop("'message' must be of length 1")
    message <- paste(message, collapse="\n\n")
  }

  if (is.null(names(to))) names(to) <- to
  if (is.null(names(from))) names(from) <- from
  if (!is.null(attachment)) if (!file.exists(attachment)) stop(paste("'", attachment, "' does not exist!", sep=""))

  if (missing(username)) username <- winDialogString("Please enter your e-mail username", "")
  if (missing(password)) password <- winDialogString("Please enter your e-mail password", "")

  require(rJython)
  rJython <- rJython()

  rJython$exec("import smtplib")
  rJython$exec("import os")
  rJython$exec("from email.MIMEMultipart import MIMEMultipart")
  rJython$exec("from email.MIMEBase import MIMEBase")
  rJython$exec("from email.MIMEText import MIMEText")
  rJython$exec("from email.Utils import COMMASPACE, formatdate")
  rJython$exec("from email import Encoders")
  rJython$exec("import email.utils")

  mail<-c(
  #Email settings
  paste("fromaddr = '", from, "'", sep=""),
  paste("toaddrs  = '", to, "'", sep=""),
  "msg = MIMEMultipart()",
  paste("msg.attach(MIMEText('", message, "'))", sep=""),
  paste("msg['From'] = email.utils.formataddr(('", names(from), "', fromaddr))", sep=""),
  paste("msg['To'] = email.utils.formataddr(('", names(to), "', toaddrs))", sep=""),
  paste("msg['Subject'] = '", subject, "'", sep=""))

  if (!is.null(attachment)){
    mail <- c(mail,
      paste("f = '", attachment, "'", sep=""),
     "part=MIMEBase('application', 'octet-stream')",
     "part.set_payload(open(f, 'rb').read())",
     "Encoders.encode_base64(part)",
     "part.add_header('Content-Disposition', 'attachment; filename=\"%s\"' % os.path.basename(f))",
     "msg.attach(part)")
  }

#SMTP server credentials
  mail <- c(mail,
    paste("username = '", username, "'", sep=""),
    paste("password = '", password, "'", sep=""),

#Set SMTP server and send email, e.g., google mail SMTP server
    paste("server = smtplib.SMTP('", server, "')", sep=""),
    "server.ehlo()",
    "server.starttls()",
    "server.ehlo()",
    "server.login(username,password)",
    "server.sendmail(fromaddr, toaddrs, msg.as_string())",
    "server.quit()")

  message.details <-
    paste("To:               ", names(to), " (", unlist(to), ")", "\n",
          "From:             ", names(from), " (", unlist(from), ")", "\n",
          "Using server:     ", server, "\n",
          "Subject:          ", subject, "\n",
          "With Attachments: ", attachment, "\n",
          "And the message:\n", message, "\n", sep="")

  if (confirmBeforeSend)
   SEND <- winDialog("yesnocancel", paste("Are you sure you want to send this e-mail to ", unlist(to), "?", sep=""))
   else SEND <- "YES"

  if (SEND %in% "YES"){
    jython.exec(rJython,mail)
    cat(message.details)
  }
  else cat("E-mail Delivery was Canceled by the User")
}