You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Microsoft Graph API创建Teams会议时遇‘请求负载不能为空’错误

调用Microsoft Graph API创建Teams在线会议时出现400错误:请求负载为空

我尝试用Python调用Microsoft Graph API创建Microsoft Teams在线会议,Azure AD应用已配置委托权限(delegated)OnlineMeetings.ReadWrite,使用/me/onlineMeetings端点创建会议时,持续收到以下错误:

错误:400,{"error":{"code":"General","message":"Request payload cannot be null.","innerError":{"request-id":"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX","date":"2025-01-28T06:03:29","client-request-id":"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"}}}

我的Python代码如下:

import requests

# Azure AD App credentials
CLIENT_ID = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
TENANT_ID = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
CLIENT_SECRET = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}"

# User credentials
USERNAME = "XXXX@example.com"
PASSWORD = "password"


# Authentication
def get_access_token():
    data = {
        "grant_type": "password",
        "client_id": CLIENT_ID,
        "client_secret": CLIENT_SECRET,
        "scope": "https://graph.microsoft.com/.default",
        "username": USERNAME,
        "password": PASSWORD,
    }

    response = requests.post(f"{AUTHORITY}/oauth2/v2.0/token", data=data)

    if response.status_code == 200:
        return response.json().get("access_token")
    else:
        raise Exception(f"Error: {response.status_code}, {response.text}")


def create_teams_meeting():
    try:
        access_token = get_access_token()

        # Prepare the meeting data
        meeting_data = {
            "startDateTime": "2025-01-29T10:00:00",  
            "endDateTime": "2025-01-29T11:00:00",   
            "subject": "Random Meeting",
        }

        # Send the request to create the meeting
        headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
        response = requests.post(
            "https://graph.microsoft.com/v1.0/me/onlineMeetings", 
            headers=headers, 
            json=meeting_data
        )

        if response.status_code == 201:
            meeting = response.json()
            return meeting["joinUrl"]
        else:
            raise Exception(f"Error creating meeting: {response.status_code}, {response.text}")

    except Exception as e:
        print(f"An error occurred: {e}")
        return None

已排查内容:

  • Access Token:令牌生成成功
  • Permissions:确认Azure AD应用已拥有OnlineMeetings.ReadWrite委托权限且已获得管理员同意
  • Payload:meeting_data负载包含startDateTime、endDateTime和subject,符合Microsoft Graph API文档要求
  • Headers:请求已包含Authorization和Content-Type头

问题排查与解决

1. 修正日期时间格式

Microsoft Graph要求日期时间必须是带时区的ISO 8601格式,当前代码中的日期缺少时区信息,可能导致API无法解析负载,进而判定请求体为空。修改日期格式:

meeting_data = {
    "startDateTime": "2025-01-29T10:00:00Z",  # UTC时区,末尾加Z
    "endDateTime": "2025-01-29T11:00:00Z",
    "subject": "Random Meeting",
}

如果需要使用本地时区,可写成"2025-01-29T10:00:00+08:00"(东八区)。

2. 手动序列化JSON请求体

虽然requests.post的json参数会自动序列化,但某些环境下可能出现序列化异常。尝试手动序列化:

import json

# 替换原请求中的json参数为data参数
response = requests.post(
    "https://graph.microsoft.com/v1.0/me/onlineMeetings", 
    headers=headers, 
    data=json.dumps(meeting_data)
)

3. 显式指定权限范围

当前使用的https://graph.microsoft.com/.default范围虽包含已配置权限,但显式指定所需权限可确保令牌包含正确的权限声明:

# 修改get_access_token函数中的scope字段
"data": {
    # ...其他参数
    "scope": "OnlineMeetings.ReadWrite https://graph.microsoft.com/.default",
}

4. 验证请求头正确性

打印请求头确认Content-Type是否被正确设置:

print(headers)

确保输出中包含"Content-Type": "application/json",若被覆盖,可尝试重新设置或检查环境是否有拦截修改请求头的情况。

5. 使用官方SDK简化调用

直接使用requests库容易出现序列化或权限问题,推荐使用Microsoft Graph Python SDK,自动处理请求细节:

from msgraph import GraphServiceClient
from msgraph.generated.models.online_meeting import OnlineMeeting
from azure.identity import UsernamePasswordCredential

CLIENT_ID = "your-client-id"
TENANT_ID = "your-tenant-id"
USERNAME = "your-username"
PASSWORD = "your-password"

# 初始化凭证与客户端
credential = UsernamePasswordCredential(CLIENT_ID, USERNAME, PASSWORD, tenant_id=TENANT_ID)
client = GraphServiceClient(credential, scopes=["OnlineMeetings.ReadWrite"])

# 创建会议对象
meeting = OnlineMeeting(
    start_date_time="2025-01-29T10:00:00Z",
    end_date_time="2025-01-29T11:00:00Z",
    subject="Random Meeting"
)

# 发送请求
result = client.me.online_meetings.post(meeting)
print(result.join_url)

内容的提问来源于stack exchange,提问作者mohannad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 19:04:54