2016-11-19 6 views
2

Я использую код на основе фрагмента на http://datamakessense.com/easy-scheduled-emailing-with-python-for-typical-bi-needs/, чтобы отправлять PDF-приложения клиентам через электронную почту моей компании. Мы отправляем около 100 из них за один раз по одному адресу электронной почты («[email protected]»), и для каждого отправленного письма я отправляю копию BCC на внутренний адрес электронной почты («reports @ companyname.com ").SMTPlib Вложения не получены

Время от времени (около 5 из 100) клиент не получает вложение. Иногда он вообще не отображается, и иногда он показывает красным вопросительным знаком. Тем не менее, копия BCC всегда имеет приложение без каких-либо проблем и, входя в отправляющую учетную запись, отправленная копия электронной почты всегда показывает вложение, также без проблем. В письмах клиентов нет заметных сходств, которые не получили вложения (например, общий домен, на самом деле, большинство из них - gmail.com). Нет никаких исключений или ошибок для отчета. Все выглядит так, как будто оно правильно работает.

Это мой первый опыт работы с MIME или автоматизацией электронной почты через Python, но тот факт, что он работает 98% времени, меня сбивает с толку. Известны ли причины, почему это может произойти? Может быть, я не правильно задаю тип? Или есть что-то особенное, что я должен делать с MIME для 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

Sending около 100 вложений в электронной почте не используется то, что каждый чтобы делать каждый день, вы проверяли, нет ли ограничений на стороне сервера SMTP Google?

Эти следующие вопросы относятся к «лимитам отправки Gmail в G Suite», но, на мой взгляд, существуют аналогичные правила, применяемые к любой другой учетной записи 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

Я фактически уже назвал Google (я платный/бизнес-пользователь) о лимитах, и они разрешают несколько тысяч электронных писем в день через реле. – Xodarap777