shawwwn/uMail

Attachment?

Closed this issue · 3 comments

Is there an easy way add option to send attachment (image)?

Do you know what would be the correct headers to send a jpeg image? I'm sending these, but the jpeg gets distorted, could that be of wrong headers?

smtp.to('aaa@bbb.com')
smtp.write("From: Camera aaa@bbb.com\n")
smtp.write("To: aaa aaa@bbb.com\n")
smtp.write("Subject: Picture\n")
smtp.write("MIME-Version: 1.0\n")
smtp.write("Content-type: multipart/mixed; boundary=12345678900987654321\n")

smtp.write("--12345678900987654321\n")
smtp.write("Content-Type: text/plain; charset=utf-8\n")
smtp.write("Test")
smtp.write("\n")

smtp.write("--12345678900987654321\n")
smtp.write("Content-Type: image/jpeg; name=cam.jpeg\n")
smtp.write("Content-Disposition: attachment; filename="cam.jpeg"\n")

#Jpeg picture from camera buffer
smtp.write(buf)

smtp.write("\n")
smtp.write("--12345678900987654321--")
smtp.send()

pm4r commented

Image should be base64 encoded. I made utility function to send email with optional attachment. Looks messy but works as expected.

import umail
import ubinascii
import urandom as random

smtp_config = {'host' : 'xxx',
                'port' : 587,
                'username' : 'yyy',
                'password' : 'zzz'}

def boundary():
    return ''.join(random.choice('0123456789ABCDEFGHIJKLMNOUPQRSTUWVXYZ') for i in range(15))

def send_mail(email, attachment = None):
    smtp = umail.SMTP(**smtp_config)
    smtp.to(email['to'])
    smtp.write("From: {0} <{0}>\n".format(email.get('from', smtp_config['username'])))
    smtp.write("To: {0} <{0}>\n".format(email['to']))
    smtp.write("Subject: {0}\n".format(email['subject']))
    if attachment:
        text_id = boundary()
        attachment_id = boundary()
        smtp.write("MIME-Version: 1.0\n")
        smtp.write('Content-Type: multipart/mixed;\n boundary="------------{0}"\n'.format(attachment_id))
        smtp.write('--------------{0}\nContent-Type: multipart/alternative;\n boundary="------------{1}"\n\n'.format(attachment_id, text_id))
        smtp.write('--------------{0}\nContent-Type: text/plain; charset=utf-8; format=flowed\nContent-Transfer-Encoding: 7bit\n\n{1}\n\n--------------{0}--\n\n'.format(text_id, email['text']))
        smtp.write('--------------{0}\nContent-Type: image/jpeg;\n name="{1}"\nContent-Transfer-Encoding: base64\nContent-Disposition: attachment;\n  filename="{1}"\n\n'.format(attachment_id, attachment['name']))
        b64 = ubinascii.b2a_base64(attachment['bytes'])
        smtp.write(b64)
        smtp.write('--------------{0}--'.format(attachment_id))
    else:
        smtp.send(email['text'])
    smtp.send()
    smtp.quit()

I use it to send image from esp32-cam like this:

send_mail({'to': 'my@email', 'subject': 'Message from camera', 'text': 'check this out'},
          {'bytes' : camera.capture(), 'name' : 'img.jpeg'})

@pm4r Thanks a lot! Indeed, that was my problem. When I encode with base64, all goes well as expected.