Reputation: 27
I'm working on python code to send an email from Outlook using Microsoft Graph API. For this, I have created an Enterprise Application in my Azure Active Directory Tenant. I have granted admin consent for the tenant to the application on Mail.Send permission. I'm able to get the access token for Graph API with the help of this application, but I'm not able to send the mail. Can anyone please help me to understand, what is the issue with my code?
Python Code:
from requests import post
CLIENT_SECRET_VALUE = 'CLIENT_SECRET_VALUE'
TENANT_ID = 'TENANT_ID'
CLIENT_ID = 'CLIENT_ID'
LOGIN_URI = f'https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token'
headers = {
'Host': 'login.microsoftonline.com',
'Content-Type': 'application/x-www-form-urlencoded'
}
body = {
'client_id': CLIENT_ID,
'scope': 'https://graph.microsoft.com/.default',
'client_secret': CLIENT_SECRET_VALUE,
'grant_type': 'client_credentials',
'tenant': TENANT_ID
}
response = post(url=LOGIN_URI, headers=headers, data=body)
response.raise_for_status()
response_body = response.json()
authorization_token = f"{response_body['token_type']} {response_body['access_token']}"
print(authorization_token)
email_header = {
'Authorization': authorization_token,
'Content-Type': 'application/json'
}
message = {
'body': {
'content': 'Outlook Mail Testing Demo',
'contentType': 'Text'
},
'sender': {
'emailAddress': {
'address': '[email protected]',
'name': 'Name of Shared Mailbox'
}
},
'subject': 'Testing email',
'toRecipients': [
{
'emailAddress': {
'address': '[email protected]',
'name': 'Name of person to whom email belongs'
}
}
]
}
email_body = {
'message': message
}
email_send_response = post(url='https://graph.microsoft.com/v1.0/users/me/sendMail', headers=email_header, data=email_body)
email_send_response.raise_for_status()
[N.B.: CLIENT_SECRET_VALUE is getting generated by the enterprise application. TENANT_ID & CLIENT_ID are the tenant and client ids assigned to the application]
On running the code, I'm getting an error:
400 Client Error: Bad Request for url: https://graph.microsoft.com/v1.0/users/me/sendMail
Upvotes: 0
Views: 5097
Reputation: 3575
There are two problems in your code. As I specified the first issue in comments that the URL should be as below as you are using client credential flow.
https://graph.microsoft.com/v1.0/users/{userid/UPN}/sendMail
The second problem I have identified after a long research in python is that the body which you are sening with the API call is not in the format of json. So I have used import json
and method json.dumps
and tested it. Then it worked.
Code:
from requests import post
import json
CLIENT_SECRET_VALUE = 'aX27Q~insds3EvI4z8otRNGHRcCgdjeFOTSpCLPZ'
TENANT_ID = '363147dc-b3be-41a7-af56-f67894ef5a7'
CLIENT_ID = 'e61195e5-7955-4558-9126-37f6cf372d45'
LOGIN_URI = f'https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token'
headers = {
'Host': 'login.microsoftonline.com',
'Content-Type': 'application/x-www-form-urlencoded'
}
body = {
'client_id': CLIENT_ID,
'scope': 'https://graph.microsoft.com/.default',
'client_secret': CLIENT_SECRET_VALUE,
'grant_type': 'client_credentials',
'tenant': TENANT_ID
}
response = post(url=LOGIN_URI, headers=headers, data=body)
response.raise_for_status()
response_body = response.json()
authorization_token = f"{response_body['token_type']} {response_body['access_token']}"
print(authorization_token)
email_header = {
'Authorization': authorization_token,
'Content-Type': 'application/json'
}
message = {
'body': {
'content': 'Outlook Mail Testing Demo',
'contentType': 'Text'
},
'sender': {
'emailAddress': {
'address': '[email protected]',
'name': 'Name of Shared Mailbox'
}
},
'subject': 'Testing email',
'toRecipients': [
{
'emailAddress': {
'address': '[email protected]',
'name': 'Name of person to whom email belongs'
}
}
]
}
email_body = {
'message': message
}
email_send_response = post(url='https://graph.microsoft.com/v1.0/users/1ab4e76f-5f52-44b8-8a72-7d03c05e6ff4/sendMail', headers=email_header, data=json.dumps(email_body))
print(email_send_response)
Upvotes: 5