2016-11-19 124 views
2

我一直在使用基於代碼片段的代碼http://datamakessense.com/easy-scheduled-emailing-with-python-for-typical-bi-needs/通過我公司的電子郵件向客戶發送PDF附件。我們通過一個電子郵件地址(「[email protected]」)一次發送約100封郵件,並且對於發送的每封電子郵件,我還會將密件抄送副本發送到內部電子郵件地址(「報告@ companyname.com「)。未收到SMTPlib附件

有時候(100箇中大約有5個),客戶報告沒有收到附件。有時它根本不顯示,有時會顯示一個紅色的問號。但是,BCC副本始終有附件沒有問題,並進入發送帳戶,發送的電子郵件副本始終顯示附件,也沒有問題。沒有收到附件的客戶電子郵件中沒有明顯的相似之處(例如共享域;實際上,大多數是@ gmail.com)。沒有例外或錯誤需要報告。一切看起來好像正常工作。

這是我第一次使用MIME或通過Python自動化電子郵件,但98%的時間正在工作的事實讓我感到困惑。有沒有已知的原因可能會發生這種情況?也許我沒有正確設置類型?或者有什麼特別的我可以用MIME for Gmail做什麼?

這裏是我的代碼:

wdir = 'PDFs\\' 
filelist = [] 
for file in os.listdir(wdir): 
    if file.endswith('.pdf'): 
     filelist += [wdir + file] # sending all of the PDFs in a local directory 

email = {} 
rf = wdir + 'Reports_data.csv' # get email addresses for customers by ID (row[2]) 
with open(rf, 'rbU') as inf: 
    read = csv.reader(inf) 
    read.next() 
    for row in read: 
     email[row[2]] = row[3] 

hfi = open('HTML\\email.html', 'rb') # the HTML for the email body, itself 
htmltxt = hfi.read() 
hfi.close() 


class Bimail: 
    def __init__(self, subject, recipients): 
     self.subject = subject 
     self.recipients = recipients 
     self.htmlbody = '' 
     self.sender = "[email protected]" 
     self.senderpass = 'password' 
     self.attachments = [] 

    def send(self): 
     msg = MIMEMultipart('alternative') 
     msg['From'] = self.sender 
     msg['Subject'] = self.subject 
     msg['To'] = self.recipients[0] 
     msg.preamble = "preamble goes here" 
     if self.attachments: 
      self.attach(msg) 
     msg.attach(MIMEText(self.htmlbody, 'html')) 
     s = smtplib.SMTP('smtp.gmail.com:587') 
     s.starttls() 
     s.login(self.sender, self.senderpass) 
     s.sendmail(self.sender, self.recipients, msg.as_string()) 
     s.quit() 

    def htmladd(self, html): 
     self.htmlbody = self.htmlbody + '<p></p>' + html 

    def attach(self, msg): 
     for f in self.attachments:  
      ctype, encoding = mimetypes.guess_type(f) 
      if ctype is None or encoding is not None: 
       ctype = "application/octet-stream" 
      maintype, subtype = ctype.split("/", 1) 
      fn = f.replace(wdir, '') 
      fp = open(f, "rb") 
      attachment = MIMEBase(maintype, subtype) 
      attachment.set_payload(fp.read()) 
      fp.close() 
      encoders.encode_base64(attachment) 
      attachment.add_header("Content-Disposition", "attachment", filename=fn) 
      attachment.add_header('Content-ID', '<{}>'.format(f)) # or should this be format(fn)? 
      msg.attach(attachment) 

    def addattach(self, files): 
     self.attachments = self.attachments + files 


if __name__ == '__main__': 
    for fi in filelist: 
     code = fi.split('_')[1].split('\\')[1] # that "ID" for email is in the filename 
     addr = email[code] 
     mymail = Bimail(('SUBJECT HERE'), [addr, '[email protected]']) 
     mymail.htmladd(htmltxt) 
     mymail.addattach([fi]) 
     mymail.send() 

回答

2

試試這個代碼塊:

import smtplib 
from email.MIMEMultipart import MIMEMultipart 
from email.MIMEText import MIMEText 
from email.MIMEBase import MIMEBase 
from email import encoders 

fromaddr = "[email protected]" 
password = "password" 
toaddr = "[email protected]" 

msg = MIMEMultipart() 

msg['From'] = fromaddr 
msg['To'] = toaddr 
msg['Subject'] = "Report" 

body = "Hi, have a look at the Report" 

msg.attach(MIMEText(body, 'plain')) 

filename = "Report.pdf" 
attachment = open("Report.pdf", "rb") 

part = MIMEBase('application', 'octet-stream') 
part.set_payload((attachment).read()) 
encoders.encode_base64(part) 
part.add_header('Content-Disposition', "attachment; filename= %s" % filename) 

msg.attach(part) 

server = smtplib.SMTP('smtp.office365.com', 587) 
server.starttls() 
server.login(fromaddr, "password") 
text = msg.as_string() 
server.sendmail(fromaddr, toaddr, text) 
server.quit() 

它爲我

+0

有一些細微的差別,但它幾乎等同於我在做什麼。就像我說的那樣,我的代碼「也適用於我」 - 絕大多數時間。然而,對於成千上萬的客戶來說,1%的失敗率是一件大事。 – Xodarap777

+0

事實上,這確實有效。我不知道我的原始代碼有什麼問題。我在賞金上遲到了;抱歉。 – Xodarap777

+0

我很高興代碼有幫助。 –

2

接近每電子郵件100名的附件發送不每個人都使用每天做,你檢查有沒有限制在谷歌SMTP服務器端?

以下問題與「G Suite中的Gmail發送限制」有關,但我認爲其他任何gmail帳戶都有類似的規則。

https://support.google.com/a/answer/2956491#sendinglimitsforrelay

https://support.google.com/a/answer/166852?hl=en

請參見下文我的sendmail的功能:

def sendMail(to, subject, text, files=[],server="smtp.gmail.com:587",username="contact.name",password="mygmailurrentpassord"): 
    assert type(to)==list 
    assert type(files)==list 
    fro = "Contact Name <[email protected]>" 
    msg = MIMEMultipart() 
    msg['From'] = fro 
    msg['To'] = COMMASPACE.join(to) 
    msg['Date'] = formatdate(localtime=True) 
    msg['Subject'] = subject 
    msg.attach(MIMEText(text))  
    for file in files: 
     part = MIMEBase('application', "octet-stream") 
     part.set_payload(open(file,"rb").read()) 
     Encoders.encode_base64(part) 
     part.add_header('Content-Disposition', 'attachment; filename="%s"' 
         % os.path.basename(file)) 
     msg.attach(part)  
    smtp = smtplib.SMTP(server) 
    smtp.starttls() 
    smtp.login(username,password) 
    smtp.sendmail(fro, to, msg.as_string()) 
    smtp.close() 

問候

+0

我實際上已經打電話給谷歌(我是一個付費/商業用戶)關於限制,他們每天允許通過中繼數千封電子郵件。 – Xodarap777