Pergunta

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 = 'testing@test.co.uk'
    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).

Foi útil?

Solução

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. :)

Outras dicas

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
)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top