Отправить вложение в 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.
Вам просто нужно будет взломать этот код вместе с вашим.
Ответ, который работает и работает хорошо, находится здесь:
http://r.789695.n4.nabble.com/Email-out-of-R-code-td3530671.htmlСпасибо nutterb за ответ из списка rhelp. Спасибо всем, кто пытался мне помочь и терпеливо относился к моему незнанию питона.
Вариант 1: для
Я не уверен, что это решит ваши другие проблемы, но это должно дать вам правильный порт.sendmailR
, похоже, что у вас возникли проблемы с добавлением порта 25. Вы должны иметь возможность указать порт назначения черезsendmail_options(smtpPort = 587)
, прежде чем использовать командуsendmail()
.
Вариант 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 и выполнить это:
Хотя это очень наивный подход, он прост, и отладка скрипта включает в себя только проверку того, работает ли ваша выходная программа Python и генерирует ли R правильную выходную программу Python. Это противоречит отладке того, что происходит с R, передавая объекты в различные пакеты и языки и из них.cat(OutPy, file = "sendmail_new.py", sep = "\n") system("chmod u+x sendmail_new.py; ./sendmail_new.py")
Сегодня я наткнулся на этот код из 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 Лучший рабочий пример доступен здесь. Это основное, как показано ниже:
Проект в консоли разработчиков Google для управления использованием API Gmail
Пакет gmailr R от Джима Хестера, который обертывает Gmail API (разработка на GitHub)
Пакеты plyr и dplyr для обработки данных (сделайте это с базой R, Если хотите)
Адреса.csv файл, содержащий адреса электронной почты, идентифицированные с помощью ключа. В нашем случае-имена студентов.
Отметины.csv-файл, содержащий переменные биты электронной почты, которую вы планируете отправить, включая тот же идентификационный ключ, что и выше. В нашем случае это отметки за домашнее задание.
Скрипт send-email-with-r.r
Вставляем сюда для удобства код из одной ссылки выше
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") }