[英]"BadRequest" error while using SendMail request of Microsoft Graph API
I am writing a python script to send a mail using the Microsoft Graph API.我正在编写一个 python 脚本来使用 Microsoft Graph API 发送邮件。 The mail is sent to only those IDs which exists in our AAD.
邮件仅发送到我们 AAD 中存在的那些 ID。
I wrote the code:我写了代码:
from adal import AuthenticationContext
import adal
import string
import urllib
import json
import requests
import pprint
import base64
import mimetypes
API_VERSION = 'beta'
RESOURCE = 'https://graph.microsoft.com'
TENANT = <my tenant ID>
CLIENTID = <Client ID>
CLIENTSECRET = <sescret>
DOMAIN = <mydomain>
# AUTHENTICATION - get access token and update session header
def get_session():
authority_host_url = 'https://login.windows.net'
tenant = TENANT
authority_url = authority_host_url + '/' + tenant
service_endpoint = "https://graph.microsoft.com/"
client_id = CLIENTID
client_secret = CLIENTSECRET
# Retrieves authentication tokens from Azure Active Directory and creates a new AuthenticationContext object.
context = AuthenticationContext(authority_url, validate_authority=True, cache=None, api_version=None, timeout=300, enable_pii=False)
# Gets a token for a given resource via client credentials.
token_response = context.acquire_token_with_client_credentials(service_endpoint, client_id, client_secret)
# Create a persistent session with the access token
session = requests.Session()
session.headers.update({'Authorization': f'Bearer {token_response["accessToken"]}', 'SdkVersion': 'python-adal', 'x-client-SKU': 'DynaAdmin'})
#session.headers.update({'Authorization': f'Bearer {token_response["accessToken"]}'})
return session
def build_uri(url):
if 'https' == urllib.parse.urlparse(url).scheme:
return url
result = urllib.parse.urljoin(f'{RESOURCE}/{API_VERSION}/', url.lstrip('/'))
print("\nURL:\n")
print(result)
return result
def sendmail(*, session, subject=None, recipients=None, body='',
content_type='HTML', attachments=None):
"""Helper to send email from current user.
session = user-authenticated session for graph API
subject = email subject (required)
recipients = list of recipient email addresses (required)
body = body of the message
content_type = content type (default is 'HTML')
attachments = list of file attachments (local filenames)
Returns the response from the POST to the sendmail API.
"""
# Verify that required arguments have been passed.
if not all([session, subject, recipients]):
raise ValueError('sendmail(): required arguments missing')
# Create recipient list in required format.
recipient_list = [{'EmailAddress': {'Address': address}}
for address in recipients]
# Create list of attachments in required format.
attached_files = []
if attachments:
for filename in attachments:
b64_content = base64.b64encode(open(filename, 'rb').read())
mime_type = mimetypes.guess_type(filename)[0]
mime_type = mime_type if mime_type else ''
attached_files.append( \
{'@odata.type': '#microsoft.graph.fileAttachment',
'ContentBytes': b64_content.decode('utf-8'),
'ContentType': mime_type,
'Name': filename})
# Create email message in required format.
email_msg = {'Message': {'Subject': subject,
'Body': {'ContentType': content_type, 'Content': body},
'ToRecipients': recipient_list,
'Attachments': attached_files},
'SaveToSentItems': 'true'}
print("\nBody:\n")
print(email_msg)
# Do a POST to Graph's sendMail API and return the response.
resp = session.post(build_uri('/users/8368b7b5-b337ac267220/sendMail'), data=email_msg, stream=True, headers={'Content-Type': 'application/json'})
return resp
# ------------ RUN CODE ------------
session = get_session()
myRecipients = "sea.chen@mydomain.com;anj.dy@mydomain.com"
response = sendmail(session=session,
subject= "hai",
recipients=myRecipients.split(';'),
body="hai this is a new mail")
print("\nRequest headers: \n")
print(response.request.headers)
print("\nResponse: \n")
print(response)
print(response.text)
Most likely the body of your POST is not properly formatted. POST正文很可能格式不正确。 When I did this with the
requests
library, I found I needed to set data
like so: 当我使用
requests
库进行此操作时,我发现需要像这样设置data
:
data = json.dumps(email_msg)
The default for data
is to form-encode, not pass as JSON. data
的默认值是表单编码,而不是作为JSON传递。 Have a look at https://docs.microsoft.com/outlook/rest/python-tutorial#contents-of-tutorialoutlookservicepy 看看https://docs.microsoft.com/outlook/rest/python-tutorial#contents-of-tutorialoutlookservicepy
Thanks for sharing this.谢谢你分享这个。 I had different issue when I was trying to get Graph API to send one-on-one chat message to Microsoft Teams.
当我尝试让 Graph API 向 Microsoft Teams 发送一对一聊天消息时,我遇到了不同的问题。 I could run the following code using http.client and get most of the messages posted in chat.
我可以使用 http.client 运行以下代码并获取聊天中发布的大部分消息。
import http.client
headers = {'Content-type':'application/json',
"Authorization": f"Bearer {getGraphAccessToken()}"
}
body = {
"body": {
"contentType": "text",
"charset" : "utf-8",
"content": text
}}
connection = http.client.HTTPSConnection("graph.microsoft.com")
connection.request("POST",f"/v1.0/chats/{chatId}/messages",headers=headers, body = str(body))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.