使用 Python 请求库以 HTML 格式发送 Mailgun 内联图像

Posted

技术标签:

【中文标题】使用 Python 请求库以 HTML 格式发送 Mailgun 内联图像【英文标题】:Sending Mailgun Inline Images in HTML using Python Requests library 【发布时间】:2013-02-24 08:00:42 【问题描述】:

我无法确定如何使用 Mailgun api 从 Python 应用程序使用 requests 库发送多条内联消息。目前我有(使用 jinja2 作为模板和烧瓶作为 web 框架,托管在 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

所以电子邮件发送正常,但最后电子邮件中没有图像。当我点击下载它们时,它们不显示。根据 mailgun api 在 HTML 中引用图像(当然是简化的!);

<img src="cid:img1.jpg"/>
<img src="cid:img2.jpg"/>
etc ...

显然我做错了什么,但是我尝试使用 requests.files 对象附加这些内容,它甚至没有发送电子邮件并且没有给出错误,所以我认为这根本不是正确的方法。

遗憾的是,这方面的文档相当稀少。

让 HTML 直接指向服务器端图像会更好吗?然而,这并不理想,因为服务器端图像通常不会是静态的(有些会,有些不会)。

【问题讨论】:

【参考方案1】:

发送内联图像记录在 here。

在 HTML 中,您将像这样引用图像:

<html>Inline image here: <img src="cid:test.jpg"></html>

然后,定义一个 Multidict,将文件发布到 API:

files=MultiDict([("inline", open("files/test.jpg"))])

披露,我为 Mailgun 工作。 :)

【讨论】:

我要补充一个事实,即来自 Mailgun 的人回答 SO 问题作为我喜欢使用 Mailgun 的原因 #1024(我已经创办了 2 家公司,并为第三家公司工作,他们都在 Mailgun 上工作) 我刚刚看到 Mailgun 大约一年前提交的一个错误:github.com/kennethreitz/requests/issues/285 Piers - 事实证明... 最新版本的 Requests 不支持 Multidict。 github.com/kennethreitz/requests/issues/1155。我们将更新网站上的文档以更好地解释这一点。现在,我建议这样做:files=[("inline[1]", open("test.jpg")), ("inline[2]", open("test2.jpg"))] 嗯。我想知道为什么“内联”文件仍然使用这种方法显示为附件:\ 如果内联图像是使用 PIL(python 图像库)而不是服务器上的文件创建的,该怎么办?【参考方案2】:

截至 2020 年,此处的实际文档:https://documentation.mailgun.com/en/latest/api-sending.html#examples

我的例子:

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
)

【讨论】:

以上是关于使用 Python 请求库以 HTML 格式发送 Mailgun 内联图像的主要内容,如果未能解决你的问题,请参考以下文章

python发送.xml格式的post请求;

Python+requests库发送接口入参为xml格式的接口请求多测师

Python+requests库发送接口入参为xml格式的接口请求多测师

python接口自动化3-发送post及其他请求

python发送post请求

python/http协议