Ответ 1
Ответ, который работает и работает хорошо, можно найти здесь:
http://r.789695.n4.nabble.com/Email-out-of-R-code-td3530671.html
Спасибо nutterb за ответ из списка rhelp. Спасибо всем, кто пытался помочь мне, и терпели свое незнание питона.
Я желаю отправить электронное письмо в R с вложением с помощью gmail. Я обнаружил, что sendmailR не работает с gmail, потому что он требует аутентификации (я не мог заставить его работать с gmail, поэтому я предполагаю, что это правда, если кто-то не говорит мне, что я ошибаюсь, и в этом случае я опубликую R выход и сообщение об ошибке). Я нашел фрагмент кода, найденный здесь (LINK). Поскольку сайт предлагает, что код не отформатирован для отправки вложений, но у меня есть его, чтобы отправить электронное письмо. Я хотел бы расширить этот код для отправки вложений (в электронной почте автору этого кода не удалось расширить код для отправки вложений).
Я хочу отправить электронные письма с помощью R, используя gmail. Я пользователь Windows 7 с бета-версией версии 2.14.
Код, отправляющий электронные письма, но не вложения:
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 = '[email protected]'",
"toaddrs = '[email protected]'",
"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 = '[email protected]'",
"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. Я не получил ответа там (просто участники сказали мне, что они хотели бы помочь). Если я получу работоспособное решение, я также опубликую его там.
Ответ, который работает и работает хорошо, можно найти здесь:
http://r.789695.n4.nabble.com/Email-out-of-R-code-td3530671.html
Спасибо nutterb за ответ из списка rhelp. Спасибо всем, кто пытался помочь мне, и терпели свое незнание питона.
Вы используете код Jython внутри среды R, поэтому вы ищете способ отправки вложения с использованием языка Jython, а не R.
Так как Jython - это в основном Python, вот способ отправить электронное письмо с вложением с Python: Как отправить вложения электронной почты с помощью Python.
Вам просто нужно взломать этот код в ваш.
Вариант 1: для sendmailR
кажется, что у вас возникли проблемы с добавлением порта 25. Вы должны иметь возможность указать порт назначения через sendmail_options(smtpPort = 587)
, прежде чем использовать команду sendmail()
.
Я не уверен, что это решит ваши другие проблемы, но он должен получить правильный порт.
Вариант 2: если вы хотите вызвать Python script, этот выглядит наиболее актуальным. Вы можете с легкостью сделать замену токена, т.е. Взять базу script, поместить строки, которые вы просто найдете (то есть, токены), и замените (то есть подстановку на нужные строки), а затем выполните пересмотренный script.
Например, используя script по ссылке выше (сохраненной в локальном каталоге как "sendmail_base.py" ):
BasePy = scan("sendmail_base.py", what = "character", sep = "\n")
OutPy = gsub("[email protected]", "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")
Хотя это очень наивный подход, он прост, и отладка script включает в себя только проверку того, работает ли ваша выходная программа Python и независимо от того, генерирует ли R правильную выходную программу Python. Это контрастирует с отладкой того, что происходит с объектами, проходящими мимо R, в различные пакеты и языки и из них.
Сегодня я нашел этот код из списка rhelp. Возможно, это поможет вам:
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" ="[email protected]") 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("[email protected]"), list("[email protected]"), 'dogs',
'I sent it!', attachment=x, '[email protected]', 'mypassword',
server="smtp.gmail.com:587", confirmBeforeSend=FALSE)
И ОШИБКА:
> x<-paste(getwd(),"/Eercise 6.doc",sep="")
>send.email(list("[email protected]"), list("[email protected]"), 'dogs',
+ 'I sent it!', attachment=x, '[email protected]', '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 = "[email protected]",
to = c("[email protected]", "[email protected]"),
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 Developers Console для управления использованием API Gmail
пакет gmailr R от Jim Hester, который обертывает API Gmail (разработка на GitHub)
пакеты plyr и dplyr для перебора данных (сделайте это с базой R, если хотите)
address.csv файл, содержащий адреса электронной почты, идентифицированные ключом. В нашем случае имена студентов.
marks.csv файл, содержащий переменные биты отправляемого вами электронного письма, включая тот же ключ идентификации, что и выше. В нашем случае отметки о домашнем задании.
script 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" = "[email protected]") 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")
}