Gmail Python multiple attachments

前端 未结 3 640
轮回少年
轮回少年 2020-12-16 06:55

I am trying to create a little script that will email multiple attachments using gmail. The code below sends the email but not the attachments. The intended use is to cron a

相关标签:
3条回答
  • 2020-12-16 07:27

    Should have waited another hour before posting. Made 2 changes:

    1.) moved the attachment loop up

    2.) swapped out part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file))

    for part.add_header('Content-Disposition', 'attachment; filename="%s"' % file)

    Works like a champ. Gmail with multiple recipients and multiple attachments.

    import os 
    import smtplib
    from email.MIMEMultipart import MIMEMultipart
    from email.MIMEText import MIMEText
    from email.MIMEImage import MIMEImage
    from email.MIMEBase import MIMEBase
    from email import Encoders
    
    
    #Set up crap for the attachments
    files = "/tmp/test/dbfiles"
    filenames = [os.path.join(files, f) for f in os.listdir(files)]
    #print filenames
    
    
    #Set up users for email
    gmail_user = "joe@email.com"
    gmail_pwd = "somepasswd"
    recipients = ['recipient1','recipient2']
    
    #Create Module
    def mail(to, subject, text, attach):
       msg = MIMEMultipart()
       msg['From'] = gmail_user
       msg['To'] = ", ".join(recipients)
       msg['Subject'] = subject
    
       msg.attach(MIMEText(text))
    
       #get all the attachments
       for file in filenames:
          part = MIMEBase('application', 'octet-stream')
          part.set_payload(open(file, 'rb').read())
          Encoders.encode_base64(part)
          part.add_header('Content-Disposition', 'attachment; filename="%s"' % file)
          msg.attach(part)
    
       mailServer = smtplib.SMTP("smtp.gmail.com", 587)
       mailServer.ehlo()
       mailServer.starttls()
       mailServer.ehlo()
       mailServer.login(gmail_user, gmail_pwd)
       mailServer.sendmail(gmail_user, to, msg.as_string())
       # Should be mailServer.quit(), but that crashes...
       mailServer.close()
    
    #send it
    mail(recipients,
       "Todays report",
       "Test email",
       filenames)
    
    0 讨论(0)
  • 2020-12-16 07:35

    Thanks @marc! I can't comment on your answer, so here are few fixes (misnamed variables) and small improvements:

    import os
    import smtplib
    from email.mime.multipart import MIMEMultipart
    from email.mime.text import MIMEText
    from email import MIMEImage
    from email.mime.base import MIMEBase
    from email import Encoders
    
    def mail(to, subject, text, attach):
        # allow either one recipient as string, or multiple as list
        if not isinstance(to,list):
            to = [to]
        # allow either one attachment as string, or multiple as list
        if not isinstance(attach,list):
            attach = [attach]
    
        gmail_user='username@gmail.com'
        gmail_pwd = "password"
        msg = MIMEMultipart()
        msg['From'] = gmail_user
        msg['To'] = ", ".join(to)
        msg['Subject'] = subject
    
        msg.attach(MIMEText(text))
    
        #get all the attachments
        for file in attach:
            print file
            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)
    
        mailServer = smtplib.SMTP("smtp.gmail.com", 587)
        mailServer.ehlo()
        mailServer.starttls()
        mailServer.ehlo()
        mailServer.login(gmail_user, gmail_pwd)
        mailServer.sendmail(gmail_user, to, msg.as_string())
        # Should be mailServer.quit(), but that crashes...
        mailServer.close()
    
    if __name__ == '__main__':
        mail(['recipient1', 'recipient2'], 'subject', 'body text',
             ['attachment1', 'attachment2'])
    
    0 讨论(0)
  • 2020-12-16 07:43

    I have a similar problem. I am able to send multiple attachments but on my Mac mail app not all attachments appear and html also not appear (on Gmail web all works ok). If someone have the same problem, the code bellow worked for me with python3.8. All attachments and html now appear on mail app.

    https://docs.python.org/3/library/email.examples.html#email-examples

    little updated:

    import os, ssl, sys
    import smtplib
    # For guessing MIME type based on file name extension
    import mimetypes
    from email.message import EmailMessage
    from email.policy import SMTP
    from datetime import datetime
    from uuid import uuid4
    
    directory = '/path/to/files'
    recipients = ['recipient@gmail.com']
    sender = 'username@gmail.com'
    password = 'password'
    email_host, email_port = 'smtp.gmail.com', 465
    
    msg = EmailMessage()
    msg['Subject'] = f'This is a subject {datetime.utcnow()}'
    msg['To'] = ', '.join(recipients)
    msg['From'] = sender
    msg.preamble = f'{str(uuid4())}\n'
    
    msg.add_alternative('This is a PLAIN TEXT', subtype='plain')
    msg.add_alternative('''\
        <html>
        <head></head>
        <body>
            <h4>Hello World! this is HTML </h4>
            <p style="margin: 0;">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
            tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
            quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
            consequat.</p>
        </body>
        </html>''', subtype='html')
    
    for filename in ['sample.pdf', 'sample2.pdf']:
        path = os.path.join(directory, filename)
        if not os.path.isfile(path):
            continue
        # Guess the content type based on the file's extension.  Encoding
        # will be ignored, although we should check for simple things like
        # gzip'd or compressed files.
        ctype, encoding = mimetypes.guess_type(path)
        if ctype is None or encoding is not None:
            # No guess could be made, or the file is encoded (compressed), so
            # use a generic bag-of-bits type.
            ctype = 'application/octet-stream'
        maintype, subtype = ctype.split('/', 1)
        with open(path, 'rb') as fp:
            msg.add_attachment(fp.read(),
                                maintype=maintype,
                                subtype=subtype,
                                filename=filename)
    
    context = ssl.create_default_context()
    with smtplib.SMTP_SSL(email_host, email_port, context=context) as server:
        server.login(sender, password)
        server.send_message(msg)
    
    
    
    
    
    0 讨论(0)
提交回复
热议问题