【发布时间】:2022-12-09 03:59:32
【问题描述】:
我们的网络应用程序通过 python 的 smtplib 发送格式良好的消息(包括一些嵌入的图像)。这些消息是使用 python 的 email.message.EmailMessage 类生成的,如下面的代码所示。
10 月初,Microsoft deprecated support for Basic Auth 在他们的 Office365 电子邮件帐户中。我们一直在使用 Basic Auth,现在需要找到一个新的解决方案。在struggling with getting OAuth2 working for some time 之后,我们决定重构并改用Microsoft Graph API。
奇怪的是,尽管 Graph API 站点上的大多数示例都包含多语言(HTTP / C# / Javascript / PHP 等)示例,但用于发送具有 MIME 格式的电子邮件的示例(Examlpe 4)只有一个 HTTP 示例。
我们想知道是否可以使用图形 API 发送我们使用 python.email.EmailMessage 构建的电子邮件,如果可以,如何发送。
下面是一些示例代码,显示了我们之前所做的以及我们现在正在尝试获得的内容。
当我们运行代码时,我们得到错误
'{"error":{"code":"RequestBodyRead","message":"Requested value \'text/plain\' was not found."}}'
import smtplib
from email.utils import formatdate
from email.message import EmailMessage
import requests
server = 'smtp.office365.com' # for exampler
port = 587 # for example
from_mail = 'levrai@ninjane.er'
to_mail = 'desti@nati.on'
subject = 'Demo sending the old way!'
password = 'not_so_Secur3!'
message_parts = ['Hi sir', 'This is a demo message.', 'It could help others to help me, and possbily others too.']
# the below function builds up the nice message based on an html template
text_msg, html_msg, cids, locs = doc_mail_from_template(message_parts)
msg = EmailMessage()
msg.set_content(text_message)
msg.add_alternative(html_msg, subtype='html')
msg['From'] = from_mail
msg['To'] = to_mail
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
# now embed images to the email
for loc, cid in zip(locs, cids):
with open(loc, 'rb') as img:
maintype, subtype = guess_type(img.name)[0].split('/') # know the Content-Type of the image
msg.get_payload()[1].add_related(img.read(), maintype=maintype, subtype=subtype, cid=cid) # attach it
if date_now < '2022-10-01': # before, we could do this
with smtplib.SMTP(server, port) as smtp:
smtp.starttls(context=context)
smtp.login(from_mail, password)
smtp.sendmail(from_mail, [to_mail, ], msg.as_string())
else: # now we must do this
client_id = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx8c5'
client_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxb96'
tenant_id = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxx973'
userId = "levrai@ninjane.er"
authority = f"https://login.microsoftonline.com/{tenant_id}"
scopes = ["https://graph.microsoft.com/.default"]
app = msal.ConfidentialClientApplication(client_id=client_id, client_credential=client_secret, authority=authority)
result = app.acquire_token_silent(scopes, account=None)
if not result:
result = app.acquire_token_for_client(scopes=scopes)
# setup message:
email_msg = {'Message': {'Subject': subject,
'Body': {
'ContentType': 'text/plain', 'Content': e_message.as_string() }, # what do i put here?
'ToRecipients': [{'EmailAddress': {'Address': to_mail}}]
},
'SaveToSentItems': 'true'}
endpoint = f'https://graph.microsoft.com/v1.0/users/{from_user}/sendMail'
r = requests.post(endpoint, json=email_msg,
headers={'Authorization': 'Bearer ' + result['access_token'], "Content-Type": "application/json"})
【问题讨论】:
标签: python email smtp microsoft-graph-api mime-types