调用Microsoft Graph API的user:sendMail接口时遇500内部服务器错误
Microsoft Graph API sendMail 500内部服务器错误排查求助
错误信息
向https://graph.microsoft.com/v1.0/users/myemail@contoso.com/sendMail发送POST请求时,收到500内部服务器错误,响应如下:
JSON Response {'error': {'code': 'ErrorInternalServerError', 'message': 'An internal server error occurred. The operation failed.'}} SystemExit: 500 Server Error: Internal Server Error for url: https://graph.microsoft.com/v1.0/users/myemail@contoso.com/sendMail
相关情况
- 使用相同认证方式访问
https://graph.microsoft.com/v1.0/users/端点功能正常; - 相同的JSON数据在Graph Explorer中可正常发送邮件;
- 在Entra ID的「监控与健康>审核日志」中无法找到相关日志。
附代码
import json import msal import requests ''' Sjabloonscript 26-9-23 Graph API Zie https://developer.microsoft.com/en-us/graph/graph-explorer voor typen eindpunten ''' #send from? versturende_email = "myemail@contoso.com" #demomode? demo = True #config config = { "client_id": "------", "scope": ["https://graph.microsoft.com/.default"], "secret": "SECRETHERE", "tenant-id": "tenid", "authority": 'https://login.microsoftonline.com/-----', "eindpunt": 'https://graph.microsoft.com/v1.0/users/'+versturende_email+'/sendMail' } def O365_toegangstoken(): ''' Haal toegangstoken op met je app registratie , let op de duur van de token ''' #Get token scopes = ["https://graph.microsoft.com/.default"] app = msal.ConfidentialClientApplication( config["client_id"], authority=config["authority"], client_credential=config["secret"], ) # Since MSAL 1.23, acquire_token_for_client(...) will automatically look up # a token from cache, and fall back to acquire a fresh token when needed. resultaat = app.acquire_token_for_client(scopes=config["scope"]) #check if token was returned if "access_token" in resultaat: toegangstoken = 'Bearer ' + resultaat['access_token'] return toegangstoken else: print(result.get("error")) print(result.get("error_description")) print(result.get("correlation_id")) # Nodig voor als je een bug wil rapporteren raise Exception("Tokenerrrrror") def main(): #get token token = O365_toegangstoken() #headers hoofd = { 'Authorization': token } #de toegangstoken is goed gegenereerd #generate mail json mailbericht = {} html = """ <html> <head></head> <body> <p>Beste {0},<br><br> blablatestmessage {2}{3} <b>Let op!</b> blablabla <br><br> <i>Dit betreft een automatisch gegenereerd bericht</i> <br><br> Met vriendelijke groet, <br><br> Automatisering. </p> {4} </body> </html> """.replace("\n", "") mailbericht["message"] = { 'subject' : 'Hallo', 'body' : { 'contentType' : 'HTML', 'content' : html } } mailbericht["message"]['toRecipients'] = [] mailbericht["message"]['toRecipients'].append({'emailAddress': { "address": naar }}) #print json and header? if demo: print("{0}\n{0}Header{0}\n{2}\n{0}\n{1}\n{0}".format("-"*50,json.dumps(mailbericht,indent=5),hoofd)) try: #post to graph r = requests.post(url= config["eindpunt"], headers=hoofd, json = json.dumps(mailbericht)) r.raise_for_status() #error handling except requests.exceptions.HTTPError as err: print("Status Code", r.status_code) print("JSON Response ", r.json()) raise SystemExit(err) #non-error handling print("Status Code", r.status_code) print("JSON Response ", r.json()) main()
排查建议
1. 修复请求体传递方式
代码中使用json = json.dumps(mailbericht)传递请求体是错误的:requests库的post方法的json参数接受Python字典,会自动将其序列化为JSON字符串并设置Content-Type: application/json头。手动转成字符串会导致Graph API无法正确解析请求体,引发内部错误。
修改为:
r = requests.post(url=config["eindpunt"], headers=hoofd, json=mailbericht)
2. 检查未定义变量naar
代码中"address": naar里的naar变量未定义,这会导致请求体缺失收件人信息,引发错误。请确保naar变量已被赋值为有效的收件人邮箱地址。
3. 启用请求调试日志
添加以下代码到脚本中,查看实际发送的请求头和请求体,对比Graph Explorer的请求内容,定位差异:
import logging import http.client http.client.HTTPConnection.debuglevel = 1 logging.basicConfig() logging.getLogger().setLevel(logging.DEBUG) requests_log = logging.getLogger("requests.packages.urllib3") requests_log.setLevel(logging.DEBUG) requests_log.propagate = True
4. 确认应用权限配置
确保应用注册已添加Mail.Send应用权限(或委托权限,根据认证方式),且已获得管理员同意。虽然users端点能访问,但sendMail需要特定权限。
5. 获取Correlation ID
检查响应头中的Correlation-ID字段(可通过调试日志查看),该ID可用于向微软支持查询详细错误原因,或在Graph API的日志系统中定位问题。
内容的提问来源于stack exchange,提问作者Zr.Ms. Bruinvis
相关产品推荐
相关产品推荐

