I am having trouble working out how I can send multiple inline messages using the Mailgun api, from a Python app using the requests library. Currently I have (using jinja2 for templates and flask as the webframework, hosted on Heroku):
def EmailFunction(UserEmail):
Sender = '[email protected]'
Subject = 'Hello World'
Text = ''
name = re.sub('@.*','',UserEmail)
html = render_template('GenericEmail.html', name=name)
images = []
imageloc = os.path.join(dirname, 'static')
images.append(open(os.path.join(imageloc,'img1.jpg')))
images.append(open(os.path.join(imageloc,'img2.jpg')))
send_mail(UserEmail,Sender,Subject,Text,html,images)
return html
def send_mail(to_address, from_address, subject, plaintext, html, images):
r = requests.\
post("https://api.mailgun.net/v2/%s/messages" % app.config['MAILGUN_DOMAIN'],
auth=("api", app.config['MAILGUN_KEY']),
data={
"from": from_address,
"to": to_address,
"subject": subject,
"text": plaintext,
"html": html,
"inline": images
}
)
return r
So the email sends fine, but no images are in the email at the end. When I click to download them they don't show. The images are referenced in the HTML as per the mailgun api (simplified of course!);
<img src="cid:img1.jpg"/>
<img src="cid:img2.jpg"/>
etc ...
Clearly I am doing something wrong, however I tried attaching these using the requests.files object, which didn't even send the email and gave no error so I assume that is not the right way at all.
Sadly the documentation on this is rather sparse.
Would it be better to have the HTML directly point the server side images? However this is not ideal as server side images in general will not be static (some will, some won't).
As of 2020, actual documentation here: https://documentation.mailgun.com/en/latest/api-sending.html#examples
My example:
response = requests.post(
'https://api.mailgun.net/v3/' + YOUR_MAILGUN_DOMAIN_NAME + '/messages',
auth=('api', YOUR_MAILGUN_API_KEY),
files=[
('inline[0]', ('test1.png', open('path/filename1.png', mode='rb').read())),
('inline[1]', ('test2.png', open('path/filename2.png', mode='rb').read()))
],
data={
'from': 'YOUR_NAME <' + 'mailgun@' + YOUR_MAILGUN_DOMAIN_NAME + '>',
'to': [adresat],
'bcc': [bcc_adresat],
'subject': 'email subject',
'text': 'email simple text',
'html': '''<html><body>
<img src="cid:test1.png">
<img src="cid:test2.png">
</body></html>'''
},
timeout=5 # sec
)
Sending Inline Images is documented here.
In the HTML, you'll reference the image like this:
<html>Inline image here: <img src="cid:test.jpg"></html>
Then, define a Multidict, to post the files to the API:
files=MultiDict([("inline", open("files/test.jpg"))])
Disclosure, I work for Mailgun. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With