请原谅我。当我试图研究这个问题时,我最终会看到我根本无法理解的代码。我有大约3个小时的Python经验,我可能尝试的比我能处理的更多。
问题很简单。我可以成功地从R(我的分析软件)调用Python来发送电子邮件。添加消息,主题,来自和我可以执行的字段。我希望能够发送附件。如果我只发送一个附件,生活会很棒。
到目前为止我的代码是
import smtplib
import os
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
import email.utils
fromaddr = 'someone@gmail.com'
toaddrs = 'recipient@gmail.org'
msg = MIMEMultipart(MIMEText('This is the body of the e-mail'))
msg['From'] = email.utils.formataddr(('Benjamin Nutter', fromaddr))
msg['To'] = email.utils.formataddr(('Benjamin Nutter', toaddrs))
msg['Subject'] = 'Simple test message'
f = 'filename.pdf'
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)
"username = 'user'
"password = 'pw'
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()
当我运行此代码时,我收到消息 预期的字符串有效负载:[type'list'](但使用< not [)
我今天的自我学习极限。我希望这对于比我更有经验的人来说是一个明显的解决方案。
我希望你们都过得愉快。
答案 0 :(得分:1)
您可以尝试使用“邮件程序”,而不是尝试直接使用SMTP。可以找到邮件程序here。
以下是一些显示其工作原理的简单代码。
messages=[]
message = mailer.Message()
message.attach('filename.txt')
message.From = 'Cool guy <cool.guy@example.com>'
message.To = 'Random Dude <random.dude@example.com>'
message.Cc = 'Cards Fan <cardsfan@example.com>'
message.Subject = 'Test Email'
message.body = 'Here is the body of the email.'
messages.append(message)
emailer = mailer.Mailer(smtphost.example.com)
emailer.send(messages)
我从本地的一些例子中拼凑了这些。上面链接的邮件页面也显示了其他示例。一旦我找到这个代码,我就转换了所有其他python电子邮件代码来使用这个包。
答案 1 :(得分:0)
我知道回答我自己的问题是不好的形式,但它开始奇迹般地工作,没有任何变化。有什么方法可以给我留下第一印象,对吗?
无论如何,我将它包装成R函数。这将从gmail发送,但我还没有尝试从其他帐户发送它。我最感兴趣的是从Outlook发送,因为我将使用它从我的脚本中发送分析报告。当我进入雇主的SMTP服务器时,它给出了错误“服务器不支持SMTP AUTH扩展”。我怀疑我必须和我的技术支持人员合作。
这可能只适用于Windows,这要归功于winDialog()函数。但这是一个好的开始。
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")
}